
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
//	FILE	: Scr2Bin.h
//	AUTHOR	: Catalin Cocos
//__________________________________________________________________________________________________

#ifndef __CONVERT2__
#define __CONVERT2__

//__________________________________________________________________________________________________
//	includes
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
#include "parser.h"
#include "array.h"



//__________________________________________________________________________________________________
//	defines
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

#define TAG_Comments                -1
#define TAG_EndComments             -2
#define TAG_ForceAnalyse            -3
#define TAG_EndForceAnalyse         -4
#define TAG_NotSaveSection          -5
#define TAG_EndNotSaveSection       -6
#define TAG_SetCurrentFileLong      -7
#define TAG_SetCurrentFileDouble    -8
#define TAG_BreakPoint				-9
#define TAG_UpdateLog				-10

#define TAG_SECTION					-11
#define TAG_ENDSECTION				-12
#define TAG_FILEENTRY				0xf2

#define SB_ENUM			CTP_UserCode(0) 
#define SB_END_ENUM		CTP_UserCode(1)
#define SB_ATTRIB		CTP_UserCode(2)
#define SB_KEYWORD		CTP_UserCode(3)

#define SB_BEGINSECTION	CTP_UserCode(4)
#define SB_ENDSECTION	CTP_UserCode(5)
#define SB_DIRECTIVE	CTP_UserCode(6)

#define SB_STR_SUBSECT	"::"
#define SB_STR_VALUE	"<>"

//error codes
enum
{
	SB_ERR_NONE = 0,
	SB_ERR_UNKNOWN,
	SB_ERR_FILEOPEN,
	SB_ERR_UNKNOWN_KEYWORD,
	SB_ERR_MISPLACED_KEYWORD,
	SB_ERR_UNKNOWN_TYPE,
	SB_ERR_TAG_VALUE_MISSING,
	SB_ERR_ILLEGAL_ASSIGNEMENT,
	SB_ERR_VOID_ENTRY_DESCRIPTION,
	SB_ERR_BAD_FILE_EXTENSION,
	SB_ERR_PARAMETER_MISSING,
	SB_ERR_TOO_MANY_PARAMETERS,
	SB_ERR_UNKNOWN_DIRECTIVE,
	SB_ERR_UNKNOWN_SECTION,
	SB_ERR_SUBSECTIONS_NOT_SUPPORTED,
	SB_ERR_UNKNOWN_ENTRY,
	SB_ERR_UNEXPECTED_EOF,
	SB_ERR_OUTPUT_FILEOPEN
};

//__________________________________________________________________________________________________
//	List Element
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
template <class TYPE>
class CListElement
{
	TYPE* m_pNext;
public:
	CListElement() {m_pNext = NULL;}
	TYPE* Next() { return m_pNext; }
	void Append( TYPE* next) { m_pNext = next; }
	void DeleteList()
	{
		if(m_pNext) m_pNext->DeleteList();
		delete (TYPE*)this;
	}
};

template <class TYPE>
class CList
{
	TYPE* m_pFirst;
	TYPE* m_pLast;
	int m_nSize;
public:
	CList() {m_pFirst = m_pLast = NULL; m_nSize = 0; }
	TYPE* Start() { return m_pFirst; }
	int GetSize() { return m_nSize; }
	void Add( TYPE* pNew )
	{
		if(m_pLast)
		{
			m_pLast->Append(pNew);
			m_pLast = pNew;
		}
		else m_pFirst = m_pLast = pNew;
		m_nSize++;
	}
	void DeleteAll()
	{
		if(m_pFirst) m_pFirst->DeleteList();
		m_pFirst = m_pLast = NULL;
		m_nSize = 0;
	}
};

//__________________________________________________________________________________________________
//	Name
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
class CName
{
	void Set( char* szName ) { m_szName = strcpy (new char[lstrlen(szName)+1], szName); }
	void Del() {  if(m_szName) delete[] m_szName; }
protected:
	char* m_szName;
public:
	CName() { m_szName  = 0; }
	CName( char* szName ) { Set(szName); }
	void SetName( char* szName ) { Del(); Set(szName); }
	const char * Name() { return m_szName; }
	~CName(){ Del(); }
	static int Compare( CName* a, CName* b, int key = 0 ) { return strcmp(a->m_szName,b->m_szName); }
};

