// ------------------------------------------------------------------------------------ //
//																						//
//	File: Asura_GUIMenu_Modifier.h														//
//																						//
//	Description: container for data modifier on objects									//
//																						//
//	Created: Steve Keen - 6/3/07														//
//																						//
//	Copyright (C) 2006 Rebellion (Derby), All Rights Reserved.							//
// ------------------------------------------------------------------------------------ //

#ifndef __ASURA_GUIMENU_MODIFIER_H__
#define __ASURA_GUIMENU_MODIFIER_H__

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifdef ASURA_USE_GUI_MENU_SYSTEM
#include "Core/Asura_PlatformBasics.h"

#include "GuiMenu/Asura_GUIMenu_CommandConsole.h"

// -- struct -------------------------------------------------------------------------

// -- Enums ---------------------------------------------------------------------------
// new enum for types of data that can be modified, rather than using bit flags from inheritance enums
// Corresponding inheritance flag is indicated by comment after each entry.
// Don't modify any existing values as they are saved out.
enum ASURA_GUIMENU_MODIFY_TYPE
{
	ASURA_GUIMENU_MODIFY_TYPE_INVALID		=  0,
	ASURA_GUIMENU_MODIFY_POSITION			=  1,	// ASURA_GUIMENU_ROOT_LOCAL_FLAG_POSITION
	ASURA_GUIMENU_MODIFY_COLOUR				=  2,	// ASURA_GUIMENU_ROOT_LOCAL_FLAG_COLOUR
	ASURA_GUIMENU_MODIFY_TRANSLUCENCY_MODE	=  3,	// ASURA_GUIMENU_ROOT_LOCAL_FLAG_TRANSLUCENCY
	ASURA_GUIMENU_MODIFY_WIDTH				=  4,	// ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH
	ASURA_GUIMENU_MODIFY_HEIGHT				=  5,	// ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT
	ASURA_GUIMENU_MODIFY_TEXT_STRING		=  6,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_TEXT
	ASURA_GUIMENU_MODIFY_TEXT_OFFSET_X		=  7,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_OFFSET_X
	ASURA_GUIMENU_MODIFY_TEXT_OFFSET_Y		=  8,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_OFFSET_Y
	ASURA_GUIMENU_MODIFY_TEXT_RENDER_FLAGS	=  9,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_RENDER_FLAGS
	ASURA_GUIMENU_MODIFY_TEXT_ID			= 10,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_TEXT_ID
	ASURA_GUIMENU_MODIFY_FONT_SCALE			= 11,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_FONT_SCALE
	ASURA_GUIMENU_MODIFY_FONT_NAME			= 12,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_FONT_NAME
	ASURA_GUIMENU_MODIFY_TEXTURE			= 13,	// ASURA_GUIMENU_ELEMENT_IMAGE_LOCAL_FLAG_TEXTURE
	ASURA_GUIMENU_MODIFY_UVS				= 14,	// ASURA_GUIMENU_ELEMENT_IMAGE_LOCAL_FLAG_UVS
	ASURA_GUIMENU_MODIFY_ALPHA_SCALED		= 15,	// ASURA_GUIMENU_ROOT_LOCAL_FLAG_COLOUR
	ASURA_GUIMENU_MODIFY_WIDTH_SCALED 		= 16,	// ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH
	ASURA_GUIMENU_MODIFY_HEIGHT_SCALED		= 17,	// ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT
	ASURA_GUIMENU_MODIFY_TEXT_SCROLL_RATE 	= 18,	// ASURA_GUIMENU_ELEMENT_TEXT_LOCAL_FLAG_OFFSET_X
	ASURA_GUIMENU_MODIFY_IMAGE_ROTATE		= 19,	// ASURA_GUIMENU_ELEMENT_IMAGE_LOCAL_FLAG_ROTATION
	ASURA_GUIMENU_MODIFY_POSITION_RELATIVE	= 20,	// ASURA_GUIMENU_ROOT_FLAG_USE_RELATIVE_POSITIONING
	ASURA_GUIMENU_MODIFY_SIZE_SCALE			= 21,	// ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH, ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT
	ASURA_GUIMENU_NUM_MODIFY_TYPES
};

// -- Defines -------------------------------------------------------------------------

/*
Versions: ASURA_CHUNK_ELEMENT_TEXT_VERSION

0: Initial data - SK 6.3.07
1: ?
2: changed to vector 2 - NY 01/08/2008
*/
#define ASURA_CHUNK_MODIFIER_VERSION 2

// -- Forward Declarations ------------------------------------------------------------
class Asura_RGBA;
class Asura_Vector_2;
class Asura_Chunk_Stream;
struct Asura_GUIMenu_UV_Set;
class Tools_GUIMenu_XMLExporter;


// -- Structures ----------------------------------------------------------------------

class Asura_GUIMenu_Modifier
{
public :
	enum MODIFIER_TYPE
	{
		DATA_TYPE_NONE = 0,
		DATA_TYPE_UINT,
		DATA_TYPE_INT,
		DATA_TYPE_FLOAT,
		DATA_TYPE_RGBA,
		DATA_TYPE_VECTOR_2,
		DATA_TYPE_UNICODE_STRING,
		DATA_TYPE_CHAR_STRING,
		DATA_TYPE_UV_SET,
		DATA_TYPE_TEXTUREINDEX, //just an int , but special loading/saving code required for this
	};

// -- Class Definition ----------------------------------------------------------------
public:

