#if defined COMMON_FUNCTION_INCLUDED___
  #endinput
#endif
#define COMMON_FUNCTION_INCLUDED___

/*!

	\file ヘルパー関数

*/

#include <all.inc>

obj: CreateCharacterWH(float:x, float:y, float:w, float:h, texture:tex = 0, obj:parent = 0) {

	new obj:object;
	if (parent) {	//親オブジェクトが渡されてきているなら親を設定
		object = CreatePlane(parent);
	} else {
		object = CreatePlane(Disp2D());
	}
	SetLocalScale(object, w, h, 1.0);
	SetPos(object, x, y, 1.0);
	SetColor(object, 1.0, 1.0, 1.0, 1.0);

	if (tex) {
		SetTexture(object, tex);
	}

	return object;
}

/*!

	指定のタグ名から小数点データを取得する。

*/
stock float:GetFloatData(xmltag:tag, attr[]) {

	new tmp_value[64];

	domGetTagName(tag, tmp_value);
	domGetData(tag, attr, tmp_value);

	return atof(tmp_value);

}

/*!

	指定のタグ名から整数データを取得する。

*/
stock GetNumericData(xmltag:tag, attr[]) {

	new tmp_value[64];

	domGetTagName(tag, tmp_value);
	domGetData(tag, attr, tmp_value);

	return atoi(tmp_value);

}

/*

	テクスチャ同期読み込み

*/
stock texture: TextureLoad(const url[], bool:is_keep = false) {

	if (strlen(url) == 0) {
		return texture:0;
	}

	new filename[256];
	sprintf( filename, url );

//	printf("Loade Texture : %s ....", filename);

	// デコード起動
	imgDecStart(filename);

	// デコード待ち
	new result = imgDecWait();
	if (result != IMGDEC_OK) {
		printf("Failured  Texture : %s ....", filename);
		return texture:0;
	}

//	printf("Done.\n");

	if (is_keep) {
		new texture:tex = imgTexID();
		imgKeepTex(tex);

		return tex;
	}

	return imgTexID();

}

/*!

	texture_arrayにtagとtagname以下に設定されているテクスチャを全部読み込む
	offsetを指定すると、指定した配列のインデックスから処理される。

	\param xmltag:tag
	\param const tagname[]
	\param const id[]
	\param texture:texture_array[]
	\param offset = 0

	↓こんな構造のxml対応
	<TEXTURE id = "baseparts" comment = "共通BGテクスチャ">
		<PARTS path = "texture/block_start.png" />
		<PARTS path = "texture/block_goal.png" />
	</TEXTURE>

*/
stock TextureLoadFromXml(xmltag:tag, const tagname[], const id[],
									 texture:texture_array[], offset = 0) {

	//テクスチャを取り込み
	new xmltag:parent = domFindTag( tag, tagname, id);
	new i = offset;
	for (new xmltag: child = domFirstChild(parent) ; child ; child = domNext(child)) {
		{	//座標とサイズを設定
			new tmp_value[64];
			domGetData(child, "path", tmp_value);

			texture_array[i] = TextureLoad(tmp_value, true);
		}
		++i;
	}
}

/*!

	指定されたtagとidからindex番目のテクスチャを
	texture_array[array_index]に読み込む

	\param xmltag:tag
	\param const tagname[]
	\param const id[]
	\parama texture:texture_array[]
	\param array_index = 0
	\parama tex_index = 0

	↓こんな構造のxml対応
	<TEXTURE id = "baseparts" comment = "共通BGテクスチャ">
		<PARTS path = "texture/block_start.png" />
		<PARTS path = "texture/block_goal.png" />
	</TEXTURE>

*/
stock TextureLoadFromXmlofIndex(xmltag:tag, const tagname[], const id[],
									 texture:texture_array[], array_index = 0, tex_index = 0) {

	new xmltag:parent = domFindTag( tag, tagname, id);
	new xmltag:child = domFirstChild(parent);
	for (new i = 0; i < tex_index;i++) child = domNext(child);

	{	//座標とサイズを設定
		new tmp_value[64];
		domGetData(child, "path", tmp_value);

		texture_array[array_index] = TextureLoad(tmp_value, true);
	}

}

/*!

	指定されたtagとidからindex番目のテクスチャを
	texture_array[array_index]に読み込む

	\param xmltag:tag
	\param const tagname[]
	\param const id[]
	\parama texture:texture_array[]
	\param array_index = 0
	\parama tex_index = 0

	↓こんな構造のxml対応
	<TEXTURE id = "alphabet" comment = "文字テクスチャ">
		<PARTS x =   "0" y = "32" w = "12" h = "16" char = "A"/>
		<PARTS x =  "12" y = "32" w = "12" h = "16" char = "B"/>
		<PARTS x =  "24" y = "32" w = "12" h = "16" char = "C"/>
	</TEXTURE>

*/

