#if !defined(_CPLUSBASE_H)
#define _CPLUSBASE_H

#include "PubHeader.h"
#include "Base.h"
#include "Callback.h"
#include "Varient.h"
#include "Utility.h"
#include "Lex.h"
#include "ObGrid.h"

////////////////////////////////////////////////////////
#define SHOW_WHEN_COMMENT_NOT_FOUND  "unknow"

#define NW_TRAN_MODE_L_TO_H    1
#define NW_TRAN_MODE_H_TO_L    0
#define DEFAULT_NW_TRAN_MODE   NW_TRAN_MODE_L_TO_H


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

// GetTokenEx(nExStyle)
enum 
{ 
    EN_PROCIDENT    = 1 ,  // 允许函数调用类型值, 例如 Func(...)
    EN_LINEREMARKRET= 2 ,
    EN_VALUESET     = 4 ,  // 允许 { ... }
    EN_DOLLARITEM   = 8 ,  // 允许 $Num
};

#ifdef _DLL_PROJECT
class CLASS_EXPORT CPlusLex: public CLex
#else
class CPlusLex: public CLex
#endif
{
public:
    enum register_type 
    { 
        REG_KEYWORD =0,    // KEYWORD允许两个单词的复合词
        REG_OPERATOR=1,    // Operator和RelateOperator支持双字符
    };

public:
    CPlusLex();	
   ~CPlusLex();	

    bool  OpenFile(char* szfilename,bool bAsTextFile=true);
    char* GetName() { return m_BufFile.getFilename(); }
    char* GetPath() { return m_BufFile.getFilepath(); }
    char* GetAbsoluteFilename() { return m_BufFile.getAbsoluteFilename(); }
    
    void  Reset(bool bResetBuffer);
    
    /////////////////////////////////////////////////////////////////////
    // Extend Function, implement through GetToken()
    int   GetToken(LexToken& Token, bool bJustPreview=false);     // KeyWord
    int   GetToken(LexToken& Token, WORD nExStyle, bool bJustPreview);
    int   GetTokenEx(LexToken& Token, WORD nExStyle=0);             // 扩展: 支持Ident 加 . () [] :: 
                                                                    // 不返回REMARKS
    bool  GetSpecificToken(LexToken& Token,long  TokenId);          // 支持基本TokenId和KeyWord, 如果TokenId!=Remark, 则跳过Remark
                                                                    // 如果不成功,则位置指针停留在原地
    bool  GetSpecificToken(LexToken& Token,char* szTokenName,bool bcase=false);
     
    bool  Fetch_string(char* szLeftOperator, char* szRightOperator, // 考虑了配对的() []
                       bool bReturnBetween, OTSTR& strReturn);      // 返回串包含Left,RightOperator

    bool  ForwardLocatTo(long nLocat);

    Location& getLocation();
    bool  setLocation(Location& locat);
    
private:
    BufferFile  m_BufFile;

    bool        m_bTokenValid;
    LexToken    m_Token;    // 最多可保存一个元素, 用于Preview情况
    
    ///////////////////////////////
    static LexRules     m_Rules;
    static StringArray  m_KeyWord_List;
    
    static bool Register(register_type type, char* lpstring);
    
public:
    //////////////////////////////////////////////////
    static void Initial();          // 程序开始时调用一次
    static void Destroy();          // 程序结束时调用一次

    static bool isValue(LexToken& Token);
    static bool isValueSet(LexToken& Token);
    static bool isKeyWord(LexToken& Token);
    static bool isIdent(LexToken& Token);   // 包含扩展的Ident
    static bool isOperator(LexToken& Token);
    static bool isProcIdent(LexToken& Token);
        
    static bool VarstringParser(char* varString,
                                OTSTR& strVar,OTSTR& strRestrict,OTSTR& strNext,
                                long* pRestrictLocat=NULL,long* pNextLocat=NULL);
};

//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
#ifdef _DLL_PROJECT
class CLASS_EXPORT ExprNode: public LexToken
#else
class ExprNode: public LexToken
#endif
{
public:
    enum { MAX_CHILD_NUM=3 };
    
public:
    //////////////////////////////////
    ExprNode* m_pChildList[MAX_CHILD_NUM];  // 单目 0, 双目 0,1, 三目 0,1,2
    
public:
    ExprNode();
   ~ExprNode();
    
    bool isLeaf();
    int  GetHeight();
    
    void operator=(const ExprNode& right);
    
private:
    friend class ExprAnalyser;

    int  Height(ExprNode* pNode);
};

