package;

import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.Sprite;

import openfl.events.Event;
import openfl.events.MouseEvent;

import openfl.text.TextField;
import openfl.text.TextFormat;
import openfl.text.TextFieldAutoSize;

import openfl.Assets;
//import openfl.Lib;

/**
 * ...
 * @author m-ushi
 */

class Jockey
{
	public var name:String; // 騎手名
	public var speed:Int;   // スピード
	public var odds:Float;  // 倍率
	public var chara:Int;   // キャラ特性 1なら1枠優待

	public function new(name:String = "", speed:Int = 1, odds:Float = 1.0, chara:Int = 0)
	{
		this.name  = name;
		this.speed = speed;
		this.odds  = odds;
		this.chara = chara;
	}
	public function adjustedSpeed(waku:Int = 0):Int
	{
		if (this.chara == 1 && waku == 0) // 1枠優待
		{
			return this.speed + 18;
		}
		return this.speed;
	}
}

enum State
{
	Start;
	Select;
	Play;
	Goal;
	GameOver;
	Clear;
}

class Main extends Sprite 
{

	private var jtable:Array<Jockey> =
	[
		new Jockey("ｵｻﾞﾜｲﾁﾛｰ", 255,   1.3),
		new Jockey("ｾｷﾄﾊﾞ"   , 192,   1.9, 1),
		new Jockey("ﾄｳｶｲﾃｲｵｰ", 175,   2.1),
		new Jockey("ﾁｰﾀｰ"    , 162,   2.6),
		new Jockey("ｶｰﾙﾙｲｽ"  , 150,   2.4),
		new Jockey("ﾘｰﾀﾞｰX"  , 140,   2.7),
		new Jockey("ｸﾁｻｹｵﾝﾅ" , 130,   2.5),
		new Jockey("ｽﾗｲﾑ"    , 120,   3.4),
		new Jockey("ﾘｰﾀﾞｰA"  , 110,   2.9),
		new Jockey("ﾘｰﾀﾞｰB"  , 100,   3.6),
		new Jockey("ﾄﾞﾗｷｰ"   ,  90,   3.3),
		new Jockey("ﾋｸﾞﾙﾏ"   ,  81,   4.1, 1),
		new Jockey("ﾉﾛｰｽﾍﾟｰｽ",  72,   5.6),
		new Jockey("ﾊﾞｶﾎﾞﾝ"  ,  63,   3.9),
		new Jockey("ﾄｳﾀｸ"    ,  54,   5.4),
		new Jockey("ｳﾏｶﾞｴﾙ"  ,  46,   6.6),
		new Jockey("ｻﾝﾘﾝｼｬ"  ,  38,   7.3),
		new Jockey("ｳﾊﾞｸﾞﾙﾏ" ,  30,   8.7),
		new Jockey("ｺﾆｼｷ"    ,  24,   9.4),
		new Jockey("ﾅﾏｹﾓﾉ"   ,   7, 102.4)
	];
	private var jindex:Array<Int> = [0, 0, 0, 0];
	private var jdistance:Array<Int> = [0, 0, 0, 0];

	private var money:Int;
	private var bet:Int;
	private var ticket:Int;

	private var jcolor:Array<Int> =
	[
		0xFF0000, 0x00FF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0xFFFFFF, 0x770077
	];
	private var jcolor_bg:Array<Int> =
	[
		0x770000, 0x007700, 0x007777, 0x770077
	];
	
	private var bitmap:Array<Bitmap> = [
		for (i in 0...8) new Bitmap()
	];
	private var text:Array<TextField> = [
		for (i in 0...7) new TextField()
	];
	private var state:State;

	// 賭金描画
	public function drawBet() {
		text[4].text = "ｼｮｼﾞｷﾝ " + money + "ｴﾝ, ｶｹｷﾝ " + bet + "ｴﾝ";

		bitmap[2].width = 576;
		bitmap[3].width = 576 * bet / money;
	}

	// 枠pngをボタンにする
	public function setColorButton() {
		for (i in 4...8)
		{
			bitmap[i].x = i  * 160 - 608;
			bitmap[i].y = 276;
			bitmap[i].width = 96;
			bitmap[i].height = 96;
		}
	}

	// 枠pngを競争馬にする
	public function setColorJockey() {
		for (i in 4...8)
		{
			bitmap[i].x = 0;
			bitmap[i].y = i * 80 - 280;
			bitmap[i].width = jdistance[i - 4];
			bitmap[i].height = 48;
		}
	}