stock TrimingTextureFromXml(
			xmltag:tag,
			const tagname[],
			const id[],
			texture:texture_array[], offset = 0, x_offset = 0, y_offset = 0) {

//	printf("%s\n", id);

	new xmltag:parent = domFindTag(tag, tagname, id);
	new i = offset;
	for (new xmltag: child = domFirstChild(parent) ; child ; child = domNext(child)) {
		//座標とサイズを設定
		new x, y, w, h;
		x = GetNumericData(child, "x");
		y = GetNumericData(child, "y");
		w = GetNumericData(child, "w");
		h = GetNumericData(child, "h");

		imgTrimStart(x + x_offset, y + y_offset, w, h);

		if(imgTrimWait() == IMGTRIM_OK) {
			new texture:tex_id = imgTexID();
			texture_array[i] = tex_id;
			imgKeepTex(tex_id);
//			printf("Trim OK : %d \n",i);
		}
		++i;
	}
}


/*
	Zソートオプションを決めます。

	ZSORT_NORMAL = 0,	// 普通にZ値でソート
	ZSORT_TOP,			// 兄弟の中でTOP
	ZSORT_BOTTOM,		// 兄弟の中でBOTTOM
	ZSORT_TOP_MOST,		// シーンの中でTOP
	ZSORT_BOTTOM_MOST,	// シーンの中でBOTTOM

	\sa 3d.inc

*/
stock SetZOrder(obj:target, value) {
	SetOptionI(target, TAG("ZSRT"), value);
}

/*
	Zソートを決めます。
*/
stock SetZOffset(obj:target, float:value) {
	SetOptionF(target, TAG("ZOFS"), value);
}

/*
	最背面を作成します。
*/
stock obj: CreateBG() {

	new obj:bg_parts = CreatePlane(Disp2D());
	SetColor(bg_parts, 0.0, 0.0, 0.0, 1.0);
	SetPos(bg_parts, 320.0, 224.0, 1.0);
	SetLocalScale(bg_parts, 640.0, 448.0, 1.0);

	SetZOrder(bg_parts, ZSORT_BOTTOM_MOST);

	return bg_parts;

}

