module yamalib.draw.screenframe;

private import y4d;
private import y4d_aux.filesys;
private import y4d_aux.lineparser;
private import yamalib.log.log;
private import yamalib.counterfsp;

/// 特殊画面フレーム描画を行います
class ScreenFrame {
public:
	/** シネマスコープオリジナルアスペクト比 */
	static const float LC_HEIGHT_RATE = 1.0F;
	static const float LC_WIDTH_RATE = 2.35F;

	/** 画面フレームタイプの列挙 */
	enum {	NONE, 	// なし
			CHINEMA_SCOPE,	// シネマスコープ 1 * 2.35
	};
	
	/// 描画処理
	void onDraw(Screen screen) {
		switch (screenType) {
		case NONE : break;
		case CHINEMA_SCOPE:
			drawChinemaSope(screen);
			break;
		default:
			assert(false);
		}
	}
	
	/// 閉じ開きの描画
	void drawCloseOpen(Screen screen) {
		// 画面サイズの取得
		int width = screen.getWidth();
		int height = screen.getHeight();
		// オリジナルカラーの取得
		Color4ub color = screen.getColor4ub();
		
		screen.setColor( 0, 0, 0, 255 );
		
		if ( !effecting ) {
			// 初期化処理やね
			counter.setEnd(height / 2);
			counter.setReverse(true);
			waitCounter.setEnd(closeWait);
			
			// 開始位置修正
			if (CHINEMA_SCOPE == screenType) {
				float heightRate = height_rate / width_rate;
				int drawHeight = height - cast(int)(height * heightRate);
				counter.opAssign(drawHeight / 2);
			}
			effecting  = true;
		}
		
		if ( counter.isLapAroundI() ) {
		} else {
			int pos = counter.get();
			// 上部非描画領域の塗りつぶし
			screen.drawPolygon(
				0, 0,
				width, 0,
				width, pos,
				0, pos ); 
			
			// 下部非描画領域の塗りつぶし
			screen.drawPolygon(
				0, (height - pos),
				width, (height - pos),
				width, height,
				0, height );			
			
			if ( wait ) {
				if (!openManual) {
					waitCounter.incS();
					if (waitCounter.isLapAround()) {
						wait = false;
					}
				}
			} else {
				// カウンター増加
				counter.inc();
				if (counter.getReversing() && (0 != closeWait || openManual) && !waitCounter.isLapAround() ) {
					wait = true;
				}
			}
		}
		
		screen.setColor(color);
	}	
	
	/// 描画するスクリーンタイプを設定する
	void setScreenType(int type) {
		screenType = type;
	}
	
	/// 閉じる開くのスピード
	void setColseOpneSpeed(int speed, int closeWait = 0) {
		counter.setStep(speed);
		// 閉じたままの停止時間
		this.closeWait = closeWait;
	}
	
	/// Openメッセージを手動で送るか？
	/// メッセージが送られるまで閉じたまま
	void setOpenManual(bool b) {
		openManual = b;
	}
	
	/// 閉じられたスクリーンをオープンする
	void screenOpen() {
		wait = false;
		openManual = false;
	}
	
	/// 画面のアスペクト比を設定します
	void setAspectRate(float h, float w) {
		height_rate = h;
		width_rate = w;
	} 
	
	/// 停止中か？
	bool isWait() { return wait; }
	
	/// 枠のサイズ (= 0 非描画)
	void setFrameSize(int n) {
		frameSize = n;
	}

	/// コンストラクタ
	this() {
		setScreenType( CHINEMA_SCOPE );
		setAspectRate(1.0f, 1.8f);
		counter = new RootCounter();
		waitCounter = new RootCounter();
	}
	
	/// デストラクタ
	~this() {
	}
protected:
	
	/// シネマスコープにします(1 * 2.35)
	void drawChinemaSope(Screen screen) {
		// 画面サイズの取得
		int width = screen.getWidth();
		int height = screen.getHeight();
		float heightRate = height_rate / width_rate;
		int drawHeight = height - cast(int)(height * heightRate);
		// オリジナルカラーの取得
		Color4ub color = screen.getColor4ub();
		
		// 黒塗りつぶし
		screen.setColor(0, 0, 0, 255);
		
		// 上部非描画領域の塗りつぶし
		screen.drawPolygon(
			0, 0,
			width, 0,
			width, (drawHeight / 2),
			0, (drawHeight / 2) ); 
		
		// 下部非描画領域の塗りつぶし
		screen.drawPolygon(
			0, (height - (drawHeight / 2)),
			width, (height - (drawHeight / 2)),
			width, height,
			0, height );
			
		if (frameSize > 0) {
			// 白塗りつぶし
			screen.setColor(255, 255, 255, 255);
			
			// 上部非描画領域の塗りつぶし
			screen.drawPolygon(
				0, (drawHeight / 2) - frameSize,
				width, (drawHeight / 2)  - frameSize,
				width, (drawHeight / 2),
				0, (drawHeight / 2) ); 
			
			// 下部非描画領域の塗りつぶし
			screen.drawPolygon(
				0, (height - (drawHeight / 2)),
				width, (height - (drawHeight / 2)),
				width, (height - (drawHeight / 2)) + frameSize,
				0, (height - (drawHeight / 2)) + frameSize );
		}
			
		// 色を元に戻す
		screen.setColor(color);
	}
	
private:
	int screenType;
	float height_rate;
	float width_rate;
	RootCounter counter;
	// エフェクト中か？
	bool effecting;
	// 停止中か？
	bool wait;
	// 枠を描画するか
	int frameSize;
	// スクリーンオープンをマニュアルで行うか？
	bool openManual;
	int closeWait;
	RootCounter waitCounter;


}