#include "_Global.h"

#include "Main.h"

/**
 * メイン
 */
class Main extends _Main {
	var g;

#ifdef _USE_BITMAPDATA
	var bitmap:Array;
#endif // _USE_BITMAPDATA

	var rand;
	var stage;
//	var wave;
	var speeder;

	var bar;	// バー情報

//	var SPEEDER1_X = [ 0, 17, 34, 51, 68, 85, 103, 121, 140, 160, 181, 202, 224, 247, 270, 294 ];
//	var SPEEDER1_X_M = [ 318, 301, 284, 267, 250, 232, 214, 195, 175, 154, 133, 111, 88, 65, 41, 17 ];
	var SPEEDER1_W = [ 17, 17, 17, 17, 17, 18, 18, 19, 20, 21, 21, 22, 23, 23, 24, 24 ];

//	var SPEEDER2_X = [ 0, 17, 34, 51, 68, 86, 105, 124, 144, 164, 185, 206, 228, 250, 273, 296 ];
//	var SPEEDER2_X_M = [ 320, 303, 286, 269, 251, 232, 213, 193, 173, 152, 131, 109, 87, 64, 41, 17 ];
	var SPEEDER2_W = [ 17, 17, 17, 17, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24 ];

//	var SPEEDER3_X = [ 0, 17, 34, 51, 68, 85, 103, 121, 140, 160, 181, 202, 224, 246, 269, 292 ];
//	var SPEEDER3_X_M = [ 315, 298, 281, 264, 247, 229, 211, 192, 172, 151, 130, 108, 86, 63, 40, 17 ];
	var SPEEDER3_W = [ 17, 17, 17, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 23, 23 ];

	var state = STATE_LAUNCH;	// アプリの状態
	var _elapse;				// 経過時間
	var _elapse_p;				// ポーズ中の経過時間
	var _elapse_s;				// シールド切り替え速度
	var pause = false;		// ポーズ中かどうか
	var shield_lag;
	var shield_index;
	var shield_wait;
	var shield_col;

	var change_col;

	var neutral;			// キー解放でニュートラルにするかどうか
	var level;					// レベル
	var player;					// 使用キャラクタ

	var first;				// 初挑戦かどうか

	var time;					// 今回のタイム
	var best_time;			// ベストタイム
	var win;				// １位になった回数
	var ranking;				// 順位
	var new_time;			// 記録更新かどうか

	var best_distance;			// ベスト走行距離
	var old_distance;			//
	var new_distance;		// 記録更新かどうか

	var _elapse_l;				// 計測ポイント通過時の時間
	var lap;					// ラップ
	var lap_time;				// ラップタイムの差
	var dsp_lap;			// ラップタイムの差を表示するかどうか
	var finish;				// フィニッシュラインかどうか

	var boost;				// ブースト可能かどうか
	var _elapse_b;				// ブースト使用時の時間

	var old_y;
	var new_y;

	var hide_status;

	var load_movie;
	var clip;
	var clip_select;
	var clip_bg;

	var so;

	/**
	 * 設定の読み込み
	 */
	function load_config() {
		var i, j;

		// デフォルト値
		neutral       = true;
		level         = 0;
		player        = 0;
		shield_lag[0] = 10;
		shield_lag[1] = 10;
		shield_index  = 0;
		for ( i = 0; i < 7; i++ ) {
			for ( j = 0; j < 10; j++ ) {
				best_time[i][j] = 99999;
			}
		}
		for ( i = 0; i < 3; i++ ) {
			for ( j = 0; j < 3; j++ ) {
				win[i][j] = 0;
			}
		}
		best_distance = 0;

		var str = new String("");
		so.beginRead();
		str = so.read(); if ( str.length > 0 ) neutral = (Number(str) == 1) ? true : false;
		str = so.read(); if ( str.length > 0 ) level = Number(str);
		str = so.read(); if ( str.length > 0 ) player = Number(str);
		str = so.read(); if ( str.length > 0 ) shield_lag[0] = Number(str);
		str = so.read(); if ( str.length > 0 ) shield_lag[1] = Number(str);
		str = so.read(); if ( str.length > 0 ) shield_index = Number(str);
		for ( i = 0; i < 6; i++ ) {
			for ( j = 0; j < 10; j++ ) {
				str = so.read(); if ( str.length > 0 ) best_time[i][j] = Number(str);
			}
		}
		for ( i = 0; i < 2; i++ ) {
			for ( j = 0; j < 3; j++ ) {
				str = so.read(); if ( str.length > 0 ) win[i][j] = Number(str);
			}
		}
		str = so.read(); if ( str.length > 0 ) best_distance = Number(str);
		for ( j = 0; j < 10; j++ ) {
			str = so.read(); if ( str.length > 0 ) best_time[6][j] = Number(str);
		}
		for ( j = 0; j < 3; j++ ) {
			str = so.read(); if ( str.length > 0 ) win[2][j] = Number(str);
		}
		so.endRead();
	}

	/**
	 * 設定の書き出し
	 */
	function save_config() {
		var i, j;
		so.beginWrite();
		so.write("" + (neutral ? "1" : "0"));
		so.write("" + level);
		so.write("" + player);
		so.write("" + shield_lag[0]);
		so.write("" + shield_lag[1]);
		so.write("" + shield_index);
		for ( i = 0; i < 6; i++ ) {
			for ( j = 0; j < 10; j++ ) {
				so.write("" + best_time[i][j]);
			}
		}
		for ( i = 0; i < 2; i++ ) {
			for ( j = 0; j < 3; j++ ) {
				so.write("" + win[i][j]);
			}
		}
		so.write("" + best_distance);
		for ( j = 0; j < 10; j++ ) {
			so.write("" + best_time[6][j]);
		}
		for ( j = 0; j < 3; j++ ) {
			so.write("" + win[2][j]);
		}
		so.endWrite();
	}