//__________________________________________________________________________________________________
//	file extension storage
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
class CFileExtension: public CName
{
	BOOL m_bEnabled;
public:
	CFileExtension( char* szName )
	{
		for(int i = strlen(szName)-1; i>=0; i--)
			szName[i] = toupper(szName[i]);
		SetName(szName);
		Enable(TRUE);
	}
	static int Compare( CFileExtension* a, CFileExtension* b, int key = 0 ) { return stricmp(a->m_szName,b->m_szName); }
	void Enable( BOOL mode) { m_bEnabled = mode; }
	BOOL IsEnabled() { return m_bEnabled; }
};

//__________________________________________________________________________________________________
//	Output stream
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
#define BUFFER_SIZE (1024*32)

class COutStream
{
	DWORD m_written;
	char m_buffer[BUFFER_SIZE];
	unsigned m_spaceUsed;
	HANDLE m_hFile;
	void Flush();
public:
	COutStream() { m_written = 0; m_hFile = INVALID_HANDLE_VALUE; m_spaceUsed = 0; }
	~COutStream() { Close(); }
	int Open( char* szName);
	void Close();
	void Write( void* pSource, unsigned size);
	DWORD Written() { Flush(); return m_written; }
};

//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
//	DESC.	: flushes the stream buffer
//	AUTHOR	: Catalin Cocos
//__________________________________________________________________________________________________
__inline void COutStream::Flush()
{
	DWORD written;
	WriteFile( m_hFile, m_buffer, m_spaceUsed, &written, NULL);
	m_spaceUsed = 0;
	m_written += written;
}
__inline void COutStream::Write( void* pSource, unsigned size)
{
	if( m_spaceUsed + size > BUFFER_SIZE ) Flush();
	memcpy( m_buffer+ m_spaceUsed, pSource, size);
	m_spaceUsed += size;
}


//__________________________________________________________________________________________________
//	Element conversion 
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
class CConversionUnit: public CListElement<CConversionUnit>
{
public:
	virtual ~CConversionUnit() {}
	virtual DWORD Size() = 0;
	virtual void Write( COutStream& stream ) {};
	virtual int Code() {return 0;}
};

//__________________________________________________________________________________________________
//	Parameters description
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
class CParamDesc
{
public:
	virtual ~CParamDesc(){}
	virtual void SetDefaultValue(char* szWord ) = 0;
	virtual CConversionUnit* CreateConversionUnit( char* szWord = NULL ) = 0;
};

enum{	CET_PARAM_COUNT = 0x01,
		CET_ENTRY_COUNT = 0x02,
		CET_TAGGED		= 0x04,
		CET_DEFAULT		= 0x08,
		CET_NOSORT		= 0x10
};


//__________________________________________________________________________________________________
//	reference tag
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
class CRefChk: public CListElement<CRefChk>
{
	char* m_szStr;
	WORD m_Tag;
public:
	CRefChk( char* szStr, WORD size );
	~CRefChk( ) { delete[] m_szStr; }
	void SetTag( WORD Tag ) { m_Tag = Tag; }
	WORD Tag() { return m_Tag; }
	void WriteTags( COutStream& stream, WORD len );
	static int Compare( CRefChk* a, CRefChk* b, int key = 0 ) { return strcmp(a->m_szStr,b->m_szStr); }
	int Size() {return strlen(m_szStr); }
	void Write( COutStream& stream );
};
//__________________________________________________________________________________________________
//	file conversion engine
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
class CScr2bin
{
	//__________________________________________________________________________________________________
	//	Entry description
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CEntryTypeDesc: public CName
	{
	protected:
		int				m_nIdx;
		unsigned char	m_ucTag;
		int				m_nFlags;
		CTypedPtrArray<CParamDesc*> m_arParams;			// the parameters
		void EnableTag( unsigned char ucTag ) { m_nFlags |= CET_TAGGED; m_ucTag = ucTag; }
		void EnableParamCount() { m_nFlags |= CET_PARAM_COUNT; }
		void AddParameter( CParamDesc* pPm ) { m_arParams.Add( pPm ); }
	public:
		void SetDef() {m_nFlags |= CET_DEFAULT;}
		BOOL IsDef() { return m_nFlags & CET_DEFAULT; }
		void EnableEntryCount() { m_nFlags |= CET_ENTRY_COUNT; }
		int NumParam(){ return m_arParams.GetSize(); }
		CParamDesc* Param(int i) { return m_arParams[i]; }
		CEntryTypeDesc( char* szName, int nIdx ): CName( szName ) { m_nIdx = nIdx; m_nFlags = 0; }
		~CEntryTypeDesc() { m_arParams.DeleteAll(); }
		int SetProperties( CTextParser & P, DWORD& i );
		BOOL IsTagged(){ return m_nFlags & CET_TAGGED; }
		BOOL HasCount(){ return m_nFlags & CET_ENTRY_COUNT; }
		BOOL HasParamCount() { return m_nFlags & CET_PARAM_COUNT;}
		unsigned char Tag() { return m_ucTag; }
		int Index() {return m_nIdx; }
	};

