var adj = new Array();

function initAdjacency(adjList) {
  function trueMap(s) {
    var m = new Array();
    for (var i = 0; i < s.length; i++) {
      m[s[i]] = true;
    }
    return m;
  }

  for (var i = 0; i < adjList.length; i++) {
    x = adjList[i].split(" ");
    y = trueMap(x);
    for (var j = 0; j < x.length; j++) {
      adj[x[j]] = y;
    }
  }
}

function map(coords, href) {
  if (!adj[href]) return "";
  return "<area shape='rect' coords='" + coords + "' " +
    "href='javascript:click(\"" + href + "\")' id='" + href + "'>";
}

function xy(x0, y0, xC, yC, w, h, i) {
  var x = (x0 + xC * i);
  var y = (y0 + yC * i);
  return x + "," + y + "," + (x + w) + "," + (y + h);
}

function initMap(minus, plus, pins, n) {
  document.writeln("<map name='map'>");
  document.writeln(map(minus, "-"));
  document.writeln(map(plus, "+"));

  for (var j = 0; j < pins.length; j++) {
    var data = pins[j].split(",");
    var label = data[0];
    var x  = parseInt(data[1], 10);
    var y  = parseInt(data[2], 10);
    var x1 = parseInt(data[3], 10);
    var y1 = parseInt(data[4], 10);
    var x2 = parseInt(data[5], 10);
    var y2 = parseInt(data[6], 10);
    var w  = parseInt(data[7], 10);
    var h  = parseInt(data[8], 10);
    var c  = parseInt(data[9], 10);

    for (var i = 1; i <= n; i++) {
      document.writeln(map(xy(x + x1, y, c, 0, w, h, i - 1), label + "N" + i));
      document.writeln(map(xy(x + x1, y + y2, c, 0, w, h, i - 1), label + "S" + i));
      document.writeln(map(xy(x, y + y1, 0, c, h, w, i - 1), label + "W" + i));
      document.writeln(map(xy(x + x2, y + y1, 0, c, h, w, i - 1), label + "E" + i));
    }
  }
  document.writeln("</map>");
}

var node;
var stack;
var playing;
var log;
var maze = document.getElementById("maze");
var arrow = " => ";

var cursorImage = document.images[0];
var cursorDy = maze.vspace - cursorImage.height / 2;
var cursorDx = maze.hspace - cursorImage.width / 2;

function updateCursor() {
  var coords = document.getElementById(node).coords.split(",");
  var x = (parseInt(coords[0],10) + parseInt(coords[2],10)) / 2;
  var y = (parseInt(coords[1],10) + parseInt(coords[3],10)) / 2;
  document.getElementById("cursor").style.top = y + cursorDy;
  document.getElementById("cursor").style.left = x + cursorDx;
}

function addLog() {
  log += (node + '|' + stack) + "\n";
  document.theform.log.value = log;
  updateCursor();
}

function clickPush(next, label) {
  node = 'X' + next.substring(1);
  stack = label + stack;

  log += (next + arrow);
  addLog();
}

function clickPop(next) {
  var label = stack.charAt(0);
  var newnode = label + next.substring(1);
  if (!adj[newnode]) {
    alert("Dead end!");
  } else {
    node = newnode;
    stack = stack.substring(1);

    log += (next + arrow);
    addLog();
  }
}

function click(next) {
  if (!playing) {
    return;
  }
  if (next == node) {
    return;
  }
  if (!adj[node][next]) {
    alert("No direct path to destination!");
  } else {
    var label = next.charAt(0);
    if (label == 'X') {
      clickPop(next);
    } else
    if (label >= 'A' && label < 'X') {
      clickPush(next, label);
    } else
    if (label == '+') {
      if (stack == "") {
        node = next;
        addLog();
        document.theform.log.value += outline(document.theform.log.value);
        playing = false;
      } else {
        alert("You need to reach the + at the top-most level!");
      }
    }
  }
}

function undo() {
  var lines = log.split("\n");
  if (lines.length <= 3) {
    restart();
    return;
  }
  var lastline = lines[lines.length - 3].split(arrow)[1];
  node = lastline.substring(0, lastline.indexOf("|"));
  stack = lastline.substring(lastline.indexOf("|") + 1);
  log = "";
  for (var i = 0; i < lines.length - 2; i++) {
    log += lines[i] + "\n";
  }
  document.theform.log.value = log;
  updateCursor();
  playing = true;
}

function restart() {
  log = "";
  node = "-";
  stack = "";
  playing = true;
  addLog();
}

function outline(s) {
  s = s.split("\n");
  var outline = "";
  var oldStack = "";
  for (var i = 1; i < s.length; i++) {
    var newStack = s[i].substring(s[i].indexOf('|') + 1);
    if (newStack.length > oldStack.length) {
      outline += newStack.charAt(0) + "(";
    } else
    if (newStack.length < oldStack.length) {
      outline = (outline + ")").replace("()", "");
    }
    oldStack = newStack;
  }
  return outline;
}
