module kyojintati4d.component.ending.scene01;

private import y4d;
private import y4d_draw.transbltter;

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

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

/**
 * シーン１の効果を取り扱うクラス
 */
public class Scene01 : EndingSceneBase {
	
	/// コンストラクタ
	this(FixTimer timer) {
		// 使用する画像をロード
		textureLoader = new TextureLoader();
		textureLoader.setCacheSize(-1);
		textureLoader.loadDefFile(cast(char[]) "img2/ending/s01/list.txt");
		this.timer = timer;
		setupTimingData();
	}

	/// すべての画像をキャッシュする	
	override void cacheTexture() {
		cacheTextureAll(textureLoader);
	}
	
	// 念のため時間でも終了時間もチェック
	private static const uint END_TIME = 66_000 + MUSIC_OFFSET_TIME; 
	// シーンが終了したか
	override bool isEnd() {
		return sceneEndFlg || END_TIME <= timer.get();
	}
	
	// リソースの解放
	override void release() {
		textureLoader.releaseAll();
		textureLoader.releaseFileList();
	}
	
	/// タイミングデータ作成
	protected void setupTimingData() {
		TimingData[] t1_1 = [
			new TimingData(MUSIC_OFFSET_TIME + 2_170,  [&eventCallback1_1]), 
			new TimingData(MUSIC_OFFSET_TIME + 2_880,  [&eventCallback1_2]), 
			new TimingData(MUSIC_OFFSET_TIME + 4_840,  [&eventCallback1_3]), 
			new TimingData(MUSIC_OFFSET_TIME + 5_510,  [&eventCallback1_4]), 
			new TimingData(MUSIC_OFFSET_TIME + 7_500,  [&eventCallback1_5]), 
			new TimingData(MUSIC_OFFSET_TIME + 8_320,  [&eventCallback1_6]), 
			new TimingData(MUSIC_OFFSET_TIME + 10_160, [&eventCallback1_7]),
			new TimingData(MUSIC_OFFSET_TIME + 10_810, [&eventCallback1_8]),
		];
		m_timingData ~= t1_1;
		
		TimingData[] t1_2 = [
			new TimingData(MUSIC_OFFSET_TIME + 12_820, [&eventCallback2_1]),
			new TimingData(MUSIC_OFFSET_TIME + 13_480, [&eventCallback2_2]),
			new TimingData(MUSIC_OFFSET_TIME + 15_480, [&eventCallback2_3]),
			new TimingData(MUSIC_OFFSET_TIME + 16_150, [&eventCallback2_4]),
			new TimingData(MUSIC_OFFSET_TIME + 18_140, [&eventCallback2_5]),
			new TimingData(MUSIC_OFFSET_TIME + 18_970, [&eventCallback2_6]),
			new TimingData(MUSIC_OFFSET_TIME + 20_810, [&eventCallback2_7]),
			new TimingData(MUSIC_OFFSET_TIME + 21_640, [&eventCallback2_8]),
		];
		m_timingData ~= t1_2;


		TimingData[] t1_3 = [
			new TimingData(MUSIC_OFFSET_TIME + 23_480, [&eventCallback3_1]),
			new TimingData(MUSIC_OFFSET_TIME + 24_160, [&eventCallback3_2]),
			new TimingData(MUSIC_OFFSET_TIME + 26_150, [&eventCallback3_3]),
			new TimingData(MUSIC_OFFSET_TIME + 26_850, [&eventCallback3_4]),
			new TimingData(MUSIC_OFFSET_TIME + 28_820, [&eventCallback3_5]),
			new TimingData(MUSIC_OFFSET_TIME + 29_660, [&eventCallback3_6]),
			new TimingData(MUSIC_OFFSET_TIME + 31_470, [&eventCallback3_7]),
			new TimingData(MUSIC_OFFSET_TIME + 32_260, [&eventCallback3_8]),
		];
		m_timingData ~= t1_3;


		TimingData[] t1_4 = [
			new TimingData(MUSIC_OFFSET_TIME + 34_150, [&eventCallback4_1]),
			new TimingData(MUSIC_OFFSET_TIME + 34_810, [&eventCallback4_2]),
			new TimingData(MUSIC_OFFSET_TIME + 36_810, [&eventCallback4_3]),
			new TimingData(MUSIC_OFFSET_TIME + 37_490, [&eventCallback4_4]),
			new TimingData(MUSIC_OFFSET_TIME + 39_460, [&eventCallback4_5]),
			new TimingData(MUSIC_OFFSET_TIME + 40_270, [&eventCallback4_6]),
			new TimingData(MUSIC_OFFSET_TIME + 42_150, [&eventCallback4_7]),
			new TimingData(MUSIC_OFFSET_TIME + 42_960, [&eventCallback4_8]),
		];
		m_timingData ~= t1_4;

		// 1-5 original is 3-5
		static long OFFSET1_5 = 88_000 - MUSIC_OFFSET_TIME;
		TimingData[] t1_5 = [
			new TimingData(132_820 - OFFSET1_5, [&eventCallback5_1], true),
			new TimingData(133_490 - OFFSET1_5, [&eventCallback5_2], true),
			new TimingData(135_480 - OFFSET1_5, [&eventCallback5_3], true),
			new TimingData(136_160 - OFFSET1_5, [&eventCallback5_4], true),
			new TimingData(138_140 - OFFSET1_5, [&eventCallback5_5], true),
			new TimingData(138_980 - OFFSET1_5, [&eventCallback5_6], true),
			new TimingData(140_810 - OFFSET1_5, [&eventCallback5_7], true),
			new TimingData(141_650 - OFFSET1_5, [&eventCallback5_8], true),
		];
		m_timingData ~= t1_5;

		// 1-6 original is 3-6
		static long OFFSET1_6 = 88_000 - MUSIC_OFFSET_TIME;
		TimingData[] t1_6 = [
			new TimingData(143_490 - OFFSET1_6, [&eventCallback6_1], true),
			new TimingData(144_140 - OFFSET1_6, [&eventCallback6_2], true),
			new TimingData(146_130 - OFFSET1_6, [&eventCallback6_3], true),
			new TimingData(146_820 - OFFSET1_6, [&eventCallback6_4], true),
			new TimingData(148_820 - OFFSET1_6, [&eventCallback6_5], true),
			new TimingData(149_640 - OFFSET1_6, [&eventCallback6_6], true),
		];
		m_timingData ~= t1_6;

		TimingData[] t1_7 = [
			new TimingData(MUSIC_OFFSET_TIME + 62_500, [&eventCallback7_1]),
			new TimingData(MUSIC_OFFSET_TIME + 62_840, [&eventCallback7_2]),
			new TimingData(MUSIC_OFFSET_TIME + 63_190, [&eventCallback7_3]),
			new TimingData(MUSIC_OFFSET_TIME + 63_500, [&eventCallback7_4]),
			new TimingData(MUSIC_OFFSET_TIME + 63_840, [&eventCallback7_5]),
			new TimingData(MUSIC_OFFSET_TIME + 64_120, [&eventCallback7_6]),
			new TimingData(MUSIC_OFFSET_TIME + 64_500, [&eventCallback7_7]),
		];
		m_timingData ~= t1_7;
	}
	