	// 経過時間を確認する
	function elapse() { return pause ? _elapse_p : _elapse; }

	// おまけモードがプレイできるか確認する
	function omake1() {
		var i;
		for ( i = 0; i < 6; i++ ) {
			if ( best_time[i][0] == 99999 ) {
				return false;
			}
		}
		return true;
	}
	function omake2() {
		var i, j;
		for ( i = 0; i < 2; i++ ) {
			for ( j = 0; j < 3; j++ ) {
				if ( win[i][j] == 0 ) {
					return false;
				}
			}
		}
		return true;
	}

	function level_max() {
		if ( omake1() ) {
			return omake2() ? 7 : 6;
		}
		return 5;
	}

	function index_b() { return (level == 7) ? 6 : level; }
	function index_w() { return (level == 7) ? 2 : level; }

	/**
	 * アプリの状態を変更する
	 */
	function set_state(new_state) {
		var i;

		var old_state = state;
		state = new_state;
		_elapse = 0;
		_elapse_l = 0;
		_elapse_b = 0 - WAIT_BOOST;

		switch ( old_state ) {
		case STATE_TITLE_LOADING:
		case STATE_SELECT_LOADING:
			if ( state == STATE_READY ) {
				change_col = 0;

				if ( level != 6 ) {
					shield_wait[0] = 0;
					shield_wait[1] = 0;

					first = (best_time[index_b()][0] == 99999) ? true : false;

					time[0] = 0;

					lap     = 0;
					dsp_lap = false;
					finish  = false;
				} else {
					old_distance = best_distance;
				}

				boost = false;

				if ( (level < 2) || (level == 7) ) {
					var tmp = (rand.nextInt() > 0) ? true : false;
					switch ( player ) {
					case 0:
						speeder[0].init(true, SPEEDER1, 0, 0);
						speeder[1].init(false, tmp ? SPEEDER2 : SPEEDER3, 0, -50);
						speeder[2].init(false, tmp ? SPEEDER3 : SPEEDER2, 0,  50);
						break;
					case 1:
						speeder[0].init(true, SPEEDER2, 0, 0);
						speeder[1].init(false, tmp ? SPEEDER1 : SPEEDER3, 0, -50);
						speeder[2].init(false, tmp ? SPEEDER3 : SPEEDER1, 0,  50);
						break;
					case 2:
						speeder[0].init(true, SPEEDER3, 0, 0);
						speeder[1].init(false, tmp ? SPEEDER1 : SPEEDER2, 0, -50);
						speeder[2].init(false, tmp ? SPEEDER2 : SPEEDER1, 0,  50);
						break;
					}
				} else {
					switch ( rand.next(2) ) {
					case -1: speeder[0].init(true, SPEEDER1, (level != 6) ? 0 : 495, 0); break;
					case  0: speeder[0].init(true, SPEEDER4, (level != 6) ? 0 : 495, 0); break;
					case  1: speeder[0].init(true, SPEEDER5, (level != 6) ? 0 : 495, 0); break;
					}
				}
			}

			break;
		case STATE_CLEAR:
		case STATE_STOP:
			save_config();
			break;
		}

		switch ( state ) {
		case STATE_TITLE:
			if ( old_state != STATE_SELECT ) {
				pause = false;
				save_config();
			}
			break;
		case STATE_SELECT:
			break;
		case STATE_READY:
			wave_create();
			stage.create();
			break;
		case STATE_CLEAR:
			new_time = false;
			if ( time[0] < best_time[index_b()][0] ) {
				new_time = first ? false : true;
				best_time[index_b()][0] = time[0];
				best_time[index_b()][1] = time[1];
				for ( i = 2; i < 10; i++ ) {
					best_time[index_b()][i] = time[i] - time[i - 1];
				}
			}
			ranking = 1;
			if ( (level < 2) || (level == 7) ) {
				if ( speeder[0]._distance < speeder[1]._distance ) ranking++;
				if ( speeder[0]._distance < speeder[2]._distance ) ranking++;
				if ( ranking == 1 ) {
					win[index_w()][player]++;
				}
			}
			break;
		case STATE_STOP:
			new_distance = false;
			if ( speeder[0]._distance > best_distance ) {
				new_distance = (best_distance == 0) ? false : true;
				best_distance = speeder[0]._distance;
			}
			break;
		}
	}

	function drawImage(img, x0, y0, w, h) {
		if ( (x0 + w) <= 0 ) {
			return -1;
		} else if ( x0 >= 240 ) {
			return 1;
		}
#ifdef _USE_BITMAPDATA
		g.copyPixels(bitmap[img], x0, y0);
#else
		g.drawImage(img, x0, y0);
#endif // _USE_BITMAPDATA
		return 0;
	}

	function drawImage2(img, x0, y0) {
#ifdef _USE_BITMAPDATA
		g.copyPixels(bitmap[img], x0, y0);
#else
		g.drawImage(img, x0, y0);
#endif // _USE_BITMAPDATA
	}

	/**
	 * start
	 */
	function start() {
		var i;

		g = getGraphics();

#ifdef _USE_BITMAPDATA
		bitmap = new Array(IMAGE_NUM);
		for ( i = 0; i < IMAGE_NUM; i++ ) {
			bitmap[i] = new _BitmapData(this, i);
		}
#endif // _USE_BITMAPDATA

		set_state(STATE_LAUNCH);

		shield_lag  = new Array(2);
		shield_wait = new Array(2);
		shield_col  = new Array(2);

		time = new Array(10);
		best_time = new Array(7);
		for ( i = 0; i < 7; i++ ) {
			best_time[i] = new Array(10);
		}
		win = new Array(3);
		for ( i = 0; i < 3; i++ ) {
			win[i] = new Array(3);
		}

		old_y = new Array(2);
		new_y = new Array(2);

		rand = new _Random();
		stage = new MyStage(this);
//		wave = new Wave(this);

		bar = new _Vector(128);

		speeder = new Array(3);
		speeder[0] = new Speeder(this);
		speeder[1] = new Speeder(this);
		speeder[2] = new Speeder(this);

		hide_status = false;

		load_movie = new _LoadMovie(this);
		clip_select = new Array(3);
		clip_select[0] = new _MovieClip();
		clip_select[1] = new _MovieClip();
		clip_select[2] = new _MovieClip();
		clip_bg = new Array(2);
		clip_bg[0] = new _MovieClip();
		clip_bg[1] = new _MovieClip();

		so = new _SharedObject(this, "config");
		load_config();

		set_state(STATE_TITLE);

		return true;
	}

