///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains custom lists.
 *	\file		IceCustomList.h
 *	\author		Pierre Terdiman
 *	\date		April, 4, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICECUSTOMLIST_H__
#define __ICECUSTOMLIST_H__

	class ICECORE_API SymbolicList
	{
		public:
		// Constructor/Destructor
											SymbolicList(const char* name=null);
											~SymbolicList();
		// Create a new symbol
						bool				AddSymbol(const char* symbol, udword value);
						bool				AddSymbol(const char* symbol, float value);
		// Get the current number of symbols
						udword				GetNbSymbols()											const;
		// Get ith symbol
						const String*		GetSymbol(udword i)										const;
		// Get ith symbolic value
						bool				GetSymbolicValue(udword i, udword& value)				const;
						bool				GetSymbolicValue(udword i, float& value)				const;
		// Symbol-to-value mapping
						bool				GetSymbolicValue(const String& symbol, udword& value)	const;
						bool				GetSymbolicValue(const String& symbol, float& value)	const;
		// Delete all symbols
						bool				FlushSymbols();
		// Naming
		__forceinline	void				SetName(const String& name)			{ mName = name;		}
		__forceinline	void				SetName(const char* name)			{ mName = name;		}
		__forceinline	const String&		GetName()					const	{ return mName;		}
		private:
						String				mName;
						Container			mList;
	};

	// Global symbolic lists
	ICECORE_API	bool			RegisterSymbolicList(const SymbolicList* list);
	ICECORE_API	bool			UnregisterSymbolicList(const SymbolicList* list);
	ICECORE_API	SymbolicList*	GetSymbolicList(const char* name);
	ICECORE_API	SymbolicList*	CreateSymbolicList(const char* name);

	class ICECORE_API SymbolicStrList
	{
		public:
		// Constructor/Destructor
											SymbolicStrList(const char* name=null);
											~SymbolicStrList();
		// Create a new symbol
						bool				AddSymbol(const char* symbol, const char* value);
		// Get the current number of symbols
						udword				GetNbSymbols()											const;
		// Get ith symbol
						const String*		GetSymbol(udword i)										const;
		// Get ith symbolic value
						bool				GetSymbolicValue(udword i, String& value)				const;
		// Symbol-to-value mapping
						bool				GetSymbolicValue(const String& symbol, String& value)	const;
		// Delete all symbols
						bool				FlushSymbols();
		// Naming
		__forceinline	void				SetName(const String& name)			{ mName = name;		}
		__forceinline	void				SetName(const char* name)			{ mName = name;		}
		__forceinline	const String&		GetName()					const	{ return mName;		}
		private:
						String				mName;
						Container			mList;
	};

	// Global symbolic lists
	ICECORE_API	bool				RegisterSymbolicStrList(const SymbolicStrList* list);
	ICECORE_API	bool				UnregisterSymbolicStrList(const SymbolicStrList* list);
	ICECORE_API	SymbolicStrList*	GetSymbolicStrList(const char* name);
	ICECORE_API	SymbolicStrList*	CreateSymbolicStrList(const char* name);


	// Helpers
	ICECORE_API bool	GetBool(const String& name, bool& flag);
	ICECORE_API bool	GetDecimal(const String& name, udword& value);
	ICECORE_API bool	GetFloat(const String& name, float& value);


	class ICECORE_API CustomList : public Cell
	{
						DECLARE_PROTECTED_CLASS(CustomList)
		public:
						bool			Init(FieldDescriptor* desc, udword nbvalues, bool symbolic=false);

						bool			IsCompatible(FieldDescriptor* fld)	{ return (fld && fld->Type==mBaseType && fld->UserParam==mType);	}

		__forceinline	udword			GetNbValues()		const			{ return mNbValues;					}
		__forceinline	void*			GetValues()			const			{ return mValues;					}
		__forceinline	String*			GetSymbolicValues()	const			{ return mSymbolic;					}

						bool			BuildSymbolicValue(udword index, String& value);

		__forceinline	eFieldType		GetBaseType()		const			{ return mBaseType;					}
		__forceinline	udword			GetCustomType()		const			{ return mType;						}

						bool			Replace(Cell* cell, FieldDescriptor* field, udword index);
		protected:
		// List values
						udword			mNbValues;		//!< Number of values in the list
						udword			mValueSize;		//!< Size in bytes of a single value
						void*			mValues;		//!< List of values
						String*			mSymbolic;		//!< Possible extra list of symbolic values
		// List descriptor
						eFieldType		mBaseType;		//!< Base type for values
						udword			mType;			//!< User subtype for values
		public:
		// List identifier
						udword			mUserID;		//!< Extra possible ID, left to the user - not used at all by the CustomList
	};


//	ICECORE_API CustomList* CreateDefaultCustomList(eFieldType type);

#endif // __ICECUSTOMLIST_H__
