
<!--
//global configuration (change these to alter the position of the playing board)
var gtop = 200; //168;          //constant denotes top of board
var gleft = 10;          //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><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 reposition()
{
  var osrc,odest,x1,y1,x2,y2,cx1,cy1,cx2,cy2,s;

  if (!gactive) return;
  if (!gdragging) return;
  gdragging = false;
  
  osrc = eval(gcurrobjid);
  osrc.style.zIndex = 0;

  osrc.style.display = "none";
  odest = document.elementFromPoint(event.clientX,event.clientY)
  osrc.style.display = "block";  
  
  if (!osrc) return;
  osrc.style.pixelLeft = gsrcx;
  osrc.style.pixelTop = gsrcy;

  a = odest.id.replace('p','a');
  if (a.substr(0,2) != "a_") return;
  odest = eval(a);
  if (!odest) return;
  
  swapPieces(osrc,odest);
  
  gmoves++;
  
  showProgress();
  
  if (isWin())
  {  
    gactive = false;
    butPause.disabled = true;
    stopTimer();
    showProgress(); //needed because isWin() may update the status
    getPiece(0,0).style.clip = "rect(auto)"; //show the full image
    
    //vbYesNo=4 vbYes=6 vbNo=7
    if (6 == VBMsgBox('!!  C  O  N  G  R  A  T  S  !!\n\n' +
      'You did it in ' + gmoves + ' moves and ' + gtime + ' secs!\n\n'
                + 'Do you wish to play it again?',4,"Game Over!") )
      restartGame();
  }
}

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()
{
//  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()
{
  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);
}  

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("jigsaw/" + 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);
}
//-->