#ifndef _CEGOBTREENODE_H_INCLUDED_
#define _CEGOBTREENODE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoBTreeNode.h
// ---------------
// BTree node class definition
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2013 Bjoern Lemke
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// 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: 2.16
//
///////////////////////////////////////////////////////////////////////////////

// lfc includes
#include <lfc/ListT.h>

// cego includes
#include "CegoField.h"
#include "CegoBTreeValue.h"
#include "CegoDataPointer.h"

class CegoBTreeNode {

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

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

    void setFileId(int fileId);
    int getFileId() const;

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

    void setNextFileId(int fileId);
    int getNextFileId() const;

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

    void initNode();

    int maxEntries();
    int numEntries();

    void getChildPage(const CegoBTreeValue& iv, int& fileId, int& pageId);

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

    bool addValue(const CegoBTreeValue& iv, const CegoDataPointer& dp, const Chain& btreeName, bool isUnique = false);
    bool deleteValue(const CegoBTreeValue& iv, const CegoDataPointer& dp);
    bool addNode(const CegoBTreeValue& iv, const CegoBTreeNode& node);

    void split(CegoBTreeNode& n);

    CegoBTreeValue getMin();
    CegoBTreeValue getMax();

    void incEntries();
    void decEntries();

    bool propagate(const CegoBTreeValue& iv, const CegoBTreeNode& leftNode, const CegoBTreeNode& rightNode);

    CegoBTreeNode& operator = (const CegoBTreeNode& n);

    void printNode(int level = 0);    
    
    void reset();
    bool nextChildPointer(int& fileId, int &pageId);

    bool rightChild(CegoBTreeValue& val);

    bool nextValue(CegoBTreeValue& val, CegoDataPointer& dp);    

 private:

    void shiftEntries(int pos, int offset);
    int getEntrySize() const;

    Chain levelIndent(int level);

    int _fileId;
    int _pageId;

    int _nextFileId;
    int _nextPageId;

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

    char* _pNextChild;
};

#endif
