module kyojintati4d.tasktelopkyojin;

private import std.stream;

private import y4d;
private import y4d_thread.gamescenetransiter;
private import y4d_aux.filesys;

private import kyojintati4d.myapp;
private import kyojintati4d.gameinfo;

private import yamalib.counterfsp;
private import yamalib.log.log;

/***
	シナリオテロップクラス
*/
class TaskTelopKyojin : GameTaskBase {

	/// タスク名を返却する
	/**
		このタスク名称を使って、コントローラ部でタスク判別を行う可能性があるので
		ユニークな名前で、実装しておくべきである
	*/	
	override char[] getTaskName() {
		with (kyojintati4d.val.kyojinconst) {
			return KyojinConst.TASK_NAME[KyojinConst.Task.Task_Telop];
		}
	}

	/// 移動の処理を行います
	override int onMove(Object o) {
		try {
			info = cast(GameInfo)o;
	
			if (!init) {
				onInit();
				info.screen.setClearColor(255,255,255);
				info.screen.clear();
				info.screen.blendSrcAlpha();
				init = true;
			}
			
			if ( info.gameSceneTransiter.isTransit() ) {
				return 0;
			}
	
			if ( m_drawCount > 200 ) {
				info.screen.setClearColor( 0,0,0 );
	
				// すべてのスタックを破棄		
				info.gameSceneTransiter.exitScene();
				
				// 強制バックアップを行う
				info.gameSceneTransiter.setTransitType( GameSceneTransiter.C_NO_EFFECT, 1, true );
				info.gameSceneTransiter.jumpScene(KyojinConst.Task.Task_EyeCatche);
		
				// タイトル画面ＢＧＭの終了
				info.bgmloader.stopFade(0,1000);
				destroy();
				
				return -1;
			}
	
			return 0;
		} catch (Exception e) {
			Log.printFatal("RuntimeException %s#onMove : [%s] [%s]", 
				super.toString(), e.toString(), e.msg);
			throw e;
		}
	}

	/// 描画の処理を行います
	override int onDraw(Object o) {
		try {
			info = cast(GameInfo) o;
	
			if ( info.gameSceneTransiter.isTransit() ) {
				return 0;
			}
			
			if ( m_phase == 0 ) {
				info.screen.clear();
				m_alpha++;
				info.screen.setColor( 255, 255, 255, m_alpha.get() );
				int mx = cast(int) (info.screen.getWidth() - m_texMain.getWidth()) / 2;
				int my = cast(int) (info.screen.getHeight() - m_texMain.getHeight()) / 2;
				
				info.screen.blt( m_texMain, mx, my );
				
				if ( m_alpha.isEnd() ) {
					m_phase++;
					m_alpha.reset();
					m_stopCounter.set(0,100,1);
				}
				
			} else if ( m_phase == 1 ) {
				info.screen.clear();
				m_alpha++;
				m_dy++;
				int mx = cast(int) (info.screen.getWidth() - m_texMain.getWidth()) / 2;
				int my = cast(int) (info.screen.getHeight() - m_texMain.getHeight()) / 2;
				int ax = cast(int) (info.screen.getWidth() - m_texA.getWidth()) / 2;
				int bx = cast(int) (info.screen.getWidth() - m_texB.getWidth()) / 2;
				
				info.screen.setColor( 255, 255, 255, 255 );
				info.screen.blt( m_texMain, mx, my );
	
				info.screen.setColor( 255, 255, 255, m_alpha.get() );
				
				info.screen.blt( m_texA, ax, my - m_dy.get() );
				info.screen.blt( m_texB, bx, my + m_dy.get() );
				
				if ( m_dy.isEnd() ) {
					m_stopCounter++;
					if ( m_stopCounter.isEnd() ) {
						m_phase++;
						m_stopCounter.set(0,0,1);
					}
				}
	
			} else {
				// draw out フェーズ
				int drawnum = m_drawNum.get();
				info.screen.setColor(0, 0, 0, 255);
				
				if ( drawnum <= 0 ) {
					
					m_stopCounter++;
					
					if ( m_stopCounter.isEnd() ){
						int x = rand.get(640);
						int y = rand.get(480);
						int add = rand.get(1) == 1 ? 256 : 0;
						info.screen.bltRotate(
							m_texTarms[rand.get(length)], 
							x, y, 
							rand.get(90) + add - 45, 
							2.0f, 
							0);
							
						m_stopCounter.set(0, drawnum, 1);
						m_drawNum++;
					}
					
				} else {
					for (int i = 0; i < drawnum; ++i) {
						int x = rand.get(640) - 20;
						int y = rand.get(480) - 10;
						int add = rand.get(1) == 1 ? 256 : 0;
						info.screen.bltRotate(
							m_texTarms[rand.get(length)], 
							x, y, 
							rand.get(90) + add - 45, 
							2.0f, 
							0);
					}
					m_drawNum++;
					m_drawCount++;
				}
	
			}
			
			return 0;
		} catch (Exception e) {
			Log.printFatal("RuntimeException %s#onDraw : [%s] [%s]", 
				super.toString(), e.toString(), e.msg);
			throw e;
		}
	}

