/* Copyright 2004 Louis Jean­Richard (www.ljr.ch). All Rights Reserved. */
//	-----------------------------------
var MAX_SIDE = 8
var side = 3
var last_side = 0
var emptyCell = -1
var	notSelected = -1
var moves = 0
var cells, magicSum, total
//	-----------------------------------
var digit = new Preload("../aa/game/1/")
digit.load("magics", 16, ".gif")
var separatorsBase = 10
//	-----------------------------------
function					Array2(xCells, yCells) {
	this.length = xCells
	for (var x = 0; x < this.length; x++)
		this[x] = new Array(yCells)
}
var board = new Array2(MAX_SIDE + 2, MAX_SIDE + 2)
//	-----------------------------------
function                                imageFile(imageNumber){
	if (imageNumber < 0)
		return digit.image[separatorsBase - imageNumber].src
	else
		return digit.image[imageNumber].src
}
//	-----------------------------------
function                                cellName(y,x,d){
//	return 'SQ' + (2*(y * (MAX_SIDE + 2) + x)+d)
	return 'SQ' + (y) + (x) + (d)
}
var selectedY = notSelected
var selectedX = notSelected
//	-----------------------------------
function                                displayNumber(y,x) {
	var n = board[y][x]
	document.images[cellName(y,x,3)].src = imageFile(-2)
	if (n < 0) {
		document.images[cellName(y,x,2)].src = imageFile(-1)
		document.images[cellName(y,x,1)].src = imageFile(-1)
		document.images[cellName(y,x,0)].src = imageFile(-1)
	}
	else {
		document.images[cellName(y,x,0)].src = imageFile(n % 10)
		n = Math.floor(n / 10)
		if (n == 0) {
			document.images[cellName(y,x,1)].src = imageFile(10)
			document.images[cellName(y,x,2)].src = imageFile(10)
		}
		else {
			document.images[cellName(y,x,1)].src = imageFile(n % 10)
			n = Math.floor(n / 10)
			if (n == 0)
				document.images[cellName(y,x,2)].src = imageFile(10)
			else
				document.images[cellName(y,x,2)].src = imageFile(n)
		}
	}
}
//	-----------------------------------
function                                displayDiagonalTotal() {
	board[total][total] = 0
	for (var d=0; d<side; d++)
		board[total][total] += board[d][d]
	displayNumber(total,total)
	moves++
	score.update(moves)
}
//	-----------------------------------
function                                moveCellTo(y,x) {
	var n = board[selectedY][selectedX]
	board[selectedY][total] -= n
	board[total][selectedX] -= n
	board[selectedY][selectedX] = board[y][x]
	displayNumber(selectedY,selectedX)
	board[selectedY][total] += board[y][x]
	displayNumber(selectedY,total)
	board[total][selectedX] += board[y][x]
	displayNumber(total,selectedX)
	board[y][total] -= board[y][x]
	board[total][x] -= board[y][x]
	board[y][x] = n
	displayNumber(y,x)
	board[y][total] += n
	displayNumber(y,total)
	board[total][x] += n
	displayNumber(total,x)
	displayDiagonalTotal()
}
//	-----------------------------------
function                                moveRowTo(y) {
	for (var x=0; x<=total; x++)
		if (x != side) {
			var n = board[selectedY][x]
			board[selectedY][x] = board[y][x]
			displayNumber(selectedY,x)
			board[y][x] = n
			displayNumber(y,x)
		}
	displayDiagonalTotal()
}
//	-----------------------------------
function                                moveColumnTo(x) {
	for (var y=0; y<=total; y++)
		if (y != side) {
			var n = board[y][selectedX]
			board[y][selectedX] = board[y][x]
			displayNumber(y,selectedX)
			board[y][x] = n
			displayNumber(y,x)
		}
	displayDiagonalTotal()
}
//	-----------------------------------
function                                rotateRows() {
	for (var x=0; x<=total; x++)
		if (x != side) {
			var n = board[0][x]
			for (var y=0; y<side-1; y++) {
				board[y][x] = board[y+1][x]
				displayNumber(y,x)
			}
			board[y][x] = n
			displayNumber(y,x)
		}
	displayDiagonalTotal()
}
//	-----------------------------------
function                                rotateColumns() {
	for (var y=0; y<=total; y++)
		if (y != side) {
			var n = board[y][0]
			for (var x=0; x<side-1; x++) {
				board[y][x] = board[y][x+1]
				displayNumber(y,x)
			}
			board[y][x] = n
			displayNumber(y,x)
		}
	displayDiagonalTotal()
}
//	-----------------------------------
function                                goalAttained() {
	var n = 0
	for (var i=0; i<side; i++) {
		if (board[total][i] == magicSum)
			n++
		if (board[i][total] == magicSum)
			n++
	}
	return (n == (2 * side))
}
//	-----------------------------------
function                                clickedCell(y,x) {
	if (((y < side) || (y == total) && (x != total))
		&& ((x < side) || (x == total) && (y != total))) {
		if (selectedX == notSelected) {
			window.defaultStatus = msg1(board[y][x])
			selectedY = y
			selectedX = x
		}
		else {
			if ((selectedY < side) && (selectedX < side))
				moveCellTo(y,x)
			else
				if ((selectedY == total) && (x < side))
					moveColumnTo(x)
				else
					if ((selectedX == total) && (y < side))
						moveRowTo(y)
			selectedX = notSelected
			selectedY = notSelected
			if (goalAttained())
				window.defaultStatus = msg2(moves)
			else
				window.defaultStatus = msg3(magicSum,moves)
		}
	}
	else
		if ((y == side) && (x == total))
			rotateRows()
		else
			if ((y == total) && (x == side))
				rotateColumns()
}
//	-----------------------------------
function								repaint() {
	for (var y=0; y<=MAX_SIDE+1; y++)
		for (var x=0; x<=MAX_SIDE+1; x++)
			displayNumber(y,x)
}
//	-----------------------------------
function								orderChanged() {
	squareOrder.read()
	side = squareOrder.selected.order
	cells = side * side
	var perm = new Permutation(cells)
	perm.random()
	total = side + 1
	moves = 0
	score.update(moves)
	var y, x
	for (x=0;  x<=MAX_SIDE+1;  x++)
		if ((x < side) || (x == total))
			board[total][x] = 0
		else
			board[total][x] = emptyCell
	var cell = 0
	for (y=0; y<side; y++) {
	 	board[y][total] = 0
		for (x=0; x<=MAX_SIDE+1; x++) {
			if (x < side) {
				cell++
				board[y][x] = perm.index[cell]
				board[y][total] += board[y][x]
				board[total][x] += board[y][x]
			}
			else
				if (x != total)
					board[y][x] = emptyCell
		}
		board[total][total] += board[y][y]
	}
	for (x=0; x<=MAX_SIDE+1; x++)
		board[side][x] = emptyCell
	for (y=total+1; y<=MAX_SIDE+1; y++)
		for (x=0; x<=MAX_SIDE+1; x++)
			board[y][x] = emptyCell
	magicSum = side * (cells + 1) / 2
	window.onResize=repaint
	repaint()
	window.defaultStatus = msg4(magicSum)
}
//	============================================================
//						S Q U A R E   O R D E R
//	============================================================
function text1(N){
	switch (langCode) {
	case 'de':
		return N + ' x ' + N + ' Quadrat.'
	case 'es':
		return 'quadrado ' + N + ' x ' + N
	case 'fr':
		return 'carr&eacute; ' + N + ' x ' + N
	case 'it':
		return 'quadrato ' + N + ' x ' + N
	default:
		return N + ' x ' + N + ' square.'
	}
}
//	-----------------------------------
function   								SquareOrder(order) {
	this.order = order
	this.optionText = text1(order)
	this.magicSum = order * (order * order + 1) / 2
}

