//======================================================
//
// Sliding Puzzle javascript
//
//======================================================

/******* CHANGE PARAMETERS HERE *******/
/* extension of tile filename */
file_extension=".jpg";

/* Width and height of the board */
boardwidth=3; boardheight=4;maxblanks=6;

/* Width and height of the tiles */
tilewidth=119; tileheight=134;

/* Number of random moves to make in shuffle */
shufflemoves=60;
blank_tile="leeg_0.jpg";

// The empty square may be filled with other pictures
blank_filestem="Leeg";

/* Should not need to change the code below. */

/* Number of moves made by user */
movessofar=0;

/* Original arrangement of board and array for the blanks */
original=new Array(boardwidth * boardheight);
blanks = new Array(boardwidth * boardheight);

/* Starting index into original[] where the "space" lives. Set up by function below. */
originalspaceisat=-1;
spaceisat=-1;

/* Current arrangement of the board */
board=new Array();


/* Populate "original" array, containing the original board layout.
   Always put empty space in bottom right.
   Populates from left to right then top to bottom.
   Assume filenames starting with the string "filestem".
   Then the filename will follow the Paint Shop Pro naming when
   using the PSP slice function, eg. for a 2 by 2 sliced image
   use "file_1x1", "file_1x2", "file_2x1", "file2x2".
   */
function populateoriginal()
{
	var iRow = 1;
	var iCol = 1;

    for (var blocknum=0; blocknum<(original.length - 1); blocknum++)
    {
		original[blocknum]=filestem+"_"+(iRow)+"x"+(iCol)+file_extension;

		// If at the end of a row, start column at 1 again and increase row number
		if (iCol == boardwidth) {
			iCol = 1;
			iRow++;
		}
		else
			iCol++;
    }
    original[(original.length - 1)] = blank_tile;
    originalspaceisat=(original.length - 1);      /* Bottom right square */

	// Also fill the array with the pictures of the blank space
    for (var blanknum=0; blanknum<maxblanks; blanknum++)
    {
		blanks[blanknum]=blank_filestem+"_"+(blanknum + 1)+file_extension;

    }
}

populateoriginal();


/* Produce a status message */
function message(value)
{
    self.window.status=value;
    return true;
}


/* Return TRUE if the board is back to the original setting, FALSE otherwise. */
function havewon()
{
    var returnvalue = true;

    for (var blocknum=0; blocknum<(original.length - 1); blocknum++)
    {
	if (original[blocknum] != board[blocknum])
	{
		returnvalue = false;
		break;
	}
    }

    return returnvalue;
}


/* This function returns the piece with the given index */
function getpiece(blocknum)
{
    return document.images["piece"+blocknum];
}


/* Reset the board... */
function resetboard()
{
   for (var blocknum=0; blocknum<original.length; blocknum++)
   {
      board[blocknum]=original[blocknum];
      getpiece(blocknum).src=board[blocknum];
   }
   spaceisat=originalspaceisat;
   movessofar=0;
   message ("The board has been reset.");
}


/* About the puzzle */
function aboutpuzzle()
{
    alert ("Sliding Block Puzzle\n\nOriginal code copyright (c) 2002 Mark Thurman\n" +
    	   "Adjusted for my own use: (c) Wouter van de Weerd\n" +
           "Picture copyright (c) 2006 Wouter van de Weerd");
}


/* Move a block */
function moveblock(blocknum, blnUseDefaultBlankTile)
{
  var iBlankIndex;

    /* If user clicked the space, do nothing. */
    if (blocknum!=spaceisat)
    {
        if (isnextto(blocknum))
        {
            getpiece(spaceisat).src=board[blocknum];

            ///// Original:
            /////getpiece(blocknum).src=blank_tile;

	    if (blnUseDefaultBlankTile)
              getpiece(blocknum).src=blank_tile;
	    else {
              // New: Randomly pick a blank tile image from the array
	      iBlankIndex = Math.floor(Math.random() * (maxblanks));
              getpiece(blocknum).src=blanks[iBlankIndex];
	    }

            board[spaceisat]=board[blocknum];

            ///// Original:
            /////board[blocknum]=blank_tile;


	    if (blnUseDefaultBlankTile)
              board[blocknum]=blank_tile;
	    else {
              // New: use the random blank tile
              board[blocknum]=blanks[iBlankIndex];
	    }

            spaceisat=blocknum;

			movessofar++;

			if (havewon())
			{
				message ("You won in " + movessofar + " moves!");
				movessofar = 0;
			}
			else
			{
				if (movessofar != 1)
				{
					message (movessofar + " moves made.");
				}
				else
				{
					message ("1 move made.");
				}
			}
        }
        else
        {
            message ("Can't move this block");
        }
    }
    else
    {
       /* Reset the status indicator */
       message ("");
    }
}


