module kyojintati4d.component.ending.scene03;

private import y4d;
private import y4d_draw.transbltter;
private import y4d_aux.filesys;

private import kyojintati4d.gameinfo;
private import kyojintati4d.component.rhythm.keyconfigdialon;
private import kyojintati4d.component.ending.scenebase;
private import kyojintati4d.component.ending.scene01;

private import kyojintati4d.component.ending.MoviePlayer;

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

/**
 * シーン１の効果を取り扱うクラス
 */
public class Scene03 : Scene01 {
	
	private MoviePlayer movie;
	
	// 全ムービーファイルの列挙
	private static char[][] ALL_MOVIE_FILE;
	private static FileSys.TmpFile[] ALL_MOVIE_TMP_FILE;
	
	/** コンストラクタ */
	this(FixTimer timer, bool useMovie) {
		super(timer);

		rand = new Rand();
		rand.randomize();

		// 使用する画像をロード
		textureLoader.loadDefFile(cast(char[]) "img2/ending/s03/list.txt");
		this.timer = timer;
		
		this.useMovie = useMovie;
		
		if (this.useMovie) {
			Log.print("ENDING SHOW MOVIE SETUP START");
			MovieFileInfo[] allMovieFileInfo = MovieFileInfo.createFromDefFile(
					cast(char[]) "img2/ending/movie/movielist.txt"); 
			movie = new MoviePlayer();
			movie.setPlayFile(allMovieFileInfo);
			Log.print("ENDING SHOW MOVIE SETUP END");
		}
	}
	
	/** デストラクタ */
	~this() {
		release();
	}
	
	/** 解放 */
	override void release() {
		if (movie !is null) {
			movie.release();
		}
	}
	
	/// すべての画像をキャッシュする	
	override void cacheTexture() {
		cacheTextureAll(textureLoader);
	}

	private static const uint START_TIME = 88_300 + MUSIC_OFFSET_TIME;
	// シーンは開始しているか
	override bool isStart() {
		return START_TIME <= timer.get();
	}
	
	// 念のため時間でも終了時間もチェック
	private static const uint END_TIME = 153_700 + MUSIC_OFFSET_TIME; 
	// シーンが終了したか
	override bool isEnd() {
		return sceneEndFlg || END_TIME <= timer.get();
	}
	
