function var_dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects 
		for(var item in arr) {
			var value = arr[item];
			
			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}
function MoveToFirst() {
	game.view.variation = 0;
	game.view.move = 0;
	
	$('.notation .move').removeClass('active');
	$('.notation .move-'+game.view.variation+'-'+game.view.move).addClass('active');
	RedrawBoard();
}
function MoveToLast() {
	game.view.variation = 0;
	game.view.move = game.board[game.view.variation].length-1;
	
	$('.notation .move').removeClass('active');
	$('.notation .move-'+game.view.variation+'-'+game.view.move).addClass('active');
	RedrawBoard();
}
function MoveBackward() {
	if(game.board[game.view.variation][game.view.move]) {
		game.view.variation = game.board[game.view.variation][game.view.move].parent.variation;
		game.view.move = game.board[game.view.variation][game.view.move].parent.move;

		$('.notation .move').removeClass('active');
		$('.notation .move-'+game.view.variation+'-'+game.view.move).addClass('active');
		//g_lastMove = move;
		AnimateMove(game.board[game.view.variation][game.view.move+1].move, true);
		setTimeout(function() { RedrawBoard(); }, 100);
		//alert(game.board[game.view.variation][game.view.move].parent.move+' '+game.board[game.view.variation][game.view.move].parent.variation);
	}
}
function MoveForward() {
	if(game.board[game.view.variation][game.view.move+1]) {
		//game.view.variation = game.board[game.view.variation][game.view.move].parent.variation;
		game.view.move++;
	
		$('.notation .move').removeClass('active');
		$('.notation .move-'+game.view.variation+'-'+game.view.move).addClass('active');						
		
		//g_lastMove = move;
		AnimateMove(game.board[game.view.variation][game.view.move].move);
		setTimeout(function() { RedrawBoard(); }, 100);
		//alert(game.board[game.view.variation][game.view.move].parent.move+' '+game.board[game.view.variation][game.view.move].parent.variation);
	}
}
function flipBoard(color,white) {
	var row, column, i;
	if(color) {
		if(white) {
			row = ['a','b','c','d','e','f','g','h'];
			column = 8;
			i = -1;
		}
		else {
			row = ['h','g','f','e','d','c','b','a'];
			column = 1;
			i = 1;
		}
	}
	else {
		if($('.a8').css('top')!='1px') {
			row = ['a','b','c','d','e','f','g','h'];
			column = 8;
			i = -1;
		}
		else {
			row = ['h','g','f','e','d','c','b','a'];
			column = 1;
			i = 1;
		}
	}
	for(var y=0; y<8; y++) {
		for(var x=0; x<8; x++) {
			$('.board .'+row[x]+(column+y*i)).css('left', x*50+1).css('top', y*50+1);
		}
	}
}
function ConvertSquareToNum(square) {
    var numbers = {'a':0,'b':1,'c':2,'d':3,'e':4,'f':5,'g':6,'h':7};
    return 36 + parseInt(numbers[square[0]] | ((8-parseFloat(square[1])) << 4));
}
function ConvertSquareToLet(square) {
	var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    return letters[((square-36) & 0xF)] + (8 - ((square-36) >> 4));
}
function AnimateMove(move, backwords) {
	if(backwords) {
		var to = ConvertSquareToLet(move & 0xFF);
		var from = ConvertSquareToLet((move >> 8) & 0xFF);
	}
	else {
		var from = ConvertSquareToLet(move & 0xFF);
		var to = ConvertSquareToLet((move >> 8) & 0xFF);
	}
	var left = parseInt($('.board .'+to).css('left'))-parseInt($('.board .'+from).css('left'));
	var top = parseInt($('.board .'+to).css('top'))-parseInt($('.board .'+from).css('top'));
	$('.board .'+from).children().css('z-index', '9999').animate({'left': left, 'top': top}, 100);
}
function UpdateGameView(move) {
	game.view.move++;
	game.board[game.view.variation][game.view.move] = {
		position: g_board.slice(0),
		move: move,
		parent: {
			variation: game.view.variation,
			move: game.view.move-1,
		}
	}
}

var game = {
	board: [],
	ai: {
		level: 1,
	},
	view: {
		move: 0,
		variation: 0,
	},
	from: null,
	to: null
};

var g_startOffset;
var moveNumber = 1;

var g_lastMove = null;
var g_playerWhite = true;
var g_changingFen = false;
var g_analyzing = false;

function UINewGame() {
    moveNumber = 1;

    var pgnTextBox = document.getElementById("PgnTextBox");
	$('.notation').empty();
    pgnTextBox.value = "";

    EnsureAnalysisStopped();
    ResetGame();
	game.view.move = 0;
	game.view.variation = 0;
	game.from = null;
	game.to = null;
	game.board = [];
	game.board[0] = [];
	game.board[0][0] = {
		position: g_board.slice(0),
		move: null,
		parent: {
			variation: 0,
			move: 0,
		},
	}
    if (InitializeBackgroundEngine()) {
        g_backgroundEngine.postMessage("go");
    }
    g_lastMove = null;
	
    if (!g_playerWhite) {
        SearchAndRedraw();
    } else {
        RedrawBoard();
    }
}

