#ifndef _CEGOBTREENODE_H_INCLUDED_
#define _CEGOBTREENODE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoBTreeNode.h
// ---------------
// BTree node class definition
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 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, unsigned len);
    void* getPtr();
    unsigned getLen() const;

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

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

    void initNode();

    unsigned numEntries() const;

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

    void setSchema(NodeType nt, ListT<CegoField>* pSchema, unsigned keyLen);
    
    bool valueExists(const CegoBTreeValue& iv, CegoObjectManager *pOM, unsigned tabSetId, unsigned long long tid) const;

    bool addValue(const CegoBTreeValue& iv, const CegoDataPointer& dp);
    bool deleteValue(const CegoBTreeValue& iv, const CegoDataPointer& dp);
    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(unsigned tabSetId, CegoObjectManager *pOM);
	
    void dump(Chain &chainDump, unsigned level = 0);
    
    void reset();
    void setPosition(unsigned pos);
    bool nextChildPointer(PageIdType &pageId);

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

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

    bool rightChild(CegoBTreeValue& val);

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

private:

    bool isTupleVisible(CegoObjectManager* pOM, const CegoDataPointer &dp, unsigned tabSetId, unsigned long long tid) const;

    void sortSchema();    
    
    // offset can be < 0
    void shiftEntries(unsigned pos, int offset);
    unsigned getEntrySize() const;

    Chain levelIndent(unsigned level);

    PageIdType _pageId;
    PageIdType _nextPageId;

    ListT<CegoField>* _pSchema;

    ListT<CegoField> _sortFL;
    
    unsigned _keyLen;
    unsigned _entrySize;
    unsigned _maxEntries;
    NodeType _nt;
    void* _pI;
    unsigned _len;

    char* _pNextChild;
};
#endif
