///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoTriggerObject.cc 
// --------------------
// Cego trigger object entry implementation
//     
// Design and Implementation by Bjoern Lemke               
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoTriggerObject
//
// Description: Derived class from CegoDecodable to use as a container class for trigger objects
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// CEGO INCLUDES
#include "CegoTriggerObject.h"
#include "CegoXMLdef.h"

// LFC INCLUDES
#include <string.h>
#include <stdlib.h>

CegoTriggerObject::CegoTriggerObject()
{
}

CegoTriggerObject::CegoTriggerObject(const CegoTriggerObject& to) : CegoDecodableObject(to)
{   
    _tabName = to._tabName;
    _triggerText = to._triggerText;
}

CegoTriggerObject::CegoTriggerObject(ObjectType type, const Chain& objName, unsigned tabSetId) : CegoDecodableObject(type, objName, tabSetId)
{
}

CegoTriggerObject::CegoTriggerObject(unsigned tabSetId,
				     const Chain& triggerName,
				     bool isBefore,
				     bool isOnInsert,
				     bool isOnUpdate,
				     bool isOnDelete,				     
				     const Chain& tabName, const Chain& triggerText) : CegoDecodableObject(CegoObject::TRIGGER, triggerName, tabSetId)
{
    _triggerText = triggerText;
    _isBefore = isBefore;
    _isOnInsert = isOnInsert;
    _isOnUpdate = isOnUpdate;
    _isOnDelete = isOnDelete;
    _tabName = tabName;
}

CegoTriggerObject::~CegoTriggerObject()
{
}

void CegoTriggerObject::setBefore(bool isBefore)
{
    _isBefore = isBefore;
}

bool CegoTriggerObject::isBefore() const
{
    return _isBefore;
}

void CegoTriggerObject::setOnInsert(bool isOnInsert)
{
    _isOnInsert = isOnInsert;
}

bool CegoTriggerObject::isOnInsert() const
{
    return _isOnInsert;
}

void CegoTriggerObject::setOnUpdate(bool isOnUpdate)
{
    _isOnUpdate = isOnUpdate;
}

bool CegoTriggerObject::isOnUpdate() const
{
    return _isOnUpdate;
}

void CegoTriggerObject::setOnDelete(bool isOnDelete)
{
    _isOnDelete = isOnDelete;
}

bool CegoTriggerObject::isOnDelete() const
{
    return _isOnDelete;
}

void CegoTriggerObject::setTabName(const Chain& tabName)
{
    _tabName = tabName;
}

const Chain& CegoTriggerObject::getTabName() const
{
    return _tabName;
}
  
void CegoTriggerObject::setTriggerText(const Chain& triggerText)
{
    _triggerText = triggerText;
}

const Chain& CegoTriggerObject::getTriggerText() const
{
    return _triggerText;
}

unsigned CegoTriggerObject::getEntrySize() const
{
    unsigned entrySize = CegoObject::getBaseSize();

    entrySize += 4; // isBefore + isOnInsert + isOnUpdate + isOnDelete
    entrySize += 1; // object tabname size
    entrySize += _tabName.length();

    entrySize += _triggerText.length() + 1;
    
    return entrySize;
}

void CegoTriggerObject::encode(char *buf) const
{
    char* bufPtr = buf;

    unsigned entrySize = getEntrySize();

    CegoObject::encodeBase(bufPtr, entrySize);
    bufPtr += CegoObject::getBaseSize();

    char c;

    c = _isBefore;
    memcpy (bufPtr, &c , 1);
    bufPtr++;

    c = _isOnInsert;    
    memcpy (bufPtr, &c , 1);
    bufPtr++;

    c = _isOnUpdate;
    memcpy (bufPtr, &c , 1);
    bufPtr++;

    c = _isOnDelete;
    memcpy (bufPtr, &c , 1);
    bufPtr++;

    c = (char)_tabName.length();
    memcpy (bufPtr, &c , 1);
    bufPtr++;

    memcpy(bufPtr, (char*)_tabName, _tabName.length());    
    bufPtr=bufPtr + _tabName.length();
    
    memcpy (bufPtr, (char*)_triggerText , _triggerText.length() + 1);   
}

void CegoTriggerObject::decode(char *buf)
{
    char* bufPtr = buf;

    unsigned size;

    CegoObject::decodeBase(bufPtr, size);
    bufPtr += CegoObject::getBaseSize();

    char c;
    memcpy (&c, bufPtr, 1);
    _isBefore = c;
    bufPtr++;

    memcpy (&c, bufPtr, 1);
    _isOnInsert = c;
    bufPtr++;

    memcpy (&c, bufPtr, 1);
    _isOnUpdate = c;
    bufPtr++;

    memcpy (&c, bufPtr, 1);
    _isOnDelete = c;
    bufPtr++;

    // tablename len
    bufPtr++;
    
    _tabName =  Chain(bufPtr);    
    bufPtr=bufPtr + _tabName.length();

    _triggerText = Chain(bufPtr);
}

CegoTriggerObject& CegoTriggerObject::operator = ( const CegoTriggerObject& to)
{
    CegoObject::operator=(to);

    _isBefore = to._isBefore;
    _isOnInsert = to._isOnInsert;
    _isOnUpdate = to._isOnUpdate;
    _isOnDelete = to._isOnDelete;
    _tabName = to._tabName;
    _triggerText = to._triggerText;
    return (*this);
}

bool CegoTriggerObject::operator == ( const CegoTriggerObject& to)
{
    return CegoObject::operator==(to);
}

Chain CegoTriggerObject::toChain() const
{
    Chain s;
    s = Chain("trigger ") + getName() + Chain(" ");

    if ( _isBefore )
	s += Chain("before ");
    else
	s += Chain("after ");

    if ( _isOnInsert )
	s += Chain("insert ");
    if ( _isOnUpdate )
    {
	if ( _isOnInsert )
	    s += Chain("or ");
	s += Chain("update ");
    }
    if ( _isOnDelete )
    {
	if ( _isOnInsert || _isOnUpdate )
	    s += Chain("or ");		
	s += Chain("delete");
    }
    
    s += Chain("on ") + _tabName;

    s += Chain("\n");
    s += Chain("begin\n");
    s += _triggerText;    
    s += Chain("end");
    return s;    
}

Chain CegoTriggerObject::getInfo() const
{
    Chain s;
    s = Chain("Trigger=")+ toChain() + Chain("\n");
    return s;
}