	/**
	 * ステータス描画
	 */
	function drawStatus(ready) {
		var i, x, y;
		var tmp;

		if ( hide_status ) return;

		if ( level != 6 ) {
			drawImage2(IMAGE_STATUS_23, 10, 0);
			x = 15 + 12 * 3;
			tmp = time[0];
			for ( i = 0; i < 4; i++ ) {
				drawImage2(IMAGE_STATUS_00 + _MOD(tmp, 10), x, 6);
				tmp = _DIV(tmp, 10);
				x -= 12;
			}

			if ( !first && dsp_lap ) {
				if ( (lap > 0) && ((_elapse - _elapse_l) < WAIT_2) ) {
					drawImage2(IMAGE_STATUS_42, 10, 24);
					x = 15 + 12 * 3;
					y = 0;
					tmp = lap_time;
					if ( tmp < 0 ) {
						tmp = 0 - tmp;
						drawImage2(IMAGE_STATUS_21, 15, 30);
						y = 10;
					} else if ( tmp == 0 ) {
						drawImage2(IMAGE_STATUS_22, 15, 30);
					} else {
						drawImage2(IMAGE_STATUS_20, 15, 30);
					}
					for ( i = 0; i < 3; i++ ) {
						drawImage2(IMAGE_STATUS_00 + y + _MOD(tmp, 10), x, 30);
						tmp = _DIV(tmp, 10);
						x -= 12;
					}
				} else {
					dsp_lap = false;
				}
			}
		}

		drawImage2(IMAGE_STATUS_24, 148, 0);
		x = 190 + 12 * 2;
		tmp = ready ? 0 : speeder[0]._speed;
		for ( i = 0; i < 3; i++ ) {
			drawImage2(IMAGE_STATUS_00 + _MOD(tmp, 10), x, 6);
			tmp = _DIV(tmp, 10);
			x -= 12;
		}

		drawImage2(IMAGE_STATUS_41, 0, 0);
		drawImage2(IMAGE_STATUS_41, 230, 0);

		if ( (level < 2) || (level == 7) ) {
			for ( i = 1; i < 3; i++ ) {
				drawImage2(IMAGE_STATUS_26, 1, 240 - _DIV(240 * speeder[i]._distance, DISTANCE) - 4);
			}
			drawImage2(IMAGE_STATUS_25, 1, 240 - _DIV(240 * speeder[0]._distance, DISTANCE) - 4);

			for ( i = 1; i < 3; i++ ) {
				drawImage2(IMAGE_STATUS_26, 231, (120 - 4) - _DIV(speeder[i]._distance - speeder[0]._distance, 100));
			}
			drawImage2(IMAGE_STATUS_25, 231, 120 - 4);
		} else if ( (level != 6) || (old_distance == 0) ) {
			y = 240 - _DIV(240 * speeder[0]._distance, DISTANCE);
			drawImage2(IMAGE_STATUS_25, 1, y - 4);
			drawImage2(IMAGE_STATUS_25, 231, y - 4);
		} else {
			y = 240 - _DIV(240 * old_distance, old_distance * 2);
			drawImage2(IMAGE_STATUS_26, 1, y - 4);
			drawImage2(IMAGE_STATUS_26, 231, y - 4);
			y = 240 - _DIV(240 * speeder[0]._distance, old_distance * 2);
			drawImage2(IMAGE_STATUS_25, 1, y - 4);
			drawImage2(IMAGE_STATUS_25, 231, y - 4);
		}

		if ( boost ) {
			drawImage2(IMAGE_STATUS_39 + ((_MOD(elapse(), 4) < 2) ? 0 : 1), 184, 24);
		}
	}

	function unlock() {
#ifdef _DEBUG
		g.setFont(_FONT_TINY);
		g.setColor(g.getColorOfRGB(255, 0, 255));
		g.drawString("use " + g._d, 0, 12);
		g.drawString("create " + g._create, 0, 24);
		g.drawString("attach " + g._attach, 0, 36);
#endif // _DEBUG

		// ゲーム画面の外を塗りつぶす
		g.setColor(g.getColorOfRGB(0, 0, 0));
		g.fillRect(-240, -240, 720, 240);
		g.fillRect(-240, 0, 240, 240);
		g.fillRect(240, 0, 240, 240);
		g.fillRect(-240, 240, 720, 240);

		g.unlock();
	}

