#ifndef _CEGOFUNCTION_H_INCLUDED_
#define _CEGOFUNCTION_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoFunction.h
// --------------
// Cego internal sql function class definition
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoFunction
// 
// Description: All internal SQL database functions
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

#include <lfcbase/Chain.h>
#include <lfcbase/ListT.h>

#include "CegoAttrDesc.h"
#include "CegoField.h"
#include "CegoFieldValue.h"
#include "CegoProcBlock.h"

class CegoProcedure;
class CegoQueryManager;
class CegoTableManager;
class CegoAggregation;
class CegoExpr;
class CegoDatabaseFormater;

class CegoFunction {
    
public:
    
    enum FunctionType { INT2ASC,
			ASC2INT,
			TRIM, 
			RTRIM,
			LTRIM,
			ROUND,
			DATE2STR, 
			DATE2LONG, 
			LONG2DATE,
			NEWDATE,
			LEFT,
			RIGHT,
			GETCOUNT,
			GETPOS,
			SUBSTR,
			REPLACE,
			REGMATCH,
			LENGTH,
			LOWER,
			UPPER,
			TRUNC,
			SCANDATE, 
			STR2INT,
			STR2LONG,
			RANDSTR,
			RANDINT,
			MOD,
			DIV,
			LMOD,
			LDIV,
			POWER,
			BITAND,
			BITOR,
			BITXOR,
			BLOBSIZE,
			BLOBREF,
			CLOBSIZE,
			CLOBREF,
			CLOB2STR,
			NEXTCOUNT,
			SETCOUNT,
			USERDEFINED };
    
    CegoFunction(FunctionType funcType);
    CegoFunction(FunctionType funcType, ListT<CegoExpr*>& exprList);
    CegoFunction(char* buf);
    CegoFunction(CegoQueryManager* pTabMng, unsigned tabSetId, CegoFunction::FunctionType type);
    CegoFunction(CegoQueryManager* pTabMng, unsigned tabSetId, const Chain& funcName, ListT<CegoExpr*>& exprList);
    
    ~CegoFunction();

    void cleanUp();

    void setQueryManager(CegoQueryManager* pTabMng);
    void setTabSetId(unsigned tabSetId);
    
    unsigned getTabSetId() const;
    Chain getName() const;
	
    CegoDataType getReturnType();
    unsigned getReturnTypeLen(const ListT<CegoField>& fl);
    unsigned getReturnTypeDim();

    ListT<CegoExpr*>& getExprList();
    void getFieldList(ListT<CegoField>& fl, ListT<CegoField>** pFLA) const;
    
    const FunctionType getType() const;

    void setExprList(ListT<CegoExpr*>& exprList);

    void clearAttrCache();

    ListT<CegoAttrDesc*> getAttrRefList() const;
    unsigned evalReferences(CegoContentObject *pCO, const ListT<CegoField>& fl);

    void setCounterId(const Chain& counterId);
    void setCounterExpr(CegoExpr* pCounterExpr);

    ListT<CegoAggregation*> getAggregationList();
    
    CegoFieldValue evalFieldValue(ListT<CegoField>** pFLA, CegoProcBlock *pBlock);
    
    Chain getId(CegoProcBlock *pBlock) const;
    Chain toChain(unsigned defTabSetId, const Chain& indent = Chain("")) const;
    Chain dbFormat(CegoDatabaseFormater *pForm) const;
    
    void encode(char *buf, CegoProcBlock* pBlock);
    void decode(char *buf);
    unsigned getEncodingLength(CegoProcBlock* pBlock = 0) const;

    CegoFunction* clone(bool isAttrRef = false);

    CegoFunction& operator = ( const CegoFunction& f);

    friend ostream& operator << (ostream& s, const CegoFunction& f);

    CegoFunction* map(const Chain& viewAlias, const ListT<CegoExpr*>& exprList) const;
    
private:

    CegoProcedure* loadProcedure(unsigned tabSetId, const Chain& procName) const;
  
    CegoQueryManager* _pTabMng;
    CegoProcedure* _pProc;	    
    Chain _funcName;
    Chain _counterId;  
    FunctionType _type;
    ListT<CegoExpr*> _exprList;
    unsigned _tabSetId;
};
#endif
