var answer = "solved.html";
var size = 4;
var magnify = 96;
var hole = size*size - 1;
var solution = "";
var is_solved = false;
var is_moving = false;
var move_fraction = 0.2,move_delay = 50;

var where,which;

if (document.layers)
  document.write("<div><ilayer name='box' width=387 height=387>");
else
  document.write("<div style='width: 387; height: 387; position: relative;'>");

for (var i = 0; i < size*size; ++i) {
  var name = "i" + i;
  if (document.layers)
    document.write("<layer id='",name,"' visibility='hidden'>");
  document.write("<a href='' onclick='on_click(",i,"); return false'>");
  document.write("<img border='0' width='",magnify,"' height='",magnify,"'");
  if (!document.layers) {
    document.write(" style='visibility: hidden; position: absolute'");
    document.write(" id='",name,"'");
  }
  document.write(" src='",i,".jpg'>");
  document.write("</a>");
  if (document.layers)
    document.write("</layer>");
}

if (document.layers)
  document.write("</ilayer>");
document.write("</div>");

function move(i,x,y) {
  var name = "i" + i;
  var gutter = is_solved ? 0 : 1;
  var offset = 2*(1 - gutter);
  x = offset + (gutter + magnify)*x + 0.25;
  y = offset + (gutter + magnify)*y + 0.25;
  if (document.layers) {
    var l = document.layers.box.layers[name];
    l.hidden = false;
    l.x = x;
    l.y = y;
  } else if (document.all) {
    var l = document.all[name];
    l.style.visibility = "visible";
    l.style.pixelLeft = x;
    l.style.pixelTop = y;
  } else {
    var l = document[name];
    l.style.visibility = "visible";
    l.style.left = x + "px";
    l.style.top = y + "px";
  }
}

function draw() {
  for (var i = 0; i < size*size; ++i)
    if (is_solved || hole != i)
      move(i,where[i].x,where[i].y);
}

function test_solved() {
  if (which[size - 1][size - 1] == hole) {
    var test = 0,maxint = Math.pow(2,32);
    for (var y = 0; y < size; ++y) for (var x = 0; x < size; ++x)
      test = (101*test + which[x][y])%maxint;
    if (test == hash) {
      is_solved = true;
      draw();
      setTimeout('on_timeout()',5000);
    }
  }
}

function on_timeout() {
  location.href = answer;
}

function tozero(x) {
  if (x > 0) return x - 1;
  if (x < 0) return x + 1;
  return x;
}

function slide(f,x,y,dx,dy) {
  if (f + move_fraction > 1.0) {
    is_moving = false;
    while (0 != dx || 0 != dy) {
      var nx = tozero(dx);
      var ny = tozero(dy);
      var i = which[x + nx][y + ny];
      if (0 == dx) solution += (dy < 0) ? "N" : "S";
      if (0 == dy) solution += (dx < 0) ? "W" : "E";
      where[i].x = x + dx;
      where[i].y = y + dy;
      which[x + dx][y + dy] = i;
      move(i,x + dx,y + dy);
      dx = nx; dy = ny;
    }

    where[hole].x = x;
    where[hole].y = y;
    which[x][y] = hole;
    test_solved();
  } else {
    is_moving = true;
    setTimeout("slide("
      + (f + move_fraction) + ","
      + x + "," + y + ","
      + dx + "," + dy + ")",move_delay);
    while (0 != dx || 0 != dy) {
      var nx = tozero(dx);
      var ny = tozero(dy);
      move(which[x + nx][y + ny],x + nx + (dx - nx)*f,y + ny + (dy - ny)*f);
      dx = nx; dy = ny;
    }
  }
}

function on_click(i) {
  if (is_solved)
    on_timeout();
  else if (!is_moving && hole != i) {
    if (where[i].x == where[hole].x)
      slide(0,where[i].x,where[i].y,0,where[hole].y - where[i].y);
    else if (where[i].y == where[hole].y)
      slide(0,where[i].x,where[i].y,where[hole].x - where[i].x,0);
  }
}

function get_width() {
  if (window.innerWidth)
    return window.innerWidth;
  else
    return document.body.clientWidth;
}

function get_height() {
  if (window.innerHeight)
    return window.innerHeight;
  else
    return document.body.clientHeight;
}

function on_init() {
  where = new Array;
  which = new Array;
  for (var x = 0; x < size; ++x) {
    which[x] = new Array;
    for (var y = 0; y < size; ++y) {
      var i = size*y + x;
      where[i] = new Object;
      where[i].x = x;
      where[i].y = y;
      which[x][y] = i;
    }
  }

  draw();
}

function on_resize() {
  if (document.layers) {
    location.reload();
    return;
  }
}

onresize = on_resize;
onload = on_init;