////////////////////
enum {
    EN_VALUSET_ASSIGN      = 1,
    EN_FIRST_VALUESET_ITEM = 2,
};

#ifdef _DLL_PROJECT
class CLASS_EXPORT ExprAnalyser  
#else
class ExprAnalyser  
#endif
{
public:
    class TResult: public CVarient
    {
    public:
        bool bisIdent;  // true   CVarient保存的是变量名(szIdent)
                        // false  CVarient保存的是具体的值
    public:
        TResult() { bisIdent=false; }
       ~TResult() {}
        
        bool clone(TResult& ResultObject)
        {
            bisIdent=ResultObject.bisIdent;
            return CVarient::clone(ResultObject);
        }
        bool isIdent() 
        {
            return bisIdent;
        }
        void setIdent(char* szIdent)
        {
            bisIdent=true;
            set(szIdent);
        }
        char* getIdent()
        {
            char* szIdent;
            if (get(&szIdent)) return szIdent;
            return NULL;
        }
    };
    
public:
    ExprAnalyser();
   ~ExprAnalyser();
    
    ExprNode* GetExpression(char* lpstr_expression,WORD nFlag=0);
    ExprNode* GetExpression(CPlusLex& Parser, WORD nFlag=0); // 分析取得最大的表达式串, 不得为空表达式
                                                                                // bEnableValueSetAssign指数组赋值 {...}
    ///////////////////////////////////////////////////////////////////
    void setCallback(void* handler, cCallback::tFunction pFunctionPointer);
    void setCallback(cCallback* pCallback);
    cCallback* getCallback();
    
    ///////////////////////////////////////////////////////////////////
    bool calculate(char* lpstr_expression,long&     result); // 表达式求值(不允许数组或结构类型的变量,因无法运算)
    bool calculate(char* lpstr_expression,OTSTR&    result);
    bool calculate(char* lpstr_expression,CVarient& result,bool bNullResultAllowed=false);  // bNullResultAllowed用于void函数返回
    bool calculate(ExprNode* pNode,long&     result);
    bool calculate(ExprNode* pNode,CVarient& result);
    
    bool execute(char* lpstr_expression);
    bool execute(ExprNode* pNode);
    bool execute(ExprNode* pNode,TResult& result); // 返回值或结果变量名
    
    ///////////////////////////////////////////////////////////////////
    static OTSTR GetExprstring(ExprNode* pNode,char* szParentOperator="#");
    static Location& GetExprLocat(ExprNode* pNode);
    static void OffsetExprLocat(ExprNode* pNode,Location& offset);
    static void GetExprNodes(ExprNode* pNode,TObArray<ExprNode>& List, bool bPrefixMode=true);  // 取得归属pNode的所有ExprNode
    static void GetExprSuffixstring(ExprNode* pNode,OTSTR& str);
        
    static void DelExprNode(ExprNode* pNode);

    char*  GetLastError() { return m_strLastError.GetBuffer(); }
    
private:
    OTSTR     m_strLastError;
    cCallback m_Callback;
    bool      m_bEnableValueSetAssign;
    bool      m_bEnableFirstValueSetItem;
    
    //////////////////////////////////////
    ExprNode* NewExprNode();
    
    ExprNode* BuildExprTree(CPlusLex& Parser,char* szPrecedeOperator,bool bFirstChildNode=true);
    ExprNode* ExtendNode   (CPlusLex& Parser,char* szPrecedeOperator, ExprNode* pNode); // if Found error, return NULL
    
    static int  GetOperatorType(char* pOperator,bool bAfterIdent=true);
    static int  GetOperatorPri (char* pOperator,bool bAfterIdent=true);
    
    bool GetValue   (LexToken* pToken,TResult& result);
    bool GetValue   (char* szIdent,TResult& result);
    bool AssignValue(LexToken* pToken,TResult& result);
    bool AssignValue(char* szIdent,TResult& result);
    bool AssignValueData(char* szIdent,char* szData);   // 可用于结构赋值

    bool calculate(char* lpstr_expression,TResult& result,bool bNullResultAllowed=false);  // bNullResultAllowed用于void函数返回
    bool calculate(ExprNode* pNode,TResult& result);
    
    bool Check(ExprNode* pNode,bool bValueSetAllowed,Location* plocationOffset=NULL);  //### also should check ident validate
};

