
#include <all.inc>

#include "../common/bn_defs.inc"
#include "../parts/focus.inc"
#include "../parts/listsys.inc"

// 各チャンネルで使用する場合, 以下をincludeする必要あり
//#include "../common/bn_defs.inc"
//#include "../parts/focus.inc"
//#include "../parts/listsys.inc"

// スクリプトは以下をロードしておく
// <SCRIPT id="general_menu" src="parts/general_menu.amx" type="binary/small"/>
// <SCRIPT id="label_item" src="parts/label_item.amx" type="binary/small"/>

// メニューの文言は xml にて以下のように宣言
// <TEXT id="navimenu" group="menu_title" value="navigator menu" subgroup="navimenu_item" />
// <TEXT id="navimenu_item0" group="navimenu_item" value="About Broadband Navigator" />

const float: INFOMENU_ALIGN_X = 0.344; // 220
const float: INFOMENU_ALIGN_Y = 0.42; //
const float: INFOMENU_ITEM_INTERVAL = 0.06; //

const float:title_r = MENU_TITLE_COL_R ;//200/200/200
const float:title_g = MENU_TITLE_COL_G ;
const float:title_b = MENU_TITLE_COL_B ;

const float:item_r = MENU_ITEM_COL_R ;//60/150/230
const float:item_g = MENU_ITEM_COL_G ;
const float:item_b = MENU_ITEM_COL_B ;

//INFOMENU_STAT_RETURNTOP,
enum{
	INFOMENU_STATE_NONE = 0,
	INFOMENU_STATE_FINISH,
	INFOMENU_STATE_XMLCURR,
	INFOMENU_STATE_XMLSUB,
	INFOMENU_STATE_XMLRET,
	INFOMENU_STATE_ALLFINISH,
	INFOMENU_STATE_INVALIDFINISH,
	INFOMENU_STATE_ERRFINISH,
	INFOMENU_STATE_USRFUNC0,
};

enum{
	INFOMENU_STYLE_LEFT = 0,
	INFOMENU_STYLE_RIGHT,
	INFOMENU_STYLE_HELP,
};

enum{
	INFOMENU_DATA_XML = 0,
	INFOMENU_DATA_DB0,
	INFOMENU_DATA_DB1,
	INFOMENU_DATA_DB2,
	INFOMENU_DATA_DB3,
};


