﻿/*----------------------------------------------------------------\
|                                                                 |
|  Fair License                                                   |
|                                                                 |
|  JS Games :: Jigsaw Puzzle                                      |
|  Copyright (C) 2002-2004 Arun Narayanan                         |
|                                                                 |
|  For latest release information and downloads visit:            |
|  http://jsgames.sourceforge.net/                                |
|                                                                 |
|  Usage of the works is permitted provided that this             |
|  instrument is retained with the works, so that any entity      |
|  that uses the works is notified of this instrument.            |
|                                                                 |
|  DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.                    |
|                                                                 |
|  [2004, Fair License: rhid.com/fair]                            |
|                                                                 |
\----------------------------------------------------------------*/

//global configuration (change these to alter the position of the playing board)
var offset = parseInt(screen.width)/1280;
var gtop = 470; //250;          //constant denotes top of board
var gleft = 140*offset;          //constant denotes left of board

//internal use variables
var gintervalid = -1;    //keeps track of the game timer
var gtime = 0;           //stores time in seconds
var gmoves = 0;          //stores the total moves per game
var gpicid = -1;         //keeps track of the picture loading timer
var gpictick = 0;        //counter for the picture loading timer
var gpicture = "";       //current picture path
var gloaded = false;     //becomes true when a proper picture has been loaded
var gdragging = false;   //true while a block is being dragged
var gcurrobjid = "";     //id of the block being dragged
var gdx = 0;             //width of a block of the picture
var gdy = 0;             //height of a block of the picture
var gsrcx = 0;           //x coordinate of the block before the drag started
var gsrcy = 0;           //y coordinate of the block before the drag started
var gpicurl = "";        //last valid picture url used
var gprogress = 0;       //stores the % of correctly positioned pieces
var gactive = false;     //keeps track of whether the game timer is active

function toggleHelp()
{
  /*if (butHelp.value == "Hide Help")
  {
    help.style.display = "none";
    divTip.style.display = "block";
    butHelp.value = "Show Help";
  }
  else
  {
    help.style.display = "block";
    divTip.style.display = "none";
    butHelp.value = "Hide Help";
  } */ 
}

function loadPicture(picture)
{
	var i;
  
	gloaded = false;
	selPic.disabled = true;
	//butLoad.value = "Cancel Loading";  
	board.style.display = "none";
	board.style.pixelLeft = gleft;
	board.style.pixelTop = gtop;
	divPic.style.pixelLeft = gleft;
	divPic.style.pixelTop = gtop;
	divPic.style.display = "block";
	showStatus("Picture Loading... Please Wait!");
	pic.src = picture;
	gpictick = 0;
	gpicture = picture;
	stopPicTimer();
	gpicid = setInterval("checkPictureLoadStatus()",300);
}

function checkPictureLoadStatus()
{
	gpictick++;
  
	if (pic.readyState != "complete")
	{
		if (gpictick >= 100) //after each 30 secs
		{
			gpictick = 0; //reset the timer
      

			//ask user if he wants to continue loading the picture
			//vbRetryCancel=5 vbRetry=4 vbCancel=2
			if (2 == VBMsgBox("The url you provided may be invalid or too slow!\n\n"+"Do you wish to continue loading the picture?",5,"Loading Picture"))
			{

				//do a final check to see if by this time the picture has already loaded!
				if (pic.readyState == "complete")
				{
					checkPictureLoadStatus();
					return;
				}
				gloaded = false;
				divPic.style.display = "block";
				showStatus('Unable to load Picture: ' + gpicture);
				stopPicTimer();
				return;
			}
		}
	}
	else //picture loaded!
	{
		stopPicTimer();
		showStatus(""); //'Picture \"'+gpicture+'" Loaded!<p>'+"Press 'Start Game' to start the game."
		gloaded = true;
		//butLoad.disabled = true;
		selPic.disabled = false;
		//butLoad.value="Load Picture";
		butStart.disabled = false;
		butStart.focus();
		gpicurl = gpicture;
	}
}

