// Utility functions
function getAbsoluteLeft(o) {
  var oLeft = o.offsetLeft;       // Get left position from the parent object
  var oParent;
  var o;
  while(o.offsetParent!=null) {   // Parse the parent hierarchy up to the document element
    oParent = o.offsetParent      // Get parent object reference
    oLeft += oParent.offsetLeft   // Add parent left position
    o = oParent
  }
  return oLeft
}

function getAbsoluteTop(o) {
  var oTop = o.offsetTop;         // Get top position from the parent object
  var oParent;
  var o;
  while(o.offsetParent!=null) {   // Parse the parent hierarchy up to the document element
    oParent = o.offsetParent      // Get parent object reference
    oTop += oParent.offsetTop     // Add parent top position
    o = oParent
  }
  return oTop
}

/*
   inherited from GxMarker version 1.2
   http://code.toeat.com/packages/gxmarker

*/
function GxMarkerNamespace() {

var n4=(document.layers);
var n6=(document.getElementById&&!document.all);
var ie=(document.all);
var o6=(navigator.appName.indexOf("Opera") != -1);
var safari=(navigator.userAgent.indexOf("Safari") != -1);
var currentSpan = new GBounds();

function setCursor( container, cursor ) {
  try {
    container.style.cursor = cursor;
  }
  catch ( c ) {
    if ( cursor == "pointer" )
      setCursor("hand");
  }
};

/*
  the given tooltip html is wrapped in an unstyled div for display (none|block).
  styling informations must be provided in the given html (no implicit classes anymore).
*/
function GxMarker( a, b, tooltipHtml ) {
    this.inheritFrom = GMarker;
    this.inheritFrom(a,b);
    if ( !currentSpan.minX || a.x < currentSpan.minX ) currentSpan.minX = a.x;
    if ( !currentSpan.maxX || a.x > currentSpan.maxX ) currentSpan.maxX = a.x;
    if ( !currentSpan.minY || a.y < currentSpan.minY ) currentSpan.minY = a.y;
    if ( !currentSpan.maxY || a.y > currentSpan.maxY ) currentSpan.maxY = a.y;
    if ( typeof tooltipHtml != "undefined" ) {
        this.setTooltip( tooltipHtml );
    }
}

GxMarker.prototype = new GMarker(new GLatLng(1, 1));

GxMarker.prototype.setTooltip = function( string ) {
    this.removeTooltip();

    this.tooltip = new Object();
    // krob: quite ugly in our case
    this.tooltip.opacity = 100;
    this.tooltip.contents = string;
};

GxMarker.prototype.initialize = function( a ) {
    try {
      GMarker.prototype.initialize.call(this, a);
      // Setup the mouse over/out events (TODO: bindDom)
      GEvent.addListener(this, "mouseover", this.onMouseOver);
      GEvent.addListener(this, "mouseout", this.onMouseOut);
      this.map = a;
    } catch(e) {
		  console.error(e);
    }
}

GxMarker.prototype.setCursor = function( cursor ) {
    var c = this.iconImage;
    // Use the image map for Firefox/Mozilla browsers
    if ( n6 && this.icon.imageMap && !safari) {
        c = this.imageMap;
    }
    // If we have a transparent icon, use that instead of the main image
    else if ( this.transparentIcon && typeof this.transparentIcon != "undefined" ) {
        c = this.transparentIcon;
    }
}

GxMarker.prototype.remove = function( a ) {
    GMarker.prototype.remove.call(this);
    this.removeTooltip();
}

GxMarker.prototype.removeTooltip = function() {
  if ( this.tooltipElement ) {
    try {
      // krob: working on document
      document.body.removeChild(this.tooltipElement);
    } catch(e) {
      console.error(e);
    }
    this.tooltipElement = null;
  }
}

GxMarker.prototype.onInfoWindowOpen = function() {
    this.hideTooltip();
    GMarker.prototype.onInfoWindowOpen.call(this);
}

GxMarker.prototype.onMouseOver = function() {
    this.showTooltip();
    
    // krob: triggered only inline
    // GEvent.trigger(this, "mouseover");
};

GxMarker.prototype.onMouseOut = function() {
    this.hideTooltip();
    // krob: triggered only inline
    // GEvent.trigger(this, "mouseout");
};

GxMarker.prototype.showTooltip = function() {
  if ( this.tooltip ) {
    if ( !this.tooltipElement ) {
      var opacity = this.tooltip.opacity / 100;
      this.tooltipElement = document.createElement("div");
      this.tooltipElement.style.display    = "none";
      this.tooltipElement.style.position   = "absolute";
      this.tooltipElement.style.background = "#fff";
      this.tooltipElement.style.padding    = "0";
      this.tooltipElement.style.margin     = "0";
      this.tooltipElement.style.MozOpacity = opacity;
      this.tooltipElement.style.filter     = "alpha(opacity=" + this.tooltip.opacity + ")";
      this.tooltipElement.style.opacity    = opacity;
      this.tooltipElement.style.zIndex     = 50000;
      this.tooltipElement.innerHTML        = this.tooltip.contents;

      // krob: working on document
      document.body.appendChild(this.tooltipElement);
	  }

    markerPosition = calculateMarkerPosition(this.map, this.getPoint());
	  try {
  	  this.tooltipElement.style.top  = markerPosition.top  - ( this.getIcon().iconAnchor.y + 0 ) + "px";
  	  this.tooltipElement.style.left = markerPosition.left + ( this.getIcon().iconSize.width - this.getIcon().iconAnchor.x - 5 ) + "px";
      this.tooltipElement.style.display = "block";
	  } catch(e) {
		  console.error(e);
	  }
  }
}

function calculateMarkerPosition(map, markerLatLngPoint) {
  // krob: handle map movements
  gmapTopLeftLatLng = map.fromContainerPixelToLatLng(new GPoint(0,0));
  gmapTopLeftPixel  = map.fromLatLngToDivPixel(gmapTopLeftLatLng);
  myMarkerDivPixel  = map.fromLatLngToDivPixel(markerLatLngPoint);

  markerTop  = getAbsoluteTop(map.getContainer())  - gmapTopLeftPixel.y + myMarkerDivPixel.y;
  markerLeft = getAbsoluteLeft(map.getContainer()) - gmapTopLeftPixel.x + myMarkerDivPixel.x;

  return {top:markerTop, left:markerLeft};
}

GxMarker.prototype.hideTooltip = function() {
    if ( this.tooltipElement ) {
        this.tooltipElement.style.display = "none";
    }
}

function makeInterface(a) {
    var b = a || window;
    b.GxMarker = GxMarker;
}

makeInterface();
}


