module kyojintati4d.component.option.keyconfigdialon;

private import std.string;
private import y4d_aux.widestring;
private import y4d_draw.font;
private import y4d_draw.fontloader;
private import y4d_draw.screen;
private import y4d_draw.texture;
private import y4d_draw.drawbase;
private import y4d_draw.sprite;

private import y4d_input.mouse;
private import y4d_input.keyinputbase;

private import ytl.y4d_result;

private import yamalib.auxil.properties;
private import yamalib.draw.tiletexture;
private import yamalib.gui.guiparts;
private import yamalib.gui.dialog;
private import yamalib.gui.guibutton;
private import yamalib.gui.keygroup;
private import yamalib.log.log;

/// KYOJINTACHI4Dで、KeyConfigを行うクラス
class KeyConfigDialog : DialogBox {
	
	/// 指定ファイルとフォントからダイアログボックスを生成する
	static KeyConfigDialog createDialogBox(
		DialogBoxResources dlgRes,
		char[] filename, 
		MouseInput mouse,
		KeyInputBase key=null,
		int prevKeyNo=3,
		int nextKeyNo=4 ) 
	{
		Properties prop = Properties.getInstance(filename);
//		prop.load(filename);
		
		int sx = cast(int) prop.getPropertyNum( C_PROP_KEY_SIZEX, 320 );
		int sy = cast(int) prop.getPropertyNum( C_PROP_KEY_SIZEY, 240 );
		char[] msg = prop.getProperty(C_PROP_KEY_MESSAGE);
		int mox = cast(int) prop.getPropertyNum( C_PROP_KEY_MESSAGE_OX, 0 );
		int moy = cast(int) prop.getPropertyNum( C_PROP_KEY_MESSAGE_OY, 0 );
		char[] actCol = prop.getProperty(C_PROP_KEY_BUTTON_ACTIVE);;
		char[] nonActCol = prop.getProperty(C_PROP_KEY_BUTTON_NON_ACTIVE);
		char[][] buttonNm = getButtonText(prop);
		int titleType = cast(int) prop.getPropertyNum( C_PROP_KEY_TITLE_TYPE, 0 );
		int dlgAlpha = cast(int) prop.getPropertyNum( C_PROP_KEY_DLG_ALPHA,  255 );
		prevKeyNo = cast(int) prop.getPropertyNum( C_PROP_KEY_TAB_PREV,  prevKeyNo );
		nextKeyNo = cast(int) prop.getPropertyNum( C_PROP_KEY_TAB_NEXT,  nextKeyNo );
		
		// ダイアログボックスの表示位置
		int dx = cast(int) prop.getPropertyNum( C_PROP_KEY_POSX, 0 );
		int dy = cast(int) prop.getPropertyNum( C_PROP_KEY_POSY, 0 );
		// 上の座標は何を意味するか(左上、中央)
		int pos_base = cast(int) prop.getPropertyNum( C_PROP_KEY_POS_BASE, 0 );
		
		// 指定された表示位置は基準点
		if (0 != pos_base) {
			switch(pos_base) {
			case 1:
				// 中央
				dx -= sx / 2; 
				dy -= sy / 2; 
				break;
			default :
				// そなん実装してないよ...
				break;
			}
		}
		
		// ここ直さないといかんかも
		dlgRes.titleTile = new TileTexture(TileTexture.TILE_TYPE.H_LINE3);
		dlgRes.titleTile.load("img/dialog/title.sdf");
		
		KeyConfigDialog dialog = new KeyConfigDialog();
		dialog.setDialogBoxResources(dlgRes);
		
		// KeyGroupで使用するキーと使用するキー番号を設定
		dialog.setKey(key,prevKeyNo,nextKeyNo);
		dialog.setDialogSize(sx, sy);
		dialog.setXY(dx, dy);
		dialog.setXYOffsetType(DialogBox.POS_OFFSET.LEFT_TOP);
		dialog.setTitleType(cast(DialogBox.TITLE) titleType);
		dialog.setDialogAlpha( dlgAlpha );

		if (0 != msg.length) {
			Texture t = setMessageText(dlgRes.messageFont, msg);
			dialog.setMessageTexture(t, mox, moy, true);
		}
		
		GUIButton[] bts;
		int box, boy;

		foreach(int i, char[] btLabel; buttonNm) {
			getButtonXY(prop, i, box,boy);
			GUIButton bt = createButton(mouse, 
								dlgRes.getButtonLabelFontLoader(),
								dlgRes.getButtonLabelFontLoaderNo(), 
								btLabel, actCol, nonActCol, dlgRes.cursorTile);
			bt.setXY( dx + box, dy + boy);
			bts ~= bt;
		}
		activeButton(bts[0]);
		
		dialog.setButton(bts);

		// コンフィグを行うキーの設定
		dialog.setSrcKey(key);

		return dialog;
	}
	
	
	/// 対象となるキーをセットする
	void setSrcKey(KeyInputBase key) 
	in
	{
		assert( !(key is null) );
	}
	body
	{
		m_srcKey = key;
	}
	
