///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAVLIndexEntry.cc
// -----------------
// Cego index entry class implementation
//     
// 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.
//
// IMPLEMENTATION MODULE
//
// Class: CegoAVLIndexEntry
// 
// Description: Implementation of tree entry for full balanced AVL index trees
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfc/Exception.h>

// cego includes
#include "CegoAVLIndexEntry.h"

#include <string.h>
#include <stdlib.h>

CegoAVLIndexEntry::CegoAVLIndexEntry()
{
    _pI = 0;
    _len = 0;
    _isLocal = false;
    _tid = 0;
}

CegoAVLIndexEntry::CegoAVLIndexEntry(int tid)
{
    _pI = 0;
    _len = 0;
    _isLocal = false;
    _tid = tid;
}

CegoAVLIndexEntry::~CegoAVLIndexEntry()
{
    if (_isLocal)
    {
	free (_pI);
    }
}

void CegoAVLIndexEntry::initEntry(const CegoDataPointer& dp, char* idxPtr, int idxLen)
{
    
    if (_isLocal)
	free (_pI);

    CegoDataPointer zp(0,0,0);

    _len = 4 * zp.getEncodingLength() + sizeof(char) + sizeof(int) + idxLen;

    _pI = malloc(_len);

    if (_pI == 0 )
    {
	throw Exception(EXLOC, Chain("Cannot allocate index entry"));
    }

    _isLocal = true;

    setParent(zp);
    setLeftBranch(zp);
    setRightBranch(zp);
    setData(dp);
    setHeight(0);
    setTID(_tid);
    
    _idxDataPtr =  (char*)((long)_pI + _len - idxLen);
    memcpy(_idxDataPtr, idxPtr, idxLen);
}

void CegoAVLIndexEntry::setPtr(void* p, int len)
{
    _isLocal = false;
    _pI = p;
    _len = len;
    CegoDataPointer dp;
    _idxDataPtr = (char*)((long)_pI + 4 * dp.getEncodingLength() + sizeof(char) + sizeof(int));
}

void* CegoAVLIndexEntry::getPtr()
{
    return _pI;
}

int CegoAVLIndexEntry::getLen() const
{
    return _len;
}
   
void CegoAVLIndexEntry::setParent(const CegoDataPointer& dp)
{
    dp.encode(_pI);
}

CegoDataPointer CegoAVLIndexEntry::getParent() const
{
    CegoDataPointer dp;
    dp.decode(_pI);
    return dp;
}

void CegoAVLIndexEntry::setLeftBranch(const CegoDataPointer& dp)
{
    dp.encode((void*) ((long)_pI + (long)dp.getEncodingLength()));    
}

CegoDataPointer CegoAVLIndexEntry::getLeftBranch() const
{
    CegoDataPointer dp;
    dp.decode((void*) ((long)_pI + (long)dp.getEncodingLength()));
    return dp;    
}

void CegoAVLIndexEntry::setRightBranch(const CegoDataPointer& dp)
{
    dp.encode((void*) ((long)_pI + 2 * (long)dp.getEncodingLength())); 
}

CegoDataPointer CegoAVLIndexEntry::getRightBranch() const
{
    CegoDataPointer dp;
    dp.decode((void*) ((long)_pI + 2 * (long)dp.getEncodingLength()));
    return dp;
}

void CegoAVLIndexEntry::setData(const CegoDataPointer& dp)
{
    dp.encode((void*) ((long)_pI + 3 * (long)dp.getEncodingLength()));
}

CegoDataPointer CegoAVLIndexEntry::getData() const
{
    CegoDataPointer dp;
    dp.decode((void*) ((long)_pI + 3 * (long)dp.getEncodingLength()));
    return dp;
}

char* CegoAVLIndexEntry::getIdxPtr()
{
    return _idxDataPtr;
}

int CegoAVLIndexEntry::getIdxLen()
{
    CegoDataPointer dp;
    return _len - 4 * dp.getEncodingLength() + sizeof(char) + sizeof(int);
}

void CegoAVLIndexEntry::setHeight(char h)
{   
    CegoDataPointer dp;
    char* p = (char*)((long)_pI +  4 * dp.getEncodingLength() );
    *p = h;
}

char CegoAVLIndexEntry::getHeight() const
{
    CegoDataPointer dp;
    char h = *((char*)((long)_pI +  4 * dp.getEncodingLength() ));
    return (h);
}

void CegoAVLIndexEntry::setTID(int tid)
{
    CegoDataPointer dp;
    void* pTid = (int*)((long)_pI + 4 * dp.getEncodingLength() + sizeof(char));
    memcpy(pTid, &tid, sizeof(int));
}

int CegoAVLIndexEntry::getTID() const
{
    CegoDataPointer dp;
    void* pTid = (void*)((long)_pI + 4 * dp.getEncodingLength() + sizeof(char));
    int tid;
    memcpy(&tid, pTid, sizeof(int));
    return (tid);
}

CegoAVLIndexEntry& CegoAVLIndexEntry::operator = (const CegoAVLIndexEntry& ie)
{
    _pI = ie._pI;
    _len = ie._len;
    _idxDataPtr = ie._idxDataPtr;
    return (*this);
}

