// マジカルスピード

//-------------------- 定数 --------------------
var DATA_ID     = 0;		// MAGICAL_SPEED_DATA の 0 番目の項目：カードID
var DATA_CARD   = 1;		// MAGICAL_SPEED_DATA の 1 番目の項目：カード名
var DATA_NUMBER = 2;		// MAGICAL_SPEED_DATA の 2 番目の項目：消費ストーン数

var NUMBER_MAX = 6;				// 消費ストーン数の最大値

var FIELD_NUM_MAX = 12;			// 場札の枚数

var GAME_TIME_DEFAULT = 90;		// ゲーム開始時の残プレイ時間（秒）
var NG_PENALTY = 3;				// おてつきをしたときに減少する残プレイ時間（秒）

var TIME_DISP_INTERVAL = 10;	// 時間表示の間隔（ミリ秒）

var SHUFFLE_DO_TIME  = 150;		// シャッフル時のカード裏返し処理の待ち時間（ミリ秒）
var SHUFFLE_END_TIME = 1200;	// シャッフル終了処理の待ち時間（ミリ秒）

var BG_HIGHLIGHT_TIME = 150;	// セルの背景色を変化させる時間（ミリ秒）

var CHECK_LOAD_IMAGE_INTERVAL = 1000;	// 画像の事前読み込みチェックの間隔（ミリ秒）
var CHECK_LOAD_IMAGE_MAX_NUM  = 5;		// 画像の事前読み込みチェックの最大回数

//-------------------- グローバル変数 --------------------
var GameStatus;						// ゲームの状態(0:開始前 1:操作待ち 2:シャッフル中 3:終了)
var GameTimeDefault;				// ゲーム開始時の残プレイ時間（おてつきで減少する）
var TimeInterval;					// 時間計測のタイマーID
var StartTime;						// ゲーム開始時の Date オブジェクト
var Score;							// 得点
var BoardCardIndex;					// 台札となっているカードの MAGICAL_SPEED_DATA 中の位置
var FieldCardIndex = new Array();	// 場札となっているカードの MAGICAL_SPEED_DATA 中の位置
var LastSelectedField;				// 最後に選択された場札番号（セルの背景色変化で使用）
var BgHighlightTimer;				// セルの背景色変化のタイマーID
var ShuffleTimer;					// シャッフル時のタイマーID
var ShuffleSeq;						// シャッフル処理のシーケンス
var ImgObj = new Array();			// 画像の事前読み込み用オブジェクト
var CheckLoadInterval;				// 画像の事前読み込みチェックのタイマーID
var CheckLoadNum;					// 画像の事前読み込みチェックの回数

//--------------------------------------------------------------------------------
// 画像処理
//--------------------------------------------------------------------------------
// 初期化処理
function initImg()
{
	var base_src = $('img_board').src;
	var init_src = base_src.substr(0, base_src.lastIndexOf('/') + 1) + 'card.jpg';
	$('img_board').src = init_src;
	$('img_board').alt = '';
	for(var i = 0; i < FIELD_NUM_MAX; i++){
		$('img' + i).src = init_src;
		$('img' + i).alt = '';
	}
}

// 画像ID、画像ファイル名、カード名を指定して画像をセット
function setImgById(img_id, img_file, card_name)
{
	var base_src = $(img_id).src;
	var init_src = base_src.substr(0, base_src.lastIndexOf('/') + 1) + img_file;
	$(img_id).src = init_src;
	$(img_id).alt = card_name;
}

// 台札画像をセット
function setBoardImg(index)
{
	setImgById('img_board', 'co' + MAGICAL_SPEED_DATA[index][DATA_ID] + '.jpg', MAGICAL_SPEED_DATA[index][DATA_CARD]);
}

// 場札画像をセット
function setFieldImg(field, index)
{
	var img_file;
	var card_name;
	if(index < 0){
		img_file = 'card.jpg';
		card_name = '';
	} else {
		img_file = 'co' + MAGICAL_SPEED_DATA[index][DATA_ID] + '.jpg';
		card_name = MAGICAL_SPEED_DATA[index][DATA_CARD];
	}
	setImgById('img' + field, img_file, card_name);
}

