
#ifndef __MSGDIC_H__
#define __MSGDIC_H__

//#include <stdio.h>
//#include <string.h>
#include <sys/types.h>

#include "exception.h"
#include "cstring.h"
#include "cstream.h"
#include "str_array.h"
#include "ptr_array.h"
#include "int_array.h"
#include "dbl_array.h"
#include "bool_array.h"
#include "date_array.h"
#include "int_hash.h"

#include "msg_error.h"

#define MAX_TAG_NUM			102400	// 10 * 1024
#define MAX_MSG_NUM			10000
#define MAX_HASHBAG_SIZE	128

// Tag Type values
enum E_TagType {
	TT_UNKNOWN   = 0
	, TT_STRING  = 1
	, TT_INTEGER = 2
	, TT_DOUBLE  = 3
	, TT_BOOLEAN = 4
	, TT_DATE    = 5
	, TT_SUBMSG	 = 6	// Sub message
};

class CTagInfo
{
public:
	int m_iTagNum;		// tagnum
	CString m_sName;	// tagname
	E_TagType m_eType;	// tagtype
	int m_iSubMsgNum;	// submsg number
	bool m_bArrayYN;
	CTagInfo *m_pNext;

	CTagInfo();
	CTagInfo(int p_iTagNum, const char *m_szTagName, E_TagType p_eTagType, int p_iSubMsgNum, bool p_bArrayYN);
	static CString ReprType(E_TagType p_eType);
};


//============================================================================
class CMsgInfo : public CPtrArrayItem	// used msg_handler.h as CPtrArray item
{
private:
	int m_iMsgNum;				// msgno
	CString m_sName;			// msg name
	CString m_sVer;				// msg version signature
	int m_iHashKey;				// msg hash key value	//#NEW

private:
	CIntArray m_iaTagNumList;	// tagnum list
	CTagInfo *m_paHashBag[MAX_HASHBAG_SIZE];
	CIntHash m_ihTagNameMap;	// <CString, int> for converting TagName --> TagNum

public:
	CMsgInfo();
	CMsgInfo(int p_iMsgNum, const char *p_szMsgName, const char *p_szVer, int p_iHashKey);
	virtual ~CMsgInfo();
	int GetMsgNum();
	CString GetMsgName();
	int GetHashKey();
	int GetNoTags();
	int GetTagNumAt(int p_iIdx);
	int GetTagNumByName(const char *p_szTagName);
	char *GetTagName(int p_iTagNum);
	E_TagType GetTagType(int p_iTagNum);
	bool IsDefinedTag(int p_iTagNum);
	bool IsMultiTag(int p_iTagNum);
	CTagInfo *GetTagInfo(int p_iTAgNum);
	void SetTagInfo(int p_iTagNum, const char *p_szTagName, E_TagType p_eTagType, int p_iSubMsgNum, bool p_bArrayYN);
	void Dump(CStream *p_pBuffer);
};



//============================================================================
class V2_DLL_API CMsgDic : public CLastError
{
private:
	CMsgInfo *m_paMsgSlot[MAX_MSG_NUM];
	static bool m_bLoaded;

public:
	static bool IsValidMsgNum(int p_iMsgNum)
	{
		if (p_iMsgNum > 0 && p_iMsgNum < MAX_MSG_NUM) {
			return true;
		}
		return false;
	}

	CMsgDic();
	~CMsgDic();

	void InitDictionary(const char *p_szMsgDicPath);
	CMsgInfo *GetMsgInfo(int p_iMsgNum);
	void Dump(CStream *p_pBuffer);

	/* called following functions are called in msg_dic_handler.cpp */
	void SetMsgInfo(int p_iMsgNum, const CString &p_sMsgName, const CString &p_sVer, const CString &p_sHashKey);	// throw CException
	void SetMsgDetail(int p_iMsgNum, int p_iTagNum, const CString &p_sTagName, const CString &p_sTagType, const CString &p_sArrayYN);	// throw CException
};


extern V2_DLL_API CMsgDic *MA_GetMsgDic(void);		// in msg_dic.cpp

#endif	// __MSGDIC_H__
