#pragma once

/*
	This is the base classes for all game menus.
	
	Menu are somewhat legacy part of this code, since they were first written
	about 4 or 5 years ago for completely different game and I reused them many
	times since then. It's not a very extensible or even easy-to-use system, it
	has many quirks. But it COULD be used to quickly make simple menus, which was
	the main idea hehind it.

	There are some parts of system which are not used by this game. They may have
	become obsolete and broken.
*/

typedef int EntryID;

class MenuEntry;
class IRender;
class IInput;

/*
	Base class for menu. Provides basic functionality like storing entries,
	supporting cursor movement and selection.
*/
class BaseMenu
{
protected:
	  // Menu caption, Not used.
	std::string m_caption;
	  // List of menu entries
	typedef std::vector< MenuEntry* > EntryVector;
	EntryVector m_entries;
	  // Menu position on screen (top-left cornet)
	int m_x, m_y;
	  // Selected entry
	EntryID m_selected;

	friend class MenuEntry;

	  // Entries add themselves. Ain't it nice?
	void AddEntry( MenuEntry *entry );

public:
	BaseMenu( const std::string & caption, int x, int y )
		: m_caption( caption )
		, m_x( x )
		, m_y( y )
		, m_selected( 0 )
	{
	
	}

	virtual void Render( IRender *pRender );
	virtual void ProcessInput( IInput *pInput );
	virtual void Update( float dt );
	virtual void OnShow(){}

	  // Called when player presses Escape
	virtual void Back(){}

	void SetSelected( int index );
	void SetSelected( const MenuEntry *entry );
};

/*
	This is a very basic menu entry class.
	It doesn't even know how to display itself.
	You will only need to use it if you want to
	create your own kind of menu entry. Otherwise,
	looks at MenuHelpers.h.
*/
class MenuEntry
{
protected:
	  // The bigger this is, the lower entry's position will be
	int m_order;
	  // True if entry is selected
	bool m_selected;

public:
	MenuEntry( BaseMenu *menu, int order )
		: m_selected( false )
		, m_order( order )
	{
		if ( menu )
			menu->AddEntry( this );
	}

	virtual void Render( IRender *pRender, int x, int y ) = 0;
	virtual void ProcessInput( IInput *pInput ) = 0;
	virtual void Update( float dt ) = 0;
	
	int GetOrder() const { return m_order; }
	void SetSelected( bool value ) { m_selected = value; }
};
