#ifndef _CEGOFIELDVALUE_H_INCLUDED_
#define _CEGOFIELDVALUE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoFieldValue.h
// ----------------
// Field value implementation
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2019 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoFieldValue
//
// Description: Data field value which can contain all supported data types
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// LFC INCLUDES
#include <lfcbase/Chain.h>

// CEGO INCLUDES
#include "CegoDefs.h"
#include "CegoDataType.h"

class CegoDatabaseFormater;

class CegoFieldValue {
    
public:

    enum Comparison { LESS, EQUAL, MORE };
    
    CegoFieldValue();
    CegoFieldValue(const CegoFieldValue& fv);
    CegoFieldValue(CegoDataType type, void* pValue, int len, bool isLocalCopy = false);
    CegoFieldValue(CegoDataType type, const Chain& v);

    ~CegoFieldValue();

    void setNull();
    
    const CegoDataType& getType() const;
    void setType(const CegoDataType t);

    int getDim() const;
    
    void* getValue() const;
    int getLength() const;

    bool castTo(CegoDataType t, int d = MAX_CAST);

    void setValue(void* pV);
    void setLength(int l);

    CegoFieldValue& operator = ( const CegoFieldValue& f);
    bool operator == ( const CegoFieldValue& f) const;
    bool operator != ( const CegoFieldValue& f) const;
    bool operator < ( const CegoFieldValue& fv) const;
    bool operator > ( const CegoFieldValue& fv) const;
    bool operator <= ( const CegoFieldValue& fv) const;
    bool operator >= ( const CegoFieldValue& fv) const;

    Comparison comp(const CegoFieldValue& fv) const;
    static Comparison fastComp( CegoDataType t1, void* pV1, int l1, CegoDataType t2, void* pV2, int l2 );
    
    friend CegoFieldValue operator + ( const CegoFieldValue& fv1, const CegoFieldValue& fv2);
    friend CegoFieldValue operator - ( const CegoFieldValue& fv1, const CegoFieldValue& fv2);
    friend CegoFieldValue operator * ( const CegoFieldValue& fv1, const CegoFieldValue& fv2);
    friend CegoFieldValue operator / ( const CegoFieldValue& fv1, const CegoFieldValue& fv2);
    friend CegoFieldValue operator | ( const CegoFieldValue& fv1, const CegoFieldValue& fv2);

    void setLocalCopy(bool isLocal);
    bool isLocalCopy() const;

    CegoFieldValue getLocalCopy() const;

    bool isNull() const;

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

    void encode(char *buf) const;
    void decode(char *buf);
    int getEncodingLength() const;

    int size() const;
    Chain toChain() const;
    Chain dbFormat(CegoDatabaseFormater *pForm) const;
	
    Chain typeToChain() const;
    Chain valAsChain(bool doEval = true) const;

    int asInteger() const;
    long long asLong() const;

    int usedMemory() const;
    
private:

    bool isEqual( const CegoFieldValue& fv2 ) const;
    bool isLess( const CegoFieldValue& fv2 ) const;
    bool isMore( const CegoFieldValue& fv2 ) const;
    bool isLessEqual( const CegoFieldValue& fv2 ) const;
    bool isMoreEqual( const CegoFieldValue& fv2 ) const;
    
    CegoFieldValue add( const CegoFieldValue& fv2 ) const;
    CegoFieldValue sub( const CegoFieldValue& fv2 ) const;
    CegoFieldValue mul( const CegoFieldValue& fv2 ) const;
    CegoFieldValue div( const CegoFieldValue& fv2 ) const;
    CegoFieldValue concat( const CegoFieldValue& fv2 ) const;
    CegoFieldValue negate() const;

    void normFloatValue(Chain& floatVal) const;
    void denormFloatValue(Chain& floatVal) const;

    CegoDataType _type;
    void *_pV;
    int _len;
    bool _isLocalCopy;
    char _staticBuf[STATICFIELDBUF];
};

#endif