	/// タイミングデータ作成
	protected override void setupTimingData() {
		long phase3Offset = 88_000 + MUSIC_OFFSET_TIME;
		TimingData[] t3_1 = [
			new TimingData( 2_170 + phase3Offset, [&eventCallback1_1]), 
			new TimingData( 2_880 + phase3Offset, [&eventCallback1_2]), 
			new TimingData( 4_840 + phase3Offset, [&eventCallback1_3]), 
			new TimingData( 5_510 + phase3Offset, [&eventCallback1_4]), 
			new TimingData( 7_500 + phase3Offset, [&eventCallback1_5]), 
			new TimingData( 8_320 + phase3Offset, [&eventCallback1_6]), 
			new TimingData(10_160 + phase3Offset, [&eventCallback1_7]),
			new TimingData(10_810 + phase3Offset, [&eventCallback1_8]),
		];
		m_timingData ~= t3_1;
		
		TimingData[] t3_2 = [
			new TimingData(12_820 + phase3Offset, [&eventCallback2_1]),
			new TimingData(13_480 + phase3Offset, [&eventCallback2_2]),
			new TimingData(15_480 + phase3Offset, [&eventCallback2_3]),
			new TimingData(16_150 + phase3Offset, [&eventCallback2_4]),
			new TimingData(18_140 + phase3Offset, [&eventCallback2_5]),
			new TimingData(18_970 + phase3Offset, [&eventCallback2_6]),
			new TimingData(20_810 + phase3Offset, [&eventCallback2_7]),
			new TimingData(21_640 + phase3Offset, [&eventCallback2_8]),
		];
		m_timingData ~= t3_2;

		TimingData[] t3_3 = [
			new TimingData(23_480 + phase3Offset, [&eventCallback3_1]),
			new TimingData(24_160 + phase3Offset, [&eventCallback3_2]),
			new TimingData(26_150 + phase3Offset, [&eventCallback3_3]),
			new TimingData(26_850 + phase3Offset, [&eventCallback3_4]),
			new TimingData(28_820 + phase3Offset, [&eventCallback3_5]),
			new TimingData(29_660 + phase3Offset, [&eventCallback3_6]),
			new TimingData(31_470 + phase3Offset, [&eventCallback3_7]),
			new TimingData(32_260 + phase3Offset, [&eventCallback3_8]),
		];
		m_timingData ~= t3_3;
		
		TimingData[] t3_4 = [
			new TimingData(34_150 + phase3Offset, [&eventCallback4_1]),
			new TimingData(34_810 + phase3Offset, [&eventCallback4_2]),
			new TimingData(36_810 + phase3Offset, [&eventCallback4_3]),
			new TimingData(37_490 + phase3Offset, [&eventCallback4_4]),
			new TimingData(39_460 + phase3Offset, [&eventCallback4_5]),
			new TimingData(40_270 + phase3Offset, [&eventCallback4_6]),
			new TimingData(42_150 + phase3Offset, [&eventCallback4_7]),
			new TimingData(42_960 + phase3Offset, [&eventCallback4_8]),
		];
		m_timingData ~= t3_4;

		TimingData[] t3_5 = [
			new TimingData(MUSIC_OFFSET_TIME + 132_820, [&eventCallback5_1]),
			new TimingData(MUSIC_OFFSET_TIME + 133_490, [&eventCallback5_2]),
			new TimingData(MUSIC_OFFSET_TIME + 135_480, [&eventCallback5_3]),
			new TimingData(MUSIC_OFFSET_TIME + 136_160, [&eventCallback5_4]),
			new TimingData(MUSIC_OFFSET_TIME + 138_140, [&eventCallback5_5]),
			new TimingData(MUSIC_OFFSET_TIME + 138_980, [&eventCallback5_6]),
			new TimingData(MUSIC_OFFSET_TIME + 140_810, [&eventCallback5_7]),
			new TimingData(MUSIC_OFFSET_TIME + 141_650, [&eventCallback5_8]),
		];
		m_timingData ~= t3_5;

		TimingData[] t3_6 = [
			new TimingData(MUSIC_OFFSET_TIME + 143_490, [&eventCallback6_1]),
			new TimingData(MUSIC_OFFSET_TIME + 144_140, [&eventCallback6_2]),
			new TimingData(MUSIC_OFFSET_TIME + 146_130, [&eventCallback6_3]),
			new TimingData(MUSIC_OFFSET_TIME + 146_820, [&eventCallback6_4]),
			new TimingData(MUSIC_OFFSET_TIME + 148_820, [&eventCallback6_5]),
			new TimingData(MUSIC_OFFSET_TIME + 149_640, [&eventCallback6_6]),
		];
		m_timingData ~= t3_6;

		TimingData[] t3_7 = [
			new TimingData(62_500 + phase3Offset, [&eventCallback7_1]),
			new TimingData(62_840 + phase3Offset, [&eventCallback7_2]),
			new TimingData(63_190 + phase3Offset, [&eventCallback7_3]),
			new TimingData(63_500 + phase3Offset, [&eventCallback7_4]),
			new TimingData(63_840 + phase3Offset, [&eventCallback7_5]),
			new TimingData(64_120 + phase3Offset, [&eventCallback7_6]),
			new TimingData(64_500 + phase3Offset, [&eventCallback7_7]),
		];
		m_timingData ~= t3_7;
	}
	
	/// 移動処理
	void onMove(Screen screen) {
		foreach (phase; activePhase) {
			phase.onMove(screen);
		}
		foreach (hitEffect; hitEffects) {
			if (hitEffect !is null) {
				hitEffect.onMove(screen);
			}
		}
		
		if (useMovie) 
		{
			movie.onMove(screen);
		}
	}
	
