/+
module kyojintati4d.taskmovie;

private import SDL;
private import SDL_smpeg;
private import opengl;
private import y4d;
private import y4d_aux.filesys;
private import kyojintati4d.myapp;
private import kyojintati4d.gameinfo;
private import yamalib.log.log;

class TaskMovie : GameTaskBase {

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

	/// 移動の処理を行います
	override int onMove(Object o) {
		return 0;
	}

	/// 描画の処理を行います
	override int onDraw(Object o) {
		try {
			info = cast(GameInfo)o;
	
			if (!init) {
				init = true;
				onInit();
			}
	
			if (SMPEG_status(smpeg) == SMPEG_PLAYING) {
			} else {
			}
			return 0;
		} catch (Exception e) {
			Log.printFatal("RuntimeException %s#onMove : [%s] [%s]", 
				super.toString(), e.toString(), e.msg);
			throw e;
		}
	}

	/// メインタスク
	override int task(Object o) {
		try {
			info = cast(GameInfo)o;
	
			if (!init) {
				init = true;
				onInit();
			}
	
			if (SMPEG_status(smpeg) == SMPEG_PLAYING) {
			} else {
			}
	
			return 0;
		} catch (Exception e) {
			Log.printFatal("RuntimeException %s#onMove : [%s] [%s]", super.toString(), e.toString(), e.msg);
			throw e;
		}
	}

	/// 占有しているメモリを解放する
	override void destroy() {

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

	/// コンストラクタ
	this() {
	}

private:

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

		smpeg = SMPEG_new(FileSys.makeFullName("kyojin.mpeg"),&smpeg_info,1);
		Log.print("INPUT:%s", SMPEG_error(smpeg));

		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);
		SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
		SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
		SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
		SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
		scr = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
		glEnable(GL_TEXTURE_2D);

		SMPEG_setdisplay(smpeg, scr, null, null);

		SMPEG_play(smpeg);
	}

private:
	GameInfo info;
	SDL_Surface* scr;
	bool init = false;
	SMPEG* smpeg;
	SMPEG_Info smpeg_info;


}
+/



///+
module kyojintati4d.taskmovie;

private import std.thread;

private import SDL;
private import SDL_smpeg;

private import y4d;
private import y4d_aux.filesys;

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

private import yamalib.draw.movie;
private import yamalib.log.log;

class TaskMovie : GameTaskBase {

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

	/// 移動の処理を行います
	override int onMove(Object o) {
		return 0;
	}
	
	ulong count = 0;
	/// 描画の処理を行います
	override int onDraw(Object o) {
		try {
			info = cast(GameInfo)o;
	
			if (!init) {
				init = true;
				onInit();
			}
			info.screen.clear();
			
			if (movie.isReadyToDraw) 
			{
				// まずテクスチャにする
				movie.draw(viewTexture);
				// それを描画
				info.screen.blt(viewTexture,0,0);
			}

			if (movie2.isReadyToDraw) 
			{
				// まずテクスチャにする
				movie2.draw(viewTexture2);
				// それを描画
				info.screen.blt(viewTexture2,320,0);
			}

			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) {
		try {
			info = cast(GameInfo)o;
	
			if (!init) {
				init = true;
				onInit();
			}
	
			return 0;
		} catch (Exception e) {
			Log.printFatal("RuntimeException %s#task : [%s] [%s]", super.toString(), e.toString(), e.msg);
			throw e;
		}
	}

	/// 占有しているメモリを解放する
	override void destroy() {
		if (movie !is null) {
			movie.release();
		}
		if (movie2 !is null) {
			movie2.release();
		}
		Log.print("%s#destroy : destroyed.", super.toString());
	}

	/// コンストラクタ
	this() {
	}

private:

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

//		void delegate(SDL_Surface * dst, int x, int y, uint w, uint h) call1 = cast(void delegate(SDL_Surface * dst, int x, int y, uint w, uint h)) &smpeg_DisplayCallback;

		Log.print("create Instance");

		{
			state1 = new MovieState();	
			movie = new Movie(cast(SMPEG_DisplayCallback) &smpeg_DisplayCallback1, 
				state1);
			Log.print("load movie file");
			if (y4d_result.no_error != movie.load(cast(char[]) "kyojin.mpeg", false) ) {;
				Log.printError("load error");
			}
			viewTexture = new Texture();
			Log.print("set texture");
			// サーフェイスを喰わせてテクスチャを予約する
			viewTexture.setSurface(movie.surface.clone());
			Log.print("set loop true");
			movie.isLoop = true;
			Log.print("play movie");
			movie.play();
			movie.volume = 0.1;
		}

		{
			state2 = new MovieState();	
			movie2 = new Movie(cast(SMPEG_DisplayCallback) &smpeg_DisplayCallback2, 
				state2);
			Log.print("load movie file");
			if (y4d_result.no_error != movie2.load(cast(char[]) "kyojin2.mpeg", false) ) {;
				Log.printError("load2 error");
			}
			viewTexture2 = new Texture();
			viewTexture2.setSurface(movie2.surface.clone());
			movie2.isLoop = true;
			movie2.play();
			movie2.volume = 0.1;
		}


		Log.print("onInit finish");
	}

	/// <summary>
	/// 描画時に呼び出されるコールバック関数。
	/// 別スレッドらしいので、GL周りの処理とかは止めとくのが無難っぽい。
	/// </summary>
	extern (C) static void smpeg_DisplayCallback1(SDL_Surface* dst, int x, int y, uint w, uint h)
	{
		Rect rc;
		rc.setRect(x, y, cast(int)w, cast(int)h);
		state1.updateRect = rc;
		state1.updated = true;
		// readyToDraw = true; // 一度でも描画されたら描画準備完了と見なす。
		if (!state1.readyToDraw)
		{
			// 全面が更新されたら描画準備完了
//			Rect* r = &m_updateRect;
//			if (width <= r.getWidth && height <= r.getHeight)
			{
				state1.readyToDraw = true;
			}
		}
	}

	/// <summary>
	/// 描画時に呼び出されるコールバック関数。
	/// 別スレッドらしいので、GL周りの処理とかは止めとくのが無難っぽい。
	/// </summary>
	extern (C) static void smpeg_DisplayCallback2(SDL_Surface* dst, int x, int y, uint w, uint h)
	{
		Rect rc;
		rc.setRect(x, y, cast(int)w, cast(int)h);
		state2.updateRect = rc;
		state2.updated = true;
		// readyToDraw = true; // 一度でも描画されたら描画準備完了と見なす。
		if (!state2.readyToDraw)
		{
			// 全面が更新されたら描画準備完了
//			Rect* r = &m_updateRect;
//			if (width <= r.getWidth && height <= r.getHeight)
			{
				state2.readyToDraw = true;
			}
		}
	}


private:
	GameInfo info;
	bool init = false;
	
	
	Movie movie;
	Texture viewTexture;
	static MovieState state1;

	Movie movie2;
	Texture viewTexture2;
	static MovieState state2;

}


