//the smallest piece has index 0, the biggest - 4
//columns are: left - 0; middle - 1; right - 2

//initialize array to any valid position (0,0,0,0,0 - all the pieces are in the left column)
var pieceLocation = new Array(0,0,0,0,0);
var pieceLocationSaved = new Array(0,0,0,0,0);
var hc = new Array(0,77,154,231,308);
var wc = new Array(0,100,210,310,420);
var X, Y, nr, iTime, timerID;
//this arrays will contain the solution moves
var pieceToMove = new Array;	//piece number (index) that should be moved
var moveToColumn = new Array;	//column where to move the piece
var moveToVerticalPosition = new Array;	//vertical position in the column where
var movesCount;	//number of moves
var movesCountCustomer;	//number of moves
var fromVerticalPosition = new Array(0,0,0,0,0);	//vertical position in the column where
var modeFlag;

document.onmousedown=mouseDownEvent; 
document.onmousemove=mouseMoveEvent; 
document.onmouseup=mouseUpEvent;
document.onmouseover=mouseOver; 
document.onmouseout=mouseOut;
document.oncontextmenu = disableRightClick;

function disableRightClick()
{
  alert('Source code is COPYRIGHTED. Please, do not reproduce.');
  return false;
}

function doLoad()
{
	iTime = 0;
	movesCountCustomer = 0;
}

function checkForFinish()
{	
	var i, j;
	j = 0;
	for (i=0; i<5; i++)
		if (pieceLocation[i] == 2) 
			j++;
	if(j==5)
		return true;
	else
		return false;
}

function checkForUpper(pieceIndex)
{	
	for (var i=pieceIndex-1; i>=0; i--)
		if (pieceLocation[i] == pieceLocation[pieceIndex]) 
			return false;
	return true;
}

function checkForDrop(pieceIndex, column)
{	
	for (var i=pieceIndex-1; i>=0; i--)
		if (pieceLocation[i] == column) 
			return false;
	return true;
}

function mouseOver(e)         
{
  if (e == null) e = window.event;
  var tgt = e.target != null ? e.target : e.srcElement;
  var strID;
  try { strID = tgt.id; } catch (ex) { strID = e.id; }
  var i;

	if (strID.indexOf("p") != -1)   
	{
		i = String(strID).substring(1,2) - 1;
		if(checkForUpper(i))
			window.event.srcElement.style.cursor = "hand";
	}
}

function mouseOut(e)         
{
  if (e == null) e = window.event;
  var tgt = e.target != null ? e.target : e.srcElement;
  var strID;
  try { strID = tgt.id; } catch (ex) { strID = e.id; }
  var i;

	if (strID.indexOf("p") != -1)   
	{
		i = String(strID).substring(1,2) - 1;
		if(checkForUpper(i))
			window.event.srcElement.style.cursor = "auto";
	}
}

function mouseDownEvent(e)         
{
  if (e == null) e = window.event;
  var tgt = e.target != null ? e.target : e.srcElement;
  var strID;
  try { strID = tgt.id; } catch (ex) { strID = e.id; }
  var i;

	if (strID.indexOf("p") != -1)   // if this is a jigsaw piece
	{
		nr = strID;        // save the ID in a global variable
		i = String(nr).substring(1,2);
		i--;
		if(checkForUpper(i))
		{
			document.getElementById(nr).style.cursor = "hand";
			X = document.getElementById(nr).style.pixelLeft;
			Y = document.getElementById(nr).style.pixelTop;
			document.getElementById(nr).style.zIndex = 1;
		}
		else
			nr = null;
	}
}

function mouseMoveEvent(e)    
{
  if (e == null) e = window.event;
  if (nr != null)
	{
		var saveX, saveY;
	
		saveX = document.getElementById(nr).style.pixelLeft;
		saveY = document.getElementById(nr).style.pixelTop;
	 	document.getElementById(nr).style.pixelLeft = e.x - MainDiv.style.posLeft - 30;
	 	document.getElementById(nr).style.pixelTop = e.y - MainDiv.style.posTop - 30;
	 	if (document.getElementById(nr).style.pixelLeft < 0)
			document.getElementById(nr).style.pixelLeft = saveX;
	 	if (document.getElementById(nr).style.pixelTop < 0)
			document.getElementById(nr).style.pixelTop = saveY;
	}
	e.cancelBubble = true;
	e.returnValue = false;
}