function drawBoard() 
{
  var i,j,s="",dx,dy,t=0,l=0,n=0,picWidth,picHeight;
  
  if (!gloaded)
  {
    alert("No Picture selected!. Please use the picture drop down.");
    //selPic.focus();
    return;
  }
  
  divisionsX = parseInt(selCols.value);
  divisionsY = parseInt(selRows.value);
  
  picWidth = pic.clientWidth;
  picHeight = pic.clientHeight;
  
  if (picWidth == 0) picWidth = 400;
  if (picHeight == 0) picHeight = 400;

  divPic.style.display = "none";
  
  board.style.display = "block";
  
  dx = parseInt(picWidth/divisionsX);
  dy = parseInt(picHeight/divisionsY);
  board.style.pixelWidth = divisionsX * dx + 1;
  board.style.pixelHeight = divisionsY * dy + 1;      

  for (i=0;i<divisionsY;i++)
    for (j=0;j<divisionsX;j++)
    {
      t = i*dy;
      l = j*dx;
      s += '<div id=a_' + j + '_' + i + ' style="position:absolute;clip:rect(' 
            + (t+1) + ',' + (l+dx) + ',' + (t+dy) + ',' + (l+1) + ');"'
            + ' ondragstart="startDrag(this)" ondrag="move();" ondragend="reposition()">'
            + '<img id=p_' + j + '_' + i + ' src="' + gpicture + '" width=' + picWidth 
            + ' height=' + picHeight + "></div>\n";
    }

  s += '<table width="100%" style="position:absolute;top:-60;" cellpadding=0 cellspacing=0 bgcolor="#FFFFFF"><tr>'
        + '<td width="33%"><input style="width:120px" type=button class=but onclick="quitGame();" value="Quit Game">&nbsp;</td>'
        + '<td width="33%" align=center><input style="width:120px" type=button class=but onclick="restartGame();" value="Restart Game">&nbsp;</td>'
        + '<td width="33%" align=right><!-- <input style="width:120px" type=button name=butPause class=but onclick="pauseGame();" value="Pause Game"> --></td>'
        + '</tr><tr><td height=6 colspan=4></td></tr>'
        + '<tr><td valign=center id=fldTime class=capt1 nowrap></td>'
        + '<td align=center valign=center id=fldMoves class=capt1 nowrap></td>'
        + '<td valign=center id=fldProgress class=base nowrap>'
        + '<span class=bar id=divProgressBar></span></td></tr></table>'

  board.innerHTML = s                    
  gdx = dx;
  gdy = dy;
}

function startDrag(obj)
{
  /*if (!gactive)
  {
    if (butPause.value == "Continue Game")
      alert("Press the 'Continue Game' button above to resume the game");
    else
      alert("Press the 'Restart Game' button to start a new game");

    return;
  }*/
  
  gsrcx = obj.style.pixelLeft;
  gsrcy = obj.style.pixelTop;
  gcurrobjid=obj.id;    
  obj.style.zIndex = 1; //make topmost layer
  gdragging=true;
}

function move()
{
  var obj,a;
  
  if (!gactive) return;
  if (!gdragging) return;

  obj = eval(gcurrobjid);
  a = getRowCol(obj)
  obj.style.pixelLeft = event.clientX - (parseInt(a[0])+1)*gdx + gdx/2 + document.body.scrollLeft - gleft;
  obj.style.pixelTop = event.clientY - (parseInt(a[1])+1)*gdy + gdy/2 + document.body.scrollTop - gtop;
}

function getPiece(row,col)
{
  return eval("a_" + col + "_" + row);
}

function getRow(obj)
{
  var a = obj.id.split('_');
  return parseInt(a[1]); 
}

function getCol(obj)
{
  var a = obj.id.split('_');
  return parseInt(a[2]);
}

function getRowCol(obj)
{
  var a = obj.id.split('_');
  return new Array(a[1],a[2]);
}

function getClipRow(col)
{
  return (col*gdx); 
}

function getClipCol(row)
{
  return (row*gdy); 
}

function getX(obj)
{
  return getClipRow(getRow(obj));
}

function getY(obj)
{
  return getClipCol(getCol(obj));
}

function showStatus(msg)
{
  fldStatus.innerHTML = msg;
}