//	-----------------------------------
function               			        displayControl() {
	var output = '<form name="CONTROL"><p>'
	output += squareOrder.htmlList("CONTROL")
	output += '</p><p><input class="button" type="button" value='
	output += sQuoted(text2)
	output += " onClick='orderChanged();'>"
	output += "</p></form>"

	return output
}
//	-----------------------------------
function                         		displayBoard() {
	last_side = side
	var y, x
	var eet = ' style="display: block" />'
	var ee = ' />'
	var output = '<table><tr>'
	var bar = '<td><img src=' + quoted(imageFile(-3)) + eet
	for (x=0; x <= MAX_SIDE + 1; x++)
		output += bar
	output +=  '<td><img src=' + quoted(imageFile(-5)) + eet + '</td>'
	output += '</tr>'
	var vbar = ' src=' + quoted(imageFile(-2)) + ee
	var blank = ' src=' + quoted(imageFile(-1)) + ee
	var rowEnd = '<td><img src=' + quoted(imageFile(-4)) + ee + '</td>'
	for (y=0; y <= MAX_SIDE + 1; y++) {
		output += '<tr>'
		for (x=0; x <= MAX_SIDE + 1; x++) {
			output += '<td><a href="javascript:clickedCell(' + y + ',' + x + ')">'
			output += '<img name=' + cellName(y,x,3)
			output += vbar
			for (var d=2; d>=0; d--) {
				output += '<img name=' + cellName(y,x,d)
				output += blank
			}
			output += '</a></td>'
		}
		output += rowEnd
		output += '</tr>'
	}
	output += '</table>'
	return output
}

//	============================================================
//							S C O R E
//	============================================================