	/// 移動処理
	void onMove(Screen screen) {
		foreach (phase; activePhase) {
			phase.onMove(screen);
		}
		foreach (hitEffect; hitEffects) {
			if (hitEffect !is null) {
				hitEffect.onMove(screen);
			}
		}
	}
	
	/// 描画処理
	void onDraw(Screen screen) {
		foreach (phase; activePhase) {
			phase.onDraw(screen);
		}
		foreach (hitEffect; hitEffects) {
			if (hitEffect !is null) {
				hitEffect.onDraw(screen);
			}
		}
		
		if (fadeTitile) {
			if (phase1_5 !is null) {
				screen.setColor(255,255,255,phase1_5.getTransCounter.get());
//				screen.bltRotate(textureLoader.get(0), LOGO_X, LOGO_Y, 0, 1.0f, 4);
			}
		} else {
//			screen.bltRotate(textureLoader.get(0), LOGO_X, LOGO_Y, 0, 1.0f, 4);
		}
	}
	
protected:
	static const int LOGO_X = 320;
	static const int LOGO_Y = 120;

	PhaseBase[] activePhase;
	TextureLoader textureLoader;
	FixTimer timer;
	bool fadeTitile = false;
	bool sceneEndFlg = false;
	HittingEffect[] hitEffects;