public info_menu_core()
{
	//obj:parent, item_num, const title_str[], const group_str[] )

	new title_curr[64];
	GetArg( "title", title_curr );
	new group_curr[64];
	GetArg( "group", group_curr );
	new id_curr[64];
	GetArg( "id", id_curr );

	new obj:self = Self();
	new float:vp_w;
	new float:vp_h;
	bn_get_viewport( vp_w, vp_h );

	//先にタイトルを表示
    new obj:menutitle = obj: 0;
#if 0
    {
		menutitle = CreateLabel( self );
		SetPos( menutitle, vp_w*0.0, vp_h*0.25, 0.0 );
		SetColor( menutitle, title_r, title_g, title_b, 0.0 );
		AnimColor( menutitle, title_r, title_g, title_b, 1.0, 300.0 );
		SetOptionI( menutitle, TAG("FONT"), FontID(FONT_HGRSGU) );
		SetOptionS( menutitle, TAG("UTF8"), title_curr );
		SetOptionI( menutitle, TAG("FSIZ"), FONTSIZE_TITLE );
		SetOptionI( menutitle, TAG("ZSRT"), ZSORT_TOP_MOST );
    }
#endif
	new obj:popmenu = obj: 0;
	new obj:scroll_bar = obj: 0; //メニュー row以下なら出さない!!

	new obj:parent;
	new menu_status;
	new menu_style;
	new data_type;
	{
		new param0, param1, param2, param3;
		WaitMessage( TAG("INIT"), param0, param1, param2, param3 );
		parent = obj:param0; // 親オブジェ取得
		menu_style = param1;
		menu_status = param2;
		data_type = param3;
		//item_num = param1;
		//selected = param2;
	}

	// 外部に出す関数
	new selected = 0;
	new item_num = 0;
	if( data_type==INFOMENU_DATA_XML ){
		//printf( "std menu create %s\n", group_curr );
		item_num += xmlGroupNum( "TEXT", group_curr );
		selected = info_menu_find_id( group_curr, id_curr ) ;
		//if( selected < 0 ) selected = 0;
	}
	//@@ 4/08 hatakda
	// XMLにDBのデータ混ぜこめる仕様
	item_num += info_menu_open_database( menu_style, menu_status, data_type,
										title_curr, group_curr, id_curr,
										selected );

	// アイテムがない or タイトルが無い
	if( item_num <= 0 && selected < 0 ){
		//menu_status = INFOMENU_STATE_ERRFINISH;
		goto FINISH_SCRIPT;
	}

	// リスト作成
	popmenu = CreateNull( self );
	new col = 1;
	new row = 6;
	//new item_num;
	{
		SetPos( popmenu, vp_w*INFOMENU_ALIGN_X, vp_h*INFOMENU_ALIGN_Y, 0.0 );//64+36
		SetOptionI( popmenu, TAG("ZSRT"), ZSORT_TOP_MOST );
		AttachScript( popmenu, "general_menu", "general_menu" );
		SetPubVar( popmenu, "manager", Self() );
		SetPubVar( popmenu, "focus", GetPubVar( parent, "focus_glowfly") );
		SetPubVar( popmenu, "pad_enable", PAD_ENABLE_RD ) ;
		//SetPubVar( popmenu, "padhelp", PAD_HELP_RD|PAD_HELP_RR ) ;

		// list initialization
		SendMessage( popmenu, TAG("INUM"), item_num );
		SendMessage( popmenu, TAG("CLRW"), col, row ); // 1行 3列
		SendMessage( popmenu, TAG("PADL"), -1, 1, 0, 0 ); //各キーのリスト進度
		SendMessage( popmenu, TAG("DIST"), 0.0, vp_h*INFOMENU_ITEM_INTERVAL );
		SendMessage( popmenu, TAG("MGIN"), 2, 2 ); // margin
		SendMessage( popmenu, TAG("MODE"), LIST_CTRL_POPUP, LIST_ANIM_TODIRECT, LIST_OPEN_NONE );
		SendMessage( popmenu, TAG("ANIM"), 100.0, 0.0, ANIM_TIMER_EXPONENT );
		SendMessage( popmenu, TAG("OFFA"), -1.0 ) ; //margin末端のalp_offset
		SendMessage( popmenu, TAG("IDLA"), 1.0 ) ; //margin末端のalp_offset
		SendMessage( popmenu, TAG("REPT"), 100.0 ) ;
		SendMessage( popmenu, TAG("SLCT"), selected ) ;// 初期フォーカス位置
		// フォーカス渡す POPUPなので返って来ない
		SendMessage( popmenu, TAG("FOCS"), TAG("FRST") ) ; //フォーカス入れ
	}

	if( item_num > row*col ){
		//scroll_active = true;
	    scroll_bar = CreateNull( self );
		SetPos( scroll_bar, vp_w*0.05, vp_h*0.57, 0.0 );
		SetScale( scroll_bar, 2.0, 0.73, 1.0 );
		SetOptionI( scroll_bar, TAG("ZSRT"), ZSORT_TOP_MOST );
		AttachScript( scroll_bar, _, "scroll_bar" );
		SetPubVar( scroll_bar, "manager", Self() );
		SetPubVar( scroll_bar, "focus", GetPubVar( parent, "focus_glowfly") );
	}

	for(;;)
	{
		new bool:listexit = false;
		new id, param, param1, param2;
		while( RecvMessage( id, param, param1, param2 ) )
		{
			if( id==TAG("ITEM"))
			{
				// 子からのアイテム作成要求
				if( obj:param == popmenu && IsValidObject(obj:param1) )
				{
					// 子アイテムへスクリプトアタッチ
					new index = param2;
					new itemstr[64];
					new itemedit[16];
					if( data_type==INFOMENU_DATA_XML ){
						// XML
						xmlGetGroupAttr( "TEXT", group_curr, index,
										 "value", itemstr, 64 );
						xmlGetGroupAttr( "TEXT", group_curr, index,
										 "edit", itemedit, 16 );
					}
					//@@ 4/08 hatakeda 
					// ここは必ず処理, XMLにもDB混ぜこめる仕様に
					/*
					info_menu_create_itemstring( menu_style, data_type, index,
												 group_curr, itemstr );
												 */
					new obj:newitem
						= info_menu_create_item( obj:param1,itemstr,itemedit);

					info_menu_postcreate_item( parent, newitem,
					                           menu_style, data_type, index,
											   group_curr, itemstr );

					SendMessage( obj:param, TAG("ITEM"), newitem, param2 );
				}
			}
			// popup menu
			if( id==TAG("PUSH"))
			{
				// 一度フォーカスを外してやる
				SendMessage( popmenu, TAG("PUSH") );
				SendMessage( popmenu, TAG("FOCS"), TAG("FOUT") );

				// param0:選んだ番号 param1:押したボタン
				// param1 から xmlGetGroupAttr などすればよい
				selected = param;
				if( data_type==INFOMENU_DATA_XML ){
					// XMLなら id_curr IDを返してあげる
					xmlGetGroupAttr( "TEXT", group_curr, selected,
									 "id", id_curr, 64 );
				}

				// 外部に出す関数
				menu_status = info_menu_process( parent, obj:param2,
												 menu_style, data_type,
												 selected, param1,
												 title_curr, group_curr,
												 id_curr );

				// xml後処理
				if( data_type==INFOMENU_DATA_XML ){
					info_menu_postprocess_xml( menu_status, selected,
											  title_curr, group_curr, id_curr);
				}

				// 同一フレーム内なら, 上のFOUTをここでキャンセルする
				SendMessage( popmenu, TAG("FOCS"), TAG("FRST") );

				if( menu_status >= INFOMENU_STATE_FINISH )
				{
					//親に今のメニュー終了を伝える
					SendMessageStr( parent, TAG("TITL"), title_curr );
					SendMessageStr( parent, TAG("GRUP"), group_curr );
					SendMessageStr( parent, TAG("IDTY"), id_curr );
					listexit = true;
				}
			}
		}

		if(scroll_bar)
		{ //スクロールバー操作
			new sel_curr = GetPubVar( popmenu, "scroll_top" );
			SetPubVar( scroll_bar, "top", float(sel_curr)/float(item_num) );
			SetPubVar( scroll_bar, "length", float(row*col)/float(item_num) );
		}

		if( ScriptState(popmenu)==SCRIPT_FINISHED || listexit ) break;
		sleep;
 	}

FINISH_SCRIPT:

	SendMessage( parent, TAG("FNSH"),
				 menu_status, data_type, selected );
	// フォーカス外してやる
	if(popmenu) SendMessage( popmenu, TAG("FOCS"), TAG("FOUT") );
	if(popmenu) SendMessage( popmenu, TAG("FADE"), 0.0, 300.0 );
	if(menutitle) AnimColor( menutitle, title_r, title_g, title_b, 0.0, 300.0 );
	wait(300);

    if(popmenu) Destroy( popmenu );
    if(scroll_bar) Destroy( scroll_bar );
	if(menutitle) Destroy( menutitle );

   	return selected;
}

