module yamalib.draw.sequencedrawmanager;

private import std.stream;

private import y4d_draw.drawbase;
private import y4d_draw.screen;
private import y4d_draw.texture;
private import y4d_aux.filesys;
private import y4d_aux.lineparser;

private import yamalib.draw.sequencedraw;
private import yamalib.counterfsp;


/**
　連続描画を一連の処理として実行するクラス
*/
class SequenceDrawManager {
	
	/// 一連の処理を定義ファイルから読み込みます
	void loadDefFile(char[] filename) {
		ubyte[] mem = cast(ubyte[]) FileSys.read(filename);
		if (!mem) return; // 読み込みエラー
		
		std.stream.MemoryStream m = new std.stream.MemoryStream(mem);
		LineParser lp = new LineParser();
		while (!m.eof) {
			char[] linebuf = cast(char[]) m.readLine();
			lp.setLine(linebuf);
			
			// 文字セット
			if ( lp.isMatch( cast(char[]) "#MOJI" ) ){
				char[] fname = lp.getStr();
				if (!fname) continue; // ダメやん
				
				SequenceDraw sd = new SequenceDraw();
				sd.loadDefFile(fname);
				
				if ( sd.isFinish() ) {
					// 読み込みに失敗した
					continue;
				}
				
				// 描画位置
				int x = cast(int) lp.getNum(0);
				int y = cast(int) lp.getNum(0);
				sd.setPos(x,y);
	
				seqDraws ~= sd;
				continue;
			}
			
			// 水平バー
			if ( lp.isMatch( cast(char[]) "#H_BAR" ) ){
				char[] fname = lp.getStr();
				if (!fname) continue; // ダメやん
				
				this.texLine = new Texture();
				this.texLine.load(fname);
				
				this.linePosx = cast(int) lp.getNum(0);
				this.linePosy = cast(int) lp.getNum(0);

				linePos.set(640, linePosx, 30);
				
				continue;
			}
			
			// 垂直バー
			if ( lp.isMatch( cast(char[]) "#V_BAR" ) ){
				char[] fname = lp.getStr();
				if (!fname) continue; // ダメやん

				this.texBar = new Texture();
				this.texBar.load(fname);

				this.barPosx = cast(int) lp.getNum(0);
				this.barPosy = cast(int) lp.getNum(0);
				
				barPos.set(480, this.barPosy, 30);
				continue;
			}
			
			// キャラクタ
			if ( lp.isMatch( cast(char[]) "#CHARA" ) ){
				char[] fname = lp.getStr();
				if (!fname) continue; // ダメやん

				this.texChara = new Texture();
				this.texChara.load(fname);

				this.charaPosx = cast(int) lp.getNum(0);
				this.charaPosy = cast(int) lp.getNum(0);

				continue;
			}
		}
	}
	
	/// 毎回呼び出すなり
	void onMove(Screen screen) {
		if (!init) {
			onInit();
			init = true;
		}
		
		for(int i = 0; i <= indexer; ++i) {
			seqDraws[i].onMove(screen);
		}
		
		// 次の文字
		if ( seqDraws[indexer].isFinish() && !drawFinish) {
			if ( indexer < seqDraws.length-1 ) {
				++indexer;
			} else {
				drawFinish = true;
			}
		} 
		
		if ( drawFinish ) {
			linePos++;
			barPos++;
			alphaCounter++;
		}
	}
	
	/// 毎回呼び出すなり
	void onDraw(Screen screen) {
		screen.blendSrcAlpha ();
		screen.setColor(255, 255, 255);
		
		for(int i = 0; i <= indexer; ++i) {
			seqDraws[i].onDraw(screen);
		}
		
		if (drawFinish) {
			static int x = 630;
			
			screen.setColor( 255,255,255, alphaCounter.get() );
			screen.blt( texChara, this.charaPosx, this.charaPosy );

			screen.setColor(255, 255, 255);
//			screen.blt(texFlash, x -= 20, this.linePosy-90);
			
			// ポーズきめ！
			screen.blt(texLine, linePos.get(), this.linePosy);
			screen.blt(texBar, this.barPosx, barPos.get() );
		}
	}
	
	/// 描画が終了したか？
	bool isFinish() {
		return cast(bool) (alphaCounter.isEnd() && barPos.isEnd());
	}
	
	
	/// コンストラクタ
	this() {
		linePos = new InteriorCounter();
		barPos = new InteriorCounter();
		alphaCounter = new RootCounterS();	
	}	
			
	
private:

	/// 初期化処理
	void onInit() {
		drawFinish = false;
		alphaCounter.set(0, 255, 2);
		
		texFlash = new Texture();
	}

	SequenceDraw[] seqDraws;
	bool init;
	bool drawFinish;
	int indexer;
	
	Texture texLine;
	int linePosx;
	int linePosy;
	Texture texBar;
	int barPosx;
	int barPosy;
	Texture texChara;
	int charaPosx;
	int charaPosy;
	Texture texFlash;
	
	InteriorCounter linePos;
	InteriorCounter barPos;
	RootCounterS alphaCounter;

}