//
//	Copyright © 2005 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#pragma once

namespace VWFC
{
	namespace Tools
	{
		typedef UInt16		TDataIdentifier;

		class VWDataSerializer;
		class VWDataSerializerGroup;
		// ---------------------------------------------------------------------------
		class VWDataSerializerValue
		{
			friend class VWDataSerializer;
			friend class VWDataSerializerGroup;
		public:
										VWDataSerializerValue(SInt8 data);
										VWDataSerializerValue(UInt8 data);
										VWDataSerializerValue(SInt16 data);
										VWDataSerializerValue(UInt16 data);
										VWDataSerializerValue(SInt32 data);
										VWDataSerializerValue(UInt32 data);
										VWDataSerializerValue(double data);
										VWDataSerializerValue(UInt32 data, const char* szEnum1, ...);
										VWDataSerializerValue(void* pData, size_t size);
										VWDataSerializerValue(const TXString& str);
										VWDataSerializerValue(const VWDataSerializerValue& src);
										~VWDataSerializerValue();

			VWDataSerializerValue&		operator=(const VWDataSerializerValue& src);

										operator SInt8() const;
										operator UInt8() const;
										operator SInt16() const;
										operator UInt16() const;
										operator SInt32() const;
										operator UInt32() const;
										operator double() const;
										operator TXString() const;

			TXString					GetName() const;
			void						SetName(const TXString& name);

			VWDataSerializerValue&		SetEnumValues(const char* szEnum1, ...);

			SInt32						GetSIntValue() const;
			UInt32						GetUIntValue() const;
			void						SetValue(SInt8 data);
			void						SetValue(UInt8 data);
			void						SetValue(SInt16 data);
			void						SetValue(UInt16 data);
			void						SetValue(SInt32 data);
			void						SetValue(UInt32 data);
			void						SetValue(double data);
			void						SetValue(void* pData, size_t size);
			void						SetValue(const TXString& str);

			size_t						GetBytesCount() const;
			void						CopyInto(void* pData, size_t size) const;

			void						SetValueAsString(const TXString& str);
			TXString					GetValueAsString();

		protected:
			void			SetData(void* pData, size_t size);

			TXString			m_name;
			UInt8*				m_pBytes;
			size_t				m_nBytesCnt;
			TXString			m_valueAsString;
			TXStringSTLArray	m_arrEnumValues;
		};

		// ---------------------------------------------------------------------------
		typedef std::vector<VWDataSerializerValue*>		TDataSerializerValuesArray;
		typedef std::vector<VWDataSerializerGroup*>		TDataSerializerGroupsArray;

		// ---------------------------------------------------------------------------
		class VWDataSerializerGroup
		{
			friend class VWDataSerializer;
											VWDataSerializerGroup(TDataIdentifier id, const char* szName);
		public:
											~VWDataSerializerGroup();

			bool							IsGroupIdentifier(TDataIdentifier id);

			void							ClearChildGroups();
			VWDataSerializerGroup*			CreateChildDataGroup(TDataIdentifier id, const char* szGroupName);
			VWDataSerializerGroup*			FindChildDataGroup(TDataIdentifier id, const char* szGroupName) const;
			void							FindChildDataGroups(TDataSerializerGroupsArray& outArray, TDataIdentifier id, const char* szGroupName) const;

			TXString						GetName() const;
			TDataIdentifier					GetIdentifier() const;

			void							AddValue(const VWDataSerializerValue& value, size_t index, const char* szValueName);
			VWDataSerializerValue			GetValue(size_t index, const char* szValueName) const;

			VWDataSerializerGroup*			GetChildGroup(TDataIdentifier id, const char* szGroupName);

		protected:
			TDataIdentifier					m_identifier;
			TXString						m_szName;

			TDataSerializerValuesArray		m_arrValues;
			TDataSerializerGroupsArray		m_arrChildGroups;
		};

		// ---------------------------------------------------------------------------
		// Chunk based serializator
		class VWDataSerializer
		{
		public:
										VWDataSerializer(const char* szSerializerName);
			virtual						~VWDataSerializer();

		public:
			void						ClearChildGroups();
			VWDataSerializerGroup*		CreateChildDataGroup(TDataIdentifier id, const char* szGroupName);
			VWDataSerializerGroup*		FindChildDataGroup(TDataIdentifier id, const char* szGroupName) const;
			void						FindChildDataGroups(TDataSerializerGroupsArray& outArray, TDataIdentifier id, const char* szGroupName) const;

			size_t						GetDataBytesCount() const;
			void						SaveDataInMemory(void* pData) const;
			bool						ReadDataFromMemory(void* pData, size_t size);
			void						SaveDataInVWSettings() const;
			bool						ReadDataFromVWSettings();

		protected:
			size_t						SaveDataInMemoryReq(VWDataSerializerGroup* pGroup, UInt8* pData) const;
			bool						ReadDataFromMemoryReq(VWDataSerializerGroup* pGroup, UInt8* pData, size_t size);
			void						SaveDataInVWSettingsReq(VWDataSerializerGroup* pGroup, const TXString& category) const;
			bool						ReadDataFromVWSettingsReq(VWDataSerializerGroup* pGroup, const TXString& category);

		protected:
			VWDataSerializerGroup*		m_pMainGroup;
		};
	}
}