/*
   copyright (c) 2006, keith drakard
   this program is distributed under the terms of the creative commons
   license at http://creativecommons.org/licenses/by-nc-sa/2.0/
*/

  // ############### init stuff ###################################
  // get player options or set to default
  var passed= window.location.search.substring(1);
  var maxdiscs= getParm(passed,'d')- 0; if (maxdiscs==0) maxdiscs=4;

  // globals
  var running= 1; var solving= 0; var selected= 0;
  var moves= 0; var minimum= Math.pow(2, maxdiscs)- 1;

  function preload() {
    if (document.images) {
      disc= new makeArray(maxdiscs+3);
         disc[0].src= "/wp-content/scripts/images/hanoi/segment.gif";
         for (i= 1; i<= maxdiscs; i++) {
           disc[i].src= "/wp-content/scripts/images/hanoi/towers"+i+".gif";
         }
         disc[maxdiscs+1].src= "/wp-content/scripts/images/hanoi/top.gif";
         disc[maxdiscs+2].src= "/wp-content/scripts/images/hanoi/bottom.gif";

    } else {
      alert("Sorry, this game needs to run on a browser\nwhich supports the image object.");
    }
  }


  // ############### playing stuff ################################
  function select(x) {
    // just a dummy function
    if (running && !solving) play(x);
  }

  function play(x) {

    // what have we clicked on?
    y= disc_below(x)+1; sel= is_disc(x,y);

    // do we already have a disc selected?
    if (selected) {

      // yes we do... is this disc the same one or
      //              have we clicked on the same pole?
      if (sel== selected || (document.images["x"+x+"y0"].src==disc[selected].src)) {

        // why yes it is... so drop the selected disc and ignore the move:
        document.images["x"+x+"y"+disc_below(x)].src= disc[selected].src;
        document.images["x"+x+"y0"].src= disc[0].src;
        selected= 0;

      } else {

        // okay, it's a different pole, so try to drop the selected disc:

        // is the disc below smaller than this one?
        if (y== maxdiscs+1 || (is_disc(x,y)> selected)) {

          // yep... so put it there and deselect it:
          document.images["x"+x+"y"+(y-1)].src= disc[selected].src;
          for (i=0; i<3; i++) { document.images["x"+i+"y0"].src= disc[0].src; }
          selected= 0; moves++; document.user.moves.value= moves;

          // is the game over now?
          if (y== 2 && x!=0) {
            // yes, so work out the moves and say well done:
            diff= moves- minimum; running= 0;
            if (!solving) alert("Congratulations!\n\nYou took "+moves+" moves,\n"+diff+" over the minimum.");
                     else solving= 0;
          }

        } else {

          // nope... can't drop it here
          alert("You cannot drop a bigger disc\non top of a smaller one.");
        }
      }

    } else {

      // no disc selected... so whichever pole we clicked on, lift the top disc:

      // does it exist?
      if (sel) {

        // yes... so select the disc and lift it:
        selected= sel;
        document.images["x"+x+"y"+y].src= disc[0].src;
        document.images["x"+x+"y0"].src= disc[selected].src;
      }
    }
  }

  function is_disc(x,y) {
    if (y<0 || y>maxdiscs) return(0);

    var clicked_on= document.images["x"+x+"y"+y].src;
    if (clicked_on== disc[0].src)
      { return(0); }
    else
      { for (i=1; i<=maxdiscs; i++) {
          if (clicked_on== disc[i].src) return(i);
        }
      }
    alert("Whoops... something has gone wrong in: is_disc()");
    return(0);
  }

  function disc_below(x) {
    j= 1; while (!is_disc(x,j) && j<=maxdiscs) {
      j++;
    } j--;
    return(j);
  }


  // ############### solving stuff ################################
  function solve() {

    // quick'n'dirty way of stopping NS3 from screwing up -
    // it's those setTimeouts which are doing it; the demo would
    // work with NS3 (and any other browser this fails on), but
    // you just need to implement the timeouts better...

    if (parseInt(navigator.appVersion)< 4) {
      alert("Sorry, the demo will not work properly on your browser.");

    } else if (!solving) {
      newgame();                // reset the board
      move(maxdiscs, 0, 1, 2);  // and start solving
    }
  }

  function move(n, A, B, C) {
    // number to move, source pole, spare pole and destination pole

    // solve the puzzle recursively - see practically any
    // mathematical treatment of "ToH" for more details & methods.

    if (n!=0) {
      move(n-1, A, C, B);
      setTimeout("play("+A+")", solving* 300);
      setTimeout("play("+C+")", solving* 300);
      move(n-1, B, A, C);
    }
    solving++;

    // if you don't like recursion, you might like to try this method:
    // on odd-numbered moves, move the smallest disc clockwise
    // on even-numbered moves, make the only _other_ move possible
  }


  // ############### miscellaneous stuff ##########################
  function newgame() {
    if (solving) alert("Please wait for the demo to finish\nor refresh your browser.");
    else {

    var index= document.user.noofdiscs.selectedIndex;
    var tmp_d= document.user.noofdiscs.options[index].value;

    if (tmp_d!= maxdiscs) {
      // options have changed so we need to redraw the page
      window.location.href= "?d="+tmp_d;

    } else {
      // same options so just reset the board
      for (y=0; y<=maxdiscs; y++) {
        for (x=0; x<3; x++) {
          d= (x==0) ? y : 0
          document.images["x"+x+"y"+y].src= disc[d].src;
        }
      }
      running= 1; solving= 0; selected= 0;
      moves= 0; document.user.moves.value= moves;
    }

    }
  }

  // The following functions were written by Martin Webb at http://www.irt.org/
  function makeArray(n) {
    this.length= n; for (i=0; i<n; i++) { this[i]= new Image(); }
    return this;
  }
  function getParm(string,parm) {
    var startPos= string.indexOf(parm+"=");
    if (startPos> -1) {
      startPos= startPos+ 2;
      var endPos= string.indexOf("&",startPos);
      if (endPos== -1) endPos= string.length;
      return unescape(string.substring(startPos,endPos));
    }
    return '';
  }