	/// 設定したKeyを取得
	KeyInputBase getSrcKey() {
		return this.m_srcKey;
	}
	
	/// 移動処理
	override void onMove(Screen screen) {
		super.onMove(screen);
		
		/// 終わっていたら何もしない
		if (isFinish()) {
			return;
		}
		
		int buttonNum = m_srcKey.getButtonNum();
		bool hit = false; 
		for (int i = 0; i < buttonNum; ++i) {
			if (m_srcKey.isPush(i)) {
				
				if (isRegKey(i)) {
					// すでに登録されているキー
					Log.print("KeyConfigDialog#onMove : already registrated! : %s", i);
					continue;
				}
				
				hit = true;
				m_buttonNum ~= i;
				break;
			}
		}
		
		if (hit) {
			normalButton(getButton[m_selectIndex]);
			++m_selectIndex;
			if (getButton.length > m_selectIndex) {
				activeButton(getButton[m_selectIndex]);
			}
		}
	
	}
	
	/// 状態を初期状態に戻します
	void reset() {
		m_selectIndex = 0;
		m_buttonNum.length = 0;
	}
	
	/// 設定されたボタンID列を取得
	int[] getKeyButtonIDs() {
		return this.m_buttonNum;
	}
	
	/// 終了したか
	bool isFinish() {
		return m_buttonNum.length == getButton.length;
	}
	
private:

	/// すでに登録されているキー番号か？
	bool isRegKey(int btNo) {
		foreach(inout no; m_buttonNum) {
			if (no == btNo) {
				return true;
			}
		}
		return false;
	}

	/// ボタンを生成する
	static GUIButton createButton(MouseInput mouse, FontLoader fl, int fontno, 
				char[] text, char[] colorOn, char[] colorOff, TileTexture bgTex) {
		GUIButton bt = new GUIButton();
		bt.setMouse(mouse);
		GUIFontButtonListener v = new GUIFontButtonListener;
		v.setFontLoader(fl, fontno);
		v.setType(1);
		v.setColor( colorOn, colorOff);
		v.setText( text );
		v.setActiveBackTexture(bgTex);
		bt.setEvent(v);
		bt.setXY(550,450);
		return bt;
	}
	
	/// 対象のボタンを、「常に選択」状態に設定する
	static void activeButton(inout GUIButton bt) {
		auto v = cast(GUIFontButtonListener) bt.getEvent();
		v.setActiveAlways(true);
	}
	/// 対象のボタンを、通常動作に設定する
	static void normalButton(inout GUIButton bt) {
		auto v = cast(GUIFontButtonListener) bt.getEvent();
		v.setActiveAlways(false);
	}
	
private:
	KeyInputBase m_srcKey;
	int m_selectIndex = 0;
	int[] m_buttonNum;
}