//random number between 0 and hi
function r0(hi)
{
  return Math.floor((hi)*Math.random()); 
}

function shuffle()
{
  var i, j, divisionsX, divisionsY;
  
  divisionsX = selCols.value;
  divisionsY = selRows.value;
  
  showStatus('Loading Game... Please Wait!');
  for (i=0;i<divisionsY;i++)
    for (j=0;j<divisionsX;j++)
    {
      swapPieces(getPiece(i,j),getPiece(r0(divisionsY),r0(divisionsX)));
    }
  
  if (isWin()) shuffle(); //ensure that it is not already a won puzzle!
  showStatus('');
  showProgress();
}

function swapPieces(osrc,odest)
{
  var x1,y1,x2,y2,cx1,cy1,cx2,cy2;

  if (osrc == odest) return; //nothing to swap!
  
  x1 = osrc.style.pixelLeft;
  y1 = osrc.style.pixelTop;
  cx1 = getX(osrc);
  cy1 = getY(osrc);
  
  x2 = odest.style.pixelLeft;
  y2 = odest.style.pixelTop;
  cx2 = getX(odest);
  cy2 = getY(odest);

  //Calculate new co-ordinates 
  osrc.style.pixelLeft = x2 + (cx2 - cx1);
  osrc.style.pixelTop = y2 + (cy2 - cy1);
  odest.style.pixelLeft = x1 - (cx2 - cx1);
  odest.style.pixelTop = y1 - (cy2 - cy1);
}

function changePicture(lasturl)
{
  var picurl, locfile, re, defurl="http://",retval;

  stopPicTimer();
      
  if (selPic.value == "") return;
  if (selPic.value == "myurl")
  {
    if (lasturl != null) defurl = lasturl;
    picurl = prompt("Please enter a valid Picture URL (JPG,GIF,PNG,BMP)",defurl);
    if (picurl == null || picurl == "")
    {
      selPic.value = "";
      return;
    }
    re = /^http\:\/\/[\w/.-~?&\\%=]*\.(JPG|JPEG|GIF|PNG|BMP)$/i;
    if (re.test(picurl))
    {
      loadPicture(picurl);
    }
    else
    {
      //yes=6 no=7 cancel=2
      retval = VBMsgBox("HMMM. Looks like an invalid url !!\n\n" + picurl + "\n\nDo you really want to proceed with it?",3,"Invalid URL?");

      if (retval == 6) //yes button
        loadPicture(picurl);
      else if (retval == 2) //cancel button   
        changePicture(picurl); //prompt again
      else //no button
        selPic.value = "";
      return;
    }
  }
  else if (selPic.value == "localfile")
  {
    //locfile
    loadPicture(selPic.value);
  }
  else
  {
    loadPicture(selPic.value);
  }
}

//stops the game timer if it is running
function stopTimer()
{
  if (gintervalid != -1) 
  {
    clearInterval(gintervalid);
    gintervalid = -1;
  }
}

function stopPicTimer()
{
  if (gpicid != -1) 
  {
    clearInterval(gpicid);
    gpicid = -1;
  }
}

function quitGame()
{
	document.getElementById("startbutton").style.display = "block";
//  stopGame();
  stopTimer();
  gtime = 0;
  gmoves = 0;
  gactive = false;
  
  board.style.display = "none";
  board.innerHTML = "";
  divMain.style.display = "block";
  divInfo.style.display = "block";            
  divPic.style.display = "block";
//  butStart.disabled = true;
  //selPic.focus();
  showStatus('');
}

function showProgress()
{
  fldTime.innerHTML = "Time:&nbsp;" + gtime + "&nbsp;secs";
  fldMoves.innerHTML = "Moves:&nbsp;" + gmoves + "&nbsp;";
  fldProgress.title = "Percentage Solved: " + gprogress + "%";
  if (gprogress < 40)
  {
    divProgressBar.innerHTML = "";
    fldProgress.innerHTML = divProgressBar.outerHTML + "&nbsp;" + gprogress + "%";
  }
  else
  {
    fldProgress.innerHTML = divProgressBar.outerHTML;
    divProgressBar.innerHTML = gprogress + "%";
  }
  divProgressBar.style.width = gprogress + "%";
}

