Event.observe(window, 'load', function(){

	globalOeratable = false;

	confWhitePiece             = readArgs('confWhitePiece');
	confBlackPiece             = readArgs('confBlackPiece');
	confEmptyPiece             = readArgs('confEmptyPiece');
	confHarfSizeY              = readArgs('confHarfSizeY');
	confHarfSizeX              = readArgs('confHarfSizeX');
	confSizeY                  = readArgs('confSizeY');
	confSizeX                  = readArgs('confSizeX');
	confLinkNeoAsh             = readArgs('confLinkNeoAsh');
	confRankingDate            = readArgs('confRankingDate');
	confResentTournamentNumber = readArgs('confResentTournamentNumber');
	confRootDir                = readArgs('confRootDir');

	FIRST_PLAYER     = confBlackPiece;
	WAIT_PUT_PIECE   = 100;
	WAIT_TURN_CHANGE = 300;

	Event.observe($('start-game'), 'click',  function(){
		startGame();
	});

	Event.observe($('replay'), 'click',  function(){
		replay();
	});

	Event.observe($('normal-button'), 'click',  function(){
		normalEnd();
	});

});

// ----------------
// 初期化処理
// ----------------

function initialize(){

	// ----------------
	// ボードを表す二次元配列初期化
	// ----------------

	globalBoard = returnArray2(confSizeY, confSizeX);

	for(var y = 0; y < confSizeY; y++){
		for(var x = 0; x < confSizeX; x++){

			if((y == confHarfSizeY - 1 && x == confHarfSizeX - 1) || (y == confHarfSizeY && x == confHarfSizeX)){
				globalBoard[y][x] = confWhitePiece;
				$('square-' + y + '-' + x).className = 'white';
			}else if((y == confHarfSizeY && x == confHarfSizeX - 1) || (y == confHarfSizeY - 1 && x == confHarfSizeX)){
				globalBoard[y][x] = confBlackPiece;
				$('square-' + y + '-' + x).className = 'black';
			}else{
				globalBoard[y][x] = confEmptyPiece;
				$('square-' + y + '-' + x).className = 'empty';
			}

		}
	}

	// ----------------
	// コマ数を表す配列、スコアを表す配列初期化
	// ----------------

	globalPieceListJS  = returnArray1(2, 2);
	globalPieceListPHP = returnArray1(2, 2);
	globalScoreListJS  = returnArray1(4, 0);	// 4 番目は一時領域
	globalScoreListPHP = returnArray1(3, 0);

	// ----------------
	// コマの置ける状態を表す変数等初期化
	// ----------------

	globalPuttableHuman = true;
	globalPuttableCpu   = true;
	globalPuttable      = returnArray2(confSizeX, confSizeY);
	globalFailureStatus = false;

	// ----------------

}

// ----------------
// normal end の OK ボタンを押されたときの処理
// ----------------

function normalEnd(){

	if(globalFailureStatus){
		location.reload();
		return;
	}

	$('normal-end').className   = 'normal-end-false';
	$('normal-title').innerHTML = '-';

	$('replay').disabled = '';

	abledLinks();

	globalOeratable = true;

}

// ----------------
// 最初からボタンを押されたときの処理
// ----------------

function replay(){

	if(globalOeratable){

		globalOeratable = false;

		new Ajax.Request(
			confRootDir + 'parts/asynchronous/reversi-replay.php',
			{
				method: 'GET',
				asynchronous: false
			}
		);

		$('human-count').innerHTML = '-';
		$('cpu-count').innerHTML   = '-';
		$('total-score').innerHTML = '-';
		$('human-score').innerHTML = '-';
		$('cpu-score').innerHTML   = '-';
		$('record').innerHTML      = '-';
		$('percentage').innerHTML  = '-';
		$('max-score').innerHTML   = '-';

		initialize();
		supportClear();

		$('opponent-select').disabled    = '';
		$('order-select-black').disabled = '';
		$('order-select-white').disabled = '';
		$('start-game').disabled         = '';
		$('replay').disabled             = 'disabled';

		$('order-select-white-label').className = '';
		$('order-select-black-label').className = '';

		abledLinks();

	}

}

// ----------------
// スタートボタンを押されたときの処理
// ----------------