//--------------------------------------------------------------------------------
// 表示処理
//--------------------------------------------------------------------------------
// リセットボタンを押したときの初期化処理
function initDisp()
{
	$('game_score').innerHTML   = '0';
	$('gamefinish').style.color = '#999999';
	for(var i = 0; i < FIELD_NUM_MAX; i++){
		$('td' + i).style.backgroundColor = '#dddddd';
	}
	initImg();

	dispTime(GAME_TIME_DEFAULT, 0);
}

//--------------------------------------------------------------------------------
// データ処理
//--------------------------------------------------------------------------------
// リセットボタンを押したときの初期化処理
function initData()
{
	clearInterval(TimeInterval);
	clearTimeout(ShuffleTimer);
	clearTimeout(BgHighlightTimer);

	GameStatus = 0;
	GameTimeDefault = GAME_TIME_DEFAULT;
	StartTime  = null;
	Score      = 0;
	BoardCardIndex  = -1;
	for(var i = 0; i < FIELD_NUM_MAX; i++){
		FieldCardIndex[i] = -1;
	}
	LastSelectedField = -1;
	ShuffleSeq = 0;
}

// ゲーム終了時の処理
function endGame()
{
	clearInterval(TimeInterval);
	GameStatus = 3;
	dispTime(0, 0);
	$('gamefinish').style.color = '#cc0000';
	$('shuffle_button').disabled = true;

	// Ajaxで得点を送信
	var url = document.URL.split("#")[0];
	new Ajax.Request(url, {
		method: "post",
		parameters: "score=" + Score
	});
}

//--------------------------------------------------------------------------------
// ゲーム処理
//--------------------------------------------------------------------------------
// スタートボタンを押したときのゲーム開始処理
function gameStart()
{
	GameStatus = 1;

	// 台札
	while(1){
		BoardCardIndex = Math.floor(Math.random() * MAGICAL_SPEED_DATA.length);
		var number = MAGICAL_SPEED_DATA[BoardCardIndex][DATA_NUMBER];
		if( (1 <= number) && (number <= 3) ){
			// 初期台札は消費ストーンが1～3コのカードのみ
			setBoardImg(BoardCardIndex);
			break;
		}
	}

	// 場札
	resetField();

	// スタート時間を取得
	StartTime = new Date();
	TimeInterval = setInterval('doDispTime()', TIME_DISP_INTERVAL);

	$('reset_button').disabled   = false;
	$('shuffle_button').disabled = false;
	$('start_button').disabled   = true;
}

// 残プレイ時間表示のインターバル関数
function doDispTime()
{
	var now_time;
	var play_time;
	var rest_time;
	var sec;
	var ms;

	now_time  = new Date();									// 現在の時間を取得
	play_time = now_time.getTime() - StartTime.getTime();	// プレイ時間を通算ミリ秒で計算
	rest_time = GameTimeDefault * 1000 - play_time;			// 残プレイ時間
	if(rest_time <= 0){
		endGame();
		return;
	}

	sec = Math.floor(rest_time / 1000);			// '秒'取得
	ms  = Math.floor((rest_time % 1000) / 10);	// 'コンマ○秒'取得
	dispTime(sec, ms);
}

// 残プレイ時間を表示
function dispTime(sec, ms)
{
	if(ms < 10){
		ms = '0' + ms;
	}
	$('gametime').value = sec + '.' + ms;
}

// 場札を配りなおす
function resetField()
{
	for(var i = 0; i < FIELD_NUM_MAX; i++){
		FieldCardIndex[i] = Math.floor(Math.random() * MAGICAL_SPEED_DATA.length);
		setFieldImg(i, FieldCardIndex[i]);
	}
}

// シャッフルボタンを押したときの処理
function gameShuffle()
{
	if(GameStatus != 1){
		return;
	}

	$('shuffle_button').disabled = true;
	GameStatus = 2;
	ShuffleSeq = 0;

	ShuffleTimer = setTimeout('doShuffle()', SHUFFLE_DO_TIME);
}

// シャッフル時にカードを１枚ずつ裏返す処理
function doShuffle()
{
	clearTimeout(ShuffleTimer);

	setFieldImg(ShuffleSeq, -1);

	ShuffleSeq++;
	if(ShuffleSeq < FIELD_NUM_MAX){
		ShuffleTimer = setTimeout('doShuffle()', SHUFFLE_DO_TIME);
	} else {
		ShuffleTimer = setTimeout('endShuffle()', SHUFFLE_END_TIME);
	}
}