//public data_type = INFOMENU_DATA_XML;
//public menu_style;
public pop_info_menu( title_group[], title_id[], style )
{
	new menu_status = INFOMENU_STATE_NONE;
	new data_type = INFOMENU_DATA_XML;
	new menu_style = style;

	new float:vp_w;
	new float:vp_h;
	bn_get_viewport( vp_w, vp_h );

	// メニューのベース座標を決定
	new obj:menubase = CreateNull( Disp2D() );

	if( menu_style==INFOMENU_STYLE_LEFT || menu_style==INFOMENU_STYLE_HELP )
		SetPos( menubase, vp_w*0.0, 0.0, 0.0 ); //left 64
	else
	if( menu_style==INFOMENU_STYLE_RIGHT )
		SetPos( menubase, vp_w*(0.5+0.0625), 0.0, 0.0 );

	new title_curr[64];
	new group_curr[64];
	new id_curr[64];
	//new select_curr = 0 ;
	new title_no = info_menu_find_id( title_group, title_id ) ;
	xmlGetGroupAttr( "TEXT", title_group, title_no, "value", title_curr );
	xmlGetGroupAttr( "TEXT", title_group, title_no, "subgroup", group_curr );

	//selected[0] = -1;
	for(;;)
	{
		// 新リスト作成
		new args[256];
		sprintf(args, "title = %s ; group = %s ; id = %s",
				title_curr, group_curr, id_curr );
		AttachScript( menubase, "info_menu_core", _, args ); // 新しいmenuスクリプト
		//SendMessage( menubase, TAG("INIT"), Self(), item_num, select_curr );
		SendMessage( menubase, TAG("INIT"), Self(),
					 menu_style, menu_status, data_type );

		for(;;)
		{
			new id, param0, param1, param2;
			new params[64];
			// get group & id
			while( RecvMessageStr( id, params ) )
			{
				if( id==TAG("TITL") ){
					strcpy( title_curr, params, 64 );
				}
				if( id==TAG("GRUP") ){
					strcpy( group_curr, params, 64 );
				}
				if( id==TAG("IDTY") ){
					strcpy( id_curr, params, 64 );
				}
			}

			// wait finish message
			if( FindMessage( TAG("FNSH"), param0, param1, param2 ) )
			{
				menu_status = param0;
				data_type = param1;
				//select_curr = param2;
			}

			// menuスクリプト階層終了し他の階層に行く
			if( ScriptState(menubase)==SCRIPT_FINISHED ) break;

			sleep;
		}

		if( menu_status>=INFOMENU_STATE_ALLFINISH ) break; //終了処理

	}

	// 最後に確実にDestroy
	if( menubase ) Destroy(menubase);

	return menu_status;

}