///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Var Definition Object
#define CHOICE_TYPE   "Choice"
#define ANY_TYPE      "dynamic"

#ifdef _DLL_PROJECT
class CLASS_EXPORT VariableItemAttr: public TName
#else
class VariableItemAttr: public TName
#endif
{
public:
    enum type_  
    { 
        // basic type
        T_INT1   = 0,   T_INT2    = 1,   T_INT4  = 2, 
        T_UINT1  = 3,   T_UINT2   = 4,   T_UINT4 = 5,
        T_OCTET  = 7,   T_DOUBLE  = 8,
        T_PVOID  = 10, 
        T_PSTRUCT= 128, T_PCHOICE = 129,  // 从T_PVOID演伸而来,  PCHOICE是含有动态个数变量的结构
        T_NULL   = -1,  

        T_ANYTYPE= -2,  // 表示T_NULL以外的任意类型(只在procedure定义头的引用变量和返回值中支持)
        
        // ex type
        T_BYTE   = 20,  T_WORD    = 21,  T_DWORD = 22,
        T_STRING = 23,  // VisiableString
        T_SCHAR  = 24,  // char[n] used as VisiableString
        T_MEMO   = 25   // Large octet
    };

protected:
    type_ m_type;
    long  m_size;

    type_ m_Extype;
    OTSTR m_strTypeName;
    
    int   m_BitLen;     // 对该类型数据赋值, 先(type)Data, 之后取相应Bits 
    int   m_BeginBit;
    bool  m_bisBitTail;
    
public:
    VariableItemAttr();
    virtual ~VariableItemAttr();
    
    bool  setAttr(char* varname,VariableItemAttr::type_ type,long size);
    
    VariableItemAttr::type_ getType();
    int   getSize();
    
    void  clone(VariableItemAttr& Object);
    void  clear();
    
    //////////////////////////////////////////////////////
    // Used for struct_typename and user defined typename
    void  setTypeName(char* typeName,VariableItemAttr::type_ extype);
    char* getTypeName();

    VariableItemAttr::type_ getExType();
    
    ////////////////////////////////////////////////////////////
    bool  setBitLen(int BitLen);
    int   getBitLen();
    
    bool  setBeginBit(int BeginBit);
    int   getBeginBit();
    
    void  setBitTailFlag(bool bTail);
    bool  getBitTailFlag();
    
    ////////////////////////////////////////////////////////////
    static bool isValidType(int type, bool bIncludeAnyType=true);
    static bool isBasicType(int type, bool bIncludeNull, bool bIncludePVOID=true);
    static bool isBasicType(char* szType, bool bIncludeNull, type_* returnType=NULL, type_* returnExType=NULL);

    static VariableItemAttr::type_ getBasicType(VariableItemAttr::type_ ExType);

    static char* getTypeDefaultName(int type); 
};

//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
class StructDefinition;

#ifdef _DLL_PROJECT
class CLASS_EXPORT VariableDefinition: public VariableItemAttr, public TObject
#else
class VariableDefinition: public VariableItemAttr, public TObject
#endif
{
public:
    WORD  m_nIdentifierId;
    bool  m_isNetWorkTranMode_L_TO_H;
    
protected:
    StructDefinition*  m_pParent;
    DWORD              m_wParam;                    // 可用于保存其他属性(指针)
    
    StructDefinition*  m_pStructDefinitionObject;   // 结构类型的变量,此值有效
    bool               m_bPassAddress;              // Used for procedure params define
    OTSTR              m_strInitialValueData;       // 赋初值

    OTSTR              m_strDescriptionEnd;

    long               m_Id;

public:
    VariableDefinition();
    VariableDefinition(StructDefinition* pParent,WORD nIdentifierId);
   ~VariableDefinition();

    int    ObjectTypeId() { return 4; }
   
    OTSTR  GetVariableName(bool bShowBeginBitLocat=true);
    StructDefinition* GetParent() { return m_pParent; }
    
    void   setParam(DWORD param) { m_wParam=param; }
    DWORD  getParam()  { return m_wParam; }

    ///////////////////////////////////////////////////
    void   setPassAddressFlag(bool bPassAddress) { m_bPassAddress=bPassAddress; }
    bool   getPassAddressFlag() { return m_bPassAddress; }

    void   setInitialValueData(char* szInitialValueData) { m_strInitialValueData=szInitialValueData; }
    OTSTR& getInitialValueData() { return m_strInitialValueData; }
    
    void   setDescriptionEnd(char* szDescription) { m_strDescriptionEnd=szDescription; }
    OTSTR& getDescriptionEnd() { return m_strDescriptionEnd; }
    
    void   setStructDefinitionObject(StructDefinition* pStructDefinition);  // 如果该变量是结构类型, 有效 
    StructDefinition* getStructDefinitionObject();      

    virtual StructDefinition* GetTypeOf() { return NULL; }  // 只能用于简单变量
    
protected:
    friend class CVariableItem;
};