	// ========================================================================================== //
	// =================================     PHASE 1 - 1     ==================================== //
	// ========================================================================================== //
	
	static const int P1_1_FADEOUT_SPEED = 10;
	
	static class Phase1Base : PhaseBase {
		/// 初期化処理
		this(TextObj obj, TextureLoader loader, HitStatus status) {
			phase = new RootCounterS(0,255,5);
			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 onMove(Screen screen) {
			if (start) {
				phase.inc();
			}
		}
		/// 描画処理
		void onDraw(Screen screen) {
			if (start && !end) {
				setScreenColorMax(screen);
				TransBltter.blt(effectNo, screen, m_textureLoader.get(imgNo), posx, posy, phase.get());
			}
		}
		
	private:
		int effectNo;
		int posx;
		int posy;
		int imgNo;
		RootCounterS phase;
	}
	
	Phase1Base phase1_1;
	Phase1Base phase1_2;
	Phase1Base phase1_3;
	Phase1Base phase1_4;
	Phase1Base phase1_5;
	Phase1Base phase1_6;

	// ========================================================================================== //
	// =================================     PHASE 1 - 2     ==================================== //
	// ========================================================================================== //
	
	static class Phase2Base : PhaseBase {

		/// 初期化処理
		this(TextObj obj, TextureLoader loader, HitStatus status) {
			phase = new RootCounterS(0,255,5);
			offsetX = new PowIncCounter(0, 100, 100);
			offsetY = new PowIncCounter(0, 500, 128);
			offsetY.setIncCount(150);
			alpha = new RootCounterS(200, 0, 5);
			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 slide() {
			startSlide = true;
		}
		
		void drop() {
			startDrop = true;
			alpha.set(255,255,1);
			offsetY.dec();
			posy = posy - (offsetY.getEnd() - cast(int) offsetY.get());
		}
		
		/// フェードアウトする
		void fadeOut() {
			fadeOutFlg = true;
			alpha.set(255,0,20);
		}

		/// 移動処理
		void onMove(Screen screen) {
			if (start) {
				phase.inc();
				if (startSlide) {
					alpha.inc();
					offsetX.inc();
				}
				if (startDrop) {
					offsetY.dec();
					if (fadeOutFlg) {
						alpha.inc();
					}
				}
			}
		}
		/// 描画処理
		void onDraw(Screen screen) {
			if (start && !end) {
				if (startSlide) {
					if (alpha.get() > 0) {
						screen.setColor(255,255,255, alpha.get());
						screen.blt(m_textureLoader.get(imgNo), posx + cast(int) offsetX.get(), posy);
					} else {
						startSlide = false;
					}
				}
				if (startDrop) {
					screen.setColor(255,255,255, alpha.get());
					screen.blt(m_textureLoader.get(imgNo), posx, posy + (offsetY.getEnd() - cast(int) offsetY.get()));
				} else {
					setScreenColorMax(screen);
					TransBltter.blt(effectNo, screen, m_textureLoader.get(imgNo), posx, posy, phase.get());
				}
			}
		}
		
	private:
		bool startSlide;
		bool startDrop;
		bool fadeOutFlg = false;
		int effectNo;
		int posx;
		int posy;
		int imgNo;
		RootCounterS phase;
		RootCounterS alpha;
		IDecimalCounter offsetX;
		PowIncCounter offsetY;
	}

	Phase2Base phase2_1;
	Phase2Base phase2_3;


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

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

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

	// ========================================================================================== //
	// =================================     PHASE 1 - 2     ==================================== //
	// ========================================================================================== //
	
	static class Phase7 : PhaseBase {
		/// 初期化処理
		this(TextObj obj, TextureLoader loader, HitStatus status) {
			alpha = new RootCounterS(200, 0, 15);
			super(obj, loader, status);
		}

		/// ローダの画像番号
		void setImgNo(int no) {
			imgNo = no;
		}
		
		/// 移動処理
		void onMove(Screen screen) {
			if (start) {
				alpha.inc();
			}
		}