	/**
	 * paint
	 */
	function paint() {
		var i;

		var key = getKeypadState();

		switch ( state ) {
		case STATE_LAUNCH:
			break;
		case STATE_TITLE:
		case STATE_TITLE_LOADING:
			// 描画
			g.lock();
			{
				var x;

				g.setColor(g.getColorOfRGB(0, 0, 0));
				g.fillRect(0, 0, 240, 240);

				drawImage2(IMAGE_LOGO, 0, 15);

				x = _DIV(240 - (TEXT_NEUTRAL_W + 8 + TEXT_OFF_W), 2);
				drawImage2(IMAGE_TITLE_NEUTRAL, x, 100); x += (TEXT_NEUTRAL_W + 8);
				if ( neutral ) {
					drawImage2(IMAGE_TITLE_ON, x, 100);
				} else {
					drawImage2(IMAGE_TITLE_OFF, x, 100);
				}

				drawImage2(IMAGE_TITLE_11, 115, 118);
				drawImage2(IMAGE_TITLE_12, 115, 141);
				switch ( level ) {
				case 0:
					x = _DIV(240 - (TEXT_RACE_W + 8 + TEXT_EASY_W), 2);
					drawImage2(IMAGE_TITLE_RACE, x, 127); x += (TEXT_RACE_W + 8);
					drawImage2(IMAGE_TITLE_EASY, x, 127);
					break;
				case 1:
					x = _DIV(240 - (TEXT_RACE_W + 8 + TEXT_HARD_W), 2);
					drawImage2(IMAGE_TITLE_RACE, x, 127); x += (TEXT_RACE_W + 8);
					drawImage2(IMAGE_TITLE_HARD, x, 127);
					break;
				case 2:
					x = _DIV(240 - (TEXT_FREE_W + 8 + TEXT_EASY_W), 2);
					drawImage2(IMAGE_TITLE_FREE, x, 127); x += (TEXT_FREE_W + 8);
					drawImage2(IMAGE_TITLE_EASY, x, 127);
					break;
				case 3:
					x = _DIV(240 - (TEXT_FREE_W + 8 + TEXT_HARD_W), 2);
					drawImage2(IMAGE_TITLE_FREE, x, 127); x += (TEXT_FREE_W + 8);
					drawImage2(IMAGE_TITLE_HARD, x, 127);
					break;
				case 4:
					x = _DIV(240 - (TEXT_TRAINING_W + 8 + TEXT_1_W), 2);
					drawImage2(IMAGE_TITLE_TRAINING, x, 127); x += (TEXT_TRAINING_W + 8);
					drawImage2(IMAGE_TITLE_1, x, 127);
					break;
				case 5:
					x = _DIV(240 - (TEXT_TRAINING_W + 8 + TEXT_2_W), 2);
					drawImage2(IMAGE_TITLE_TRAINING, x, 127); x += (TEXT_TRAINING_W + 8);
					drawImage2(IMAGE_TITLE_2, x, 127);
					break;
				case 6:
					x = _DIV(240 - (TEXT_OMAKE_W + 8 + TEXT_1_W), 2);
					drawImage2(IMAGE_TITLE_OMAKE, x, 127); x += (TEXT_OMAKE_W + 8);
					drawImage2(IMAGE_TITLE_1, x, 127);
					break;
				case 7:
					x = _DIV(240 - (TEXT_OMAKE_W + 8 + TEXT_2_W), 2);
					drawImage2(IMAGE_TITLE_OMAKE, x, 127); x += (TEXT_OMAKE_W + 8);
					drawImage2(IMAGE_TITLE_2, x, 127);
					break;
				}

				if ( level != 6 ) {
					drawImage2(IMAGE_TITLE_BESTTIME, _DIV(240 - TEXT_BESTTIME_W, 2), 154);
					if ( best_time[index_b()][0] == 99999 ) {
						drawImage2(IMAGE_TITLE_10, 96, 170);
						drawImage2(IMAGE_TITLE_10, 108, 170);
						drawImage2(IMAGE_TITLE_10, 120, 170);
						drawImage2(IMAGE_TITLE_10, 132, 170);
					} else {
						x = 96 + 12 * 3;
						var tmp = best_time[index_b()][0];
						for ( i = 0; i < 4; i++ ) {
							drawImage2(IMAGE_TITLE_00 + _MOD(tmp, 10), x, 170);
							tmp = _DIV(tmp, 10);
							x -= 12;
						}
					}
				} else {
					drawImage2(IMAGE_TITLE_DISTANCE, _DIV(240 - TEXT_DISTANCE_W, 2), 154);
					i = 0;
					var tmp = _DIV(best_distance, 5);
					while ( true ) {
						i++;
						tmp = _DIV(tmp, 10);
						if ( tmp == 0 ) {
							break;
						}
					}
					x = 240 - _DIV(240 - (12 * i), 2);
					tmp = _DIV(best_distance, 5);
					while ( true ) {
						x -= 12;
						drawImage2(IMAGE_TITLE_00 + _MOD(tmp, 10), x, 170);
						tmp = _DIV(tmp, 10);
						if ( tmp == 0 ) {
							break;
						}
					}
				}

				if ( state == STATE_TITLE ) {
					if ( _MOD(_elapse, WAIT_1) <= _DIV(WAIT_1, 2) ) {
						x = _DIV(240 - (TEXT_PRESS_W + 8 + TEXT_SELECT_W + 8 + TEXT_KEY_W), 2);
						drawImage2(IMAGE_TITLE_PRESS, x, 195); x += (TEXT_PRESS_W + 8);
						drawImage2(IMAGE_TITLE_SELECT, x, 195); x += (TEXT_SELECT_W + 8);
						drawImage2(IMAGE_TITLE_KEY, x, 195);
					}
				} else {
					drawImage2(IMAGE_TITLE_LOADING, _DIV(240 - TEXT_LOADING_W, 2), 195);
				}

				x = _DIV(240 - (TEXT_COPYRIGHT_W + 8 + TEXT_COPYRIGHT2_W), 2);
				drawImage2(IMAGE_TITLE_COPYRIGHT, x, 220); x += (TEXT_COPYRIGHT_W + 8);
				drawImage2(IMAGE_TITLE_COPYRIGHT2, x, 220);
			}
			unlock();

			if ( state == STATE_TITLE_LOADING ) {
				if ( !load_movie.busy() ) {
					if ( (level < 2) || (level == 7) ) {
						set_state(STATE_SELECT);
					} else {
						set_state(STATE_READY);
					}
				}
			}

			break;
		case STATE_SELECT:
		case STATE_SELECT_LOADING:
			// 描画
			g.lock();
			{
				var x = 0;
				var tmp = 0;

				g.setColor(g.getColorOfRGB(0, 0, 0));
				g.fillRect(0, 0, 240, 240);

				g.drawMovie(clip_select[player], 0, 0);

				drawImage2(IMAGE_TITLE_SELECTCHAR, _DIV(240 - TEXT_SELECTCHAR_W, 2), 15);

				drawImage2(IMAGE_TITLE_ACCELERATION, 140 - TEXT_ACCELERATION_W, 140);
				drawImage2(IMAGE_TITLE_SLOWDOWN, 140 - TEXT_SLOWDOWN_W, 160);
				drawImage2(IMAGE_TITLE_STEERING, 140 - TEXT_STEERING_W, 180);

				switch ( _MOD(_elapse, 3) ) {
				case 0: g.setColor(g.getColorOfRGB(  0, 255, 255)); break;
				case 1: g.setColor(g.getColorOfRGB(255,   0, 255)); break;
				case 2: g.setColor(g.getColorOfRGB(255, 255,   0)); break;
				}
				g.drawRect(80, 45, 80, 80);
				drawImage2(IMAGE_TITLE_13,  71, 81);
				drawImage2(IMAGE_TITLE_14, 165, 81);

				switch ( player ) {
				case 0:
					for ( i = 0; i < 3; i++ ) {
						switch ( i ) {
						case 0: x =  65; tmp = win[index_w()][2]; break;
						case 1: x = 145; tmp = win[index_w()][0]; break;
						case 2: x = 225; tmp = win[index_w()][1]; break;
						}
						while ( tmp != 0 ) {
							drawImage2(IMAGE_TITLE_00 + _MOD(tmp, 10), x, 50);
							tmp = _DIV(tmp, 10);
							x -= 12;
						}
					}

					drawImage2(IMAGE_SPEEDER3_00,  40 - _DIV(SPEEDER3_W[0], 2), 55);
					drawImage2(IMAGE_SPEEDER1_00, 120 - _DIV(SPEEDER1_W[0], 2), 55);
					drawImage2(IMAGE_SPEEDER2_00, 200 - _DIV(SPEEDER2_W[0], 2), 57);

					drawImage2(IMAGE_TITLE_RAY, _DIV(240 - TEXT_RAY_W, 2), 105);

					drawImage2(IMAGE_TITLE_FAST, 150, 140);
					drawImage2(IMAGE_TITLE_NORMAL, 150, 160);
					drawImage2(IMAGE_TITLE_NORMAL, 150, 180);

					break;
				case 1:
					for ( i = 0; i < 3; i++ ) {
						switch ( i ) {
						case 0: x =  65; tmp = win[index_w()][0]; break;
						case 1: x = 145; tmp = win[index_w()][1]; break;
						case 2: x = 225; tmp = win[index_w()][2]; break;
						}
						while ( tmp != 0 ) {
							drawImage2(IMAGE_TITLE_00 + _MOD(tmp, 10), x, 50);
							tmp = _DIV(tmp, 10);
							x -= 12;
						}
					}

					drawImage2(IMAGE_SPEEDER1_00,  40 - _DIV(SPEEDER1_W[0], 2), 55);
					drawImage2(IMAGE_SPEEDER2_00, 120 - _DIV(SPEEDER2_W[0], 2), 57);
					drawImage2(IMAGE_SPEEDER3_00, 200 - _DIV(SPEEDER3_W[0], 2), 55);

					drawImage2(IMAGE_TITLE_RAX, _DIV(240 - TEXT_RAX_W, 2), 105);

					drawImage2(IMAGE_TITLE_MIDDLE, 150, 140);
					drawImage2(IMAGE_TITLE_SLIGHT, 150, 160);
					drawImage2(IMAGE_TITLE_NORMAL, 150, 180);

					break;
				case 2:
					for ( i = 0; i < 3; i++ ) {
						switch ( i ) {
						case 0: x =  65; tmp = win[index_w()][1]; break;
						case 1: x = 145; tmp = win[index_w()][2]; break;
						case 2: x = 225; tmp = win[index_w()][0]; break;
						}
						while ( tmp != 0 ) {
							drawImage2(IMAGE_TITLE_00 + _MOD(tmp, 10), x, 50);
							tmp = _DIV(tmp, 10);
							x -= 12;
						}
					}

					drawImage2(IMAGE_SPEEDER2_00,  40 - _DIV(SPEEDER2_W[0], 2), 57);
					drawImage2(IMAGE_SPEEDER3_00, 120 - _DIV(SPEEDER3_W[0], 2), 55);
					drawImage2(IMAGE_SPEEDER1_00, 200 - _DIV(SPEEDER1_W[0], 2), 55);

					drawImage2(IMAGE_TITLE_COM, _DIV(240 - TEXT_COM_W, 2), 105);

					drawImage2(IMAGE_TITLE_SLOW, 150, 140);
					drawImage2(IMAGE_TITLE_NORMAL, 150, 160);
					drawImage2(IMAGE_TITLE_QUICK, 150, 180);

					break;
				}

				if ( state == STATE_SELECT ) {
					if ( _MOD(_elapse, WAIT_1) <= _DIV(WAIT_1, 2) ) {
						x = _DIV(240 - (TEXT_PRESS_W + 8 + TEXT_SELECT_W + 8 + TEXT_KEY_W), 2);
						drawImage2(IMAGE_TITLE_PRESS, x, 210); x += (TEXT_PRESS_W + 8);
						drawImage2(IMAGE_TITLE_SELECT, x, 210); x += (TEXT_SELECT_W + 8);
						drawImage2(IMAGE_TITLE_KEY, x, 210);
					}
				} else {
					drawImage2(IMAGE_TITLE_LOADING, _DIV(240 - TEXT_LOADING_W, 2), 210);
				}
			}
			unlock();

			if ( state == STATE_SELECT_LOADING ) {
				if ( !load_movie.busy() ) {
					set_state(STATE_READY);
				}
			}

			break;
		case STATE_READY:
			// 描画
			g.lock();
			stage.draw(true);
			wave_draw();
			speeder[0].draw(true);
			if ( (level < 2) || (level == 7) ) {
				speeder[1].draw(true);
				speeder[2].draw(true);
			}
			switch ( level ) {
			case 4:
				drawImage2(IMAGE_STATUS_AUTOSTEERING, _DIV(240 - TEXT_AUTOSTEERING_W, 2), 80);
				break;
			case 5:
				drawImage2(IMAGE_STATUS_AUTOSHIELD, _DIV(240 - TEXT_AUTOSHIELD_W, 2), 80);
				break;
			}
			drawImage2(IMAGE_STATUS_READY, _DIV(240 - TEXT_READY_W, 2), _DIV(240 - TEXT_READY_H, 2));
			drawStatus(true);
			unlock();

			// 一定時間過ぎたらゲーム開始
			if ( _elapse > WAIT_2 ) {
				set_state(STATE_PLAY);
			}

			break;
		case STATE_PLAY:
			if ( !pause ) {
				time[0]++;

				// 更新前の座標を保持
				if ( (level < 2) || (level == 7) ) {
					old_y[0] = speeder[1].dsp_y();
					old_y[1] = speeder[2].dsp_y();
				}

				// 更新
				stage.update();
				wave_update();

				if ( (level < 2) || (level == 7) ) {
					for ( i = 0; i < 2; i++ ) {
						if ( shield_wait[i] > 0 ) {
							shield_wait[i]--;
							if ( shield_wait[i] == 0 ) {
								speeder[i + 1].shield(shield_col[i]);
							}
						}

						new_y[i] = speeder[i + 1].dsp_y();
						if ( (old_y[i] > -48) && (new_y[i] <= -48) ) {
							speeder[i + 1].out(wave_top_x());
						} else if ( (old_y[i] <= -48) && (new_y[i] > -48) ) {
							speeder[i + 1]._in(wave_top_x());
						} else if ( (old_y[i] < 320) && (new_y[i] >= 320) ) {
							speeder[i + 1].out(wave_bottom_x());
						} else if ( (old_y[i] >= 320) && (new_y[i] < 320) ) {
							speeder[i + 1]._in(wave_bottom_x());
						}

						if ( new_y[i] <= -48 ) {
							if ( speeder[0]._speed < 310 ) {
								speeder[i + 1].speed_limit(300);
							} else {
								speeder[i + 1].speed_limit(speeder[0]._speed - 10);
							}
						}
					}
				}

				// スピーダーの移動
				if ( level == 4 ) {
					switch ( speeder[0]._auto ) {
					case AUTO_MOVED_INERTIA: speeder[0]._auto = AUTO_INERTIA; break;
					case AUTO_MOVED_NEUTRAL: speeder[0]._auto = AUTO_NEUTRAL; break;
					case AUTO_INERTIA: speeder[0].inertia(false); break;
					case AUTO_NEUTRAL: speeder[0].inertia(true ); break;
					}
				} else {
					if      ( ((key & keyBit(_KEY_4)) != 0) || ((key & keyBit(_KEY_LEFT )) != 0) ) speeder[0].left ();
					else if ( ((key & keyBit(_KEY_6)) != 0) || ((key & keyBit(_KEY_RIGHT)) != 0) ) speeder[0].right();
					else speeder[0].inertia(neutral);
					if ( (level < 2) || (level == 7) ) {
						for ( i = 1; i < 3; i++ ) {
							switch ( speeder[i]._auto ) {
							case AUTO_MOVED_INERTIA: speeder[i]._auto = AUTO_INERTIA; break;
							case AUTO_MOVED_NEUTRAL: speeder[i]._auto = AUTO_NEUTRAL; break;
							case AUTO_INERTIA: speeder[i].inertia(false); break;
							case AUTO_NEUTRAL: speeder[i].inertia(true ); break;
							}
						}
					}
				}
			}

			// 描画
			g.lock();
			stage.draw(false);
			{
				var cnt = wave_draw();
				if ( (cnt < 0) || (stage._offset_x < 0) ) {
					if ( _MOD(elapse(), 2) == 0 ) {
						drawImage2(IMAGE_BAR_06, 10, 102);
					}
				} else if ( (cnt > 0) || (stage._offset_x > 0) ) {
					if ( _MOD(elapse(), 2) == 0 ) {
						drawImage2(IMAGE_BAR_07, 190, 102);
					}
				}
			}
			speeder[0].draw(false);
			if ( (level < 2) || (level == 7) ) {
				speeder[1].draw(false);
				speeder[2].draw(false);
			}
			if ( level != 6 ) {
				if ( _elapse < WAIT_2 ) {
					drawImage2(IMAGE_STATUS_START, _DIV(240 - TEXT_START_W, 2), _DIV(240 - TEXT_START_H, 2));
				}
			}
			if ( pause ) {
				if ( _MOD(_elapse_p, WAIT_1) <= _DIV(WAIT_1, 2) ) {
					drawImage2(IMAGE_STATUS_PAUSE, _DIV(240 - TEXT_PAUSE_W, 2), 125);
				}
			}
			drawStatus(false);
			unlock();

			if ( level != 6 ) {
				if ( finish ) {
					// ステージクリア
					set_state(STATE_CLEAR);
				}
			} else {
				if ( speeder[0]._speed == 0 ) {
					// ゲーム終了
					set_state(STATE_STOP);
				}
			}

			break;
		case STATE_CLEAR:
			// 更新前の座標を保持
			if ( (level < 2) || (level == 7) ) {
				old_y[0] = speeder[1].dsp_y();
				old_y[1] = speeder[2].dsp_y();
			}

			// 更新
			stage.update();
			wave_update();

			if ( (level < 2) || (level == 7) ) {
				for ( i = 0; i < 2; i++ ) {
					new_y[i] = speeder[i + 1].dsp_y();
					if ( (old_y[i] <= -48) && (new_y[i] > -48) ) {
						speeder[i + 1]._in(speeder[0]._x - 88);
					} else if ( (old_y[i] >= 320) && (new_y[i] < 320) ) {
						speeder[i + 1]._in(speeder[0]._x - 88);
					}
				}
			}

			// スピーダーの移動
			speeder[0].inertia(true);
			if ( (level < 2) || (level == 7) ) {
				speeder[1].inertia(true);
				speeder[2].inertia(true);
			}

			// 描画
			g.lock();
			stage.draw(false);
			wave_draw();
			speeder[0].draw(false);
			if ( (level < 2) || (level == 7) ) {
				speeder[1].draw(false);
				speeder[2].draw(false);
			}
			if ( (level < 2) || (level == 7) ) {
				var y = _DIV(240 - (TEXT_FINISH_H + 10 + TEXT_1ST_H + 10 + TEXT_NEWRECORD_H), 2);
				drawImage2(IMAGE_STATUS_FINISH, _DIV(240 - TEXT_FINISH_W, 2), y);
				y += (TEXT_FINISH_H + 10);
				switch ( ranking ) {
				case 1:
					drawImage2(IMAGE_STATUS_1ST, _DIV(240 - TEXT_1ST_W, 2), y);
					break;
				case 2:
					drawImage2(IMAGE_STATUS_2ND, _DIV(240 - TEXT_2ND_W, 2), y);
					break;
				case 3:
					drawImage2(IMAGE_STATUS_3RD, _DIV(240 - TEXT_3RD_W, 2), y);
					break;
				}
				y += (TEXT_1ST_H + 10);
				if ( new_time ) {
					drawImage2(IMAGE_STATUS_NEWRECORD, _DIV(240 - TEXT_NEWRECORD_W, 2), y);
				}
			} else {
				drawImage2(IMAGE_STATUS_FINISH, _DIV(240 - TEXT_FINISH_W, 2), _DIV(240 - TEXT_FINISH_H, 2));
				if ( new_time ) {
					drawImage2(IMAGE_STATUS_NEWRECORD, _DIV(240 - TEXT_NEWRECORD_W, 2), 140);
				}
			}
			drawStatus(false);
			unlock();

			// 一定時間過ぎたらタイトル画面へ
			if ( _elapse > WAIT_3 ) {
				set_state(STATE_TITLE);
			}

			break;
		case STATE_STOP:
			// スピーダーの移動
			speeder[0].inertia(true);

			// 描画
			g.lock();
			stage.draw(false);
			wave_draw();
			speeder[0].draw(false);
			{
				var x = _DIV(240 - (TEXT_STOP_W + 3 + TEXT_PED_W), 2);
				var y = _DIV(240 - TEXT_STOP_H, 2);
				drawImage2(IMAGE_STATUS_STOP, x, y); x += (TEXT_STOP_W + 3);
				drawImage2(IMAGE_STATUS_PED, x, y);
			}
			if ( new_distance ) {
				drawImage2(IMAGE_STATUS_NEWRECORD, _DIV(240 - TEXT_NEWRECORD_W, 2), 140);
			}
			drawStatus(false);
			unlock();

			// 一定時間過ぎたらタイトル画面へ
			if ( _elapse > WAIT_3 ) {
				set_state(STATE_TITLE);
			}

			break;
		}

		if ( (state != STATE_PLAY) || !pause ) {
			_elapse++;
		}
		if ( pause ) {
			_elapse_p++;
		} else if ( _elapse_s > 0 ) {
			_elapse_s++;
		}
	}