switch (Qype.environment) {
  case 'test': // fall thru
  case 'development':
    Qype.GOOGLE_MARKER_PNG = "/images/google_marker.png";
    Qype.GOOGLE_MARKER_GIF = "/images/google_marker.gif";
    Qype.GOOGLE_GREYED_MARKER_PNG = "/images/google_greyed_marker.png";
    Qype.GOOGLE_GREYED_MARKER_GIF = "/images/google_greyed_marker.gif";
    Qype.GOOGLE_JUMPER = "/images/google_active_jumper.gif";
    break;
  default:
    Qype.GOOGLE_MARKER_PNG = "http://assets0.qypecdn.net/images/google_marker.png";
    Qype.GOOGLE_MARKER_GIF = "http://assets0.qypecdn.net/images/google_marker.gif";
    Qype.GOOGLE_GREYED_MARKER_PNG = "http://assets0.qypecdn.net/images/google_greyed_marker.png";
    Qype.GOOGLE_GREYED_MARKER_GIF = "http://assets0.qypecdn.net/images/google_greyed_marker.gif";
    Qype.GOOGLE_JUMPER = "http://assets0.qypecdn.net/images/google_active_jumper.gif";
    break;
}

Qype.GOOGLE_MAP_MARKER_WIDTH  = 29;
Qype.GOOGLE_MAP_MARKER_HEIGHT = 37;


