/*
  Copyright (c) 2007 Peter Schlömer

  Released under the GNU General Public License (GPL), version 2. See
  LICENSE for the full text
*/

function RectCoord(x1,y1,x2,y2) {
  this.left = x1;
  this.top = y1;
  this.right = x2;
  this.bottom = y2;
}
function CircleCoord(x,y,r) {
  this.x = x;
  this.y = y;
  this.radius = r;
}
function PolyCoord(x,y,r) {
  this.points = Array();
}

function Area(shape) {
  if (shape=="rect") {
    this.shape = "rect";
    this.coords = new RectCoord(0,0,0,0);
  }
  else if (shape=="circle") {
    this.shape = "circle";
    this.coords = new CircleCoord(0,0,20);
  }
  else {
    this.shape = "poly";
    this.coords = new PolyCoord();
  }
  this.link = "";
  this.title = "";
}

function getEvent(e) {
  if (e) {
    return e;
  }
  else {
    return window.event;
  }
}

function eventGetX(e) {
  if (typeof(e.layerX)!="undefined") {
    return e.layerX - 1;
  }
  if (typeof(e.offsetX)!="undefined") {
    return e.offsetX - 1;
  }
  else {
    return e.x - 1;
  }
}

function eventGetY(e) {
  if (typeof(e.layerY)!="undefined") {
    return e.layerY - 1;
  }
  if (typeof(e.offsetY)!="undefined") {
    return e.offsetY - 1;
  }
  else {
    return e.y - 1;
  }
}

function eventGetButton(e) {
  if (typeof(e.which)!="undefined") {
    return e.which;
  }
  else {
    return e.button;
  }
}

function mouseEventClear() {
  var img = document.getElementById("img");
  img.onmousedown = null;
  img.style.cursor = "";
}

function mouseEventSet(func) {
  var img = document.getElementById("img");
  img.onmousedown = func;
  img.style.cursor = "crosshair";
}

function eventDummy(e) {
  return false;
}

function eventRect(e) {
  e = getEvent(e);
  var button = eventGetButton(e);
  if (button==1) {
    document.form.areaRectLeft.value = eventGetX(e);
    document.form.areaRectTop.value = eventGetY(e);
  }
  else {
    document.form.areaRectRight.value = eventGetX(e);
    document.form.areaRectBottom.value = eventGetY(e);
  }
  saveArea();
  return false;
}

function eventCircle(e) {
  e = getEvent(e);
  var button = eventGetButton(e);
  if (button==1) {
    document.form.areaCircleX.value = eventGetX(e);
    document.form.areaCircleY.value = eventGetY(e);
  }
  else {
    var a = (eventGetX(e) - parseInt(document.form.areaCircleX.value));
    var b = (eventGetY(e) - parseInt(document.form.areaCircleY.value));
    document.form.areaCircleRadius.value = Math.round(Math.sqrt(a*a + b*b));
  }
  saveArea();
  return false;
}

function eventPoly(e) {
  if (currentlyEditing != -1) {
    e = getEvent(e);
    area = areas[currentlyEditing];
    area.coords.points.push(eventGetX(e));
    area.coords.points.push(eventGetY(e));
    saveArea();
  }
}

function loadImage(url, name) {
  document.getElementById("img").src = url;
  imageName = name;
  checkImage();
}

function loadImageUrl() {
  loadImage(document.form.imageUrl.value, document.form.imageNameUrl.value);
}

function loadImageWiki() {
  loadImage("http://" + document.form.imageWiki.value + "/wiki/Special:Filepath?file=" + escape(document.form.imageNameWiki.value), document.form.imageNameWiki.value);
}

function checkImage() {
  var img = document.getElementById("img");
  clickMode = "";
  img.style.cursor = "";
  updateAreas();
  document.getElementById("image").style.display="";
  document.getElementById("edit").style.display="";
}

function newArea(shape) {
  var area = new Area(shape);
  area.shape = shape;
  areas.push(area);

  currentlyEditing = areas.length-1;
  updateAreas();
  editArea(currentlyEditing);
}

function updateAreas() {
  updateSelectArea();
  updateMap();
  updateResult();
}

function updateResult() {
  var arr = document.form.imageDescriptionPos;
  var imageDescriptionPos = arr[0].value;
  for (var i=1; i<arr.length; i++) {
    if (arr[i].checked) {
      imageDescriptionPos = arr[i].value;
      break;
    }
  }

  var result = Array();
  result.push("<imagemap>");
  result.push("Image:" + imageName + "|" + document.form.imageDescription.value);
  result.push("");
  for (var i=0; i<areas.length; i++) {
    var coords = areas[i].coords;
    var s = "";
    if (areas[i].shape=='rect') {
      s = coords.left + " " + coords.top + " " + coords.right + " " + coords.bottom;
    }
    else if (areas[i].shape=='circle') {
      s = coords.x + " " + coords.y + " " + coords.radius;
    }
    else {
      s = coords.points.join(" ");
    }
    result.push(areas[i].shape + " " + s + " [[" + areas[i].link + (areas[i].title ? "|" + areas[i].title : "") + "]]");
  }
  result.push("");
  result.push("desc " + imageDescriptionPos);
  result.push("</imagemap>");

  var preResult = document.getElementById("result");

  while (preResult.lastChild) {
    preResult.removeChild(preResult.lastChild);
  }

  for (var i=0; i<result.length; i++) {
    preResult.appendChild(document.createTextNode(result[i]));
    preResult.appendChild(document.createElement("br"));
  }
}