function startGame(){

	$('opponent-select').disabled    = 'disabled';
	$('order-select-black').disabled = 'disabled';
	$('order-select-white').disabled = 'disabled';
	$('start-game').disabled         = 'disabled';
	$('replay').disabled             = '';

	if($('order-select-black').checked){
		$('order-select-white-label').className = 'no-checked';
		$('order-select-black-label').className = 'checked';
		globalHuman = confBlackPiece;
		globalCpu   = confWhitePiece;
	}else{
		$('order-select-white-label').className = 'checked';
		$('order-select-black-label').className = 'no-checked';
		globalHuman = confWhitePiece;
		globalCpu   = confBlackPiece;
	}

	disabledLinks();

	initialize();

	var opponent = $('opponent-select').value;

	var response = new Ajax.Request(
		confRootDir + 'parts/asynchronous/reversi-start.php',
		{
			method: 'POST',
			parameters: 'opponent=' + opponent + '&human=' + globalHuman + '&cpu=' + globalCpu,
			asynchronous: false
		}
	).transport.responseText;

	if(response == 'Bad Request'){
		$('normal-title').innerHTML = '不正なリクエストです';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}else if(response == 'Locked'){
		$('normal-title').innerHTML = '現在処理が込み合っています';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}else if(response == 'Not Found'){
		$('normal-title').innerHTML = 'キャラクター情報が存在しません';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}

	$('human-count').innerHTML = globalPieceListJS[0];
	$('cpu-count').innerHTML   = globalPieceListJS[1];
	$('total-score').innerHTML = globalScoreListJS[2];
	$('human-score').innerHTML = globalScoreListJS[0];
	$('cpu-score').innerHTML   = globalScoreListJS[1];

	if(response != '-'){
		var responseSpl = response.split('|');
		$('record').innerHTML     = responseSpl[0] + '<span>勝 </span>' + responseSpl[1] + '<span>敗 </span>' + responseSpl[2] + '<span>分け</span>';
		$('percentage').innerHTML = responseSpl[3] + '<span>%</span>';
		$('max-score').innerHTML  = responseSpl[4] + '<span>点</span>';
	}

	turnInitialize(FIRST_PLAYER);

}

// ----------------
// ターンごとの初期化処理
// ----------------

function turnInitialize(player){

	// ----------------
	// クライアント、サーバ両方で管理しているコマ数とスコアの値に差異がないことを確認する
	// ----------------

	var normalityFlag = false;

	if(globalPieceListJS[0] == globalPieceListPHP[0]){
		if(globalPieceListJS[1] == globalPieceListPHP[1]){
			if(globalScoreListJS[0] == globalScoreListPHP[0]){
				if(globalScoreListJS[1] == globalScoreListPHP[1]){
						if(globalScoreListJS[2] == globalScoreListPHP[2]){
							normalityFlag = true;
						}
				}
			}
		}
	}

	// ----------------
	// 差異がない場合のみ処理を行なう
	// ----------------

	if(normalityFlag){

		if(updatePuttableMatrix(player)){	// 配置可能なマスが存在する場合

			if(player == globalHuman){
				globalPuttableHuman = true;
				supportDisplay();
				globalOeratable = true;
			}else{
				globalPuttableCpu = true;
				cpuTurn();
			}

		}else{								// 配置可能なマスが存在しない場合

			if(!globalPuttableHuman && !globalPuttableCpu){
				setTimeout('endGame()', WAIT_TURN_CHANGE);
			}else if(player == globalHuman){
				globalPuttableHuman = false;
				setTimeout('turnInitialize(globalCpu)', WAIT_TURN_CHANGE);
			}else{
				globalPuttableCpu = false;
				setTimeout('turnInitialize(globalHuman)', WAIT_TURN_CHANGE);
			}

		}

	}else{
		$('normal-title').innerHTML = 'コマの数 or スコアに不正が見つかりました';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}

	// ----------------

}

// ----------------
// ゲームの終了処理
// ----------------

function endGame(){

	$('replay').disabled = 'disabled';

	var response = new Ajax.Request(
		confRootDir + 'parts/asynchronous/reversi-end.php',
		{
			method: 'GET',
			asynchronous: false
		}
	).transport.responseText;

	if(response == 'Locked'){
		$('normal-title').innerHTML = '現在処理が込み合っています';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}

	var responseSpl = response.split('|');

	if(responseSpl[0] == 'win'){		var endTitle = 'You Win!!';		}
	else if(responseSpl[0] == 'lose'){	var endTitle = 'You lose...';	}
	else{								var endTitle = 'Draw Game.';	}

	if(responseSpl[1] == 'nomal'){
		$('normal-title').innerHTML = endTitle;
		$('normal-end').className   = 'normal-end-true';
	}else{
		$('entry-title').innerHTML = endTitle + '　And Name Entry!';
		$('entry-end').className   = 'entry-end-true';
		$('entry-name').focus();
	}

}

