// ------------------------------------------------------------------------------------ //
//																						//
//	File: Asura_GUIMenu_Widget_Numeric.h												//
//																						//
//	Description: realtime numeric feedback class										//
//																						//
//	Created: Steve Keen - 21/02/07														//
//																						//
//	Copyright (C) 2006 Rebellion (Derby), All Rights Reserved.							//
// ------------------------------------------------------------------------------------ //

#ifndef __ASURA_GUIMENU_WIDGET_NUMERIC_H__
#define __ASURA_GUIMENU_WIDGET_NUMERIC_H__

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifdef ASURA_USE_GUI_MENU_SYSTEM
#include "Asura_GUIMenu_Root.h"
#include "Asura_GUIMenu_Widget_Base.h"
#include "Asura_GUIMenu_Element_Image.h"
#include "Asura_GUIMenu_Element_Text.h"

// -- Typedef -------------------------------------------------------------------------

// -- Enums ---------------------------------------------------------------------------
enum Asura_GUIMenu_Numeric_Message
{
	ASURA_GUIMENU_NUMERIC_NONE = 0,
	ASURA_GUIMENU_NUMERIC_SET_INT,		// data passed is the position value
};

// -- Defines -------------------------------------------------------------------------
#define fASURA_GUIMENU_WIDGET_NUMERIC_FLASH_TIME_DEFAULT	(0.1f)
#define ASURA_GUIMENU_WIDGET_NUMERIC_DEFAULT_FLOATING_POINT_PRECISION	(3)
#define ASURA_GUIMENU_WIDGET_NUMERIC_PRECISION_MAX				(6)

#define fASURA_GUIMENU_WIDGET_NUMERIC_CONTROL_INITIAL_REPEAT_DELAY			( 0.5f)
#define fASURA_GUIMENU_WIDGET_NUMERIC_CONTROL_SECONDARY_REPEAT_DELAY		( 0.2f)

#define ASURA_GUIMENU_WIDGET_NUMERIC_FLAGS_CONSOLEVAR_UPDATES					(1<<0)
#define ASURA_GUIMENU_WIDGET_NUMERIC_FLAGS_ALWAYS_IN_EDIT_MODE_WHEN_HIGHLIGHTED	(1<<1)
#define ASURA_GUIMENU_WIDGET_NUMERIC_FLAGS_USE_CONSOLEVAR_MIN_AND_MAX			(1<<2)

#define ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START	16

// versions: ASURA_CHUNK_WIDGET_NUMERIC_VERSION
// 0: initial data
// 1: added console var - SK
// 2: added button press auto-repeat vars - SK
// 3: added m_uNumericFlags.
// 4: version bumped to set use console var min and max flag. RAR 24/07/2007
#define ASURA_CHUNK_WIDGET_NUMERIC_VERSION 4

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

// -- Class ---------------------------------------------------------------------------

class Asura_GUIMenu_Widget_Numeric : public Asura_GUIMenu_Widget_Base
{
	friend class Asura_Chunk_GUIMenu;
	friend class Tools_GUIMenu_Widget_Numeric;