#ifdef _DLL_PROJECT
template class CLASS_EXPORT TObArray<VariableDefinition>;
#endif

#ifdef _DLL_PROJECT
class CLASS_EXPORT StructDefinition: public TName, public TObject
#else
class StructDefinition: public TName, public TObject
#endif
{
public:
    WORD  m_nIdentifierId;
    bool  m_isNetWorkTranMode_L_TO_H;

protected:
    DWORD m_wParam;
    
    TObArray<VariableDefinition>  m_VariableDefinitionList;
    
public:
    StructDefinition();
    StructDefinition(WORD nIdentifierId);
   ~StructDefinition();

    int   ObjectTypeId() { return 3; }
   
    void  setParam(DWORD param) { m_wParam=param; }
    DWORD getParam()  { return m_wParam; }
    
    int   GetVariableCount();
    
    void  Add(VariableDefinition* pObject,DWORD nParam=0);
    
    VariableDefinition* GetAt(int nIndex,DWORD* lpParam=NULL);
    VariableDefinition* GetVariableDefinition(char* name); 
    TObject*            Get_DefinitionObject(WORD nIdentifierId); 
    
    void  RemoveAll(bool bDeleteObject=true);
    
    bool  m_bLoopMark;

    virtual bool CompleteIt(OTSTR& strError);   // Check BitLen, and set BeginBit
    
    virtual bool GetIntegratedType(int* type=NULL) { return false; }
};

////////////////////////////////////////////////////
class CEnumItem: public CVarient, public TObject
{
public:
    CEnumItem() {}
   ~CEnumItem() {}

    int ObjectTypeId() { return 1; }
};

class EnumItemList: protected TObArray<CEnumItem>, public TObject
{
public:
    enum { COMMENT_OR=0, COMMENT_EQUAL=1 };

public:
    EnumItemList();
   ~EnumItemList();

    int    ObjectTypeId() { return 2; }
   
    void   setName(char* szName);
    OTSTR& getName();
    
    void   setDescription(char* szDescription);
    OTSTR& getDescription();
    
    /////////////////////////////////////////////////////
    int    GetSize();
    
    CEnumItem* AddItem(CEnumItem& EnumItem,bool bRepetitionCheck=true);
    int        FindItem(char* name);
    
    CEnumItem* GetAt(int nIndex);
    
    bool  Lookup_byName (char* name, long&  valReturn, char** szDescriptionReturn=NULL); 
    bool  Lookup_byValue(long value, OTSTR& strRetrun, char** szDescriptionReturn=NULL);
    
    void  RemoveAll();

    ////////////////////////////////////////////////////////////////
    bool  GetComments(long value,int nMode, OTSTR& strReturn,char* szDefault=NULL);
};

//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// RunTime Object
//

// DumpToList(nDisplayAttr)
enum 
{ 
    SH_INTEGRATE_STRUC=1, SH_SHOW_VALUE_ANYWAY=2,  SH_SHOW_COMMENT=4, 
    SH_SHOW_ELEMID    =8, SH_SHOW_LEADERMARK  =16, 
    SH_INDENT_ON      =32, // 缩进
};

#define COL_LOCATION     0
#define COL_BITMASK      1
#define COL_NAME         2
#define COL_DESCRIPTION  3
#define COL_COMMENT      4


class CStruct;
class RunEnv;
class NullSyntaxObject;

