/*
	menu.h
*/

enum {
	ITEMTYPE_BUTTON,
	ITEMTYPE_SCROLLBAR,
	ITEMTYPE_SELECTOR
};

/*
	構造体のメンバをモジュール menu だけに公開するためのマクロ
	（この定義を変更してコンパイルしなおせば、メンバが不正アクセス
	　されているかどうかがわかる）
*/

#define	DEBUG_M(a)	__ ## a ## __

#ifdef MODULE_MENU
	#define	M(a)	a
#else
	#define	M(a)	DEBUG_M(a)
#endif

typedef	struct _btn {
	short int	M(x),M(y);		// メニュー内での位置
	short int	M(xlen),M(ylen);	// アイテムのサイズ
	short int	M(type);			// アイテムの種別
	int			M(var);			// 種別ごとのデータ
								//		itemPIC ... 絵柄番号
								//		itemBOX ... 矩形の描画色
	void		(*M(dspfunc))(int x,int y);	// アイテム表示時に呼び出す関数
	bool		M(noselect);		// 選択が有効かどうか
	struct _btn	*next;
	int			id;
} BUTTON;

#define	barHORI		0
#define	barVERT		1

typedef struct _sbr {	// ● スクロールバー
	int			M(x),M(y);	// メニュー内での位置
	int			M(type);	// barHORI(0):横型  barVERT(1):縦型
	int			M(len);		// バーの長さ(増/減ボタンも含む)
	int			M(allsize);	// バー全体の意味する大きさ
	int			M(dspsize);	// 全体のうち､表示されている部分の大きさ
	int			M(dsppos);	//               〃               位置
	void		(*M(dspfunc))(int pos);	// 表示対象を更新する関数
	bool		M(dispnum);	//バーの左(下)にそのバーが表す数値を表示するか
	int			M(numofs);		// バーの持つ数値の底上げ値
	bool		M(inv);		// バーの意味する向きを逆にするかどうか
	struct _sbr	*next;
	int			id;
} SCROLLBAR;

typedef struct _sel_e {
	int				M(x),M(y);
	char			*M(str);
	bool			M(available);
	struct _sel_e	*next;
	int				id;
} SELECTOR_ELEMENT;

typedef struct _sel {
	int					M(var);
	SELECTOR_ELEMENT	*M(elist);
	SELECTOR_ELEMENT	*M(d_elist);
	struct _sel			*next;
	int					id;
	struct _sel_e		*cur_se;	// 選択要素を順にとりだすポインタ
	bool				se_static;	// cur_se が elist か d_elist か
} SELECTOR;

#define	SBAR	SCROLLBAR
#define	SEL		SELECTOR
#define	SEL_E	SELECTOR_ELEMENT

typedef struct _anyitem {
	struct _anyitem *M(next);
	int				M(itemtype);
	void			*M(item);
} ANYITEM;

#define	NOFNC	(void (*)())0


typedef	struct _men
{
	char		*M(title);
	int			M(xlen),M(ylen);
	BUTTON		*M(buttonlist);
	SCROLLBAR	*M(sbarlist);
	SELECTOR	*M(sellist);
	BUTTON		*M(d_buttonlist);
	SCROLLBAR	*M(d_sbarlist);
	SELECTOR	*M(d_sellist);
	void		(*M(dspfunc))();
	void		(*M(ersfunc))();
	int			M(x),M(y);
	int			M(x0),M(y0);
	bool		M(nobuf);			// 表示域退避をしているかどうか
	bool		M(display);		// 画面に表示されているかどうか
	void		*M(data);
} MENU;

#undef	M

#define	typeSTR		1
#define	typePIC		2
#define	typeBOX		3
#define	typeOTHER	4
#define	typeSTRe	5		/* 強調文字列 */
#define	typeSTRb	6		/* 箱入り文字列 */
#define	typeSTRc	7		/* センタリング立体強調文字列 */
#define	typeBUTTONS	8
#define	DMY			0


#define	OutOfMenu		-1
#define	itemOther		-2
#define	itemEraseMenu	-3
#define	itemMoveMenu	-4
#define	itemScrollBar	-5
#define	itemSelector	-6