#if 0
> stock info_menu_find_id( const group[], const id[] )
> {
> //menuから表示するページをidから探す
> 	new item_num =  xmlGroupNum( "TEXT", group );
> 	new select_curr = 0;
> 	while( select_curr < item_num )
> 	{
> 		new cmpid[64];
> 		xmlGetGroupAttr( "TEXT", group, select_curr, "id", cmpid );
> 		if( !strcmp( id, cmpid ) ) break;
> 		select_curr++;
> 	}
> 	if( select_curr >= item_num ){
> 		printf("WARNING: std menu ID doesn't match\n");
> 		select_curr = -1;
> 	}
> 
> 	return select_curr;
> }
#else
// domの低レベルAPIを使った高速バージョン
stock info_menu_find_id( const group[], const id[] )
{
	//menuから表示するページをidから探す
    new count = 0;
    for( new xmltag: tag = domFirstChild( domRoot(), "TEXT" ) ; tag ; tag=domNext(tag) )
    {
        new tmp[256 char];
        domGetData( tag, "group", tmp );
        if( strcmp( tmp, group )==0 )
        {
            domGetData( tag, "id", tmp );
            if( strcmp( tmp, id )==0 )
            {
                return count;
            }

            count ++;
        }
    }

	return -1;
}
#endif

stock info_menu_get_xmlprev( slct, const group_curr[], group_ret[], id_ret[] )
{
	xmlGetGroupAttr( "TEXT", group_curr, slct, "retgroup", group_ret, 64 );
	xmlGetGroupAttr( "TEXT", group_curr, slct, "retid", id_ret, 64 );
}

stock info_menu_get_xmltitle( const group_curr[], const id_curr[], title[] )
{
	// Get & Set Next title
	new tsel_curr = info_menu_find_id( group_curr, id_curr ) ;
	if( tsel_curr < 0 ){
		printf( "WARNING: infomenu gettitle doesn't hit no id!\n" );
		tsel_curr = 0;//とりあえずゼロに戻す
	}
	{
		new group_ret[64];
		new id_ret[64];
		info_menu_get_xmlprev( tsel_curr, group_curr, group_ret, id_ret );
		new title_no = info_menu_find_id( group_ret, id_ret);
		if( title_no>=0 ){
			xmlGetGroupAttr( "TEXT", group_ret, title_no, "value", title, 64 );
		}
		else{
			printf( "XML Can't find title!!!\n" ); //何も返さないで終了する
			sprintf( title, "" );
		}
	}
}