function 								Score(aSquareOrder) {
	this.moves = 0
	this.chrono = new Chrono()
	this.displayed = false
	//
	this.squareOrder = aSquareOrder
}
//	-----------------------------------
function                                htmlScore(){
	output = '<form name="SCORE"><table>'
	output += '<tr><td>' + text5d
	output += '</td><td>' + text5e
	output += "</td></tr><tr><td>" + htmlDisplay('moves', '')
	output += '</td><td>' + htmlDisplay('time', '')
	output += "</td></tr>"
	output += '<tr><td>' + text5f
	output += '</td><td>' + text5g
	output += "</td></tr><tr><td>" + htmlDisplay('order', '')
	output += '</td><td>' + htmlDisplay('magicSum', '')
	output += "</td></tr>"
	output += "</table></form>"
	this.displayed = true
	return output
}
Score.prototype.html = htmlScore
//	-----------------------------------
function                                resetScore(){
	this.moves = 0
	document.SCORE.time.value = ''
	document.SCORE.moves.value = this.moves
	document.SCORE.order.value = this.squareOrder.selected.order
	document.SCORE.magicSum.value =
		this.squareOrder.selected.magicSum
	this.chrono.stop()
}
Score.prototype.reset = resetScore
//	-----------------------------------
function                                updateScore(moves){
	if (moves == 0)
		this.reset()
	else {
		this.moves = moves
		if (moves == 1)
			this.chrono.start()
		else
			document.SCORE.time.value = this.chrono.elapsedMinutes()
	}
	document.SCORE.moves.value = this.moves
}
Score.prototype.update = updateScore

//	============================================================
//						I N T E R F A C E
//	============================================================

function                                displayGame(language) {
	initLanguage(language)
	squareOrder = new Selector('orderChanged', 0
		, new SquareOrder(3)
		, new SquareOrder(4)
		, new SquareOrder(5)
		, new SquareOrder(6)
		, new SquareOrder(7)
		, new SquareOrder(8)
		)
	score = new Score(squareOrder)

	var output = '<table class="game"><tr><td class="score">'
	output += score.html()
	output += '</td><td class="board" rowspan="2">'
	output += displayBoard()
	output += '</td></tr><tr><td class="control">'
	output += displayControl()
	output += '</td></tr></table>'

	document.open()
	document.write(output)
	document.close()
	window.defaultStatus = msg1()

	orderChanged()
}

//	============================================================
var langCode = undefined
var text2 = 'New game'
var text5d = 'moves'
var text5e = 'time'
var text5f = 'order'
var text5g = 'magic number'
//	-----------------------------------
function initLanguage(language) {
	if (langCode == undefined)
		langCode = language
	else
		return
	switch (langCode) {
	case 'de':
		text2 = 'Neues Spiel'
		text5d = 'Schritte'
		text5e = 'Zeit'
		text5f = 'Ordnung'
		text5g = 'magische Zahl'
		break
	case 'es':
		text2 = 'Empezar un juego nuevo'
		text5d = 'pasos'
		text5e = 'tiempo'
		text5f = 'orden'
		text5g = 'numero magico'
		break
	case 'fr':
		text2 = 'Nouveau jeux'
		text5d = 'pas'
		text5e = 'temps'
		text5f = 'ordre'
		text5g = 'nombre magique'
		break
	case 'it':
		text2 = 'Nuovo gioco'
		text5d = 'mosse'
		text5e = 'tempo'
		text5f = 'ordine'
		text5g = 'numero magico'
		break
	}
}
//	-----------------------------------
function msg1(A){
	switch (langCode) {
	case 'de':
		return A.toString() + ' gew&auml;hlt'
	case 'es':
		return 'seleccionado ' + A
	case 'fr':
		return 'selectionn&eacute; ' + A
	case 'it':
		return 'selezionato ' + A
	default:
		return 'selected ' + A
	}
}
//	-----------------------------------
function msg2(A){
	switch (langCode) {
	case 'de':
		return 'Das Quadrat ist magisch !   (' + A + ' Bewegungen)'
	case 'es':
		return 'El cuadrado es magico !   (' + A + ' pasos)'
	case 'fr':
		return 'lee carr&eacute; est magique !   (' + A + ' mouvements)'
	case 'it':
		return 'Il quadrato &eacute; magico !   (' + A + ' mosse)'
	default:
		return 'The square is magic !   (' + A + ' moves)'
	}
}
//	-----------------------------------
function msg3(A, B){
	switch (langCode) {
	case 'de':
		return 'Die magische Zahl ist ' + A + '   (' + B + ' Bewegungen)'
	case 'es':
		return 'El numero magico es ' + A + '   (' + B + ' pasos)'
	case 'fr':
		return 'Le nombre magique est ' + A + '   (' + B + ' mouvements)'
	case 'it':
		return 'Il numero magico &eacute; ' + A + '   (' + B + ' mosse)'
	default:
		return 'The magic number is ' + A + '   (' + B + ' moves)'
	}
}
//	-----------------------------------
function msg4(A){
	switch (langCode) {
	case 'de':
		return 'Die magische Zahl ist ' + A
	case 'es':
		return 'El numero magico es ' + A
	case 'fr':
		return 'Le nombre magique est ' + A
	case 'it':
		return "Il numero magico &eacute; " + A
	default:
		return 'The magic number is ' + A
	}
}
//	-----------------------------------
