///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAttrDesc.cc
// ---------------
// Cego database table attribute description
//      
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2010 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: CegoAttrDesc
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

#include "CegoAttrDesc.h"
#include "CegoXMLdef.h"

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

CegoAttrDesc::CegoAttrDesc()
{
    _isValid = false;
}

CegoAttrDesc::CegoAttrDesc(const Chain& attrName)
{
    _attrName = attrName;
    _isValid = false;
}

CegoAttrDesc::CegoAttrDesc(Element *pADE)
{
    fromElement(pADE);
    _isValid = false;
}

CegoAttrDesc::CegoAttrDesc(const Chain& tableName, const Chain& attrName, bool isValid)
{
    _tableName = tableName;
    _attrName = attrName;
    _isValid = isValid;
}
 
CegoAttrDesc::~CegoAttrDesc()
{
}

void CegoAttrDesc::setAttrName(const Chain& attrName)
{
    _attrName = attrName;
}

const Chain& CegoAttrDesc::getAttrName() const
{
    return _attrName;
}

void CegoAttrDesc::setTableName(const Chain& tableName)
{
    _tableName = tableName;
}

const Chain& CegoAttrDesc::getTableName() const
{
    return _tableName;
}

void CegoAttrDesc::setValid(bool isValid)
{
    _isValid = isValid;
}

bool CegoAttrDesc::isValid() const
{
    return _isValid;
}

CegoAttrDesc* CegoAttrDesc::clone() const
{
    return ( new CegoAttrDesc(_tableName, _attrName, _isValid) );
}

CegoAttrDesc& CegoAttrDesc::operator = ( const CegoAttrDesc& ad )
{
    _tableName = ad._tableName;
    _attrName = ad._attrName;
    _isValid = ad._isValid;
    return (*this);
}

bool CegoAttrDesc::operator == ( const CegoAttrDesc& ad)
{    
    if (_tableName == ad._tableName && _attrName == ad._attrName)
	return true;
    return false;
}

bool CegoAttrDesc::operator != ( const CegoAttrDesc& ad)
{    
    if (_tableName == ad._tableName && _attrName == ad._attrName)
	return false;
    return true;
}

Chain CegoAttrDesc::toChain() const
{
    Chain s;
    if ( _tableName.length() == 0 )
	s = _attrName;
    else
	s = _tableName + "." + _attrName;
    return s;
}


Element* CegoAttrDesc::toElement() const
{
    Element *pAttrDescElement = new Element( XML_ATTRDESC_ELEMENT );
    pAttrDescElement->setAttribute( XML_TABLENAME_ATTR, _tableName );
    pAttrDescElement->setAttribute( XML_ATTRNAME_ATTR, _attrName );
    return pAttrDescElement;
}

void CegoAttrDesc::fromElement(Element *pAttrDescElement)
{
    _tableName = pAttrDescElement->getAttributeValue(XML_TABLENAME_ATTR);
    _attrName = pAttrDescElement->getAttributeValue(XML_ATTRNAME_ATTR);
}

void CegoAttrDesc::encode(char *buf)
{
    
    char* pE = (char*)buf;

    char len = _tableName.length();

    if ( len == 0 )
    {
	
	memcpy( pE, &len, sizeof(char));
	pE = pE + sizeof(char);

	len = _attrName.length();

	memcpy( pE, &len, sizeof(char));
	pE = pE + sizeof(char);

	memcpy( pE, (char*)_attrName, len);
	pE = pE + len;

    }
    else
    {
	memcpy( pE, &len, sizeof(char));
	pE = pE + sizeof(char);

	memcpy( pE, (char*)_tableName, len);
	pE = pE + len;

	len = _attrName.length();

	memcpy( pE, &len, sizeof(char));
	pE = pE + sizeof(char);
	
	memcpy( pE, (char*)_attrName, len);
	pE = pE + len;

    }
}


void CegoAttrDesc::decode(char *buf)
{

    char* pE = (char*)buf;

    char len;
    
    memcpy( &len, pE, sizeof(char));
    pE = pE + sizeof(char);

    if ( len == 0 )
    {
	_tableName = Chain();
	memcpy( &len, pE, sizeof(char));
	pE = pE + sizeof(char);
	_attrName = Chain(pE, len-1);
    }
    else
    {
	_tableName = Chain(pE, len-1);
	pE = pE + len;
	memcpy( &len, pE, sizeof(char));
	pE = pE + sizeof(char);
	_attrName = Chain(pE, len-1);
	pE = pE + len;
    }
}

int CegoAttrDesc::getEncodingLength() const
{

    int len = 0;
    
    len += sizeof(char);
    len += _tableName.length();

    len += sizeof(char);
    len += _attrName.length();

    return len;
}

int CegoAttrDesc::evalReferences(CegoContentObject *pCO, const ListT<CegoField>& fl)
{
    int refCount = 0;

    if ( _tableName == (Chain)pCO->getTabName() || ( _tableName == (Chain)pCO->getTabAlias() && _tableName != Chain()) )
    {
	_tableName = pCO->getName();
	refCount++;
    }
    else if ( _tableName == Chain() ) // || pCO->getType() == CegoObject::JOIN )
    {
	CegoField* pF = fl.First();
	while (pF)
	{
	    if (_attrName == (Chain)pF->getAttrName())
	    {
		// _tableName = pF->getTableName();
		// cout << "Set table to " << pF->getTableAlias() << endl;
		_tableName = pF->getTableAlias();
		refCount++;
		// _tableName = pCO->getName();
	    }	
	    pF = fl.Next();	    
	}
    }
    return refCount;

}

ostream& operator << (ostream& s, const CegoAttrDesc& a)
{
    s <<  a._tableName << "." << a._attrName;
    return s;
}