function startGame()
{
  document.getElementById("startbutton").style.display = "none";
  if (parseInt(selRows.value) * parseInt(selCols.value) < 4)
  {
    alert("Sorry. At least 4 pieces are needed for a proper jigsaw game!\n\n" +
          '     No. of Jigsaw Pieces = Rows X Cols\n\n' +
          "Please try increasing the 'Rows' and/or 'Cols'.");
    return;
  }
      
  stopTimer();
  stopPicTimer();
  gtime = 0;
  gmoves = 0;
  gactive = true;
    
  drawBoard() ;
  divMain.style.display = "none";    
  divInfo.style.display = "none"; 
  shuffle();
  tickTime();
  gintervalid = setInterval("tickTime()",1000);
  document.getElementById("spacertd").setAttribute("height",510);
}  

function tickTime()
{
  showProgress();
  gtime++;
}

function isWin()
{
  var i, j, divisionsX, divisionsY, obj,s="", prog=0;
  
  divisionsX = parseInt(selCols.value);
  divisionsY = parseInt(selRows.value);
  
  for (i=0;i<divisionsY;i++)
    for (j=0;j<divisionsX;j++)
    {
      obj = getPiece(i,j);
      if (obj.style.pixelLeft != 0 || obj.style.pixelTop != 0) prog++;
    }

  gprogress = 100 - Math.round((prog * 100.0) / (divisionsX * divisionsY));
  
  if (prog == 0) 
    return true;
  else
    return false;
}

function restartGame()
{
  stopTimer();
  gtime = 0;
  gmoves = 0;
  
  getPiece(0,0).style.clip = "rect(1," + gdx + "," + gdy + ",1)" ;
  shuffle();
  tickTime();
  gintervalid = setInterval("tickTime()",1000);
  //butPause.value = "Pause Game";
  //butPause.disabled = false;
  gactive = true;
}  

function pauseGame()
{
  /*if (butPause.value == "Pause Game" && gactive)
  {
    butPause.value = "Continue Game";
    gactive = false;
    stopTimer();
  }
  else
  {
    butPause.value = "Pause Game";
    gintervalid = setInterval("tickTime()",1000); //start the count again
    gactive = true;
  }*/
}

function checkSelection()
{
  var obj;
  switch (selPic.value)
  {
    case "":
      divURL.style.display = "none";
      divFile.style.display = "none";
      divPic.style.display = "none";
      butStart.disabled = true;
      //butLoad.disabled = true;
      gloaded = false;
    showStatus("<marquee width=300 loop=4>" +
               "Select a Picture for the Jigsaw Puzzle from the drop down above." +
               "</marquee>");
      break;
      
    case "myurl":
      divURL.style.display = "block";
      divFile.style.display = "none";
      divPic.style.display = "none";
      butStart.disabled = true;
      obj = document.getElementById("fldURL");
      //butLoad.disabled = (obj.value == "") ? true : false;
      gloaded = false;
      obj.select();
      obj.focus();
      showStatus("Type in the URL of the Picture you wish to<br>" + 
                  "play the Jigsaw Game with.<p>" +
                  "Press 'Load Picture' button when done.");
      break;
      
    case "localfile":
      divURL.style.display = "none";
      divFile.style.display = "block";
      divPic.style.display = "none";
      butStart.disabled = true;
      obj = document.getElementById("fldFile");
      //butLoad.disabled = (obj.value == "") ? true : false;
      gloaded = false;
      obj.select();
      obj.focus();
      showStatus("Type in the Path to a Picture file (JPG,GIF,BMP,PNG)<br>" +
                 "OR use the 'Browse' button to locate a file in your<br>" +
                 "machine or on a shared network drive.<p>" + 
                 "Press the 'Load Picture' button when done.");
      break;
      
    default:
      divURL.style.display = "none";
      divFile.style.display = "none";
      divPic.style.display = "none";
      butStart.disabled = true;
      //butLoad.disabled = false;
      //butLoad.focus();
      gloaded = false;
      selPic.disabled = true;
      checkPicture();
  }
}