function initialise() {

  var output= '';
  output+= '<table align=center cellspacing=6 cellpadding=6 border=0>\n';

  // create the board
  output+= '<tr><td align=center bgcolor="#000000"><table cellspacing=0 cellpadding=0 border=0>\n';
  output+= '<tr>';
  for (i=0; i<3; i++) {
     output+= '<td><a href="javascript:select('+i+')" onFocus="blur();">';
     output+= '<img src="/wp-content/scripts/images/hanoi/top.gif" width=150 height=30 alt="" border=0></td>';
  }
  output+= '</tr>';
  output+= '<tr>';
  for (i=0; i<3; i++) {
    output+= '<td><a href="javascript:select('+i+')" onFocus="blur();">';
    output+= '<img src="/wp-content/scripts/images/hanoi/segment.gif" name="x'+i+'y0" width=150 height=30 alt="" border=0></td>';
  }
  output+= '</tr>';

  for (y=1; y<=maxdiscs; y++) {
    for (x=0; x<3; x++) {
      if (x==0) output+= '<tr>';
      output+= '<td><a href="javascript:select('+x+')" onDblClick="select('+x+')" onFocus="blur();"><img src=';
      output+= (x==0) ? '"/wp-content/scripts/images/hanoi/towers'+y+'.gif"' : '"/wp-content/scripts/images/hanoi/segment.gif"'
      output+= ' name="x'+x+'y'+y+'" width=150 height=30 alt="" border=0></td>';
      if (x==2) output+= '</tr>';
    }
  }

  output+= '<tr>';
  for (i=0; i<3; i++) {
    output+= '<td><a href="javascript:select('+i+')" onFocus="blur();">';
    output+= '<img src="/wp-content/scripts/images/hanoi/bottom.gif" width=150 height=30 alt="" border=0></td>';
  }
  output+= '</tr><tr><td colspan=3>&nbsp;</td></tr>';

  output+= '<form name="user"><tr><td align=center>';
  output+= '<br><br><select name="noofdiscs" size=1>';
  for (i= 3; i<=8; i++) {
    output+= '<option value="'+i+'"';
    if (i==maxdiscs) output+= ' selected';
    output+= '>'+i;
  }
  output+= '</select> discs<br>&nbsp;</td><td align=center><br><br><input style="width:5em" type="text" name="moves" size="3"';
  output+= ' value=0 onFocus="blur();"> moves<br>&nbsp;</td><td align=center><br><br><input type="button"';
  output+= ' value=" New Game " onClick="newgame()"><br>&nbsp;</td></tr>';
  output+= '<tr><td colspan=3 align=center><input type="button" value=" Demo Solution "';
  output+= ' onClick="solve()"></td></tr></form>';

  output+= '</table></td></tr>';

  output+= '</table>\n';

  document.write(output);
  preload();

}