	//__________________________________________________________________________________________________
	//	Section description
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CSectionTypeDesc: public CEntryTypeDesc
	{
		BOOL m_bNoSort;
		CSTPArray<CEntryTypeDesc> m_arEntries;
		CEntryTypeDesc* m_pDefDesc;
	public:
		CSectionTypeDesc( char* szName, unsigned char ucTag = TAG_SECTION ): CEntryTypeDesc( szName, -1 ) { m_bNoSort = FALSE; EnableTag ( ucTag ); m_arEntries.SetGranularity( 5 ); m_pDefDesc = NULL; }
		~CSectionTypeDesc() { m_arEntries.DeleteAll(); }
		void SetDefDesc( CEntryTypeDesc* pEn ) { m_pDefDesc = pEn ; AddEntryDescription(pEn); }
		void SetNoSort() { m_bNoSort = TRUE;}
		BOOL IsNotSorted() { return m_bNoSort; }
		BOOL AddEntryDescription( CEntryTypeDesc* pEn ) { BOOL NA; m_arEntries.SAdd(pEn, NA, FALSE); if(NA) delete pEn; return !NA; }
		int NumEntries() { return m_arEntries.GetSize(); }
		CEntryTypeDesc* EntryDesc(int i) { return m_arEntries[i]; }
		CEntryTypeDesc* EntryDesc(char* entryName)
		{
			int i = m_arEntries.Index((CEntryTypeDesc*)&entryName);
			if( i<0) return m_pDefDesc;
			return m_arEntries[i];
		}
		int Place(char* entryName)
		{
			int i = m_arEntries.Index((CEntryTypeDesc*)&entryName);
			if(i<0)
				if(m_pDefDesc) return m_pDefDesc->Index();
				else return i;
			return m_arEntries[i]->Index();
		}
	};

	//__________________________________________________________________________________________________
	//	NULL Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCNULL: public CConversionUnit
	{
	public:
		DWORD Size() { return 0; }
		void Write( COutStream& stream ) {}
	};