	/**
	 * キー入力処理
	 */
	function processEvent(type, param) {
		switch ( type ) {
		case _KEY_PRESSED_EVENT:
			switch ( state ) {
			case STATE_LAUNCH:
				break;
			case STATE_TITLE:
				switch ( param ) {
				case _KEY_4:
				case _KEY_6:
				case _KEY_LEFT:
				case _KEY_RIGHT:
					neutral = neutral ? false : true;
					break;
				case _KEY_2:
				case _KEY_UP:
					level--; if ( level < 0 ) level = level_max();
					break;
				case _KEY_8:
				case _KEY_DOWN:
					level++; if ( level > level_max() ) level = 0;
					break;
				case _KEY_0:
				case _KEY_5:
				case _KEY_Z:
				case _KEY_X:
				case _KEY_C:
					if ( (level < 2) || (level == 7) ) {
						clip = load_movie.load(0, "data/select.swf");
					} else {
						switch ( stage._back ) {
						case 0: clip = load_movie.load(1, "data/bg1.swf"); break;
						case 1: clip = load_movie.load(1, "data/bg2.swf"); break;
						case 2: clip = load_movie.load(1, "data/bg3.swf"); break;
						case 3: clip = load_movie.load(1, "data/bg4.swf"); break;
						case 4: clip = load_movie.load(1, "data/bg4.swf"); break;
						case 5: clip = load_movie.load(1, "data/bg5.swf"); break;
						case 6: clip = load_movie.load(1, "data/bg6.swf"); break;
						}
					}
					set_state(STATE_TITLE_LOADING);
					break;
				}
				break;
			case STATE_TITLE_LOADING:
				break;
			case STATE_SELECT:
				switch ( param ) {
				case _KEY_4:
				case _KEY_LEFT:
					player--; if ( player < 0 ) player = 2;
					break;
				case _KEY_6:
				case _KEY_RIGHT:
					player++; if ( player > 2 ) player = 0;
					break;
				case _KEY_0:
				case _KEY_5:
				case _KEY_Z:
				case _KEY_X:
				case _KEY_C:
//					stage.back();
					switch ( stage._back ) {
					case 0: clip = load_movie.load(1, "data/bg1.swf"); break;
					case 1: clip = load_movie.load(1, "data/bg2.swf"); break;
					case 2: clip = load_movie.load(1, "data/bg3.swf"); break;
					case 3: clip = load_movie.load(1, "data/bg4.swf"); break;
					case 4: clip = load_movie.load(1, "data/bg4.swf"); break;
					case 5: clip = load_movie.load(1, "data/bg5.swf"); break;
					case 6: clip = load_movie.load(1, "data/bg6.swf"); break;
					}
					set_state(STATE_SELECT_LOADING);
					break;
				case _KEY_3:
				case _KEY_BACKSPACE:
					set_state(STATE_TITLE);
					break;
				}
				break;
			case STATE_SELECT_LOADING:
				break;
			default:
				switch ( param ) {
				case _KEY_1:
				case _KEY_SPACE:
					pause = pause ? false : true; if ( pause ) _elapse_p = 0;
					break;
				case _KEY_3:
				case _KEY_BACKSPACE:
					set_state(STATE_TITLE);
					break;
				case _KEY_ASTERISK:
				case _KEY_Z:
					if ( level != 5 ) {
						if ( !pause ) {
							if ( boost && (speeder[0]._shield == 0) ) {
								_elapse_b = _elapse;
								boost = false;
								speeder[0].speed_up_v(400);
							} else {
								speeder[0].shield(0);
							}
						}
					}
					break;
				case _KEY_0:
				case _KEY_X:
					if ( level != 5 ) {
						if ( !pause ) {
							if ( boost && (speeder[0]._shield == 1) ) {
								_elapse_b = _elapse;
								boost = false;
								speeder[0].speed_up_v(400);
							} else {
								speeder[0].shield(1);
							}
						}
					}
					break;
				case _KEY_POUND:
				case _KEY_C:
					if ( level != 5 ) {
						if ( !pause ) {
							if ( boost && (speeder[0]._shield == 2) ) {
								_elapse_b = _elapse;
								boost = false;
								speeder[0].speed_up_v(400);
							} else {
								speeder[0].shield(2);
							}
						}
					}
					break;
				case _KEY_2:
					hide_status = hide_status ? false : true;
					break;
				}
				break;
			}
			break;
		}
	}