	Asura_GUIMenu_Modifier();
	Asura_GUIMenu_Modifier(const Asura_GUIMenu_Modifier& xOther);
	~Asura_GUIMenu_Modifier();

	Asura_GUIMenu_Modifier& operator=(const Asura_GUIMenu_Modifier& xOther);

	// -- SK - it's possible to specify multiple states from the list below
	// -- the values just need to be or'd together.
	// ASURA_GUIMENU_ACTION_FLAG_IS_DISABLED	
	// ASURA_GUIMENU_ACTION_FLAG_IS_DEFAULT	
	// ASURA_GUIMENU_ACTION_FLAG_IS_CLICKED	
	// ASURA_GUIMENU_ACTION_FLAG_IS_ROLL_ON	
	// ASURA_GUIMENU_ACTION_FLAG_IS_ROLL_OFF	
	// ASURA_GUIMENU_ACTION_FLAG_IS_HILIGHTED	

	inline void SetStateToModify( u_int uModifyState)	{	m_uModifyState = uModifyState;	}
	inline u_int GetStateBeingModified() const	{	return m_uModifyState;	}

	inline bool IsActivationConditionMet() const { return m_xActivationConditions.IsConditionMet(); }

	inline ASURA_GUIMENU_MODIFY_TYPE GetModifyType() const { return static_cast<ASURA_GUIMENU_MODIFY_TYPE>(m_uModifyType); }
	inline void SetModifyType(ASURA_GUIMENU_MODIFY_TYPE eModifyType) { m_uModifyType = eModifyType; }

#ifdef ASURA_TOOLS
	// GetCorrespondingInheritanceFlag allow style code to check if modifier applies to the style or not.
	u_int GetCorrespondingInheritanceFlag() const { return GetCorrespondingInheritanceFlag( GetModifyType() ); }
	
	// provide tools access to activation conditions
	Asura_GUIMenu_ConditionVarManager*  GetActivationConditions() { return &m_xActivationConditions; }
#endif

	MODIFIER_TYPE GetDataType() const { return m_eDataType;}


	void		SetData( u_int uData);
	void		SetData( int iData);
	void		SetData( float fData);
	void		SetData( const Asura_RGBA& xColourData);
	void		SetData( const Asura_Vector_2& xVector2Data);
	void		SetData( const Asura_UnicodeChar* pwszUnicodeString);
	void		SetData( const Asura_Char* pcszString);
	void		SetData( const Asura_GUIMenu_UV_Set& xUVSet);
	void		SetTextureIndexData(int iTextureIndex);

	u_int		GetUIntData() const;
	int			GetIntData() const;
	float		GetFloatData() const;
	Asura_RGBA	GetColourData() const;
	Asura_Vector_2	GetVector2Data() const;
	Asura_UnicodeChar* GetUnicodeCharStringData() const;
	Asura_Char* GetCharStringData() const;
	Asura_GUIMenu_UV_Set* GetUVSetData() const;
	int			GetTextureIndexData() const;

	void		Copy( const Asura_GUIMenu_Modifier* pxOriginalModifier);

	bool		ReadFromChunkStream( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	void		WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;
	void		ExportToXML(Tools_GUIMenu_XMLExporter* pxExporter) const;
#endif

	// static functions
	static MODIFIER_TYPE GetDataTypeForModifyType( ASURA_GUIMENU_MODIFY_TYPE eModifyType );
#ifdef ASURA_TOOLS
	// GetCorrespondingInheritanceFlag allow style code to check if modifier applies to the style or not.
	static u_int GetCorrespondingInheritanceFlag( ASURA_GUIMENU_MODIFY_TYPE eModifyType );
	static const char* GetModifyTypeName( ASURA_GUIMENU_MODIFY_TYPE eModifyType );
#endif

protected:
	
private:
	void		ReleaseExistingData();
	void		AllocateDataSpace( MODIFIER_TYPE eNewDataType, u_int uStringAllocationSize = 0);

	// -- Variables -------------------------------------------------------------------
public:
protected:
	
private:
	Asura_GUIMenu_ConditionVarManager m_xActivationConditions;

	u_int						m_uModifyState;
	u_int						m_uModifyType;
	MODIFIER_TYPE				m_eDataType;

	union
	{
		u_int*					m_puData;
		int*					m_piData;
		float*					m_pfData;
		Asura_RGBA*				m_pxColourData;
		Asura_Vector_2* 		m_pxVector2Data;
		Asura_UnicodeChar*		m_pwszUnicodeCharStringData;
		Asura_Char*				m_pcCharStringData;
		Asura_GUIMenu_UV_Set*	m_pxUVSetData;
		//u_int					m_uReserved;
		void*					m_pReserved;
	};
};
#endif // ASURA_USE_GUI_MENU_SYSTEM
#endif // __ASURA_GUIMENU_MODIFIER_H__