stock obj:CreateLabelMessage(string[], obj:parent = 0) {

	new obj:label = CreateLabel(parent);
	SetPos(label, 0.0, 0.0, 1.0);
	SetColor(label, 1.0, 1.0, 1.0, 1.0);
//	SetOptionI(label, TAG("FONT"), FontID(FONT_HGRSGU));
	SetOptionS(label, TAG("UTF8"), string);
	SetOptionI(label, TAG("FSIZ"), 18);

	return label;
}
stock MessageBox(title[], message1[], message2[]) {

	//黒い背景
	new obj:bg = CreatePlane(Disp2D());
	SetColor(bg, 0.0, 0.0, 0.0, 0.0);
	SetPos(bg, 320.0, 224.0, 1.0);
	SetLocalScale(bg, 640.0, 448.0, 1.0);
	SetZOrder(bg, ZSORT_TOP_MOST);
	SetZOffset(bg, 1.0);

	AnimColor(bg, 0.0, 0.0, 0.0, 0.5, 100.0);
	wait(100);

	//ダイアログ背景
	new obj:dlg = CreatePlane(bg);
	SetPos(dlg, 0.0, 0.0, 0.0);
	SetLocalScale(dlg, 320.0, 140.0, 1.0);
	SetColor(dlg, 0.0, 0.3, 0.6, 0.5);
	SetZOrder(dlg, ZSORT_TOP_MOST);
	SetZOffset(dlg, 2.0);
	SetOptionI(dlg, TAG("FDEG"), 65535);

	//上部バー
	new obj:caption_base = CreatePlane(bg);
	SetPos(caption_base, 0.0, -50.0, 0.0);
	SetLocalScale(caption_base, 320.0, 24.0, 1.0);
	SetColor(caption_base, 0.0, 0.3, 0.6, 0.2);
	SetZOrder(caption_base, ZSORT_TOP_MOST);
	SetZOffset(caption_base, 3.0);
	SetOptionI(caption_base, TAG("FDEG"), 65535);
	SetOptionI(caption_base, TAG("ALPH"), ALPHA_BLEND_AMPLIFY);

	//渡された文字列の作成
	new label_color[4];
	MakeCol4( label_color, { 255,255,255,255, 255,255,255,255,
							 255,192,176,228, 255,192,176,228 } );

	new obj:dlg_caption = CreateLabelMessage(title, dlg);
	SetColor(dlg_caption, 1.0, 1.0, 1.0, 1.0);
	SetPos(dlg_caption, 0.0, -42.0, 0.0);
	SetOptionI(dlg_caption, TAG("HALN"), ALIGN_CENTER);
	SetZOrder(dlg_caption, ZSORT_TOP_MOST);
	SetZOffset(dlg_caption, 10.0);

	new obj:label1 = CreateLabelMessage(message1, dlg);
	SetOptionI(label1, TAG("HALN"), ALIGN_CENTER);
	SetScale(label1, 1.0, 1.2, 1.0);
	SetZOrder(label1, ZSORT_TOP_MOST);
	SetZOffset(label1, 10.0);
	SetOptionP(label1, TAG("COL4"), label_color);

	new obj:label2 = CreateLabelMessage(message2, dlg);
	SetPos(label2, 0.0, 48.0, 0.0);
	SetOptionI(label2, TAG("HALN"), ALIGN_CENTER);
	SetScale(label2, 1.0, 1.2, 1.0);
	SetZOrder(label2, ZSORT_TOP_MOST);
	SetZOffset(label2, 10.0);
	SetOptionP(label2, TAG("COL4"), label_color);

	new obj:selector = CreatePlane(bg);
	SetLocalScale(selector, 58.0, 30.0, 1.0);
	SetColor(selector, 0.0, 0.3, 0.6, 0.5);
	SetScale(selector, 5.0, 1.0, 0.1);
	SetZOrder(selector, ZSORT_TOP_MOST);
	SetZOffset(selector, 5.0);
	SetOptionI(selector, TAG("FDEG"), 8192);
	SetOptionI(selector, TAG("ALPH"), ALPHA_BLEND_ADD);

	new obj:selector2 = CreatePlane(selector);
	SetLocalScale(selector2, 48.0, 28.0, 1.0);
	SetPos(selector2, 0.0, 1.0, 0.0);
	SetColor(selector2, 0.0, 0.3, 0.6, 1.0);
	SetScale(selector2, 1.0, 0.9, 1.0);
	SetZOrder(selector2, ZSORT_TOP_MOST);
	SetZOffset(selector2, 5.0);
	SetOptionI(selector2, TAG("FDEG"), 16384);
	SetOptionI(selector2, TAG("ALPH"), ALPHA_BLEND_ADD);

	new select_index = 0;
	SetPos(selector, 0.0, -9.0, 0.0);
	AnimColor(selector2, 0.0, 0.3, 0.6, 0.0, 400.0);

	new pad;
	for (;;) {
		//タイトル表示
		PadState(_, pad);
		if (pad & ePADRright) {
			AnimColor(selector2, 0.0, 0.3, 0.6, 1.0, 50.0);
			wait(50);
			break;
		}
		if (pad & ePADLup) {

			AnimScale(selector, 5.0, 0.0, 1.0, 50.0);
			AnimColor(selector2, 0.0, 0.0, 0.0, 0.0, 50.0);

			select_index--;
			if (select_index < 0) {
				select_index = 1;
			}

			wait(50);

			SetPos(selector, 0.0, -9 + select_index * 48.0, 0.0);
			AnimScale(selector, 5.0, 1.0, 1.0, 50.0);
			AnimColor(selector2, 0.0, 0.3, 0.6, 1.0, 50.0);
//			AnimScale(selector2, 1.0, 1.0, 1.0, 1.0, 50.0);
			wait(50);

			AnimColor(selector2, 0.0, 0.3, 0.6, 0.0, 400.0);

		}
		if (pad & ePADLdown) {

			AnimScale(selector, 5.0, 0.0, 1.0, 50.0);
			AnimColor(selector2, 0.0, 0.0, 0.0, 0.0, 50.0);

			select_index++;
			if (select_index > 1) {
				select_index = 0;
			}

			wait(50);

			AnimScale(selector, 5.0, 1.0, 1.0, 50.0);
			SetPos(selector, 0.0, -9 + select_index * 48.0, 0.0);
			AnimColor(selector2, 0.0, 0.3, 0.6, 1.0, 50.0);
//			AnimScale(selector2, 1.0, 1.0, 1.0, 1.0, 50.0);
			wait(50);

			AnimColor(selector2, 0.0, 0.3, 0.6, 0.0, 400.0);

		}
		sleep;
	}

	AnimColor(label1, 0.0, 0.0, 0.0, 0.0, 100.0);
	AnimColor(label2, 0.0, 0.0, 0.0, 0.0, 100.0);

	AnimScale(dlg, 3.0, 0.0, 1.0, 100.0);
	AnimColor(dlg, 0.0, 0.0, 0.0, 0.0, 100.0);

	AnimColor(selector, 0.0, 0.0, 0.0, 0.0, 100.0);
	AnimColor(selector2, 0.0, 0.0, 0.0, 0.0, 100.0);

	wait(100);



/*
	AnimColor(label1, 0.0, 0.0, 0.0, 0.0, 100.0);
	AnimColor(label2, 0.0, 0.0, 0.0, 0.0, 100.0);

	AnimScale(selector, 2.0, 2.0, 1.0, 100.0);
	AnimColor(selector, 0.0, 0.0, 0.0, 0.0, 100.0);

	AnimScale(dlg, 3.0, 0.0, 1.0, 100.0);
	AnimColor(dlg, 0.0, 0.0, 0.0, 1.0, 100.0);

	wait(100);
*/
	AnimColor(bg, 0.0, 0.0, 0.0, 0.0, 100.0);
	wait(100);

	Destroy(bg);

	return select_index;

}