function updateMap() {
  var preview = document.getElementById("preview");

  // Remove areas from map which are out of range
  for (var i=0; i<preview.childNodes.length; i++) {
    var child = preview.childNodes[i];
    var id = parseInt(child.id.substring(7));
    if (id>=areas.length) {
      preview.removeChild(child);
      i--;
    }
  }

  for (var i=0; i<areas.length; i++) {
    // Get existing DIV
    var area = areas[i];
    var div = document.getElementById("preview" + i);

    // If it does not exist exists, create a new one
    if (!div) {
      var div = document.createElement("div");
      div.id = "preview" + i;
      preview.appendChild(div);
    }

    if (area.shape == "rect") {
      var coords = area.coords;
      div.className = "previewRect";
      // Only if valid coordinates were given, draw
      if (coords.left<coords.right && coords.top<coords.bottom) {
        div.style.left = coords.left + "px";
        div.style.top = coords.top + "px";
        div.style.width = (coords.right - coords.left) + "px";
        div.style.height = (coords.bottom - coords.top) + "px";
      }
      else {
        div.style.left = "";
        div.style.top = "";
        div.style.width = "";
        div.style.height = "";
      }
    }
    else if (area.shape == "circle") {
      var coords = area.coords;
      div.className = "previewCircle";
      div.style.left = (coords.x - coords.radius) + "px";
      div.style.top = (coords.y - coords.radius) + "px";
      div.style.width = (coords.radius*2) + "px";
      div.style.height = (coords.radius*2) + "px";
    }
    else {
      // Determine maximum coordinates (this is how big the image is)
      var maxx = 0;
      var maxy = 0;
      var points = area.coords.points;
      for(var j=0; j<points.length; j+=2) {
        if (points[j]>maxx) maxx = points[j];
        if (points[j+1]>maxy) maxy = points[j+1];
      }
      div.className = "previewPoly";
      div.style.left = "0px";
      div.style.top = "0px";
      div.style.width = maxx + "px";
      div.style.height = maxy + "px";
    }
  }

  highlightMap();
}

function highlightMapCircle(div,radius,highlight) {
  var background;
  background = highlight ? "url('circle.php?active=1&radius=" + radius + "') no-repeat" : "url('circle.php?radius=" + radius + "') no-repeat";
  if (div.style.background != background) {
    div.style.background = background;
  }
}

function highlightMapPoly(div,points,highlight) {
  var background;
  background = highlight ? "url('poly.php?active=1&coords=" + points.join("|") + "') no-repeat" : "url('poly.php?coords=" + points.join("|") + "') no-repeat";
  if (div.style.background != background) {
    div.style.background = background;
  }
}

function highlightMap() {
  for (var i=0; i<areas.length; i++) {
    var div = document.getElementById("preview" + i);
    var area = areas[i];
    if (div && area) {
      if (area.shape == "rect") {
        div.style.background = (i==currentlyEditing) ? "red" : "black";
      }
      else if (area.shape == "circle") {
        highlightMapCircle(div,area.coords.radius,(i==currentlyEditing));
      }
      else {
        highlightMapPoly(div,area.coords.points,(i==currentlyEditing));
      }
    }
  }
}

function updateSelectArea() {
  var selectArea = document.form.area;

  while (selectArea.childNodes.length>0) {
    selectArea.removeChild(selectArea.lastChild);
  }

  for (var i=0; i<areas.length; i++) {
    var option = document.createElement("option");
    var area = areas[i];
      option.value = i;
    while (option.childNodes.length>0) {
      option.removeChild(option.lastChild);
    }
    var text = (area.title ? area.title : area.link) + " [" + area.shape + "]";
    option.appendChild(document.createTextNode(text));
    if (i == currentlyEditing) {
      option.selected = "selected";
    }
    selectArea.appendChild(option);
  }
}

function editArea(index) {
  document.getElementById("props").style.display = "none";

  var area = areas[index];

  if (area) {
    currentlyEditing = index;

    document.getElementById("props").style.display = "";
    document.getElementById("propsRect").style.display = "none";
    document.getElementById("propsCircle").style.display = "none";
    document.getElementById("propsPoly").style.display= "none";
    mouseEventClear();

    if (area.shape == "rect") {
      document.getElementById("propsRect").style.display= "";
      mouseEventSet(eventRect);
    }
    else if (area.shape == "circle") {
      document.getElementById("propsCircle").style.display= "";
      mouseEventSet(eventCircle);
    }
    else {
      document.getElementById("propsPoly").style.display= "";
      mouseEventSet(eventPoly);
    }

    document.form.areaLink.value = area.link;
    document.form.areaTitle.value = area.title;

    var coords = area.coords;
    if (area.shape == "rect") {
      document.form.areaRectLeft.value = coords.left;
      document.form.areaRectTop.value = coords.top;
      document.form.areaRectRight.value = coords.right;
      document.form.areaRectBottom.value = coords.bottom;
    }
    else if (area.shape == "circle") {
      document.form.areaCircleX.value = coords.x;
      document.form.areaCircleY.value = coords.y;
      document.form.areaCircleRadius.value = coords.radius;
    }
    else {
      var propsPolyCoords = document.getElementById("propsPolyCoords");
      if (propsPolyCoords.childNodes.length > 0) propsPolyCoords.removeChild(propsPolyCoords.lastChild);
      propsPolyCoords.appendChild(document.createTextNode(area.coords.points.join(", ")));
    }

    highlightMap();
  }
}