// シャッフル終了処理
function endShuffle()
{
	clearTimeout(ShuffleTimer);

	resetField();

	if(GameStatus != 3){
		GameStatus = 1;
		$('shuffle_button').disabled = false;
	}
}

// 場札の onclick 時の処理
function imgClick(field)
{
	if(GameStatus != 1){
		return;
	}

	if(LastSelectedField >= 0){
		endHighlight();
	}
	LastSelectedField = field;

	var board_number = MAGICAL_SPEED_DATA[BoardCardIndex][DATA_NUMBER];
	var field_number = MAGICAL_SPEED_DATA[FieldCardIndex[field]][DATA_NUMBER];
	var number_sub = (board_number - field_number + NUMBER_MAX) % NUMBER_MAX;
	if( (number_sub == 1) || (number_sub == NUMBER_MAX - 1) ){
		// OK
		Score++;
		$('game_score').innerHTML = Score;
		$('td' + field).style.backgroundColor = '#ff9999';
		// 台札
		BoardCardIndex = FieldCardIndex[field];
		setBoardImg(BoardCardIndex);
		// 新しい場札
		while(1){
			var new_card = Math.floor(Math.random() * MAGICAL_SPEED_DATA.length);
			if(new_card != FieldCardIndex[field]){
				FieldCardIndex[field] = new_card;
				setFieldImg(field, FieldCardIndex[field]);
				break;
			}
		}
	} else {
		// NG
		GameTimeDefault -= NG_PENALTY;
		$('td' + field).style.backgroundColor = '#9999ff';
	}
	BgHighlightTimer = setTimeout('endHighlight()', BG_HIGHLIGHT_TIME);
}

// セルの背景色変化の終了処理
function endHighlight()
{
	clearTimeout(BgHighlightTimer);
	$('td' + LastSelectedField).style.backgroundColor = '#dddddd';
	LastSelectedField = -1;
}

//--------------------------------------------------------------------------------
// 初期化
//--------------------------------------------------------------------------------
// onload時の初期化処理
function init()
{
	// 画像にイベントハンドラをセット
	$('img0').onclick  = function(){ imgClick(0); };
	$('img1').onclick  = function(){ imgClick(1); };
	$('img2').onclick  = function(){ imgClick(2); };
	$('img3').onclick  = function(){ imgClick(3); };
	$('img4').onclick  = function(){ imgClick(4); };
	$('img5').onclick  = function(){ imgClick(5); };
	$('img6').onclick  = function(){ imgClick(6); };
	$('img7').onclick  = function(){ imgClick(7); };
	$('img8').onclick  = function(){ imgClick(8); };
	$('img9').onclick  = function(){ imgClick(9); };
	$('img10').onclick = function(){ imgClick(10); };
	$('img11').onclick = function(){ imgClick(11); };

	// 画像の事前読み込み
	var base_src  = $('img_board').src;
	var base_path = base_src.substr(0, base_src.lastIndexOf('/') + 1);
	for(var i = 0; i < MAGICAL_SPEED_DATA.length; i++){
		ImgObj[i] = new Image();
		ImgObj[i].src = base_path + 'co' + MAGICAL_SPEED_DATA[i][DATA_ID] + '.jpg';
	}
	CheckLoadNum = 0;
	CheckLoadInterval = setInterval('isLoadedImg()', CHECK_LOAD_IMAGE_INTERVAL);
}

// 画像の読み込み待ちインターバル関数
function isLoadedImg()
{
	CheckLoadNum++;
	if(CheckLoadNum > CHECK_LOAD_IMAGE_MAX_NUM){
		endLoadingImg();
		return;
	}

	for(var i = 0; i < MAGICAL_SPEED_DATA.length; i++){
		if( !(ImgObj[i].complete) ){
			break;
		}
	}
	if(i == MAGICAL_SPEED_DATA.length){
		endLoadingImg();
	}
}

// 画像の読み込み完了
function endLoadingImg()
{
	clearInterval(CheckLoadInterval);
	gameReset();
}

// リセットボタンを押したときの初期化処理
function gameReset()
{
	initData();
	initDisp();

	$('reset_button').disabled   = true;
	$('shuffle_button').disabled = true;
	$('start_button').disabled   = false;
}

window.onload = init;