int		menu_init();
void	menu_end();
// 各種取得関数
int		menu_plt(int n);
int		menu_ifdisp();
MENU*	menu_getcurmenu();
void	menu_getmenuxy(MENU *menu, int *x, int *y, int *xlen, int *ylen);
void	menu_getbuttonxy(MENU *menu,int btnnum,int*x,int*y,int*xlen,int*ylen);
int		menu_where(int x,int y,MENU *menu, int *ax,int *ay,SCROLLBAR **sbarp);
// メニュー
int		menu_disp(MENU *menu);
int		menu_dispxy(int x, int y, MENU *menu);
void	menu_erase();
int		menu_addselector(MENU *m, SEL *s);
void	menu_clearselector(MENU *m);
void	menu_settitle(MENU *m, char *title);
// メニューの移動
void	menu_move();
// ボタン
		BUTTON	*menu_button_new(void);
		void	menu_button_delete(BUTTON *b);
		void	menu_button_setid(BUTTON *b,int id);
		BUTTON	*menu_button(MENU *menu, int id);
		void	menu_button_setxy(BUTTON *b, int x, int y);
		void	menu_button_setvar(BUTTON *b, int var);
// スクロールバー
SCROLLBAR *menu_scrollbar(MENU *menu, int id);
int		menu_scrollbar_getvar(SCROLLBAR *sp);
void	menu_scrollbar_setvar(SCROLLBAR *sp, int dsppos);
void	menu_scrollbar_setallsize(SCROLLBAR *sp, int allsize);
void	menu_scrollbar_setdispsize(SCROLLBAR *sp, int dispsize);
void	menu_scrollbar_setxy(SBAR *s,int x,int y);
void	menu_scrollbar_getxy(SBAR *s,int*x,int*y,int*len);
void	menu_scrollbar_setfunc(SBAR *s, void (*func)());
void	menu_touchscrollbar(SCROLLBAR *sp, int ax, int ay);
void	menu_drawscrollbar(SCROLLBAR *sp);
void	menu_makeupscrollbar(SCROLLBAR *sp);
// 選択子
SEL		*menu_selector_new(void);
void	menu_selector_delete(SEL *s);
void	menu_selector_setid(SEL *s, int id);
SEL		*menu_selector(MENU *m, int id);
int		menu_selector_addelement(SEL *s, SEL_E *e);
int		menu_selector_getvar(SEL *s);
void	menu_selector_setvar(SEL *s, int n);
void	menu_selector_makeup(SEL *sp);
	// 選択要素
	SEL_E	*menu_selector_element_new(void);
	void	menu_selector_element_delete(SEL_E *e);
	void	menu_selector_element_setid(SEL_E *e, int id);
	SEL_E	*menu_selector_element(SEL *s,int id);
	SEL_E	*menu_selector_element_getfirst(SEL *s);
	SEL_E	*menu_selector_element_getnext(SEL *s);
	void	menu_selector_element_setxy(SEL_E *e,int x,int y);
	void	menu_selector_element_setstr(SEL_E *e,char *s);
	void	menu_selector_element_setavail(SEL_E *e,bool f);
// int		menu_selector_getvar(SEL *s);
#define	menu_getselvar	menu_selector_getvar
// void	menu_selector_setvar(SEL *s, int n);
// void menu_selector_setavailability(MENU *menu,int sel_id,int el_id,bool flag);
void	menu_touchselector(MENU *menu);
// メニュー上の描画
void	menu_putstr(int ofsx, int ofsy, char *str, int type);
void	menu_buttonputstr(BUTTON *ip, int ofsx, int ofsy, char *str, int type);
void	menu_drawbox(int x1, int y1, int xlen, int ylen);
// 任意データの設定・取得・解除
void	menu_setdata(MENU *menu, void *data);
void	*menu_getdata(MENU *menu);
void	menu_cleardata(MENU *menu);

#define	menuX	(menu_getcurmenu()->x)
#define	menuY	(menu_getcurmenu()->y)