	/// 描画処理
	void onDraw(Screen screen) {
		
		// TEST 
		screen.setColor(255,255,255,255);
		
		foreach (phase; activePhase) {
			phase.onDraw(screen);
		}
		foreach (hitEffect; hitEffects) {
			if (hitEffect !is null) {
				hitEffect.onDraw(screen);
			}
		}

		if (useMovie) 
		{
			movie.onDraw(screen);
		}
	}

private:
	
	HittingEffect[] hitEffects;
	
	// ========================================================================================== //
	// =================================     PHASE 1 - 1     ==================================== //
	// ========================================================================================== //
	
	/// 1-1 
	bool eventCallback1_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// ステータスカウント
		countHitStatus(status);
		try {
			// poor と error がなければムービー許可
			if (movie !is null && gamePointcalculator().poorCount == 0 && gamePointcalculator.errorCount == 0) {
				movie.play();
			} else {
				useMovie = false;
			}
		} catch (Object e) {
			Log.print("PLAY MOVIE ERROR:%s", e.toString());
			useMovie = false;
		}
		if (isHitedStatus(status)) {
			phase1_1 = new Phase2Base(textObj, textureLoader, status);
			phase1_1.setImgNo(0);
			phase1_1.setXY(189,180);
			phase1_1.getTransCounter.set(0,255,9);
			phase1_1.setEffectNo(20);
			
			activePhase ~= phase1_1;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 1-2 
	bool eventCallback1_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase1_1 !is null) {
				phase1_1.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 1-3 k
	bool eventCallback1_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase1_3 = new Phase2Base(textObj, textureLoader, status);
			phase1_3.setImgNo(1);
			phase1_3.setXY(262,233);
			phase1_3.getTransCounter.set(0,255,9);
			phase1_3.setEffectNo(20);
			
			activePhase ~= phase1_3;
		hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 1-4　ブラー
	bool eventCallback1_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase1_3 !is null) {
				phase1_3.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 1-5　ドロップ
	bool eventCallback1_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase1_1 !is null) {
				phase1_1.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 1-6　ドロップ
	bool eventCallback1_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase1_3 !is null) {
				phase1_3.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 1-7　フェード
	bool eventCallback1_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase1_1 !is null) {
				if (isHitedStatus(status)) {
					phase1_1.fadeOut();
				}
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 1-8　ブラー
	bool eventCallback1_8(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase1_3 !is null) {
				phase1_3.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	// ========================================================================================== //
	// =================================     PHASE 1 - 2     ==================================== //
	// ========================================================================================== //
	/// 2-1 
	bool eventCallback2_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// 前のフェーズ分は終了
		activePhase = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase2_1 = new Phase2Base(textObj, textureLoader, status);
			phase2_1.setImgNo(2);
			phase2_1.setXY(216,189);
			phase2_1.getTransCounter.set(0,255,9);
			phase2_1.setEffectNo(20);
			
			activePhase ~= phase2_1;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 2-2 
	bool eventCallback2_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_1 !is null) {
				phase2_1.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 2-3 @lice
	bool eventCallback2_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase2_3 = new Phase2Base(textObj, textureLoader, status);
			phase2_3.setImgNo(3);
			phase2_3.setXY(274,233);
			phase2_3.getTransCounter.set(0,255,9);
			phase2_3.setEffectNo(20);
			
			activePhase ~= phase2_3;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 2-4　ブラー
	bool eventCallback2_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_3 !is null) {
				phase2_3.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 2-5　ドロップ
	bool eventCallback2_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_1 !is null) {
				phase2_1.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 2-6　ドロップ
	bool eventCallback2_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_3 !is null) {
				phase2_3.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 2-7　フェード
	bool eventCallback2_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_1 !is null) {
				phase2_1.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 2-8　ブラー
	bool eventCallback2_8(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_3 !is null) {
				phase2_3.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	
	// ========================================================================================== //
	// =================================     PHASE 1 - 3     ==================================== //
	// ========================================================================================== //
	/// 3-1 
	bool eventCallback3_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// 前のフェーズ分は終了
		activePhase = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase3_1 = new Phase2Base(textObj, textureLoader, status);
			phase3_1.setImgNo(4);
			phase3_1.setXY(191,180);
			phase3_1.getTransCounter.set(0,255,9);
			phase3_1.setEffectNo(20);
			
			activePhase ~= phase3_1;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 3-2 
	bool eventCallback3_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase3_1 !is null) {
				phase3_1.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 3-3 @lice
	bool eventCallback3_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase3_3 = new Phase2Base(textObj, textureLoader, status);
			phase3_3.setImgNo(1);
			phase3_3.setXY(262,233);
			phase3_3.getTransCounter.set(0,255,9);
			phase3_3.setEffectNo(20);
			
			activePhase ~= phase3_3;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 3-4　ブラー
	bool eventCallback3_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase3_3 !is null) {
				phase3_3.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 3-5　ドロップ
	bool eventCallback3_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase3_1 !is null) {
				phase3_1.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 3-6　ドロップ
	bool eventCallback3_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase3_3 !is null) {
				phase3_3.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 3-6　フェード
	bool eventCallback3_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase3_1 !is null) {
				if (HitStatus.POOR != status) {
					phase3_1.fadeOut();
				}
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 3-4　ブラー
	bool eventCallback3_8(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase3_3 !is null) {
				phase3_3.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	// ========================================================================================== //
	// =================================     PHASE 1 - 4     ==================================== //
	// ========================================================================================== //
	/// 4-1 
	bool eventCallback4_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// 前のフェーズ分は終了
		activePhase = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase4_1 = new Phase2Base(textObj, textureLoader, status);
			phase4_1.setImgNo(5);
			phase4_1.setXY(191,180);
			phase4_1.getTransCounter.set(0,255,9);
			phase4_1.setEffectNo(20);
			
			activePhase ~= phase4_1;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 4-2 
	bool eventCallback4_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase4_1 !is null) {
				phase4_1.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 4-3 
	bool eventCallback4_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase4_3 = new Phase2Base(textObj, textureLoader, status);
			phase4_3.setImgNo(6);
			phase4_3.setXY(241,233);
			phase4_3.getTransCounter.set(0,255,9);
			phase4_3.setEffectNo(20);
			
			activePhase ~= phase4_3;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 4-4　ブラー
	bool eventCallback4_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase4_3 !is null) {
				phase4_3.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 4-5　ドロップ
	bool eventCallback4_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase4_1 !is null) {
				phase4_1.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 4-6　ドロップ
	bool eventCallback4_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase4_3 !is null) {
				phase4_3.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 4-6　フェード
	bool eventCallback4_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase4_1 !is null) {
				if (HitStatus.POOR != status) {
					phase4_1.fadeOut();
				}
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 4-4　ブラー
	bool eventCallback4_8(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase4_3 !is null) {
				phase4_3.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	// ========================================================================================== //
	// =================================     PHASE 1 - 5     ==================================== //
	// ========================================================================================== //
	/// 5-1 
	bool eventCallback5_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// 前のフェーズ分は終了
		activePhase = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase5_1 = new Phase2Base(textObj, textureLoader, status);
			phase5_1.setImgNo(7);
			phase5_1.setXY(190,185);
			phase5_1.getTransCounter.set(0,255,9);
			phase5_1.setEffectNo(20);
			
			activePhase ~= phase5_1;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 5-2 
	bool eventCallback5_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase5_1 !is null) {
				phase5_1.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 5-3 @lice
	bool eventCallback5_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase5_3 = new Phase2Base(textObj, textureLoader, status);
			phase5_3.setImgNo(8);
			phase5_3.setXY(270,234);
			phase5_3.getTransCounter.set(0,255,9);
			phase5_3.setEffectNo(20);
			
			activePhase ~= phase5_3;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 5-4　ブラー
	bool eventCallback5_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase5_3 !is null) {
				phase5_3.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 5-5　ドロップ
	bool eventCallback5_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase5_1 !is null) {
				phase5_1.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 5-6　ドロップ
	bool eventCallback5_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase5_3 !is null) {
				phase5_3.drop();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 5-6　フェード
	bool eventCallback5_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase5_1 !is null) {
				if (HitStatus.POOR != status) {
					phase5_1.fadeOut();
				}
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 5-4　ブラー
	bool eventCallback5_8(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase5_3 !is null) {
				phase5_3.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	// ========================================================================================== //
	// =================================     PHASE 1 - 6     ==================================== //
	// ========================================================================================== //
	/// 6-1 
	bool eventCallback6_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// 前のフェーズ分は終了
		activePhase = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase6_1 = new Phase2Base(textObj, textureLoader, status);
			phase6_1.setImgNo(9);
			phase6_1.setXY(192,181);
			phase6_1.getTransCounter.set(0,255,9);
			phase6_1.setEffectNo(20);
			
			activePhase ~= phase6_1;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 6-2 
	bool eventCallback6_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase6_1 !is null) {
				phase6_1.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 6-3 @lice
	bool eventCallback6_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase6_3 = new Phase2Base(textObj, textureLoader, status);
			phase6_3.setImgNo(10);
			phase6_3.setXY(235,231);
			phase6_3.getTransCounter.set(0,255,9);
			phase6_3.setEffectNo(20);
			
			activePhase ~= phase6_3;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 6-4　ブラー
	bool eventCallback6_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase6_3 !is null) {
				phase6_3.slide();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 6-5　ドロップ
	bool eventCallback6_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase6_1 !is null) {
				phase6_1.drop();
				phase6_1.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 6-6　ドロップ
	bool eventCallback6_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase6_3 !is null) {
				phase6_3.drop();
				phase6_3.fadeOut();
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	// ========================================================================================== //
	// =================================     PHASE 1 - 7     ==================================== //
	// ========================================================================================== //
	/// 7-1 
	bool eventCallback7_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

		// 前のフェーズ分は終了
		activePhase = null;
		hitEffects = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase7_1 = new Phase7(textObj, textureLoader, status);
			phase7_1.setImgNo(12);
			activePhase ~= phase7_1;
		}
				
		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}
	/// 7-2 
	bool eventCallback7_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase7_2 = new Phase7(textObj, textureLoader, status);
			phase7_2.setImgNo(13);
			activePhase ~= phase7_2;
		}
		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}

	/// 7-3 @lice
	bool eventCallback7_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		
		if (isHitedStatus(status)) {
			phase7_3 = new Phase7(textObj, textureLoader, status);
			phase7_3.setImgNo(14);
			activePhase ~= phase7_3;
		}

		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}
	/// 7-4　TEXT
	bool eventCallback7_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase7_4 = new Phase7(textObj, textureLoader, status);
			phase7_4.setImgNo(15);
			activePhase ~= phase7_4;
		}
		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}
	/// 7-5　キャラクター
	bool eventCallback7_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		
		if (isHitedStatus(status)) {
			phase7_5 = new Phase7(textObj, textureLoader, status);
			phase7_5.setImgNo(16);
			activePhase ~= phase7_5;
		}

		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}

	/// 7-6　TEXT
	bool eventCallback7_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase7_6 = new Phase7(textObj, textureLoader, status);
			phase7_6.setImgNo(17);
			activePhase ~= phase7_6;
		}
		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}

	/// 7-7　TEXT
	bool eventCallback7_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase7_7 = new Phase7(textObj, textureLoader, status);
			phase7_7.setImgNo(18);
			activePhase ~= phase7_7;
		}

		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}


	// ========================================================================================== //
	// =================================     PHASE 3 - 1     ==================================== //
	// ========================================================================================== //
	Phase2Base phase1_1;
	Phase2Base phase1_3;

	// ========================================================================================== //
	// =================================     PHASE 3 - 2     ==================================== //
	// ========================================================================================== //
	Phase2Base phase2_1;
	Phase2Base phase2_3;


	// ========================================================================================== //
	// =================================     PHASE 3 - 3     ==================================== //
	// ========================================================================================== //
	Phase2Base phase3_1;
	Phase2Base phase3_3;

	// ========================================================================================== //
	// =================================     PHASE 3 - 4     ==================================== //
	// ========================================================================================== //
	Phase2Base phase4_1;
	Phase2Base phase4_3;
	
	// ========================================================================================== //
	// =================================     PHASE 3 - 5     ==================================== //
	// ========================================================================================== //
	Phase2Base phase5_1;
	Phase2Base phase5_3;

	// ========================================================================================== //
	// =================================     PHASE 3 - 6     ==================================== //
	// ========================================================================================== //
	Phase2Base phase6_1;
	Phase2Base phase6_3;

	// ========================================================================================== //
	// =================================     PHASE 3 - 7     ==================================== //
	// ========================================================================================== //
	
	static class Phase7Base : PhaseBase {

		/// 初期化処理
		this(TextObj obj, TextureLoader loader, HitStatus status) {
			phase = new RootCounterS(255,0,32);
			rateCounter = new PowIncCounter(1, 2, 64);
			alpha = new RootCounterS(0, 196, 15);
			super(obj, loader, status);
		}

		/// ローダの画像番号
		void setImgNo(int no) {
			imgNo = no;
		}
		
		/// 描画位置
		void setXY(int x, int y) {
			posx = x;
			posy = y;
		}
		void getXY(out int x, out int y) {
			x = posx;
			y = posy;
		}
		
		/// トランスブリッタ用のカウンタ
		RootCounterS getTransCounter() {
			return phase;
		}
		
		/// トランスブリッタの効果番号
		void setEffectNo(int no) {
			effectNo = no;
		}
		void getEffectNo() {
			return effectNo;
		}
		
		/// フェードアウトする
		void next() {
			fadeOutFlg = true;
			imgNo += 1;
			phase.set(alpha.get(), 0, 12);
			alpha.set(alpha.get(),0,12);
		}
		
		void fadeOut() {
			alpha.set(alpha.get(),0,10);
			alpha.set(128,0,10);
		}

		/// 移動処理
		void onMove(Screen screen) {
			if (start) {
				phase.inc();
				alpha.inc();
			}
			if (fadeOutFlg) {
				rateCounter.inc();
			}
		}
		/// 描画処理
		void onDraw(Screen screen) {
			if (start && !end) {
				if (alpha.get() > 0) {
					if (fadeOutFlg) {
						if (phase.get() > 0) {
							screen.setColor(255,255,255, phase.get());
							screen.blt(m_textureLoader.get(imgNo-1), posx, posy);
						}
						screen.setColor(255,255,255, alpha.get());
						auto img = m_textureLoader.get(imgNo);
						screen.bltRotate(img, posx + cast(int)img.getWidth()/2, 
							posy+cast(int)img.getHeight()/2, 0, rateCounter.getDecimal(), 4);
					} else {
						screen.setColor(255,255,255, alpha.get());
						screen.blt(m_textureLoader.get(imgNo), posx, posy);
					}
				}
			}
		}
		
	private:
		bool fadeOutFlg = false;
		int effectNo = 19;
		int posx;
		int posy;
		int imgNo;
		int imgNoText;
		RootCounterS phase;
		RootCounterS alpha;
//		IDecimalCounter offsetX;
		PowIncCounter rateCounter;
	}

	Rand rand;
	
	bool useMovie;
	Phase7 phase7_1;
	Phase7 phase7_2;
	Phase7 phase7_3;
	Phase7 phase7_4;
	Phase7 phase7_5;
	Phase7 phase7_6;
	Phase7 phase7_7;

}