#ifdef _DLL_PROJECT
class CLASS_EXPORT CVariableItem: public TVarient
#else
class CVariableItem: public TVarient
#endif
{
    /////////////////////////////////////////
    // 注: TVarient中带的name,type,size无效, 由m_Attr替代
    
public:
    CVariableItem();     
    virtual ~CVariableItem();

    bool   Create(CStruct* pParentStruct,VariableDefinition* pVariableDefinition);  // 创建已定义的变量
    bool   Create(StructDefinition* pStructDefinition, char* varname, long size);   // 根据已定义的结构创建变量
    bool   Create(VariableItemAttr::type_ extype, char* varname, long size);        // 创建简单数据类型变量
    
    bool   init()    { return false; }  // this function not allowed

    //////////////////////////////////////////////////
    VariableItemAttr&   GetAttr() { return m_Attr; }
    VariableDefinition* GetDefinition() { return m_pVariableDefinition; }
    
    int    getType() { return m_Attr.getType(); }
    int    getSize() { return m_Attr.getSize(); }
    OTSTR& getName() { return m_Attr.getName(); }
    char*  getTypeName()    { return m_Attr.getTypeName(); }
    int    getBitLen()      { return m_Attr.getBitLen();   }
        
    void   setDescription(char* szDescription) { m_Attr.setDescription(szDescription); }
    OTSTR& getDescription() { return m_Attr.getDescription(); }

    OTSTR  GetVariableName();  // name[..]
    OTSTR  GetNameEx();        // structname.itemname
    
    ////////////////////////////////////////////////
//  void   setParam(DWORD param) { m_wParam=param; }
//  DWORD  getParam()  { return m_wParam; }

    long   GetId() { return m_Id; }
    
    ////////////////////////////////////////////////
    // 对T_PCHOICE和T_PSTRUCT适用

    bool   isStruct(bool bIncludeChoice=true);

    long   GetSubElemCount(int nStructIdx,bool bConsiderImplicitChoiceElem);
    
    CVariableItem* GetSubElemAt(int nStructIdx, int nSubItemIdx, bool bConsiderImplicitChoiceElem);   // 取第nStructIdx个结构元素的第nSubItemIdx个变量
    CVariableItem* FindFirstSubElembyId(int nStructIdx, long ElemId, bool bConsiderImplicitChoiceElem);   // 例: Structname DataA; 取结构DataA下的一个变量
    CVariableItem* FindFirstSubElem    (int nStructIdx, char* name,  bool bCaseSensitive,bool bConsiderImplicitChoiceElem); 
    CVariableItem* RemoveSubElemAt(int nStructIdx, int nSubItemIdx);

    ////////////////////////////////////////////////
    // T_PCHOICE是含有动态个数变量的特殊结构
    
    bool   isChoice();
    bool   isImplicitChoice();

    bool   AddChoiceElem(CVariableItem* pVariableItem, int ElemId, char* lpLeadChForDump=NULL); // 例: Choice DataA; 在空结构DataA下加一个变量(类型可为结构)
    long   GetChoiceElemCount(bool bConsiderImplicitChoiceElem);

    CVariableItem* GetChoiceElemAt(int nSubItemIdx,     bool bConsiderImplicitChoiceElem);       // Choice Index永远=0, size=1
    CVariableItem* FindFirstChoiceElembyId(long ElemId, bool bConsiderImplicitChoiceElem);       // 例: Choice DataA; 取结构DataA下的一个变量
    CVariableItem* FindFirstChoiceElem    (char* name,  bool bCaseSensitive, bool bConsiderImplicitChoiceElem); 
    
    ////////////////////////////////////////////////
    virtual bool Clone(CVariableItem& VariableItem, bool bCloneNameAlso);   // bCloneNameAlso=false, 表示保留原名
    virtual bool PassAddressClone(CVariableItem& SrcVariableItem,long nIndex,VariableDefinition* pVariableDefinition);  // 如果有相关的Definition,则需要检查类型匹配
    
    ////////////////////////////////////////////////
    // " (nIndex>= 0)||(size==1) szdata为单一元素= ..  
    //   (nIndex==-1)&&(size> 1)       为结构    ={ .. , .. [,] }"
    bool   sets(long nIndex,  char* szdata, RunEnv* pCurRunEnv=NULL);   // pCurRunEnv 为其间表达式运算的环境
    bool   sets(char* szdata, RunEnv* pCurRunEnv=NULL);                 // nIndex=0, 方便对size=1的元素的访问
    
    bool   setAt_WithBitsData(long nIndex, CVarient& VarientVal);
    bool   setAt_WithBitsData(long nIndex, unsigned  data);

    ////////////////////////////////////////////////
    // lastIdx=-1 mean noIdx or All array[], when lastIdx==NULL, 最后一个不能有[]

    // FOR CHOICE WITH NAME=NULL
    CVariableItem* GetItem(long nIdx,char* NextString, long* retlastIdx, RunEnv* pCurRunEnv=NULL);  
    CVariableItem* GetItem(char* NextString, long* retlastIdx, RunEnv* pCurRunEnv=NULL); 
    
    ////////////////////////////////////////////////
    bool   Dump(char* filename,bool bOverWrite);

    bool   DumpToList(VirtualList& List,TObject* pTranslater,WORD nDisplayAttr); // pTranslater used by GetValueComment()
    
protected:
    CStruct*            m_pParentStruct;
    VariableDefinition* m_pVariableDefinition;      // 描述变量定义, Defined VariableDefinition 
    StructDefinition*   m_pStructDefinition;        // 描述结构定义, 如果变量是结构类型则该项有效
    VariableItemAttr    m_Attr;
    long                m_Id;                       // 标识号, 可用于Choice下成员的ElemId
    DWORD               m_wParam;
    
    virtual CStruct* NewStruct();

    bool     SetStructItem(int nIndex,CStruct* pStruct);
    CStruct* GetStructItem(int nIndex);             // 注: VariableItem为T_PSTRUCT,T_PCHOICE类型, 指向CStruct
    
    bool Clone(CVariableItem& VariableItem,CStruct* pParentStruct, bool bCloneNameAlso);
    void Destroy();

    ///////////////////////////////////////////////////
    void Dump(FILE* fp, OTSTR strHeaderFormat);     // "%?ds  %?ds  %s"  (type name = data)

    bool DumpToList(CVariableItem* pParentObject,long MaxElemIdLen,VirtualList& List,long ParentItemId,TObject* pTranslater,WORD nDisplayAttr,long nSpaceLen, bool bOneOfMultiStructMember, bool bisFirstItemInStruct); 
    bool DumpStructToList(CVariableItem& VariableItem, int nIndex, VirtualList& List,long ParentItemId,TObject* pTranslater,WORD nDisplayAttr,long nSpaceLen,int nStructIndex,bool bShowChoiceItemMark); 
    
    bool SetListItemData(VirtualList& List,bool& bFirstRow, long& nItem, long nCol, DWORD Itemparam, char* szText);
    long GetMaxSubElemIdLen(int nStructIdx,bool bConsiderImplicitChoiceElem);
    
    virtual void DumpLocationMask(OTSTR& str) { str=""; }
    virtual bool DumpErrorFlag() { return false; }
    virtual bool ValueValid() { return true; }
    virtual bool DumpBitsMask(OTSTR& str) { str=""; return true; }

    ////////////////////////////////////////////////
    class InterData
    {
    public:
        char m_NameLeadCh;
        bool m_bisImplicitChoice;

    public:
        InterData()  { Clear(); }
       ~InterData()  {}
       
        void Clear()
        {
            m_NameLeadCh=' ';
            m_bisImplicitChoice=false;
        }
        void operator=(const InterData& right)
        {
            m_NameLeadCh=right.m_NameLeadCh;
            m_bisImplicitChoice=right.m_bisImplicitChoice;
        }
    };
    InterData  m_InterData;
    InterData* m_pPassAddressInterData;

public:
    void SetNameLeadCh(char Ch);
    char GetNameLeadCh() { return m_InterData.m_NameLeadCh; }

    ////////////////////////////////////////////////////////////
    // 值的Comment: VarDefinition_Dump > TypeOF's struct's Dump
    virtual bool isValueCommentValid() { return false; }  
    virtual int  GetValueComment(TObject* pTranslater,CVariableItem* pParentObject,int nArrIndex,OTSTR& strComment,char* szDefault=SHOW_WHEN_COMMENT_NOT_FOUND) { strComment=""; return 0; } // false表示未取得匹配的Comment ( or或者equal不匹配 , strComment可返回不匹配描述)

    ////////////////////////////////////////////////////////////
    // TypeOfData: 用以取得综合值的结构体
    virtual bool isTypeOfDataValid(WORD nDisplayAttr) { return false; }
    virtual CVariableItem* GetTypeOfData(int nIndex,WORD nDisplayAttr) { return NULL; } 
    
private:
    friend class RunTimeStk;
    friend class CStruct;
};


