#ifndef _CEGOBTREENODE_H_INCLUDED_
#define _CEGOBTREENODE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoBTreeNode.h
// ---------------
// BTree node class definition
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2019 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoBTreeNode
// 
// Description: This class handles operations on btree elements.
//              These elements either can be nodes or leafs and depending on the type, the corresponding methods are available.
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// LFC INCLUDES
#include <lfcbase/ListT.h>

// CEGO INCLUDES
#include "CegoDefs.h"
#include "CegoField.h"
#include "CegoBTreeValue.h"
#include "CegoDataPointer.h"
#include "CegoObjectManager.h"

class CegoBTreeNode {
    
public:
    
    enum NodeType { UNDEFINED, NODE, LEAF };
    
    CegoBTreeNode();
    ~CegoBTreeNode();
    
    const NodeType getType() const;

    void setPtr(void* p, int len);
    void* getPtr();
    int getLen() const;

    void setPageId(PageIdType pageId);
    PageIdType getPageId() const;

    void setNextPageId(PageIdType pageId);
    PageIdType getNextPageId() const;

    void initNode();

    int numEntries() const;

    void getChildPage(const CegoBTreeValue& iv, PageIdType& pageId, bool traceMin);

    void setSchema(NodeType nt, ListT<CegoField>* pSchema, int keyLen);

    bool valueExists(const CegoBTreeValue& iv, CegoObjectManager *pOM, int tabSetId, unsigned long long tid) const;

    bool addValue(const CegoBTreeValue& iv, const CegoDataPointer& dp);
    bool deleteValue(const CegoBTreeValue& iv, const CegoDataPointer& dp);
    // bool valueExists(const CegoBTreeValue& iv);
    bool addNode(const CegoBTreeValue& iv, const CegoBTreeNode& node);
    bool propagate(const CegoBTreeValue& iv, const CegoBTreeNode& leftNode, const CegoBTreeNode& rightNode);

    void split(CegoBTreeNode& n);

    CegoBTreeValue getMin() const;
    CegoBTreeValue getMax() const;

    void incEntries();
    void decEntries();

    CegoBTreeNode& operator = (const CegoBTreeNode& n);

    bool verify();
    bool verifyLeafFull(int tabSetId, CegoObjectManager *pOM);
	
    void printNode(int level = 0);
    
    void reset();
    void setPosition(int pos);
    bool nextChildPointer(PageIdType &pageId);

    int getMedPage(int lb, int rb, PageIdType& pageId);
    bool rightValue(int pos, CegoBTreeValue& val);

    void getLastChildPointer(PageIdType &pageId) const;
    void setFirstChildPointer(PageIdType pageId);

    bool rightChild(CegoBTreeValue& val);

    void getValue(int pos, CegoBTreeValue& val, CegoDataPointer& dp);    
    bool nextValue(CegoBTreeValue& val, CegoDataPointer& dp);    

private:

    bool isTupleVisible(CegoObjectManager* pOM, const CegoDataPointer &dp, int tabSetId, unsigned long long tid) const;
    
    void shiftEntries(int pos, int offset);
    int getEntrySize() const;

    Chain levelIndent(int level);

    PageIdType _pageId;
    PageIdType _nextPageId;

    ListT<CegoField>* _pSchema;
    int _keyLen;
    int _entrySize;
    int _maxEntries;
    NodeType _nt;
    void* _pI;
    int _len;

    char* _pNextChild;
};

#endif