	/// レガシーなヤツ。使わない。
	override int task(Object o) {
		info = cast(GameInfo)o;

		if (!init) {
			onInit();
		}
		return 0;
	}

	/// タスクが使用したインスタンスを破棄し、ＧＣを起動する
	override void destroy() {
		m_message = null;;
	
		m_texMain.release();
		m_texA.release();
		m_texB.release();
		
		m_texMain = null;
		m_texA = null;
		m_texB = null;
		
		foreach( inout Texture t; m_texTarms ) {
			t.release();
			t = null;
		}

		Log.print("%s#destroy : destroyed.", super.toString());
	}	

private:

	/// 初期化処理
	void onInit() {
		// メモリー状況をプリント
		GameInfo.printMemoryState();

		if ( !rand ) {
			rand = new Rand();
			rand.randomize();
		}
		
		m_texMain = new Texture();
		m_texA = new Texture();
		m_texB = new Texture();
		
		m_texMain.load( "img/telop/kyo1/main.png" );
		m_texA.load( "img/telop/kyo1/a.png" );
		m_texB.load( "img/telop/kyo1/b.png" );

		m_alpha = new RootCounterS();
		m_alpha.set(0, 255, 2);
		
		m_stopCounter = new RootCounterS();
		m_stopCounter.set(0, 0, 1);
		
		m_drawNum = new RootCounterS();
		m_drawNum.set(-10, 12, -5);
		
		m_dy = new InteriorCounter();
		m_dy.set( 5, 100, 180 );
		
		loadTarm();
		
		m_phase = 0;
	}

	/// テキスト読み込み
	void loadTarm() {
		std.stream.MemoryStream m = 
			new std.stream.MemoryStream( cast(char[]) FileSys.read("img/telop/kyo1/telop.txt") );
		while (!m.eof) {
			char[] linebuf = m.readLine();
			m_message ~= linebuf;
		}
		m.close();
		
		m_texTarms = null;
		foreach ( inout char[] str; m_message ) {
			Texture tmp = new Texture();
			tmp.setSurface( info.fontloader.get(0).drawBlendedUnicode( toWCS(str) )  );
			m_texTarms ~= tmp;
		}
		
	}



private:
	GameInfo info;
	bool init;
	static Rand rand;
	
	int m_phase;
	int m_drawCount;
	
	char[][] m_message;
	
	Texture m_texMain;
	Texture m_texA;
	Texture m_texB;
	Texture[] m_texTarms;
	
	RootCounterS m_alpha;
	RootCounterS m_stopCounter;
	RootCounterS m_drawNum;
	InteriorCounter m_dy;
	
}