	function onLoadMovieStart():Void {
	}
	function onLoadMovieError(errorCode:String, httpStatus:Number):Void {
	}
	function onLoadMovieProgress(loadedBytes:Number, totalBytes:Number):Void {
	}
	function onLoadMovieComplete(httpStatus:Number):Void {
	}
	function onLoadMovieInit():Void {
		switch ( state ) {
		case STATE_TITLE_LOADING:
			if ( (level < 2) || (level == 7) ) {
				clip_select[0].attach(clip, "ray", "clip0");
				clip_select[1].attach(clip, "rax", "clip1");
				clip_select[2].attach(clip, "com", "clip2");
				break;
			}
			// そのまま下に流す
		case STATE_SELECT_LOADING:
			if ( stage._back < 5 ) {
				clip_bg[0].attach(clip, "back", "clip3");
			}
			clip_bg[1].attach(clip, "fore", "clip4");
			break;
		}
	}

	/**
	 * 構築
	 */
	function wave_create() {
		bar.removeAllElements();
	}

	/**
	 * バーを登録する
	 */
	function wave_add_bar(x, y, col, count, border) {
		bar.addElement(new Bar(this, x, y, col, count, border));
	}

	/**
	 * バーが無くなったかどうか
	 */
	function wave_clear() {
		if ( bar.size() <= 0 ) return true;
		return false;
	}