// ----------------
// コマの置ける状態を表す二次元配列を更新
// ----------------

function updatePuttableMatrix(player){

	var y, x;

	var puttableFlag = false;

	for(y = 0; y < confSizeY; y++){
		for(x = 0; x < confSizeX; x++){

			globalPuttable[y][x] = false;

			if(globalBoard[y][x] == confEmptyPiece){
				globalPuttable[y][x] = isPuttableLine(y, x, -1, -1, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x, -1,  0, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x, -1,  1, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x,  0, -1, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x,  0,  1, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x,  1, -1, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x,  1,  0, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
				globalPuttable[y][x] = isPuttableLine(y, x,  1,  1, player);	if(globalPuttable[y][x]){	puttableFlag = true;	continue;	}
			}

		}
	}

	return puttableFlag;

}

function isPuttableLine(pointY, pointX, vectorY, vectorX, player){

	var y = pointY + vectorY;
	var x = pointX + vectorX;

	var puttableFlag = false;

	for(cnt = 0; ; cnt++, y += vectorY, x += vectorX){

		if(y >= 0 && y < confSizeY && x >= 0 && x < confSizeX){

			if(globalBoard[y][x] == confEmptyPiece){
				return false;
			}else if(globalBoard[y][x] == player){
				return puttableFlag;
			}else{
				puttableFlag = true;
			}

		}else{
			return false;
		}

	}

}

// ----------------
// 人間がコマを置く処理（ボード上をクリックされたときの処理）
// ----------------

function boardClick(pointY, pointX){

	if(globalOeratable){
		if(globalPuttable[pointY][pointX]){

			globalOeratable = false;

			supportClear();

			var response = new Ajax.Request(
				confRootDir + 'parts/asynchronous/reversi-put.php',
				{
					method: 'POST',
					parameters: 'y=' + pointY + '&x=' + pointX + '&player=' + globalHuman,
					asynchronous: false
				}
			).transport.responseText;

			if(response == 'Bad Request'){
				$('normal-title').innerHTML = '不正なリクエストです';
				$('normal-end').className   = 'normal-end-true';
				globalFailureStatus         = true;
				return;
			}else if(response == 'Unputtable'){
				$('normal-title').innerHTML = '配置不可能な座標が指定されました';
				$('normal-end').className   = 'normal-end-true';
				globalFailureStatus         = true;
				return;
			}

			var responseSpl = response.split('\\');

			globalPieceListPHP = responseSpl[1].split('|');
			globalScoreListPHP = responseSpl[2].split('|');

			tmPointList = responseSpl[0].split('|');
			tmIndex     = 0;
			tmPlayer    = globalHuman;

			setTimeout('putPiece()', 0);

		}
	}

}

// ----------------
// コンピュータがコマを置く処理
// ----------------

function cpuTurn(){

	var response = new Ajax.Request(
		confRootDir + 'parts/asynchronous/reversi-put.php',
		{
			method: 'POST',
			parameters: 'player=' + globalCpu,
			asynchronous: false
		}
	).transport.responseText;

	if(response == 'Bad Request'){
		$('normal-title').innerHTML = '不正なリクエストです';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}else if(response == 'Unputtable'){
		$('normal-title').innerHTML = '配置不可能な座標が指定されました';
		$('normal-end').className   = 'normal-end-true';
		globalFailureStatus         = true;
		return;
	}

	var responseSpl = response.split('\\');

	globalPieceListPHP = responseSpl[1].split('|');
	globalScoreListPHP = responseSpl[2].split('|');

	tmPointList = responseSpl[0].split('|');
	tmIndex     = 0;
	tmPlayer    = globalCpu;

	setTimeout('putPiece()', 0);

}

// ----------------
// コマを置く処理
// ----------------

function putPiece(){

	var point = tmPointList[tmIndex].split(',');

	// ----------------
	// コマの画像を表示し、globalBoard を更新
	// ----------------

	if(tmPlayer == confWhitePiece){
		$('square-' + point[0] + '-' + point[1]).className = 'white';
		globalBoard[point[0]][point[1]] = confWhitePiece;
	}else{
		$('square-' + point[0] + '-' + point[1]).className = 'black';
		globalBoard[point[0]][point[1]] = confBlackPiece;
	}

	// ----------------
	// コマ数、スコアを表示し、globalPieceListJS、globalScoreListJS を更新
	// ----------------

	if(tmPlayer == globalHuman){
		globalPieceListJS[0] += 1;
		if(tmIndex == 0){
			globalScoreListJS[0] = 0;
		}else{
			globalPieceListJS[1] -= 1;
			if(tmIndex == 1){
				globalScoreListJS[0] = 1;
			}else{
				globalScoreListJS[0] *= 2;
			}
		}
		globalScoreListJS[3] = globalScoreListJS[2] + globalScoreListJS[0];
		$('human-count').innerHTML = globalPieceListJS[0];
		$('cpu-count').innerHTML   = globalPieceListJS[1];
		$('total-score').innerHTML = globalScoreListJS[3];
		$('human-score').innerHTML = globalScoreListJS[0];
	}else{
		globalPieceListJS[1] += 1;
		if(tmIndex == 0){
			globalScoreListJS[1] = 0;
		}else{
			globalPieceListJS[0] -= 1;
			if(tmIndex == 1){
				globalScoreListJS[1] = 1;
			}else{
				globalScoreListJS[1] *= 2;
			}
		}
		globalScoreListJS[3] = globalScoreListJS[2] - globalScoreListJS[1];
		$('human-count').innerHTML = globalPieceListJS[0];
		$('cpu-count').innerHTML   = globalPieceListJS[1];
		$('total-score').innerHTML = globalScoreListJS[3];
		$('cpu-score').innerHTML   = globalScoreListJS[1];
	}

	// ----------------

	if(tmIndex < tmPointList.length - 1){
		tmIndex++;
		setTimeout('putPiece()', WAIT_PUT_PIECE);
	}else{
		globalScoreListJS[2] = globalScoreListJS[3];
		if(tmPlayer == globalHuman){
			setTimeout('turnInitialize(globalCpu)', WAIT_TURN_CHANGE);
		}else{
			setTimeout('turnInitialize(globalHuman)', WAIT_TURN_CHANGE);
		}
	}

}

// ----------------
// サポートの表示とクリア
// ----------------

function supportDisplay(){

	var y, x;

	for(y = 0; y < confSizeY; y++){
		for(x = 0; x < confSizeX; x++){

			if(globalPuttable[y][x]){
				$('square-' + y + '-' + x).className = 'able';
			}

		}
	}

}

function supportClear(){

	var y, x;

	for(y = 0; y < confSizeY; y++){
		for(x = 0; x < confSizeX; x++){
			if(globalBoard[y][x] == confEmptyPiece){
				$('square-' + y + '-' + x).className = 'empty';
			}
		}
	}

}

// ----------------
// マウスオーバー、マウスアウト時の処理
// ----------------

function boardOver(pointY, pointX){

	if(globalOeratable){
		if(globalBoard[pointY][pointX] == confEmptyPiece){
			if(globalPuttable[pointY][pointX]){
				$('square-' + pointY + '-' + pointX).className = 'over-able';
			}else{
				$('square-' + pointY + '-' + pointX).className = 'over-disable';
			}
		}
	}

}

function boardOut(pointY, pointX){

	if(globalOeratable){
		if(globalBoard[pointY][pointX] == confEmptyPiece){
			if(globalPuttable[pointY][pointX]){
				$('square-' + pointY + '-' + pointX).className = 'able';
			}else{
				$('square-' + pointY + '-' + pointX).className = 'empty';
			}
		}
	}

}

// ----------------
// マウスオーバー、マウスアウト時の処理
// ----------------

function disabledLinks(){
	$('menu-registration').innerHTML = '<p>キャラクター登録</p>';
	$('menu-information').innerHTML  = '<p>キャラクター情報</p>';
	$('menu-ranking').innerHTML      = '<p>ランキング</p>';
	$('menu-tournament').innerHTML   = '<p>トーナメント</p>';
	$('foot').innerHTML              = '&copy; 2008 <strong class="mean">NeoAsh!?</strong>';
}

function abledLinks(){
	$('menu-registration').innerHTML = '<a href="registration" title="キャラクター登録">キャラクター登録</a>';
	$('menu-information').innerHTML  = '<a href="information" title="キャラクター情報">キャラクター情報</a>';
	$('menu-ranking').innerHTML      = '<a href="ranking/' + confRankingDate + '" title="ランキング">ランキング</a>';
	$('menu-tournament').innerHTML   = '<a href="tournament/' + confResentTournamentNumber + '" title="トーナメント">トーナメント</a>';
	$('foot').innerHTML              = '&copy; 2008 <a href="' + confLinkNeoAsh + '" title="NeoAsh!?"><strong class="mean">NeoAsh!?</strong></a>';
}