/* Returns the column that the given block is on (zero is leftmost) */
function oncolumn(blocknum)
{
    return (blocknum % boardwidth);
}


/* Returns the row that the given block is on (zero is topmost) */
function onrow(blocknum)
{
    return (Math.floor (blocknum / boardwidth));
}


/* Returns TRUE if the first argument (representing a block index)
   "is next to" the space horizontally */
function isnexttohoriz(blocknum)
{
    return (((spaceisat-blocknum == 1) || (spaceisat-blocknum == -1))
             &&
             (onrow(spaceisat) == onrow(blocknum)));
}


/* Returns TRUE if the first argument (representing a block index)
   "is next to" the space vertically */
function isnexttovert(blocknum)
{
    var spacerow = onrow(spaceisat);
    var blockrow = onrow(blocknum);

    return (((spacerow-blockrow == 1) || (spacerow-blockrow == -1))
            &&
            (oncolumn(spaceisat) == oncolumn(blocknum)));
}


/* Returns TRUE if the first argument (representing a block index)
   "is next to" the space */
function isnextto(blocknum)
{
    return (isnexttohoriz(blocknum) || isnexttovert(blocknum));
}


/* Generates the board to go on the page */
function addboardtopage()
{
    var rowstarted=false;

    document.write("<table cellspacing=0 cellpadding=0 border=1>\n");
    for (var blocknum=0; blocknum<original.length; blocknum++)
    {
	/* Start row */
	if (oncolumn(blocknum) == 0)
	{
           /* Terminate last row if necessary */
	   if (rowstarted)
	   {
	       document.write("</tr>");
	   }

	   document.write("<tr>");
	   rowstarted=true;
	}

        document.write("<td><img width="+tilewidth+" height="+tileheight+
                       " onmousedown='moveblock("+blocknum+", false)'"+
		       " name='piece"+blocknum+"'"+
		       " src='"+original[blocknum]+"'></td>");
    }
    document.write("</tr></table>\n");
}


/* Makes a random move */
lastrandommove=-1;  /* Variable used so that we don't undo the last move */
function makerandommove(blnLastMove)
{
    var direction = -1;
    var madeamove = false;

    /* Keep looping until we make a valid move */
    while (!madeamove)
    {
        /* Choose a random direction in the range 0..3 */
        direction = 0 + (Math.round ((Math.random() * 3.999) - 0.5));
	/* "0 +" works around a bug in Netscape 6.1 */
        madeamove=false;

        switch (direction)
        {
           case 0: /* up */
             /* if not at top */
             if ((onrow(spaceisat) != 0) && (lastrandommove != 1))
             {
                 moveblock (spaceisat - boardwidth, blnLastMove);
                 madeamove = true;
             }
             break;
           case 1: /* down */
             /* if not at bottom */
             if ((onrow(spaceisat) != (boardheight - 1)) &&
                 (lastrandommove != 0))
             {
                 moveblock (spaceisat + boardwidth, blnLastMove);
                 madeamove = true;
             }
	     break;
           case 2: /* left */
             /* if not at left edge */
             if ((oncolumn(spaceisat) != 0) &&
                 (lastrandommove != 3))
             {
                 moveblock (spaceisat - 1, blnLastMove);
                 madeamove = true;
             }
	     break;
           case 3: /* right */
             /* if not at left edge */
             if ((oncolumn(spaceisat) != (boardwidth - 1)) &&
                 (lastrandommove != 2))
             {
                 moveblock (spaceisat + 1, blnLastMove);
                 madeamove = true;
             }
	     break;
           default:
             /* Should not be possible */
             message ("ERROR: chose a direction which is not allowed (" + direction + ")");
	     return;  /* Avoid infinite loop */
        }
    }
    lastrandommove=direction;
}


/* Shuffles the board */
function shuffle()
{
    movessofar=0;
    for (var thismove=0; thismove<(shufflemoves-1); thismove++)
    {
        makerandommove(false);
    }
    makerandommove(true); // last randommove: show correct blank tile

    message ("En los nu de puzzle op...");
    /* The above function will print the number of moves made so far, but
     * that's fine. */
    movessofar=0;
}