	class CNULLDesc: public CParamDesc
	{
	public:
		void SetDefaultValue(char* szWord ) { }
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCNULL(); }
	};

	//__________________________________________________________________________________________________
	//	Char Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCChar: public CConversionUnit
	{
		char m_Value;
	public:
		CCChar( char Value ) { m_Value = Value; }
		DWORD Size() { return sizeof(char); }
		void Write( COutStream& stream ) { stream.Write( &m_Value, sizeof(char)); }
	};

	class CCharDesc: public CParamDesc
	{
		char m_Default;
	public:
		CCharDesc() { m_Default = 0; }
		void SetDefaultValue(char* szWord ) { m_Default = (char) atoi(szWord); }
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCChar( szWord? (char)atoi(szWord): m_Default ); }
	};

	//__________________________________________________________________________________________________
	//	Short Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCShort: public CConversionUnit
	{
		short m_Value;
	public:
		CCShort( short Value ) { m_Value = Value; }
		DWORD Size() { return sizeof(short); }
		void Write( COutStream& stream ) { stream.Write( &m_Value, sizeof(short)); }
	};

	class CShortDesc: public CParamDesc
	{
		short m_Default;
	public:
		CShortDesc() { m_Default = 0; }
		void SetDefaultValue(char* szWord ) { m_Default = (short) atoi(szWord); }
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCShort( szWord? (short)atoi(szWord): m_Default ); }
	};

	//__________________________________________________________________________________________________
	//	Long Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCLong: public CConversionUnit
	{
		long m_Value;
	public:
		CCLong( long Value ) { m_Value = Value; }
		DWORD Size() { return sizeof(long); }
		void Write( COutStream& stream ) { stream.Write( &m_Value, sizeof(long)); }
	};

	class CLongDesc: public CParamDesc
	{
		long m_Default;
	public:
		CLongDesc() { m_Default = 0; }
		void SetDefaultValue(char* szWord ) { m_Default = atol(szWord); }
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCLong( szWord? atol(szWord): m_Default ); }
	};

	//__________________________________________________________________________________________________
	//	Float Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCFloat: public CConversionUnit
	{
		float m_Value;
	public:
		CCFloat( float Value ) { m_Value = Value; }
		DWORD Size() { return sizeof(float); }
		void Write( COutStream& stream ) { stream.Write( &m_Value, sizeof(float)); }
	};

	class CFloatDesc: public CParamDesc
	{
		float m_Default;
	public:
		CFloatDesc() { m_Default = 0.f; }
		void SetDefaultValue(char* szWord ) { m_Default = (float) atof(szWord); }
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCFloat( szWord? (float)atof(szWord): m_Default ); }
	};

	//__________________________________________________________________________________________________
	//	Double Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCDouble: public CConversionUnit
	{
		double m_Value;
	public:
		CCDouble( double Value ) { m_Value = Value; }
		DWORD Size() { return sizeof(double); }
		void Write( COutStream& stream ) { stream.Write( &m_Value, sizeof(double)); }
	};

	class CDoubleDesc: public CParamDesc
	{
		double m_Default;
	public:
		CDoubleDesc() { m_Default = 0.; }
		void SetDefaultValue(char* szWord ) { m_Default = atof(szWord); }
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCDouble( szWord? atof(szWord): m_Default ); }
	};

	//__________________________________________________________________________________________________
	//	string Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CCString: public CConversionUnit
	{
		char* m_pString;
	public:
		CCString( char* Value );
		~CCString() { delete[] m_pString; }
		DWORD Size() { return ((unsigned short*) m_pString)[0]  + 2 ; }
		void Write( COutStream& stream )
		{
			stream.Write( m_pString, Size());
		}
	};

	class CCTabStr: public CName
	{
		unsigned m_nCnt;
	public:
	};

	class CStringDesc: public CParamDesc
	{
		static char CSTRING_DEFAULT_PARAM[1];
		char* m_Default;
	public:
		CStringDesc() { m_Default = CSTRING_DEFAULT_PARAM; }
		~CStringDesc() { if( m_Default != CSTRING_DEFAULT_PARAM) delete[] m_Default; }
		void SetDefaultValue(char* szWord ){ m_Default = strcpy(new char[lstrlen(szWord) +1], szWord);}
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCString( szWord? szWord: m_Default ); }
	};

	//__________________________________________________________________________________________________
	//	Reference Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