		/// 描画処理
		void onDraw(Screen screen) {
			if (start && !end) {
				if (alpha.get() > 0) {
					auto img = m_textureLoader.get(imgNo);
					screen.setColor(255,255,255, alpha.get());
					screen.blt(img, 0, 0);
				}
			}
		}

	private:
		RootCounterS alpha;
		int imgNo;
	}
	
	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;
	}

/*	古いバージョン
	Phase7Base phase7_1;
	Phase7Base phase7_3;
	Phase7Base phase7_5;
*/

	Phase7 phase7_1;
	Phase7 phase7_2;
	Phase7 phase7_3;
	Phase7 phase7_4;
	Phase7 phase7_5;
	Phase7 phase7_6;
	Phase7 phase7_7;

private:
	// ========================================================================================== //
	// =================================     PHASE 1 - 1     ==================================== //
	// ========================================================================================== //
	
	/// 1-1
	bool eventCallback1_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		
		if (isHitedStatus(status)) {
			phase1_1 = new Phase1Base(textObj, textureLoader, status);
			phase1_1.setImgNo(1);
			phase1_1.setXY(154,215);
			phase1_1.getTransCounter.set(0,255,5);
			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)) {
			phase1_2 = new Phase1Base(textObj, textureLoader, status);
			phase1_2.setImgNo(2);
			phase1_2.setXY(157,243);
			phase1_2.getTransCounter.set(0,255,3);
			phase1_2.setEffectNo(20);
			activePhase ~= phase1_2;
	
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 1-3
	bool eventCallback1_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);