var QypeMap = {
  the_map: null,
  the_bounds: null,  

  map: function() {
    if (this.the_map == null) this.the_map = new GMap2($('gmap'));
    return this.the_map;
  },

  bounds: function() {
    if (this.the_bounds == null) this.the_bounds = new GLatLngBounds();
    return this.the_bounds;
  },

  init: function(mapControl, latitude, longitude, zoom) {
    if (mapControl == 'Small') {
      this.map().addControl(new GSmallMapControl());
      this.map().addControl(new GMapTypeControl(true));
      this.map().getContainer().style.overflow="hidden";
    } else if(mapControl == 'SmallZoom'){
      this.map().addControl(new GSmallZoomControl());
      this.map().getContainer().style.overflow="hidden";
    } else {
      this.map().addControl(new GLargeMapControl());
      this.map().addControl(new GMapTypeControl());
    }


    if(latitude && longitude && zoom){
      var center = new GLatLng(latitude, longitude)
      this.map().setCenter(center, zoom);
    }
    else{
      var center = new GLatLng(0, 0);
      this.map().setCenter(center);
    }

  },

  addYouAreHere: function(html, url, latitude, longitude) {
    var point = new GLatLng(latitude, longitude);
    this.map().addOverlay(this.createURHereMarker(point, html, url));

    this.bounds().extend(point);
  },

  setZoomAndCenter: function(level) {
    var center = this.bounds().getCenter();
    this.map().setCenter(center);
    this.map().setZoom(level);
  },


  addPlace: function(html, url, latitude, longitude, place_id, greyed, image) {
    var point = new GLatLng(latitude, longitude);
    if (image != undefined && image != '') {
      this.map().addOverlay(this.createBrandedMarker(point, html, url, image));
    } else {
      this.map().addOverlay(this.createMarker(point, html, url));
    }
    this.bounds().extend(point);
  },

  addGreyedPlace: function(html, url, latitude, longitude) {
    var point = new GLatLng(latitude, longitude);
    this.map().addOverlay(this.createGreyedMarker(point, html, url));

    this.bounds().extend(point);
  },

  addGreyedPlaceWithNumber: function(html, url, latitude, longitude, number) {
    var point = new GLatLng(latitude, longitude);
    this.map().addOverlay(this.createGreyedMarkerWithNumber(point, html, url, number));

    this.bounds().extend(point);
  },

  createURHereMarker: function(point, html, url) {
    var icon = new GIcon();
    icon.image = "http://assets0.qypecdn.net/images/icn_map_location.png";
    icon.iconSize = new GSize(33, 33);
    icon.iconAnchor = new GPoint(13, 22);
    icon.infoWindowAnchor = new GPoint(13, 22);

    var marker = new GxMarker(point, icon, html);

    return marker;
  },

  createMarker: function(point, html, url) {
    var icon = new GIcon();
    icon.image = Qype.GOOGLE_GREYED_MARKER_PNG;
    icon.printImage = Qype.GOOGLE_GREYED_MARKER_GIF;
    icon.mozPrintImage = Qype.GOOGLE_GREYED_MARKER_GIF;
    //icon.shadow = "/images/google_marker_shadow.png";
    icon.iconSize = new GSize(Qype.GOOGLE_MAP_MARKER_WIDTH, Qype.GOOGLE_MAP_MARKER_HEIGHT);
    icon.shadowSize = new GSize(Qype.GOOGLE_MAP_MARKER_WIDTH, Qype.GOOGLE_MAP_MARKER_HEIGHT);
    icon.iconAnchor = new GPoint(13, 34);
    icon.infoWindowAnchor = new GPoint(19, 21);

    var marker = new GxMarker(point, icon, html);

    if (url)
      GEvent.addListener(marker, "click", function() {
        window.location = url;
      });

    return marker;
  },

  createGreyedMarker: function(point, html, url) {
    var icon = new GIcon();
    icon.image = Qype.GOOGLE_MARKER_PNG;
    icon.printImage = Qype.GOOGLE_MARKER_GIF;
    icon.mozPrintImage = Qype.GOOGLE_MARKER_GIF;
    //icon.shadow = "/images/google_marker_shadow.png";
    icon.iconSize = new GSize(Qype.GOOGLE_MAP_MARKER_WIDTH, Qype.GOOGLE_MAP_MARKER_HEIGHT);
    icon.shadowSize = new GSize(Qype.GOOGLE_MAP_MARKER_WIDTH, Qype.GOOGLE_MAP_MARKER_HEIGHT);
    icon.iconAnchor = new GPoint(13, 34);
    icon.infoWindowAnchor = new GPoint(19, 21);

    var marker = new GxMarker(point, icon, html);

    if (url) GEvent.addListener(marker, "click", function() {
      window.location = url;
    });

    return marker;
  },

  createGreyedMarkerWithNumber: function(point, html, url, number) {
    var icon = new GIcon();
    icon.image = "http://assets0.qypecdn.net/images/google_greyed_marker_" + number + ".png";
    //icon.shadow = "/images/google_marker_shadow.png";
    icon.iconSize = new GSize(35, 29);
    icon.shadowSize = new GSize(35, 29);
    icon.iconAnchor = new GPoint(13, 28);
    icon.infoWindowAnchor = new GPoint(35, 29);

    var marker = new GxMarker(point, icon, html);

    if (url) GEvent.addListener(marker, "click", function() {
      window.location = url;
    });

    return marker;
  },

  createLturMarker: function(point, html, url) {
    var icon = new GIcon();
    icon.image = "http://assets0.qypecdn.net/images/ltur_marker.gif";
    icon.printImage = "http://assets0.qypecdn.net/images/ltur_marker.gif";
    icon.mozPrintImage = "http://assets0.qypecdn.net/images/ltur_marker.gif";
    icon.iconSize = new GSize(23, 28);
    icon.shadowSize = new GSize(23, 28);
    icon.iconAnchor = new GPoint(9, 28);
    icon.infoWindowAnchor = new GPoint(13, 22);

    var marker = new GxMarker(point, icon, html);

    if (url)
      GEvent.addListener(marker, "click", function() {
        window.location = url;
      });

    return marker;
  },

  createBrandedMarker: function(point, html, url, image) {
    var icon = new GIcon();
    icon.image = image;
    icon.printImage = image;
    icon.mozPrintImage = image;
    icon.iconSize = new GSize(23, 28);
    icon.shadowSize = new GSize(23, 28);
    icon.iconAnchor = new GPoint(9, 28);
    icon.infoWindowAnchor = new GPoint(13, 22);

    var marker = new GxMarker(point, icon, html);

    if (url)
      GEvent.addListener(marker, "click", function() {
        window.location = url;
      });

    return marker;
  },

  addDraggablePlace: function(latitude, longitude, geo_status_code, manually_chosen_location_status) {
    this.clear();
    var point = new GLatLng(latitude, longitude);
    var marker = new GMarker(point, {
      draggable: true
    });

    QypeMap.set_geo_coordinates(point, geo_status_code);

    GEvent.addListener(marker, "dragend", function() {
      point = marker.getPoint();
      QypeMap.set_geo_coordinates(point, manually_chosen_location_status);
    });

    this.map().addOverlay(marker);
    this.bounds().extend(point);
  },

  registerListeners: function(manually_chosen_location_status) {
    GEvent.addListener(this.map(), "click", function(marker, point){
      if (!marker) {
        status_to_set = manually_chosen_location_status;
        QypeMap.addDraggablePlace(point.lat(),point.lng(), status_to_set, manually_chosen_location_status);
        enableMarkerReset();
      }
    });
  },

  set_geo_coordinates: function(point, geo_status_code) {
    $('place_latitude').value = point.lat();
    $('place_longitude').value = point.lng();
    $('place_geo_status_code').value = geo_status_code;
  },

  setCenter: function(latitude, longitude, zoom) {
    this.map().setCenter(new GLatLng(latitude,longitude),zoom);
  },

  centerAndZoom: function() {
    var bounds = this.bounds();
    var center = bounds.getCenter();

    this.map().setCenter(center);
    var zoom = Math.min(this.map().getBoundsZoomLevel(this.bounds()), 15);
    this.map().setZoom(zoom);

  },

  clear: function() {
    this.map().clearOverlays();
    this.the_bounds = null;
  }
}

