///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoProcCond.cc  
// ---------------
// Cego procedure condition class implementation
//                                                         
// 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: CegoProcCond
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

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

// cego includes
#include "CegoProcCond.h"

CegoProcCond::CegoProcCond()
{

}

CegoProcCond::CegoProcCond(CegoProcCond *pCond, CegoProcPred *pPred, CegoProcCond::ConditionMode mode)
{
    _mode = mode;
    _pCond = pCond;
    _pPred = pPred;
}

CegoProcCond::CegoProcCond(CegoProcPred *pPred)
{
    _mode = PRED;
    _pCond = 0;
    _pPred = pPred;
}

CegoProcCond::~CegoProcCond()  
{
    if ( _pCond )
	delete _pCond;
    if ( _pPred )
	delete _pPred;
}

void CegoProcCond::setBlock(CegoProcBlock *pBlock)
{
    if ( _pCond ) 
	_pCond->setBlock(pBlock);
    if ( _pPred )
	_pPred->setBlock(pBlock);	
}

bool CegoProcCond::eval() const
{

    switch ( _mode )
    {
    case AND:
    {
	return _pCond->eval() && _pPred->eval();
	break;
    }
    case OR:
    {
	return _pCond->eval() || _pPred->eval();
	break;
    }
    case PRED:
	return _pPred->eval();
	break;
    }

}

CegoProcCond& CegoProcCond::operator = (const CegoProcCond& c)
{
    _mode = c._mode;
    _pCond = c._pCond;
    _pPred = c._pPred;
    return (*this);
}

Chain CegoProcCond::toChain() const
{
    Chain s;

    switch ( _mode )
    {
    case AND:
    {
	s = _pCond->toChain() + " and " + _pPred->toChain();
	break;
    }
    case CegoProcCond::OR:
    {
	s = _pCond->toChain() + " or " + _pPred->toChain();
	break;
    }
    case CegoProcCond::PRED:
    {
	s = _pPred->toChain();
    }
    }
    
    return s;
}

ostream& operator << (ostream& s, const CegoProcCond& e)
{
    switch ( e._mode )
    {
    case CegoProcCond::AND:
    {
	s << *(e._pCond) << " and " << *(e._pPred);
	break;
    }
    case CegoProcCond::OR:
    {
	s << *(e._pCond) << " or " << *(e._pPred);
	break;
    }
    case CegoProcCond::PRED:
    {
	s << *(e._pPred);
    }
    }
    return s;
}