		if (isHitedStatus(status)) {
				phase1_3 = new Phase1Base(textObj, textureLoader, status);
			phase1_3.setImgNo(3);
			phase1_3.setXY(338,215);
			phase1_3.getTransCounter.set(0,255,5);
			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)) {
			phase1_4 = new Phase1Base(textObj, textureLoader, status);
			phase1_4.setImgNo(4);
			phase1_4.setXY(320,243);
			phase1_4.getTransCounter.set(0,255,3);
			phase1_4.setEffectNo(20);
			activePhase ~= phase1_4;
	
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 1-5
	bool eventCallback1_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);

		if (isHitedStatus(status)) {
			phase1_5 = new Phase1Base(textObj, textureLoader, status);
			phase1_5.setImgNo(5);
			phase1_5.setXY(87,274);
			phase1_5.getTransCounter.set(0,255,10);
			phase1_5.setEffectNo(22);
			activePhase ~= phase1_5;
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 1-6
	bool eventCallback1_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);

		if (isHitedStatus(status)) {
			phase1_6 = new Phase1Base(textObj, textureLoader, status);
			phase1_6.setImgNo(6);
			phase1_6.setXY(258,274);
			phase1_6.getTransCounter.set(0,255,10);
			phase1_6.setEffectNo(22);
			activePhase ~= phase1_6;
			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) {
				phase1_1.getTransCounter.set(255,0, P1_1_FADEOUT_SPEED);
			}
			if (phase1_2 !is null) {
				phase1_2.getTransCounter.set(255,0, P1_1_FADEOUT_SPEED);
			}
			if (phase1_3 !is null) {
				phase1_3.getTransCounter.set(255,0, P1_1_FADEOUT_SPEED);
				phase1_3.setEffectNo(21);
			}
			if (phase1_4 !is null) {
				phase1_4.getTransCounter.set(255,0, P1_1_FADEOUT_SPEED);
				phase1_4.setEffectNo(21);
			}
	
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 1-8
	bool eventCallback1_8(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);

		if (isHitedStatus(status)) {
			fadeTitile = true;
			// フェードアウトさせっかー
			if (phase1_5 !is null) {
				phase1_5.getTransCounter.set(255,0, P1_1_FADEOUT_SPEED + 2);
				phase1_5.setEffectNo(23);
			}
			if (phase1_6 !is null) {
				phase1_6.getTransCounter.set(255,0, P1_1_FADEOUT_SPEED + 2);
				phase1_6.setEffectNo(23);
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}

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

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

		// ステータスカウント
		countHitStatus(status);

		if (isHitedStatus(status)) {
			phase2_1 = new Phase2Base(textObj, textureLoader, status);
			phase2_1.setImgNo(7);
			phase2_1.setXY(237,185);
			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(8);
			phase2_3.setXY(280,228);
			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-6　フェード
	bool eventCallback2_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase2_1 !is null) {
				if (isHitedStatus(status)) {
					phase2_1.fadeOut();
				}
			}
			hitEffects ~= createHitEffect(textObj);
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 2-4　ブラー
	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;
		hitEffects = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase3_1 = new Phase2Base(textObj, textureLoader, status);
			phase3_1.setImgNo(9);
			phase3_1.setXY(222,192);
			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(10);
			phase3_3.setXY(263,231);
			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;
		hitEffects = null;

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase4_1 = new Phase2Base(textObj, textureLoader, status);
			phase4_1.setImgNo(11);
			phase4_1.setXY(239,186);
			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 @lice
	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(12);
			phase4_3.setXY(264,230);
			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;
		hitEffects = null;
		
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase5_1 = new Phase2Base(textObj, textureLoader, status);
			phase5_1.setImgNo(13);
			phase5_1.setXY(238,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(14);
			phase5_3.setXY(271,236);
			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(15);
			phase6_1.setXY(200,194);
			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(16);
			phase6_3.setXY(288,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(17);
			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(18);
			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(19);
			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(20);
			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(21);
			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(22);
			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(23);
			activePhase ~= phase7_7;
		}

		hitEffects ~= createHitEffect(textObj);
		// 後は自前でやるのででええわー
		return true;
	}
	
/* 古いバージョン	
	
	// ========================================================================================== //
	// =================================     PHASE 1 - 7     ==================================== //
	// ========================================================================================== //
	/// 7-1 
	bool eventCallback7_1(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {

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

		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			phase7_1 = new Phase7Base(textObj, textureLoader, status);
			phase7_1.setImgNo(17);
			phase7_1.setXY(30,96);
			phase7_1.getTransCounter.set(0,255,9);
			phase7_1.setEffectNo(20);
			activePhase ~= phase7_1;
		}
				
		// 後は自前でやるのででええわー
		return true;
	}
	/// 7-2 
	bool eventCallback7_2(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (phase7_1 !is null && isHitedStatus(status)) {
			phase7_1.next();
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 7-3 @lice
	bool eventCallback7_3(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		
		if (isHitedStatus(status)) {
			phase7_3 = new Phase7Base(textObj, textureLoader, status);
			phase7_3.setImgNo(19);
			phase7_3.setXY(205,75);
			phase7_3.getTransCounter.set(0,255,9);
			phase7_3.setEffectNo(20);
			
			activePhase ~= phase7_3;
		}

		// 後は自前でやるのででええわー
		return true;
	}
	/// 7-4　TEXT
	bool eventCallback7_4(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (phase7_3 !is null && isHitedStatus(status)) {
			phase7_3.next();
		}
		// 後は自前でやるのででええわー
		return true;
	}
	/// 7-5　キャラクター
	bool eventCallback7_5(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		
		if (isHitedStatus(status)) {
			phase7_5 = new Phase7Base(textObj, textureLoader, status);
			phase7_5.setImgNo(21);
			phase7_5.setXY(448,97);
			phase7_5.getTransCounter.set(0,255,9);
			phase7_5.setEffectNo(20);
			
			activePhase ~= phase7_5;
		}

		// 後は自前でやるのででええわー
		return true;
	}

	/// 7-6　TEXT
	bool eventCallback7_6(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (phase7_5 !is null && isHitedStatus(status)) {
			phase7_5.next();
		}
		// 後は自前でやるのででええわー
		return true;
	}

	/// 7-7　TEXT
	bool eventCallback7_7(Screen screen, TextObj textObj, long hitTime, 
		HitStatus status) {
		// ステータスカウント
		countHitStatus(status);
		if (isHitedStatus(status)) {
			if (phase7_1 !is null) {
				phase7_1.fadeOut();
			}
			if (phase7_3 !is null) {
				phase7_3.fadeOut();
			}
			if (phase7_5 !is null) {
				phase7_5.fadeOut();
			}
		} else {
			// 失敗　このシーンは終了
			sceneEndFlg = true;
		}
		// 後は自前でやるのででええわー
		return true;
	}
*/
	
}