function EnsureAnalysisStopped() {
    if (g_analyzing && g_backgroundEngine != null) {
        g_backgroundEngine.terminate();
        g_backgroundEngine = null;
    }
}

function UIAnalyzeToggle() {
    if (InitializeBackgroundEngine()) {
        if (!g_analyzing) {
            g_backgroundEngine.postMessage("analyze");
        } else {
            EnsureAnalysisStopped();
        }
        g_analyzing = !g_analyzing;
        document.getElementById("AnalysisToggleLink").innerText = g_analyzing ? "Analysis: On" : "Analysis: Off";
    } else {
        alert("Your browser must support web workers for analysis - (chrome4, ff4, safari)");
    }
}

function UIChangeFEN() {
    if (!g_changingFen) {
        var fenTextBox = document.getElementById("FenTextBox");
        InitializeFromFen(fenTextBox.value);
        EnsureAnalysisStopped();
        if (InitializeBackgroundEngine()) {
            g_backgroundEngine.postMessage("go");
            g_backgroundEngine.postMessage("position " + GetFen());
        }
        g_playerWhite = !!g_toMove;
        RedrawBoard();
    }
}

function UIChangeStartPlayer() {
    g_playerWhite = !g_playerWhite;
	flipBoard(1, g_playerWhite);
    RedrawBoard();
}

function UpdatePgnTextBox(move) {
    var pgnTextBox = document.getElementById("PgnTextBox");
	$('.notation .move').removeClass('active');
	var m = game.view.move;
	var v = game.view.variation;
	var movetxt = '<span class="move move-'+v+'-'+(m+1)+' active">';
    if (g_toMove != 0) {
		movetxt += moveNumber+'.';
        pgnTextBox.value += moveNumber + ". ";
        moveNumber++;
    }
	$('.notation').append(movetxt+GetMoveSAN(move)+'</span>');
	$('.move-'+v+'-'+(m+1)).click(function() {
		$('.move').removeClass('active');
		$(this).addClass('active');
		game.view.move = m+1;
		game.view.variation = v;
		RedrawBoard();
	});
    pgnTextBox.value += GetMoveSAN(move) + " ";
}

function UIChangeTimePerMove() {
//    var timePerMove = document.getElementById("TimePerMove");
//    g_timeout = parseInt(timePerMove.value, 10);
}

function FinishMove(bestMove, value, timeTaken, ply) {
    if (bestMove != null) {
        UIPlayMove(bestMove, BuildPVMessage(bestMove, value, timeTaken, ply));
    }
    else {
		g_toMove = g_toMove == 8 ? 0x00 : 0x8;
		var checkmate = false;
		var allMoves = new Array();
		GenerateCaptureMoves(allMoves, null);
		GenerateAllMoves(allMoves);
		g_toMove = g_toMove == 8 ? 0x10 : 0x8;
		for(var i=0; i<allMoves.length; i++) {
			if(g_board[(allMoves[i] >> 8) & 0xFF]==(g_toMove | 6)) {
				checkmate = true;
				break;
			}
			//+' | '+ConvertSquareToLet(allMoves[i] & 0xFF)+' - '+ConvertSquareToLet((allMoves[i] >> 8) & 0xFF));
		}
		if(checkmate) {
			if(g_toMove==16) {
				$('.dialog.gameresult .result').text('1 - 0');
				$('.dialog.gameresult .text').text('Vit har satt Matt');
				$('.notation').append('<span class="result move">1-0</span>');
			}
			else {
				$('.dialog.gameresult .result').text('0 - 1');
				$('.dialog.gameresult .text').text('Svart har satt Matt');
				$('.notation').append('<span class="result move">0-1</span>');
			}
		}
		else {
			$('.dialog.gameresult .text').text('Remi genom Patt');
			$('.dialog.gameresult .result').text('½ - ½');
			$('.notation').append('<span class="result move">½-½</span>');
		}
		$('.dialog.gameresult').fadeIn(500);
		setTimeout(function() {
			$('.dialog.gameresult').fadeOut(500);
		},3000);
    }
}