function deletePolyCoords() {
  areas[currentlyEditing].coords.points = Array();
  saveArea();
}

function saveArea() {
  var area = areas[currentlyEditing];
  area.link = document.form.areaLink.value;
  area.title = document.form.areaTitle.value;

  var coords = area.coords;
  if (area.shape=="rect") {
    coords.left = parseInt(document.form.areaRectLeft.value);
    coords.top = parseInt(document.form.areaRectTop.value);
    coords.right = parseInt(document.form.areaRectRight.value);
    coords.bottom = parseInt(document.form.areaRectBottom.value);
  }
  else if (area.shape=="circle") {
    if (parseInt(document.form.areaCircleRadius.value) < 0) document.form.areaCircleRadius.value = 0;
    coords.x = parseInt(document.form.areaCircleX.value);
    coords.y = parseInt(document.form.areaCircleY.value);
    coords.radius = parseInt(document.form.areaCircleRadius.value);
  }
  else {
    var propsPolyCoords = document.getElementById("propsPolyCoords");
    if (propsPolyCoords.childNodes.length > 0) propsPolyCoords.removeChild(propsPolyCoords.lastChild);
    propsPolyCoords.appendChild(document.createTextNode(coords.points.join(", ")));
  }

  updateAreas();
}

function deleteArea() {
  mouseEventClear();
  areas.splice(currentlyEditing,1);
  if (currentlyEditing>=areas.length) {
    currentlyEditing = areas.length-1;
  }
  updateAreas();
  editArea(currentlyEditing);
}

function importLines() {
  var text = document.form.importText.value;
  var lines = text.split("\n");

  for (var i=0; i<lines.length; i++) {
    var rectMatch = /rect +(\d+) +(\d+) +(\d+) +(\d+) +\[\[([^|]*)(|(.*))?\]\]/i;
    var circleMatch = /circle +(\d+) +(\d+) +(\d+) +\[\[([^|]*)(|(.*))?\]\]/i;
    var polyMatch = /poly +(.*?) +\[\[([^|]*)(|(.*))?\]\]/i;

    var line = lines[i];

    if (rectMatch.test(line)) {
      var results = rectMatch.exec(lines[i]);
      var area = new Area("rect");
      area.coords.left = results[1];
      area.coords.top = results[2];
      area.coords.right = results[3];
      area.coords.bottom = results[4];
      area.link = results[5];
      if (results[6]) area.title = results[6].substring(1);
      areas.push(area);
    }
    else if (circleMatch.test(line)) {
      var results = circleMatch.exec(lines[i]);
      var area = new Area("circle");
      area.coords.x = results[1];
      area.coords.y = results[2];
      area.coords.radius = results[3];
      area.link = results[4];
      if (results[5]) area.title = results[5].substring(1);
      areas.push(area);
    }
    else if (polyMatch.test(line)) {
      var results = polyMatch.exec(lines[i]);
      var area = new Area("poly");
      area.coords.points = results[1].replace(/ +/," ").split(" ");
      area.link = results[2];
      if (results[3]) area.title = results[3].substring(1);
      areas.push(area);
    }
  }

  updateAreas();
}

function getLanguage() {
  var href = window.location.href;
  var langMatch = /\?(..)$/;
  if (langMatch.test(href)) {
    var match = langMatch.exec(href);
    return match[1].toLowerCase();
  }
  else {
    return "en";
  }
}

function switchLanguage(node, language) {
  if (language) {
    for (var i=0; i<node.childNodes.length; i++) {
      var child = node.childNodes[i];
      if (child.lang) {
        if (child.lang == language) {
          child.style.display = "";
        }
        else {
          child.style.display = "none";
        }
      }
      switchLanguage(child, language);
    }
  }
}

function init() {
  // Change language
  switchLanguage(document, getLanguage());

  // Hide main part of page
  document.getElementById("content").style.display = "";

  // Internet Explorer
  if (typeof(navigator.userAgent) != "undefined" && navigator.userAgent.match('/MSIE/')) {
    // Internet Explorer needs different behaviour of the DIV containing
    // the preview to work properly.
    document.getElementById("previewContainer").style.overflow = "none";
  }

  // If setting oncontextmenu (needed for Firefox & co.)
  try {
    document.getElementById("img").oncontextmenu = eventDummy;
  }
  catch (e) {
  }
}

var imageName = '';
var areas = Array();
var currentlyEditing = -1;
