module yamalib.dict.dictview;

private import y4d_aux.filesys;
private import y4d_draw.drawbase;
private import y4d_draw.screen;
private import y4d_draw.texture;
private import y4d_draw.textureloader;
private import y4d_draw.fontrepository;
private import y4d_input.mouse;
private import y4d_input.mouse;

private import yamalib.dict.dictdata;
private import yamalib.gui.guibutton;
private import yamalib.gui.guilistbox;
private import yamalib.gui.guiscrollbar;

private import yamalib.log.log;

/// ビュー基底クラス
abstract class DictView {
	
	abstract void onMove(Screen);
	abstract void onDraw(Screen);
	
	/// ウィンドウ画面の表示
	void setBaseTexture(Texture t_) {
		m_baseTex = t_;
	}
	
	/// ウィンドウ画像の取得
	Texture getBasetexture() {
		return this.m_baseTex;
	}
	
	/// マウスの設定
	void setMouse(MouseInput mouse_) {
		this.m_mouse = mouse_;
	}
	
	/// 位置の設定
	void setPos(int x_,int y_) {
		this.x = x_;
		this.y = y_;
	}
	
	/// 位置の取得
	void getPos(out int x_, out int y_) {
		x_ = this.x;
		y_ = this.y;
	}

protected:
	MouseInput m_mouse;	
	Texture 	 m_baseTex;
	

	int x;	//!< ベース位置
	int y;
}


/// インデックスビュー
class IndexView : DictView {

	/// モデルデータの設定
	void setIndexData(IndexData data_ ) {
		this.data = data_;
	}
	
	/// 表示エリアの設定
	void setDispArea(RectInt rc_) {
	}
	
	/// 新規選択されたかどうか
	bool isNewSelected() {
		return m_lstBox.isNewSelect();
	}
	
	/// 新規データのファイルパス
	char[] getSelectedDataPath() {
		int selNum = m_lstBox.getSelectedNum();
		if ( selNum >= 0 ) {
			return data.getIndex(selNum).filename;
		}		
		return null;
	}
	
	/// スクロールバーの設定
	void setScrollbar(Scrollbar bar) {
		m_lstBox.setScrollbar(bar);
	}

	/// スクロールバーの取得	
	Scrollbar setScrollbar() {
		return m_lstBox.getScrollbar();
	}
	
	/// 引数に指定した添え字のListBoxItemを取得する
	ListBoxItem getItem(int i) {
		return m_lstBox.getItem(i);
	}
	
	/// 現在選択しているListBoxItemを取得する。何も選択していなければNULL
	ListBoxItem getSelectedItem() {
		return m_lstBox.getSelectedItem();
	}
	
	/// 表示位置の設定
	override void setPos(int x_, int y_) {
		super.setPos(x_,y_);
		m_lstBox.setXY(x_,y_);
	}

	/// 毎回呼び出すなり
	override void onMove(Screen screen) {
		
		if (!init) {
			onInit();
			init = true;
		}
		
//		m_btTop.onMove(screen);
//		m_btBottom.onMove(screen);
//
//		if ( m_btTop.isLClick() ) {
//			// 上へ
//		} else if ( m_btBottom.isLClick() ) {
//			// 下へ
//		}
//		
		m_lstBox.onMove(screen);
	}
	
	/// 毎回呼び出すなり
	override void onDraw(Screen screen) {
		// ウィンドゥ描画
		screen.blt( m_baseTex, x, y );
		
		// リストボックス描画
		m_lstBox.onDraw(screen);
		
		// ボタン描画
//		m_btTop.onDraw(screen);
//		m_btBottom.onDraw(screen);
	}
	
	/// コンストラクタ
	this() {
		m_lstBox = new GUIListBox();
	}
	
private:

	static const RectInt LIST_RECT = {left:0, top:0, right:135, bottom:260 };
	static const int LIST_ITEM_WIDTH = 105;
	static const int LIST_ITEM_HEIGHT = 15;

	/// 初期化処理
	void onInit() {
		createListBox();
	}
	
	/// リストボックスの生成
	void createListBox() {
		Log.print("IndexView#createListBox start!");
		
		m_lstBox.setMouse( m_mouse );
		m_lstBox.setArea(LIST_RECT);
		
		IndexData.Index[] indexes = data.getIndexes();
		foreach ( inout IndexData.Index index; indexes ) {
			Size sz;
			sz.cx = LIST_ITEM_WIDTH;
			sz.cy = LIST_ITEM_HEIGHT;

			SimpleListBoxItem item = new SimpleListBoxItem(m_mouse);
			item.setText( index.title );
			// リストのサイズ指定
			item.setSize(sz);
			m_lstBox.addItem( cast(ListBoxItem) item );
		} 
		
		Log.print("Create ListBox item %d", indexes.length);
		
		Log.print("IndexView#createListBox finish!");
	}

	/// ボタンを生成する
	void createButton() {
		m_btTop = new GUIButton();
		m_btBottom = new GUIButton();
	}
	
	GUIListBox	m_lstBox;
	bool init;

	IndexData data;			//!< データ
	GUIButton m_btTop;		//!< スクロール上
	GUIButton m_btBottom;	//!< スクロール下
	RectInt m_area;			//!< 表示エリア
}

/// メインビュー
class MainView : DictView {
	
	/// モデルデータの設定
	void setData(DictData data_) {
		this.m_data = data_;
	}
	
	/// 見出し文字列を設定する
	void setTitleText(wchar[] text) {
		m_titleText = "[" ~ text ~ "]";
	}
	
	
	/// テキストオフセットの設定
	void setTextOffset(int x_, int y_) {
		m_tox = x_;
		m_toy = y_;
	}

