// ------------------------------------------------------------------------
/*
	\author: Jaap Suter
   
	Copyright (C) Electronic Arts Canada Inc. 2002.  All rights reserved.	
*/
// ------------------------------------------------------------------------

/*! \file */

#ifndef REVEAL_MRU_MENU_FORWARD_H
#define REVEAL_MRU_MENU_FORWARD_H

namespace Reveal {
    
    class InputState;
	class Renderer;
	struct GuiColors;

	namespace Impl {

		class Tree;
		class Menu;

// -------------------------------------------------------------------------------
/*! 
	\brief Menu that forwards to a most recently used menu;	

	\todo explain;	
*/		 
// -------------------------------------------------------------------------------
class MruMenuForward
{
public:

	typedef enum
	{
		DRAW_CHILDREN,
		DONT_DRAW_CHILDREN
	} DrawChildren;

	//! Constructor, constructs an MRU that forwards to nothing;
	MruMenuForward() : mX( 0 ), mMenu( 0 ), mOpened( 0 ), mLocked( false ), mUseCount( 0 ) {}
	
	//! Sets the menu this MRU forwards to, if it isn't locked;
	void SetMruMenu( Menu* menu ) { if ( !mLocked || !menu ) { mMenu = menu; mMenu ? ++mUseCount : mUseCount = 0; } }

	//! Returns true if the MRU is not pointing to a menu;
	bool Empty() const { return mMenu == 0; }

	//! Tells the MRU to display itself;
	void Show( int x );

	//! Closes the menu this MRU forwards to;
	void Close();
	
	//! Locks the MRU so the menu it forwards to can't be replaced by another menu;
	void Lock() { mLocked = true; }

	//! Returns true if the MRU is locked, false otherwise;
	bool IsLocked() const { return mLocked; }
   
	//! Renders the MRU, and the menu it forwards to;
    void Render( const Renderer& renderer, const GuiColors& guiColors, DrawChildren drawChildren ) const;
	
	/*!
		\brief Gives the MRU and the menu it forwards to a chance to handle the input
		\return true if the MRU or one of its children handled the input, false otherwise;
	*/
	bool Handle( const InputState& inputState, Tree& tree );

	/*!	
		\brief Tests whether one MRU is used less recently used than another
		\return true If this MRU is less recently used than the given MRU;
	*/
	bool IsLessRecentlyUsedThan( const MruMenuForward& mruMenu ) const { return mUseCount < mruMenu.mUseCount; }

	//! Tests whether this MRU forwards to the given menu or not;
	bool ForwardsTo( const Menu* menu ) { if ( menu == mMenu ) { ++mUseCount; return true; } else return false; }

	//! Opens the MRU;
	void Open( Tree& t );

private:

	//! Tests whether this is the special case MRU that forwards to the root (start menu);
	bool ForwardsToStartMenu() const;

    //! Not implemented
    MruMenuForward( const Menu& );
    
    //! Not implemented
    MruMenuForward& operator = ( const MruMenuForward& );

    int			  mX;			//!< X of the top left corner of the forward widget;	
	Menu*		  mMenu;		//!< Menu this mru forwards to, can be NULL;
	bool		  mOpened;		//!< True if the menu this mru forward to is open, false otherwise;
	bool		  mLocked;		//!< True if the menu this mru forwards to cannot be replaced;
	unsigned long mUseCount;	//!< Used to control which of all mru-menus is the least recently used one;
};

	} // Namespace Impl;
} // Namespace Reveal;

#endif

