#ifndef _MENUS_
#define _MENUS_

#define MENU_EVENT_MASK KeyPressMask | KeyReleaseMask | ButtonPressMask | \
	ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | ExposureMask

#define MPOP_CENTER (1<<0)
#define MPOP_ANIM   (1<<1)

#define menu_text_padding (menu_style.item_font.ht / 2)

#include "misc.hh"

struct MenuStyle
{
	MyFont item_font;
	MyFont title_font;
	MyColor back;
	MyColor text;
	MyColor hiback;
	int hiback_fn;
	MyColor hitext;
	MyColor rule;
	MyColor title;
	GC hibackGC;
	GC ruleGC;
	GC textGC;
	GC hitextGC;
#ifdef FONTS_XCORE
	GC titleGC;
#endif
	int bw;
	
	char *bkg_xpm;
	MyPixmap bkg;

	MenuStyle ();
	int init ();
};

#include "boxes.hh"

struct MItem: Box
{
	MItem *it_next;
	MItem *it_prev;

	int state; // highlighted/unhighlighted

	MItem ();
	//  virtual ~MItem () {};

	int fill (GC);
	int cl ();
	int handle_event ();
	virtual int on ();
	virtual int off ();
	virtual int action () {};
	// virtual int type (); // 0 if MItem, 1 if MCommand or its descendant
};

struct MText: MItem
{
	int xoff, yoff;
	char *text;
	int len; // strlen(text) 

	~MText ();
	int ia ();
	int fa ();
#ifdef FONTS_XFT
	int draw_text (MyColor, MyFont);
#elif defined FONTS_XCORE
	int draw_text (GC);
#endif
};

struct MSelectable: MText
{
	int hotoff; // hot key offset; 0 - no hot key  1 - first character (offsets have 1 added)
	char hotkey;

	int parse_hotkeys ();
	int draw ();
	int handle_event ();
	int handle_KeyPress ();
	int blink ();
};

#include "commands.hh"

struct MCommand: MSelectable {
	Cmd *cmd;
	int del;
	
	MCommand ();
	MCommand (char *, Cmd *);
	~MCommand ();
	int action ();
};

#define MP_CLICKABLE (1<<0)

struct MPopup: MSelectable
{
	int flag;
	Menu *menu;

	MPopup ();
	int ia ();
	//int fa ();
	int draw ();
	int draw_triangle (GC);
	//  int handle_MotionNotify ();
	int handle_KeyPress ();
	int handle_event ();
	int off ();
	int action ();
};

struct MTitle: MText
{
	MTitle ();
	MTitle (char *);
	int ia ();
	int fa ();
	int draw ();
};

struct MHRule: MItem {
	int x1, x2;

	MHRule ();
	int ia ();
	int draw ();
};

struct MVRule: MItem {
	int y1, y2;

	MVRule ();
	int ia ();
	int draw ();
};

#include "lineparser.hh"

struct Menu: Win
{
	Menu *next;
	Menu *parent;

	MItem *focus;
	MItem *it_last;

	char *name;
	int in_use;
	VBox *vbox;

	char *src; // menu definition source

	Menu ();

	int clear ();
	int select (MItem *);
	int pop_up (int);
	int reset_line ();
	int next_line ();
	int pop_down (int=0);
	int handle_event ();
	int handle_KeyPress ();
	int handle_ButtonRelease ();
	int handle_MotionNotify ();
	int handle_Expose ();
	int go_up ();
	int go_down ();
	int exec ();
	int set_style ();
	int parse_int ();
	int border_add ();
	int parse_shell ();
	int it_add (MItem *);
	virtual int build ();
};

struct SwitchToMenu: Menu
{
	int build ();
};

struct HiddenWindowsMenu: Menu
{
	int build ();
};

struct MenuList
{
	Menu *first;

	MenuList ();
	int init ();
	int done ();

	int add (Menu *);
	int find (Menu *&m, char *);
};

//********************************************************************

extern MenuList menu_list;
extern MenuStyle menu_style;
extern Menu *winops_menu;
extern Menu *pager_winops_menu;

#endif // _MENUS_