function UIPlayMove(move, pv) {
    UpdatePgnTextBox(move);

    g_lastMove = move;
    MakeMove(move);

    UpdatePVDisplay(pv);
	
	AnimateMove(move);
	UpdateGameView(move);
	
	var moves = GenerateValidMoves();
	if(moves.length==0) {
	g_toMove = g_toMove == 8 ? 0x00 : 0x8;
		var checkmate = false;
		var allMoves = new Array();
		GenerateCaptureMoves(allMoves, null);
		GenerateAllMoves(allMoves);
		g_toMove = g_toMove == 8 ? 0x10 : 0x8;
		for(var i=0; i<allMoves.length; i++) {
			if(g_board[(allMoves[i] >> 8) & 0xFF]==(g_toMove | 6)) {
				checkmate = true;
				break;
			}
		}
		if(checkmate) {
			if(g_toMove==16) {
				$('.dialog.gameresult .result').text('1 - 0');
				$('.dialog.gameresult .text').text('Vit har satt Matt');
				$('.notation').append('<span class="result move">1-0</span>');
			}
			else {
				$('.dialog.gameresult .result').text('0 - 1');
				$('.dialog.gameresult .text').text('Svart har satt Matt');
				$('.notation').append('<span class="result move">0-1</span>');
			}
		}
		else {
			$('.dialog.gameresult .text').text('Remi genom Patt');
			$('.dialog.gameresult .result').text('½ - ½');
			$('.notation').append('<span class="result move">½-½</span>');
		}
		$('.dialog.gameresult').fadeIn(500);
		setTimeout(function() {
			$('.dialog.gameresult').fadeOut(500);
		},3000);
	}
}

function UpdatePVDisplay(pv) {
    if (pv != null) {
        var outputDiv = document.getElementById("output");
        if (outputDiv.firstChild != null) {
            outputDiv.removeChild(outputDiv.firstChild);
        }
        outputDiv.appendChild(document.createTextNode(pv));
    }
}

function SearchAndRedraw() {
    if (g_analyzing) {
        EnsureAnalysisStopped();
        InitializeBackgroundEngine();
        g_backgroundEngine.postMessage("position " + GetFen());
        g_backgroundEngine.postMessage("analyze");
        return;
    }
	if(game.ai.level<10) {
		setTimeout(function() {
			if(game.ai.level<5) {
				if((5-game.ai.level)<(Math.random()*4)) {
					Search(FinishMove, 1, null);
				}
				else {
					RandomMove(FinishMove, game.ai.level, null);
				}
				setTimeout("RedrawBoard()", 100);
			}
			else if(game.ai.level>=5) {
				Search(FinishMove, (game.ai.level-4), null);
				setTimeout("RedrawBoard()", 100);
			}
		}, 500);
	}
	else {
		Search(FinishMove, 99, null);
	    setTimeout("RedrawBoard()", 100);
    }
/*    else if (InitializeBackgroundEngine()) {
        if (g_lastMove != null) {
            g_backgroundEngine.postMessage(FormatMove(g_lastMove));
        }
        g_backgroundEngine.postMessage("search " + g_timeout);
    } else {
	    Search(FinishMove, 99, null);
	    setTimeout("RedrawBoard()", 100);
    }*/
}

var g_backgroundEngineValid = true;
var g_backgroundEngine;

function InitializeBackgroundEngine() {
    if (!g_backgroundEngineValid) {
        return false;
    }

    if (g_backgroundEngine == null) {
        g_backgroundEngineValid = true;
        try {
            g_backgroundEngine = new Worker("/wp-content/plugins/cloudlux-chess/js/chessai.js");
            g_backgroundEngine.onmessage = function (e) {
                if (e.data.match("^pv") == "pv") {
                    UpdatePVDisplay(e.data.substr(3, e.data.length - 3));
                } else {
                    UIPlayMove(GetMoveFromString(e.data), null);
                    setTimeout(function() { RedrawBoard(); }, 100);
                }
            }
            g_backgroundEngine.error = function (e) {
                alert("Error from background worker:" + e.message);
            }
        } catch (error) {
            g_backgroundEngineValid = false;
        }
    }

    return g_backgroundEngineValid;
}

function RedrawBoard() {
	$('.board .square').empty();

    var guiTable = new Array();
    for (y = 0; y < 8; ++y) {
        for (x = 0; x < 8; ++x) {
            var piece = game.board[game.view.variation][game.view.move].position[((y + 2) * 0x10) + x + 4];
            var pieceName = null;
            switch (piece & 0x7) {
                case piecePawn: pieceName = "pawn"; break;
                case pieceKnight: pieceName = "knight"; break;
                case pieceBishop: pieceName = "bishop"; break;
                case pieceRook: pieceName = "rook"; break;
                case pieceQueen: pieceName = "queen"; break;
                case pieceKing: pieceName = "king"; break;
            }
            if (pieceName != null) {
				pieceClass = 'piece ';
				pieceClass += (piece & 0x8) ? "white" : "black";
				pieceClass += ' '+pieceName; 
                pieceName += "_";
                pieceName += (piece & 0x8) ? "white" : "black";
                pieceName += ".png";
            }

            if (pieceName != null) {
				var row = ['a','b','c','d','e','f','g','h'];
				$('.board .'+row[x]+(8-y)).html('<div class="'+pieceClass+'"></div>');
				$('.board .square .piece').draggable({
					revert: true,
					revertDuration: 200,
					zIndex: 9999,
					start: function() {
						game.from = $(this).parent().attr('class').split(' ')[2];
					}
				});
            }
        }
    }

    g_changingFen = true;
    document.getElementById("FenTextBox").value = GetFen();
    g_changingFen = false;
}