	/// リンクを実行された対象のファイルのパス
	char[] getLinkData() {
		return m_linkDataPath;
	}
	
	/// 毎回呼び出すなり
	override void onMove(Screen screen) {
		
//		m_btPre.onMove(screen);
//		m_btNext.onMove(screen);

		if ( !init ) {
			onInit();
			init = true;
		}
		
/*		// ページングボタン処理
		if ( m_btPre.isLClick() ) {
			// 前頁
			m_data.prevPage();
		} else if ( m_btNext.isLClick() ) {
			// 次ページ
			m_data.nextPage();
		}
*/		
		// リンクデータ処理
		int mx,my;
		m_mouse.getPos(mx,my);
		m_linkDataPath = null;

		if ( m_mouse.isLButtonUp() ) {
			DictData.LinkInfo[] linkInfo = m_data.getLinkInfo();

			int ox = x + m_tox;
			int oy = y + m_toy;
			foreach (inout DictData.LinkInfo li; linkInfo) {
				foreach ( inout RectInt rc; li.rects ) {
					// リンクが実行された
					if ( ptInRect(mx, my, rc.left+ox, rc.top+oy, rc.right+ox, rc.bottom+oy) ) {
						m_linkDataPath = li.filename;
						Log.print("Click Link! %s", m_linkDataPath);
						break;
					}
				}
			}
		}

LINKEND:;		
		
	}
	
	/// 毎回呼び出すなり
	override void onDraw(Screen screen) {
		Color4ub colorOrg = screen.getColor4ub();
		
		screen.setColor(255, 255, 255);
		// 下地描画
		screen.blt( m_baseTex, x, y);
		
		// タイトル文字描画
		drawTitleText(screen);
		
		DictData.DrawChar[] drawchar = m_data.getDrawChar();

		screen.setColor(0,0,0);
		foreach (inout DictData.DrawChar dc; drawchar) {
			float size = dc.size; 
			// 本文字の描画
			screen.setColor( dc.color );
			int tx = x + m_tox + cast(int) dc.pos.x;
			int ty = y + m_toy + cast(int) dc.pos.y;
			
			assert( !(dc.texture is null) );
			
			// 拡大ありで描画
			if (1.0f != size) {
				screen.bltRotate(
					dc.texture,	// テクスチャ 
					tx, ty, 	// x,y 位置
					0, 			// 回転角
					size, 		// 拡大率
					0			// 描画ベース位置（左上）
					);
			} else {
				screen.blt(dc.texture, tx, ty);
			}

			// ルビの描画
			screen.setColor( 255, 255, 255 );
			foreach (inout DictData.DrawChar c; dc.rubi) {
				tx = x + m_tox + cast(int) c.pos.x;
				ty = y + m_toy + cast(int) c.pos.y;
				screen.blt(c.texture, tx, ty);
			}
		}
		
		DictData.LinkInfo[] linkInfo = m_data.getLinkInfo();
		
		// todo 複数行にまたがったときの処理をしないとあかん
		screen.setColor(0, 0, 255);
		int ox = x + m_tox;
		int oy = y + m_toy;
		int mx,my;
		m_mouse.getPos(mx,my);
		foreach (inout DictData.LinkInfo li; linkInfo) {
			foreach (inout RectInt rc; li.rects) {
				screen.drawPolygon( 
					rc.left+ox,		rc.bottom+oy, 				
					rc.right+ox,	rc.bottom+oy, 				
					rc.right+ox,	rc.bottom+m_barWeight+oy, 	
					rc.left+ox,		rc.bottom+m_barWeight+oy 	);
			
				if ( ptInRect(mx, my, rc.left+ox, rc.top+oy, rc.right+ox, rc.bottom+oy) ) {
					screen.setColor(0, 0, 255, 128);
	
					screen.drawPolygon( 
						rc.left+ox,		rc.top+oy, 				
						rc.right+ox,	rc.top+oy, 				
						rc.right+ox,	rc.bottom+oy, 	
						rc.left+ox,		rc.bottom+oy 	);
				}
			}
		}
		
		// ボタン描画
//		m_btPre.onDraw(screen);
//		m_btNext.onDraw(screen);

		screen.setColor( colorOrg );
	}
	
	/// コンストラクタ
	this() {
		m_barWeight = 2;
	}

private:

	/// 点が矩形の内側にあるかどうか
	static bool ptInRect(int px, int py, int left, int top, int right, int bottom) {
		return cast(bool) (px >= left && px < right
			&& py >= top && py < bottom);
	}
	
	/// 初期化処理
	void onInit() {
		Log.print("MainView#onInit start");
		
		createButton();
		Log.print("MainView#onInit finish!");
	}

	/// ボタンを生成する
	void createButton() {
		m_btPre = new GUIButton();
		m_btNext = new GUIButton();
	}
	
	/// 見出し文字を描画する
	void drawTitleText(Screen screen) 
	in
	{
		assert( !(m_data is null) );
	}
	body
	{
		if (m_titleText is null) {
			return;
		}
		auto text = m_data.getFontRepository().getTexture(m_titleText);
		screen.blt(text,x,y);
	}

	bool init;
	DictData m_data;
	int m_barWeight;
	
	int m_tox;
	int m_toy;
	
	wchar[] m_titleText;	//!< 見出し文字
	
	char[] m_linkDataPath;	//!< リンクデータパス
	
	GUIButton m_btPre;		//!< 前のページ
	GUIButton m_btNext;		//!< 次のページ
	

}