stock info_menu_postprocess_xml( &menu_status, slct,
								title_curr[], group_curr[], id_curr[])
{
	if( menu_status==INFOMENU_STATE_XMLCURR )
	{
		//なにもしない
		new title[64];
		info_menu_get_xmltitle( group_curr, id_curr, title );
		strcpy( title_curr, title, 64 );
	}else
	if( menu_status==INFOMENU_STATE_XMLSUB )
	{
		new group_sub[64];
		xmlGetGroupAttr( "TEXT", group_curr, slct, "subgroup", group_sub );
		if( !strcmp( group_sub, "" ) )
		{ 
			// 空ならつぎ無し
			printf( "WARNING: nothing sub item !!\n" );
		}
		else{
			// Get & Set next title
			new title[64];
			xmlGetGroupAttr( "TEXT", group_curr, slct, "value", title, 64 );
			printf("group_sub %s, title %s\n", group_sub, title);
			
			//直接次のグループに書き換え
			strcpy( group_curr, group_sub, 64 );
			strcpy( title_curr, title, 64 );
		}
	}else
	if( menu_status==INFOMENU_STATE_XMLRET )
	{
		new group_ret[64];
		new id_ret[64];
		info_menu_get_xmlprev( slct, group_curr, group_ret, id_ret );
		printf(" %d, %s, %s, %s, %s \n",
			   slct, group_curr, id_curr, group_ret, id_ret );
		if( !strcmp( group_ret, "" ) || !strcmp( id_ret, "" ) )
		{ 
			// 空なら親無し
			printf( "WARNING: nothing return menu !!\n" );
			menu_status = INFOMENU_STATE_ERRFINISH;
		}
		else{
			strcpy( group_curr, group_ret, 64 );
			strcpy( id_curr, id_ret, 64 );
			//ret_state = INFOMENU_STATE_XMLRET;
			new title[64];
			info_menu_get_xmltitle( group_ret, id_ret, title );
			strcpy( title_curr, title, 64 );
			// タイトルが見付からなかったら終了の仕様
			if( !strcmp( title, "" ) ){
				printf(" cant found title & finish menu!!\n");
				menu_status = INFOMENU_STATE_ERRFINISH;
			}
		}
	}
}

stock obj: info_menu_create_item( obj:parent, const text[], const edit[] )
{
	new args[128];
    new obj:label = CreateLabel( parent );
	sprintf( args, "label_string = %s ; edit = %s", text, edit );
	AttachScript( label, "info_item", "info_item", args );
	SetPubVar( label, "pad_enable", PAD_ENABLE_RR ) ;
	return label;
}

#if 0
// 外部に出す関数
// for DataBase Open
stock info_menu_open_database( style, menustate, dattype, const title_curr[],
							  const group_curr[], const id_curr[], &slct )
{
	new item_num = 0;
	return item_num;
}

// for DataBase DataListAccess
stock info_menu_create_itemstring( style, dattype, index, const group[], itemstr[] )
{
	// 
	if(dattype == INFOMENU_DATA_DB0){
	}
}

// for DataBase OperationAccess
stock info_menu_process( obj:parent, style, &dattype, slct, btn_id,
						title_curr[], group_curr[], id_curr[] )
{
	new ret_state = INFOMENU_STATE_FINISH;

	if( btn_id==TAG("RRGT") ){
		printf("infomenu btn RRGT\n");
		dattype = INFOMENU_DATA_XML;
		ret_state = INFOMENU_STATE_XMLSUB;
	}
	if( btn_id==TAG("RDWN") ){
		printf("infomenu btn RDWN\n");
		dattype = INFOMENU_DATA_XML;
		ret_state = INFOMENU_STATE_XMLRET;
	}
	return ret_state;
}
#endif
