#ifndef _TK_MENU_H_
#define _TK_MENU_H_


#include "tk_base.h"
#include "tk_menulistener.h"

#include <vector>
#include <map>
#include <string>

using namespace std;

/**
 * \brief Represent menu separator
 *
 * \date 01-12-2006
 *
 * \author Ondrej Svejdar
 *
 * \todo 
 *
 * \bug 
 *
 */
class TkMenuSeparator:public TObject
{
public:
	static const char* type;
    const char* getType() const
	{
		return type;
	}
};

/**
 * \brief Represent elementar menu item
 *
 * \date 01-12-2006
 *
 * \author Ondrej Svejdar
 *
 * \todo 
 *
 * \bug 
 *
 */
class TkMenuCommand:public TObject
{
	string name;
	string id;
public:
	static const char* type;
	const char* getType() const
	{
		return type;
	}
	TkMenuCommand(const string& name,const string& id):name(name),id(id)
	{
	}

	/**
	 * Get name of menu item
	 * \return name of menu item
	 */
	const string& getName() const
	{
		return name;
	}


	/**
	 * Get id of menu item
	 * \return id of menu item
	 */
	const string& getId() const
	{
		return id;
	}
};

class TkMenu;

/**
 * \brief Represent menu
 *
 * \date 01-12-2006
 *
 * \author Ondrej Svejdar
 *
 * \todo 
 *
 * \bug 
 *
 */
class TkMenu:public TkBase
{
	typedef vector<Ptr<TObject> > t_menu_vector;
	t_menu_vector submenus;

	string miName;
	static TkMenuSeparator separator;
	
	typedef map<int,TkMenu* > t_menu_map;
	static t_menu_map menuMap;

	static int idGenerator;
	int menuId;

	typedef vector<Ptr<TkMenuListener> > t_listeners_vector;
	t_listeners_vector listeners;
protected:
	void doSerialize(TiXmlElement& element) const;
	void doDeserialize(const TiXmlElement& element);
public:
	static TXmlObject* newObject()
	{
		return new TkMenu(TclInterp::defaultInterp);
	}

	const static Ptr<TkOptionDef> OPT_ACTIVEBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_ACTIVEBORDERWIDTH ;
	const static Ptr<TkOptionDef> OPT_ACTIVEFOREGROUND ;
	const static Ptr<TkOptionDef> OPT_BACKGROUND ;
	const static Ptr<TkOptionDef> OPT_CURSOR ;
	const static Ptr<TkOptionDef> OPT_FONT ;
	const static Ptr<TkOptionDef> OPT_FOREGROUND ;
	const static Ptr<TkOptionDef> OPT_RELIEF ;
	const static Ptr<TkOptionDef> OPT_SELECTCOLOR ;
	const static Ptr<TkOptionDef> OPT_TAKEFOCUS ;
	const static Ptr<TkOptionDef> OPT_TEAROFF ;
	const static Ptr<TkOptionDef> OPT_TEAROFFCOMMAND ;
	const static Ptr<TkOptionDef> OPT_TITLE ;
	const static Ptr<TkOptionDef> OPT_TYPE ;

	const static Ptr<TkOptionDef> optAll[];
	const static char* type;
	const static char* tkClass;
	
	const Ptr<TkOptionDef>* getOptionAll() const;
	const char* getType() const;
	const char* getTkClass() const;

	TObject* clone();

	/**
	 * Return menu pointer from id
	 * \param id menu id
	 * \return pointer to menu
	 */
	static TkMenu* getMenuById(int id);
	
	TkMenu(Ptr<TclInterp>& interp);
	~TkMenu();


	/**
	 * Add menu listener
	 * \param listener menu listener
	 */
	void addMenuListener(TkMenuListener* listener);
	
	/**
	 * Fired when user click on menu item
	 * \param commandId menu item id
	 */
	void fireMenuEvent(const string& commandId);
	
	
	/**
	 * Add new menu item to the menu
	 * \param miName name of item (this name will user see)
	 * \param miId id of menu item (this is used in event handling routines)
	 */
	void addCommand(const string& miName,const string& miId);
	
	
	/**
	 * Add menu item separator
	 */
	void addSeparator();
	
	
	/**
	 * Add submenu to the menu
	 * \param miName  (this name will user see)
	 * \param subMenu submenu to add
	 */
	void addSubmenu(const string& miName,TkMenu* subMenu);
	
	void create();

	void setBackgroundColor(TkColorOption* color);
	Ptr<TkColorOption>& getBackgroundColor() const;
};


#endif/*_TK_MENU_H_*/