function checkPicture()
{
  var picsrc, picurl, retval, re, re2;
  
  stopPicTimer();
  butStart.disabled = true;

  /*if (butLoad.value == "Cancel Loading")
  {
    selPic.disabled = false;
    butLoad.value = "Load Picture";  
    divPic.style.display = "none";
    showStatus("<marquee width=300 loop=4>" +
               "Select a Picture for the Jigsaw Puzzle from the drop down above." +
               "</marquee>");
    return;
  }*/
  
  switch (selPic.value)
  {
    case "":
      alert("Please select a Picture!");
      //selPic.focus();
      return;
      
    case "myurl":
      picsrc = document.getElementById("fldURL");
      picurl = picsrc.value;
      
      if (picurl == "" || picurl == "http://")
      {
        alert("Please enter the URL for the picture\nin the box provided.");
        picsrc.focus();
        return;
      }
      
      //See if it looks like a valid URL
      re = /^http[s]{0,1}\:\/\/[\w/.-~?&\\%=]*[\w]\.(JPG|JPEG|GIF|PNG|BMP)$/i;
      if (re.test(picurl)) //url ok
      {
        loadPicture(picurl);
      }
      else //url not looking ok. confirm with user on whether to proceed
      {
        //vbYes=6 vbNo=7 vbYesNo=4
        retval = VBMsgBox("HMMM. Looks like an invalid url !!\n\n" + picurl + 
                          "\n\nDo you really want to proceed with it?",4,
                          "Invalid URL?");

        if (retval == 6) //yes button
          loadPicture(picurl);
        else //no button
          return;
      }
      break;
      
    case "localfile":
      picsrc = document.getElementById("fldFile");
      picurl = picsrc.value;
      
      if (picurl == "")
      {
        alert("Please enter a valid full path to your picture file.\n\n" + 
              "Alternatively, use the 'BROWSE' button to select an image.");
        picsrc.focus();
        return;
      }
      
      //See if it looks like a valid URL
      re = /^[a-zA-Z]\:\\[^?><"|*:]*.(JPG|JPEG|GIF|PNG|BMP)$/i;
      re2 = /^\\\\[^?><"|*:]*.(JPG|JPEG|GIF|PNG|BMP)$/i;
      
      if (re.test(picurl) || re2.test(picurl)) //url ok
      {
        loadPicture(picurl);
      }
      else //url not looking ok. confirm with user on whether to proceed
      {
        //vbYes=6 vbNo=7 vbYesNo=4
        retval = VBMsgBox("HMMM. Looks like an invalid picture path !!\n\n"
                          + picurl + "\n\nDo you really want to proceed with it?",
                          4,"Invalid File?");

        if (retval == 6) //yes button
          loadPicture(picurl);
        else //no button
          return;
      }
      break;
            
    default:
      loadPicture("" + selPic.value);
  }
}

//enables/disables Load Picture button based on value in file or url fields
function checkValueChange(obj)
{
  /*if (event.propertyName == "value" && obj.value != "") 
    //butLoad.disabled = false;
  else
    //butLoad.disabled = true;*/
}

function init()
{
  var url,rows,cols,d,n,i;

  toggleHelp();

  var args = document.location.search;
  //args = "?url=d:\\jusgames\\car.jpg";
  if (args == "") return;
  
  var re = /\?url=(.*?)&rows=(.*?)&cols=(.*)/i;
  var resmall = /\?url=(.*)/i;
  
  if (re.exec(args) == null) 
  {
    if (resmall.exec(args) == null) return;
  }

  url = RegExp.$1;
  rows = parseInt(RegExp.$2);
  if (isNaN(rows) || rows < 1 || rows > 12) rows = 4;
  cols = parseInt(RegExp.$3);
  if (isNaN(cols) || cols < 1 || cols > 12) cols = 4;
  selRows.value = rows;
  selCols.value = cols;
  loadPicture(url);
  //a cached picture can start an immediate game
    setTimeout("if (pic.readyState == 'complete') startGame();",3000);
}