function mouseUpEvent(e)     
{
  if (e == null) e = window.event;
  var i, j, row, column, verticalPosition;
	if (nr)
	{
		i = String(nr).substring(1,2);
		i--;

		if (document.getElementById(nr).style.pixelLeft <= wc[1]) 
			column = 0;
		if (document.getElementById(nr).style.pixelLeft > wc[1] && document.getElementById(nr).style.pixelLeft <= wc[3]) 
			column = 1;
		if (document.getElementById(nr).style.pixelLeft > wc[3]) 
			column = 2;
		
		if(checkForDrop(i, column))
		{
			verticalPosition = 0;
			for (j=i+1; j<5; j++)
				if (pieceLocation[j] == column) 
					verticalPosition++;

			pieceLocation[i] = column;
			document.getElementById(nr).style.pixelLeft = wc[2 * column];
			document.getElementById(nr).style.pixelTop = hc[4 - verticalPosition];  
		}
		else
		{
			document.getElementById(nr).style.pixelLeft = X;
			document.getElementById(nr).style.pixelTop = Y;  
		}
		document.getElementById(nr).style.cursor = "auto";
		document.getElementById(nr).style.zIndex = 0;
		nr = null;
		e.cancelBubble = true;
		e.returnValue = false;
		movesCountCustomer++;
		if(checkForFinish())
			alert("Total moves:" + movesCountCustomer);
	}
}

function rand()
{
	return Math.round(2 * Math.random());
}

function doStart()
{
	var i, j;
	
	for (i=0; i<5; i++)
		pieceLocation[i] = rand();
		
	for (j=4; j>=0; j--)
		saveFromMove(j);
		
	for (i=0; i<5; i++)
	{
		nr = "p" + (i + 1);
		document.getElementById(nr).style.pixelLeft = wc[2 * pieceLocation[i]];
		document.getElementById(nr).style.pixelTop = hc[4 - fromVerticalPosition[i]]; 
		document.getElementById(nr).src = "images/" + nr + ".gif";
		nr = null;
	}
	movesCountCustomer = 0;
}   

function saveFromMove(pieceIndex)
{	
	var verticalPosition = 0;
	for (var i=pieceIndex+1; i<5; i++)
	{
		if (pieceLocation[i] == pieceLocation[pieceIndex]) 
			verticalPosition++;
	}
	fromVerticalPosition[pieceIndex] = verticalPosition;
}

function doStep()
{
	if(!checkForFinish())
	{
		var i;
		modeFlag = "Step";
		for (i=0; i<5; i++)
			pieceLocationSaved[i] = pieceLocation[i];
		solve();
		movesCount = 1;
		showMove();
		for (i=0; i<5; i++)
			pieceLocation[i] = pieceLocationSaved[i];
		pieceLocation[pieceToMove[0]] = moveToColumn[0];
		movesCountCustomer++;
	}
}

function doAuto()
{ 
	modeFlag = "Auto";
	solve();
	showMove();
}

function solve()
{
	movesCount = 0;
	positionPile(4, 2); //that's what we need to do - position the entire pile in the right column
}

//builds a pile in a specified column; 
//lowPieceIndex - the biggest (the lower) piece in the pile
function positionPile(lowPieceIndex, column)
{
	if (lowPieceIndex == 0)
	{
		//the pile has the only one (the smallest) piece - just move it to where it should go
		movePiece(0, column);
	}
	else
	{
		//starting with the biggest piece in the pile, move each to the destination column; positionPiece will take care
		//about the rules: can't move a pice if there's something on top of it, can't move a piece to a column if there already 
		//is a smaller one
		for (var i=lowPieceIndex; i>=0; i--)
			positionPiece(i, column);
	}
}

//positions a piece into a specified column
function positionPiece(pieceIndex, column)
{
	if (pieceLocation[pieceIndex] != column)
	{ 
		//if the piece is not already there, position all the pieceis smaller than the given in the remaining column (not the
		//the given piece column, not the destination column)
		positionPile(pieceIndex-1, 3-pieceLocation[pieceIndex]-column);
		
		//Now, the piece is free to move to the destination column
		movePiece(pieceIndex, column);
	}
}

//display piece movement and update pieceLocation to reflect the move
function movePiece(pieceIndex, column)
{
	if (pieceLocation[pieceIndex] != column)
	{
		saveMove(pieceIndex,column);
		pieceLocation[pieceIndex] = column;
	}
}

function saveMove(pieceIndex, column)
{	
	var verticalPosition = 0;
	for (var i=0; i<5; i++)
		if (pieceLocation[i] == column) 
			verticalPosition++;
	pieceToMove[movesCount] = pieceIndex;
	moveToColumn[movesCount] = column;
	moveToVerticalPosition[movesCount] = verticalPosition;
	movesCount++;
}

//display piece moving from pieceLocation[pieceIndex] to column
function showMove()
{	
	if(iTime < movesCount)
	{
		nr = "p" + (pieceToMove[iTime] + 1);
		document.getElementById(nr).style.pixelLeft = wc[2 * moveToColumn[iTime]];
		document.getElementById(nr).style.pixelTop = hc[4 - moveToVerticalPosition[iTime]]; 
		document.getElementById(nr).src = "images/" + nr + ".gif";
		timerID = window.setTimeout("showMove()",250);
		iTime++;
		nr = null;
	}
	else
	{
		window.clearTimeout(timerID);
		iTime = 0;
		if(modeFlag == "Auto")
			alert("Total moves:" + movesCount);
		else
			if(checkForFinish())
				alert("Total moves:" + movesCountCustomer);
	}
}