	// 場面切替
	public function changeState(st:State) {
		switch(st)
		{
			case Start:
				addChild(bitmap[0]);
				money = 100;
			case Select:
				this.graphics.clear();

				bet = Std.int(money / 10);
				if ( bet < 1 ) bet = 1;
				// 各枠とボタン
				for (i in 0...4) 
				{
					jindex[i] = Std.random(jtable.length);

					text[i].text = "" + (i + 1) + "ﾜｸ: " + jtable[jindex[i]].name;
					text[i].text += " ﾊﾞｲﾘﾂ: " + jtable[jindex[i]].odds;
				}

				// 賭金
				for (i in 2...4) addChild(bitmap[i]);
				drawBet();

				text[5].text = "ﾜｸｦ ｴﾗﾝﾃﾞ ｶｲｼ";
				setColorButton();
				for (i in 2...8) addChild(bitmap[i]);
				for (i in 0...6) addChild(text[i]);

			case GameOver:
				for (i in 0...6) removeChild(text[i]);
				for (i in 0...8) removeChild(bitmap[i]);
				this.graphics.clear();
				text[6].text = "ﾊｻﾝ";
				addChild(text[6]);

			case Clear:
				for (i in 0...6) removeChild(text[i]);
				for (i in 0...8) removeChild(bitmap[i]);
				addChild(bitmap[1]);
			default:
				
		}
		state = st;
	}

	public function new() 
	{
		super();

		// ビットマップのロード
		bitmap[0] = new Bitmap(Assets.getBitmapData("img/title.jpg"));
		bitmap[1] = new Bitmap(Assets.getBitmapData("img/end.jpg"));
		for (i in 0...2)
		{
			bitmap[i].x = (stage.stageWidth - bitmap[i].width) / 2;
			bitmap[i].y = (stage.stageHeight - bitmap[i].height) / 2;
		}
		bitmap[2] = new Bitmap(Assets.getBitmapData("img/bet_bg.png"));
		bitmap[3] = new Bitmap(Assets.getBitmapData("img/bet_fg.png"));
		for (i in 2...4)
		{
			bitmap[i].x = 32;
			bitmap[i].y = 156;
			bitmap[i].height = 64;
		}
		for (i in 4...8)
		{
			bitmap[i] = new Bitmap(Assets.getBitmapData("img/post_" + ( i - 3 ) + ".png"));
		}

		// テキストフィールドのロード
		for (i in 0...7)
		{
			text[i].x = 0;
			text[i].y = i * 24;
			if ( i == 4 ) text[i].y = 120;
			if ( i == 5 ) text[i].y = 240;
			if ( i == 6 ) text[i].y = 0;
			text[i].width = 400;
			text[i].height = 24;
			text[i].defaultTextFormat = new TextFormat("", 24, jcolor[i]);
			text[i].autoSize = TextFieldAutoSize.LEFT;
		}

		// 開始画面
		changeState(State.Start);

		this.stage.addEventListener(MouseEvent.CLICK, onClick);
		this.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}

	private function onClick(event:MouseEvent)
	{
		switch (state) 
		{
			case State.Start:
				removeChild(bitmap[0]);
				changeState(State.Select);
			case State.Select:
				// 賭金操作
				if ( 156 <= event.stageY && event.stageY < 220 )
				{
					bet = Std.int( money * ( event.stageX - 32 ) / 576 );
					if ( bet < 1 ) bet = 1;
					if ( bet > money ) bet = money;
					drawBet();
				}
				else if ( 276 <= event.stageY && event.stageY < 372 )
				{
					for (i in 0...4)
					{
						var j:Int = i * 160;
						if ( 32 + j <= event.stageX && event.stageX < 128 + j )
						{
							this.graphics.clear();
							ticket = i;
							jdistance = [0, 0, 0, 0];
							removeChild(text[5]);
							removeChild(bitmap[2]);
							removeChild(bitmap[3]);
							setColorJockey();
							changeState(State.Play);
						}
					}
				}
			case State.Goal:
				if ( money < 1 ) changeState(State.GameOver);
				else if ( money > 99999 ) changeState(State.Clear);
				else changeState(State.Select);
			case State.GameOver:
				removeChild(text[6]);
				changeState(State.Start);
			case State.Clear:
				removeChild(bitmap[1]);
				changeState(State.Start);
			default:
				
		}
	}
	private function onEnterFrame(event:Event)
	{
		switch (state)
		{
			case State.Play:
				var i:Int = Std.random(4);
				var j:Int = jtable[jindex[i]].adjustedSpeed(i);
				jdistance[i] += j;
				for (k in 0...4)
				{
					bitmap[k+4].width = jdistance[k];
				}
				if ( jdistance[i] >= 640 ) {
					text[5].text = jtable[jindex[i]].name + "ﾉ ｶﾁ";
					addChild(text[5]);
					money -= bet;
					if ( ticket == i ) money += Std.int(bet * jtable[jindex[i]].odds);
					text[4].text = "ｼｮｼﾞｷﾝ " + money + "ｴﾝ, ｶｹｷﾝ " + bet + "ｴﾝ";
					changeState(State.Goal);
				}
			default:
				
		}
	}
}