"use strict";

/* exported logger */

var AbstractGuiElement = require('./AbstractGuiElement');
var GuiConnector = require('../GuiConnector');

var functions = require('../functions');
var logger = require('../logger');

function OverviewDialog(params) {
  AbstractGuiElement.call(this, params);
  var self = this;
  $(self.getElement()).dialog({
    autoOpen : false,
    resizable : false,
  });
}

OverviewDialog.prototype = Object.create(AbstractGuiElement.prototype);
OverviewDialog.prototype.constructor = OverviewDialog;

OverviewDialog.prototype.showOverview = function(overviewImageId) {
  var self = this;
  var map = self.getMap();

  var project = map.getProject();

  // resize dialog
  var htmlTag = self.getElement();

  var width = Math.floor(window.innerWidth * 2 / 3);
  var height = Math.floor(window.innerHeight * 2 / 3);

  $(self.getElement()).dialog("option", "width", width + 60);
  $(self.getElement()).dialog("option", "height", height + 60);

  // remove all child nodes from overview div
  while (htmlTag.hasChildNodes()) {
    htmlTag.removeChild(htmlTag.lastChild);
  }

  var content = document.createElement("div");
  htmlTag.appendChild(content);

  var canvasDebug = document.createElement("canvas");
  canvasDebug.className = "canvasDebugClass";
  canvasDebug.style.display = "none";
  htmlTag.appendChild(canvasDebug);

  if (overviewImageId === undefined) {
    this.overviewImage = project.getTopOverviewImage();
  } else {
    this.overviewImage = null;
    var images = project.getOverviewImages();
    for (var i = 0; i < images.length; i++) {
      if (images[i].idObject === overviewImageId) {
        this.overviewImage = images[i];
      }
    }

    if (this.overviewImage === null) {
      logger.warn("Unknown overview image with id = " + overviewImageId);
      this.overviewImage = project.getTopOverviewImage();
    }
  }

  // add image to overview div
  this.overviewImageTag = document.createElement("IMG");
  this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename;
  content.appendChild(this.overviewImageTag);

  var ratio = 1.0;

  // check how image should be resized to fit dialog and resize it manually!!!
  if (width / this.overviewImage.width > height / this.overviewImage.height) {
    this.overviewImageTag.style.height = height + "px";
    ratio = height / this.overviewImage.height;
    width = this.overviewImage.width * ratio;
    $(self.getElement()).dialog("option", "width", width + 60);
  } else {
    this.overviewImageTag.style.width = width + "px";
    ratio = width / this.overviewImage.width;
    height = this.overviewImage.height * ratio;
    $(self.getElement()).dialog("option", "height", height + 60);
  }

  // on click event (what should happen when we click on the image)
  var onclickevent = function getClickPosition(e) {
    var parentPosition = functions.getPosition(e.currentTarget);
    var xPosition = e.clientX - parentPosition.x;
    var yPosition = e.clientY - parentPosition.y;

    var imgWidth = self.overviewImageTag.offsetWidth;

    var currentRatio = imgWidth / self.overviewImage.width;

    var xNormal = xPosition / currentRatio;
    var yNormal = yPosition / currentRatio;
    var point = {
      x : xNormal,
      y : yNormal
    };

    var link = null;
    for (var i = 0; i < self.overviewImage.links.length; i++) {
      if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) {
        if (link === null) {
          link = self.overviewImage.links[i];
        } else {
          logger.warn("More than one link found. Skipping");
        }
      }
    }
    if (link !== null) {
      self.openLink(link);
    }
  };

  this.overviewImageTag.onclick = onclickevent;

  // resize canvas where on mouse over highligh will appear

  // in debug mode draw clickable shapes
  if (map.isDebug()) {
    canvasDebug.style.display = "";
    canvasDebug.width = width;
    canvasDebug.height = height;
    canvasDebug.onclick = onclickevent;
    this.drawClickableShapes(canvasDebug, ratio);
  }

  this.overviewImage.mousePos = {
    x : 0,
    y : 0
  };

  // this listener should be called when mouse moves over image, it purpose is
  // to change coursor to pointer when mouse enters clickable polygon and back
  // to normal when mouse leaves such region
  var onmousemove = function getMouseOverPosition(e) {
    var position = functions.getPosition(e.currentTarget);
    position.x = e.clientX - position.x;
    position.y = e.clientY - position.y;

    var imgWidth = self.overviewImageTag.offsetWidth;

    var currentRatio = imgWidth / self.overviewImage.width;

    var xNormal = position.x / currentRatio;
    var yNormal = position.y / currentRatio;
    var point = {
      x : xNormal,
      y : yNormal
    };

    if (self.overviewImage.mousePos.x !== position.x || self.overviewImage.mousePos.y !== position.y) {
      self.overviewImage.mousePos = position;
      var link = null;
      for (var i = 0; i < self.overviewImage.links.length; i++) {
        if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) {
          link = self.overviewImage.links[i];
        }
      }
      if (link === null) {
        e.currentTarget.style.cursor = "auto";
      } else {
        e.currentTarget.style.cursor = "pointer";
      }
    }
  };

  // onmousemove listener should be assigned to canvas (which is on top of the
  // image) and overviewimage (just in case something went wrong with resizing
  // canvas)
  canvasDebug.onmousemove = onmousemove;
  this.overviewImageTag.onmousemove = onmousemove;

  $(self.getElement()).dialog("open");
};

OverviewDialog.prototype.openLink = function(link) {
  var self = this;
  var map = self.getMap();
  if (link.type === "OverviewModelLink") {
    logger.debug("Opening model from overview. ModelId: " + link.modelLinkId);
    logger.debug("link coordinates [" + link.idObject + "]: ", link.latLng);

    map.openSubmap(link.modelLinkId);
    var submap = map.getSubmapById(link.modelLinkId);
    submap.setCenter(link.latLng);
    submap.setZoom(link.zoomLevel + submap.getMinZoom());

    $(self.getElement()).dialog("close");
  } else if (link.type === "OverviewImageLink") {
    logger.debug("Opening image from overview. ImageId: " + link.imageLinkId);
    self.showOverview(link.imageLinkId);
  } else if (link.type === "OverviewSearchLink") {
    logger.debug("Sending search query. Query: " + link.query);
    GuiConnector.search(link.query);
    $(self.getElement()).dialog("close");
  } else {
    logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject);
  }
};

OverviewDialog.prototype.drawClickableShapes = function(canvas, ratio) {
  var ctx = canvas.getContext("2d");
  // clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (var i = 0; i < this.overviewImage.links.length; i++) {
    ctx.beginPath();
    var polygon = this.overviewImage.links[i].polygon;
    for (var j = 0; j < polygon.length; j++) {
      var x = polygon[j].x * ratio;
      var y = polygon[j].y * ratio;
      ctx.moveTo(x, y);
      x = polygon[(j + 1) % polygon.length].x * ratio;
      y = polygon[(j + 1) % polygon.length].y * ratio;
      ctx.lineTo(x, y);
    }
    ctx.stroke();
  }
};

OverviewDialog.prototype.destroy = function() {
  $(this.getElement()).dialog("destroy");
};

module.exports = OverviewDialog;