///////////////////////////////////////////
class CStruct: public TName
{
public:
    CStruct();
    virtual ~CStruct();

    int  GetItemCount(bool bConsiderImplicitChoiceElem);
   
    CVariableItem* GetVariable  (char* name, bool bCaseSensitive, bool bConsiderImplicitChoiceElem); 
    CVariableItem* GetVariableAt(int nIndex, bool bConsiderImplicitChoiceElem); 
    CVariableItem* RemoveVariableAt(int nIndex);
    
    bool sets(char* szdata,RunEnv* pCurRunEnv=NULL);    // " { .. } "  pCurRunEnv 为其间表达式运算的环境, 便于从环境中取得相应的数值

    ///////////////////////////////////////////////////
    // lastIdx=-1 mean noIdx or All array[], when lastIdx==NULL, 最后一个不能有[]

    // FOR CHOICE WITH NAME=NULL
    CVariableItem* GetItem(char* varString, long* retlastIdx,RunEnv* pCurRunEnv=NULL);  
    
    ////////////////////////////////////////////////
//  void   setParam(DWORD param) { m_wParam=param; }
//  DWORD  getParam()  { return m_wParam; }
    
protected:
    StructDefinition*       m_pStructDefinition;        // Defined StructDefinition
    TObArray<CVariableItem> m_VariableItemList;
    bool                    m_bHasImplicitChoiceElem;
    DWORD                   m_wParam;
    
