"use strict";

var logger = require('../logger');
var AbstractCustomMap = require('./AbstractCustomMap');
var CustomMapOptions = require('./CustomMapOptions');
var TouchMap = require('./TouchMap');

/**
 * Constructor of a submap. Submaps are created on application start. But dialog
 * (popup window) is initialized on demand using init function.
 * 
 * @param customMap
 *          parent CustomMap
 * @param id
 *          identifier of the submap
 */
function Submap(customMap, model) {
  this.setCustomMap(customMap);

  AbstractCustomMap.call(this, model, new CustomMapOptions({
    map : null,
    hideDiV : customMap.getHideDiv(),
    overviewDiv : customMap.getOverviewDiv(),
    markerOptimization : customMap.isMarkerOptimization(),
    bigLogo : customMap.isBigLogo(),
    customTouchInterface : customMap.isCustomTouchInterface(),
    project : null
  }));

  this.initialized = false;
}

// implementation of object inheritance
Submap.prototype = Object.create(AbstractCustomMap.prototype);
Submap.prototype.constructor = Submap;

/**
 * This method initializes submap with gui component. Before this point submap
 * is created and contains data, but cannot be visualized in the broswer.
 * 
 * @param htmlTag
 *          html div tag where google map should be placed
 * @param jsVar
 *          javascript component of primefaces popup dialog where submap will be
 *          visualized
 */
Submap.prototype.init = function(htmlTag, jsVar) {
  logger.debug("Initializing gui: " + this.getId());

  if (jsVar.submapControler !== undefined) {
    throw "Submodel with " + this.getId()
        + " cannot be created, because provided dialog window already has associated submodel";
  } else {
    this.htmlTag = htmlTag;
    this.jsVar = jsVar;

    this.initialized = true;

    var doc = htmlTag;
    var childDiv = null;
    for (var i = 0; i < doc.childNodes.length; i++) {
      if (doc.childNodes[i].className.indexOf("ui-dialog-content") >= 0) {
        childDiv = doc.childNodes[i];
      }
    }

    var controlDiv = document.createElement('div');
    controlDiv.id = "submap-gmap-div-" + this.getId();
    controlDiv.style.height = '100%';
    controlDiv.style.width = '100%';

    childDiv.appendChild(controlDiv);
    childDiv.style.height = '100%';
    childDiv.style.width = '100%';

    var mapOptions = this.creatMapOptions(this.configuration.MAPS.length);

    this.setGoogleMap(new google.maps.Map(controlDiv, mapOptions));
    if (this.isCustomTouchInterface()) {
      this._touchInterface = new TouchMap(this);
    }
    this.setupLayouts();

    var self = this;
    self.lastResize = 0;

    jQuery(htmlTag).bind("resize", function() {
      var timestamp = new Date().getTime();
      if (timestamp > self.lastResize) {
        self.lastResize = timestamp + 200;
        setTimeout(function() {
          google.maps.event.trigger(self.getGoogleMap(), 'resize');
          self.lastResize = Math.min(new Date().getTime(), self.lastResize);
        }, 100);
      }
    });

    htmlTag.style.width = Math.floor(window.innerWidth * 2 / 3) + "px";
    htmlTag.style.height = Math.floor(window.innerHeight * 2 / 3) + "px";
    google.maps.event.trigger(self.getGoogleMap(), 'resize');

    jsVar.submapControler = this;

    this.registerMapClickEvents();

    // after resizing center map
    var centerPoint = new google.maps.LatLng(this.configuration.CENTER_LAT, this.configuration.CENTER_LNG);
    self.getGoogleMap().setCenter(centerPoint);

    // and now send the zoom level to the client side
    google.maps.event.addListener(this.getGoogleMap(), 'zoom_changed', function() {
      ServerConnector.setModelZoomLevel(self.getId(), self.getGoogleMap().getZoom());
    });

    ServerConnector.setModelZoomLevel(self.getId(), self.getGoogleMap().getZoom());
  }

};

Submap.prototype.openLayout = function(identifier) {
  if (this.initialized) {
    this.getGoogleMap().setMapTypeId(identifier);
  }
};

Submap.prototype.loadSubmapConfiguration = function() {
  var self = this;
  var onConfigurationReload = function() {
    var submodelFound = false;
    for (var i = 0; i < self.customMap.configuration.SUBMODELS.length && (!submodelFound); i++) {
      if (self.customMap.configuration.SUBMODELS[i].getId() === self.getId()) {
        self.configuration = self.customMap.configuration.SUBMODELS[i];
        submodelFound = true;
      }
    }
    if (!submodelFound) {
      throw "Cannot find configuration for submodel " + self.getId();
    }
    logger.debug("Submodel config reloaded: " + self.getId());
  };

  onConfigurationReload();
  this.customMap.configuration.addListener("onreload", onConfigurationReload);
};

Submap.prototype.getTopMap = function() {
  return this.customMap;
};

Submap.prototype.getCustomMap = function() {
  return this._customMap;
};

Submap.prototype.setCustomMap = function(customMap) {
  this._customMap = customMap;
};

module.exports = Submap;