	function wave_top_x() {
		var i;
		var x = 0;
		var y = 240;
		var tmp;
		for ( i = bar.size() - 1; i >= 0; i-- ) {
			tmp = bar.elementAt(i);
			if ( tmp._y < y ) {
				y = tmp._y;
				x = tmp._x;
			}
		}
		return x;
	}
	function wave_bottom_x() {
		var i;
		var x = 0;
		var y = 0;
		var tmp;
		for ( i = bar.size() - 1; i >= 0; i-- ) {
			tmp = bar.elementAt(i);
			if ( tmp._y > y ) {
				y = tmp._y;
				x = tmp._x;
			}
		}
		return x;
	}

	/**
	 * ウェーブデータ更新
	 */
	function wave_update() {
		var i;
		var tmp;
		for ( i = bar.size() - 1; i >= 0; i-- ) {
			tmp = bar.elementAt(i);
			if ( !tmp.update() ) {
				bar.removeElementAt(i);
			}
		}
	}

	/**
	 * 描画
	 */
	function wave_draw() {
		var i;
		var cnt = 0;
		var tmp;
		for ( i = bar.size() - 1; i >= 0; i-- ) {
			tmp = bar.elementAt(i);
			if ( tmp._col == 3 ) {
				cnt += drawImage(IMAGE_BAR_00 + 3 * _MOD(elapse(), 2) + _MOD(elapse(), 3), 108 - (speeder[0]._x - tmp._x), tmp._y, 200, 12);
				drawImage(IMAGE_BAR_08 + tmp._count, 108 - (speeder[0]._x - tmp._x) - 24, tmp._y - 6, 24, 24);
				drawImage(IMAGE_BAR_08 + tmp._count, 108 - (speeder[0]._x - tmp._x) + 200, tmp._y - 6, 24, 24);
			} else {
				cnt += drawImage(IMAGE_BAR_00 + 3 * _MOD(elapse(), 2) + tmp._col, 108 - (speeder[0]._x - tmp._x), tmp._y, 200, 12);
			}
		}
		if ( Math.abs(cnt) == bar.size() ) {
			return cnt;
		}
		return 0;
	}
}