	// -- Functions -----------------------------------------------------------------------
public:
	enum Asura_GUIMenu_Inherit_Flag_Widget_Numeric_Type
	{
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_MINIMUM				= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+0)),
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_MAXIMUM				= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+1)),
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_STEP				= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+2)),
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_FEEDBACK_DETAILS	= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+3)),
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_FLASH_DETAILS		= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+4)),
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_CONTROL_REPEAT		= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+5)),

		//ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_MAX is here to stop another programmer adding past bit flag 31
		ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_MAX  				= (1<<(ASURA_GUIMENU_WIDGET_NUMERIC_LOCAL_FLAG_START+15))
	};

	Asura_GUIMenu_Widget_Numeric();
	virtual ~Asura_GUIMenu_Widget_Numeric();

	virtual void 				Update( float fElapsedTime);
	virtual void 				Render( u_int uState);
	virtual void				Copy( const Asura_GUIMenu_Root* pxSource);

	virtual u_int				ProcessInputActivity( const Asura_GUIMenu_Input& xInput);

	// -- UI Message handler functions --
	virtual bool				OnInit( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnDeInit( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnDataChange( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnDataRequest( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnClicked( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnRollIn( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnRollOut( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnEnable( const Asura_Message_GUIMenu_Notify* pxMessage);

	void						SetMaximumValue( float fMax);
	void						SetMinimumValue( float fMin);
	void						SetMinAndMaxValue(float fMin, float fMax);
	void						SetValue( const float fValue );
	void						SetStepValue( float fStep);

	float						GetMaximumValue( void) const { return m_fMaxValue; }
	float						GetMinimumValue( void) const { return m_fMinValue; }
	float						GetValue( void) const		 { return m_fCurrentValue; }
	float						GetStepValue( void) const;

	void						AddStep( void);
	void						SubstractStep( void);

	void 						SetDecrementImage( Asura_GUIMenu_Element_Image* pxDecImage);
	void 						SetIncrementImage( Asura_GUIMenu_Element_Image* pxIncImage);
	void 						SetFeedbackTextElement( Asura_GUIMenu_Element_Text* pxFeedbackText);

	void						StartDecrementFlash( void);
	void						StartIncrementFlash( void);

	void 						SetFeedbackTextAsInteger( void);
	void 						SetFeedbackTextAsFloatingPoint( void);
	bool 						IsFeedbackTextInteger( void) const;
	bool 						IsFeedbackTextFloatingPoint( void) const;

	void						SetFeedbackTextFloatingPointPrecision( u_int uPrecision);
	u_int						GetFeedbackTextFloatingPointPrecision( void) const;

	void 						SetFlashColour( float fRed, float fGreen, float fBlue, float fAlpha);
	void 						SetFlashColour( u_int uRGBAColourValue);
	const Asura_RGBA			GetFlashColour( void) const;

	void						SetFlashTime( float fFlashTime);
	float						GetFlashTime( void) const;

	Asura_GUIMenu_Root*			GetFeedbackTextElement( void) const	{	return m_pxFeedbackText;	}
	Asura_GUIMenu_Root*			GetIncrementImageElement( void) const	{	return m_pxIncImage;	}
	Asura_GUIMenu_Root*			GetDecrementImageElement( void) const	{	return m_pxDecImage;	}

	void						SetConsoleVarName( Asura_Char* pcVarName);

#ifdef ASURA_TOOLS
	// applies search to local console vars after calling parent method
	virtual const bool				FindAndReplaceConsoleVarName( const Asura_UnicodeChar* wszName,const Asura_UnicodeChar* wszReplacementName );
#endif // ASURA_TOOLS

	float						GetInitialControlRepeatDelay( void);//	{	return m_fInitialRepeatDelay;	}
	void						SetInitialControlRepeatDelay( float fDelay)	{	m_fInitialRepeatDelay = fDelay;	}
	float						GetSecondaryControlRepeatDelay( void);//	{	return m_fSecondaryRepeatDelay;	}
	void						SetSecondaryControlRepeatDelay( float fDelay)	{	m_fSecondaryRepeatDelay = fDelay;	}

	bool						IsNumericFlagSet( u_int uNumericFlag) const;
	void						SetNumericFlag( u_int uNumericFlag, bool bTrueOrFalse);
	u_int						GetNumericFlags( void) const;
	void						SetNumericFlags( u_int uNumericFlags);
	u_int*						GetNumericFlagsAsPtr( void);

#ifdef ASURA_TOOLS
    virtual void				UpdateLocalDataFromStyle( void);

	virtual void				WriteToChunkStream( Asura_Chunk_Stream& xStream) const;
	virtual void				ExportToXML(Tools_GUIMenu_XMLExporter* pxExporter) const;
#endif // ASURA_TOOLS

	virtual void				ReadFromChunkStream( Asura_Chunk_Stream& xStream, Asura_GUIMenu_Root* pxParentObject, u_int uChunkVersion);

	virtual bool				RemoveFromThisContainer( Asura_GUIMenu_Root* pxObject);

protected:
	void						UpdateFlashingElements( void);
	void						UpdateFeedbackText( void);

	void						SetupDefaultElements( void);

private:
	void						InitFromConsoleVar();
	void						SetConsoleVar() const;

	bool						HandleInputAutoRepeat( bool bHeldValue);

	// -- Variables -----------------------------------------------------------------------
public:

protected:

private:
	float		m_fElapsedTime;

	u_int		m_uButtonRepeatPhase;
	float		m_fCurrentRepeatDelay;
	float		m_fInitialRepeatDelay;
	float		m_fSecondaryRepeatDelay;

	float		m_fCurrentValue;

	float		m_fMinValue;
	float		m_fMaxValue;
	float		m_fStepValue;

	Asura_RGBA	m_xFlashColour;
	float		m_fDecFlashTimerCountdown;
	float		m_fIncFlashTimerCountdown;
	float		m_fFlashTimerStartVal;

	Asura_GUIMenu_Element_Image* m_pxDecImage;
	Asura_GUIMenu_Element_Image* m_pxIncImage;
	Asura_GUIMenu_Element_Text* m_pxFeedbackText;

	bool		m_bDisplayAsInteger;
	u_int		m_uFloatingPointPrecision;

	u_int		m_uNumericFlags;

	Asura_GUIMenu_ConsoleVar	m_xConsoleVar;

	//for storing state of clicking on the inc or dec images
	union
	{
		u_int	m_uClickState;
		struct
		{
			u_int m_bClickOnInc:1;
			u_int m_bClickOnDec:1;
		};
	};

	typedef Asura_GUIMenu_Widget_Base PARENT;
};
#endif // ASURA_USE_GUI_MENU_SYSTEM
#endif // __ASURA_GUIMENU_WIDGET_NUMERIC_H__