    bool Create(StructDefinition* pStructDefinition,char* szName=NULL);
    bool Clone (CStruct& StructItem);

    void Destroy();
     
    bool AddVariable(CVariableItem* pVariableItem);     // can be used For Choice

    CVariableItem* GetVariablebyId(long Id, bool bConsiderImplicitChoiceElem);  // used by Choice Item
    
    ////////////////////////////////////////////////
    bool Dump(char* filename,bool bOverWrite);
    void Dump(FILE* fp, OTSTR strHeader);
    
    //////////////////////////////////////////////
    virtual CVariableItem*  NewVariableItem();
    
private:
    friend class RunTimeStk;
    friend class CVariableItem;

    static NullSyntaxObject NullObject;
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// RunTimeProc
enum
{
    CALLBACK_ASSIGNVALUE     =0,    // 单数据变量(非数组)赋值  A=value 
                                    // PARAM: IdentName
                                    //        Value(CVarient)
        
    CALLBACK_GET_IDENTVALUE  =1,    // 取单数据变量(非数组)的值 
                                    // Ident sample:  A
                                    //                A.B
                                    //                A.B[...].C[..].D ...
                                    //                A[Idx]
                                    //                Func()
                                    //                ConstA::B     -> 到相关的Program定义中取
                                    //                ConstA        -> 到相关的Program定义中取
                                    // PARAM: IdentName
                                    //        Return: Value(CVarient)
    CALLBACK_SETVALUE        =2,    // 单数据变量(可数组)赋值  A=szData 
                                    // PARAM: IdentName
                                    //        Value( (char*)szData)
        
};

/////////////////////////////////////////////////////
// SetExStyle(nExStyle)  // FOR CHOICE WHO NAME=NULL
enum 
{ 
    EN_IMPLICIT_CHOICE_ELEM = 1 , // 设置环境变量的该属性后, 当使用与该环境有关的GetItem等操作时, 自动(!!)使用隐式CHOICE的成员变量处理模式
};

#ifdef _DLL_PROJECT
class CLASS_EXPORT RunEnv // base
#else
class RunEnv // base
#endif
{
public:
    RunEnv() { m_nExStyle=0; }
    virtual ~RunEnv() {}

    void    setExStyle(WORD nExStyle)  { m_nExStyle=nExStyle; }
    
    virtual cCallback::tFunction GetRunTimeProc() { return NULL; }
    virtual CVariableItem* GetItem(char* varString,long* lastIdx=NULL) { return NULL; }

protected:
    WORD m_nExStyle;

    friend class CVariableItem;
    friend class CStruct;
};

////////////////////////////////////////////
static char* cDumpFormat[]=  
{
    0,          // NULL 表示采用Default的
    0,
    0,
    "0x%02X",
    "0x%04X",
    "0x%08X",
    0,
    0,
    0,
    0,
    0,
    0
};

static char* cDumpListFormat[]=  
{
    0,          // NULL 表示采用Default的
    0,
    0,
    "%02X",
    "%04X",
    "%08X",
    0,
    0,
    0,
    0,
    0,
    0
};


#endif