public:
private:

	class CCRef: public CConversionUnit
	{
		char* m_szRef;
		CRefChk * m_pTags;
		char* m_crtStr;
	public:
		CCRef( char* Value ) { m_crtStr = m_szRef = Value; m_pTags = 0; }
		static int Compare( CCRef* a, CCRef* b, int key = 0 ) {	return strcmp(a->m_crtStr,b->m_crtStr); }
		DWORD Size();
		void Write( COutStream& stream );
		int Code() {return 1;}
		static void GetSimCnt ( int & Sim, CCRef* pFrst, CCRef* pScnd );
		CRefChk* GenerateChk(int size )
		{
			CRefChk* pChk = new CRefChk(m_crtStr, size);
			if(m_pTags) pChk->Append(m_pTags);
			return pChk;
		}
		void AddChk( CRefChk* pChk )
		{
			m_crtStr+= pChk->Size();
			m_pTags = pChk;
		}
	};

	class CRefDesc: public CParamDesc
	{
		static char CREF_DEFAULT_PARAM[1];
		char* m_Default;
	public:
		CRefDesc() { m_Default = CREF_DEFAULT_PARAM; }
		~CRefDesc() { if( m_Default != CREF_DEFAULT_PARAM) delete[] m_Default; }
		void SetDefaultValue(char* szWord ){ m_Default = strcpy(new char[lstrlen(szWord) +1], szWord);}
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL )
		{ return new CCRef( szWord? szWord: m_Default ); }
	};
	//__________________________________________________________________________________________________
	//	Enum Parameter & conversion unit
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

	#define ED_DEFAULT_INDEX -128

	class CEnumDesc: public CParamDesc
	{
		char m_crtValue;
		char m_Default;

		class CEnum: public CName
		{
			char m_tag;
		public:
			CEnum(	char tag, char* szName ): CName( szName ){ m_tag = tag; }
			char Tag() {return m_tag; }
		};
		
		CSTPArray<CEnum> m_arEnum;
	public:
		CEnumDesc() { m_crtValue = m_Default = 0; }
		~CEnumDesc() { m_arEnum.DeleteAll(); }
		void SetDefaultValue(char* szWord );
		void AddValue(char* szName, char Value = ED_DEFAULT_INDEX);
		CConversionUnit* CreateConversionUnit(  char* szWord = NULL );
	};


	//__________________________________________________________________________________________________
	//	Entry
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CEntry: public CConversionUnit 
	{
		CList<CConversionUnit> m_arParams;
		int m_bPCount;
		int m_bNoSort;
	public:
		CEntry() { m_bPCount = m_bNoSort = 0; }
		~CEntry() { m_arParams.DeleteAll(); }
		DWORD Size();
		void Write( COutStream& stream );
		int SetParams( CEntryTypeDesc* pEntryDesc, CSTPArray<CCRef> &Refs, CTextParser& P, DWORD& i, BOOL NoSort = FALSE);
		friend class CScr2bin;
	};

	//__________________________________________________________________________________________________
	//	Entry slot
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CEntrySlot: public CConversionUnit
	{
		CList<CConversionUnit> m_arEntries;
		CEntryTypeDesc* m_pDesc;
	public:
		CEntrySlot() {m_pDesc = NULL;}
		~CEntrySlot() {m_arEntries.DeleteAll();}
		DWORD Size();
		void Write( COutStream& stream );
		friend class CScr2bin;
	};

	//__________________________________________________________________________________________________
	//	Section
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CSection: public CEntry
	{
		unsigned char m_Level;
		CSectionTypeDesc* m_pDesc;
		CTypedPtrArray<CEntrySlot*> m_arEntries;
		CCString* m_pName;
//		CCRef* m_pName;
	protected:
		CSection() { m_pName = new CCString( "Directive"); }
	public:
//		CCRef* GetRefName() { return m_pName; }
		CSection( CSectionTypeDesc* pDesc, char* szName, unsigned char Level );
		~CSection();
		DWORD Size();
		void Write( COutStream& stream );
		friend class CScr2bin;
	};

	//__________________________________________________________________________________________________
	//	Directive
	//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
	class CDirective: public CSection, public CList<CConversionUnit>
	{
		unsigned char m_Level;
		unsigned char m_ucTag;
	public:
		CDirective( unsigned char Tag, unsigned char Level ) { m_ucTag = Tag; m_Level = Level; }
		~CDirective() {DeleteAll();}
		DWORD Size();
		void Write( COutStream& stream );
	};


	CSTPArray<CFileExtension> m_arSupportedFiles;
	CSTPArray<CSectionTypeDesc> m_arSections;
	BOOL m_bFilterDisabled;


	void AddSection( CSectionTypeDesc*& pSection );
	int ConvertDirective( CList<CConversionUnit> &Data, CTextParser& P, DWORD& i, unsigned char Level = 0 );
	int ConvertSection(CList<CConversionUnit> &Data, CSTPArray<CCRef> &Refs, CTextParser& P, DWORD& i, int & CloseSectionCount, unsigned char Level = 0);
	void SetTags( CTypedPtrArray<CRefChk*> &RefTgs, CSTPArray<CCRef> &Refs );
public:
	CScr2bin() { SetFiltering( FALSE ); }
	~CScr2bin();
	
	void SetFiltering( BOOL Mode ) { m_bFilterDisabled  = !Mode; }
	BOOL IsFilteringActive() { return !m_bFilterDisabled; }
	BOOL EnableExtension( char* ext, BOOL Mode ) {	int idx = m_arSupportedFiles.Index((CFileExtension*)&ext); if(idx>=0) m_arSupportedFiles[idx]->Enable(Mode); return (idx>=0); }
	int SetRules( char* szFile, unsigned* pLine = NULL );
	int GetExtCount() { return m_arSupportedFiles.GetSize(); }
	CFileExtension* Extension( int idx ) { return m_arSupportedFiles[idx]; }
	int Convert( char* inputFile, char* outputFile,  unsigned* pLine = NULL, unsigned long* pPosition = NULL, unsigned long* pWritten = NULL );
	BOOL IsFileSupported( char* fName);
	BOOL IsFileKnown( char* fName);
};

#endif
