/**
 * PropertiesMap instances handle a GoogleMap showing properties locations
 * and information, and can be configured to: display distinct (by number)
 * icons, group properties in clusters, and show a modal notice while loading
 * the map, limit the amount of zoom-ins to get to icons when clustering. 
 *
 * PropertiesMap requires the GoogleMaps API, MarkerClusterer, YUI Panel
 * and JQuery.
 *
 */

var DEFAULT_ZOOM = 11;
var INDEX_ICON_THRESHOLD = 20;
var CLUSTER_THRESHOLD = 20;
var CLUSTER_STYLE = { height: 53, width: 53,
                        url: "http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/images/m1.png"
};
var DEFAULT_CLICKS_TO_UNCLUSTER = 3;
var DEFAULT_SHOW_INFO_EVENT = 'mouseover'; /* or 'click' */
var DEFAULT_ICON_OPTIONS = { size: [34, 32],
                             shadowSize: [0, 0],
                             iconAnchor: [7, 6],
                             infoAnchor: [10, 25],
                             imageMap: [ 0,0, 34,0, 34,32, 0,32 ],
                             image: "/static/images/markers/single.png"
};
var INDEXED_ICON_OPTIONS = { size: [60, 50],
                             shadowSize: [0, 0],
                             iconAnchor: [20, 42],
                             infoAnchor: [18, 24],
                             imageMap: [ 0,0, 60,0, 60,50, 0,50 ]
};


// PropertiesMap class
function PropertiesMap(elementid, properties, latlng, opts) {
  options = opts || {};
  this.options = {
    index_icons: options.index_icons ||
                 properties.length > INDEX_ICON_THRESHOLD,
    cluster: options.cluster || properties.length > CLUSTER_THRESHOLD,
    clicks_to_uncluster: options.clicks_to_uncluster || DEFAULT_CLICKS_TO_UNCLUSTER,
    show_info_event: options.show_info_event || DEFAULT_SHOW_INFO_EVENT,
    wheelzoom: typeof options.wheelzoom != "undefined" ?
                                                  options.wheelzoom : true,
    show_waitpanel: typeof options.show_waitpanel != "undefined" ?
                                                  options.show_waitpanel : true
  };
  // Methods (internal)
  function zeroPad(num, count) {
    numZeropad = num + '';
    while(numZeropad.length < count) {
      numZeropad = "0" + numZeropad;
    }    return numZeropad;
  };
  function show_property_info(map, property) {
    this.openInfoWindowHtml(property.info);
  };
  function hide_property_info(map) {
    map.closeInfoWindow();
  }
  function hide_waitpanel(panel) {
    panel.hide();
  };
  var waitpanel_opts = { modal: true,
                         visible: true,
                         zindex: 4,
                         draggable: false,
                         fixedcenter: false,
                         xy: [$(window).width()/2 - 100, 400],
                         close: false };
  this.waitpanel = new YAHOO.widget.Panel("waitpanel", waitpanel_opts);
  this.waitpanel.setHeader('Please wait while loading results...');
  this.waitpanel.setBody('<img src="http://l.yimg.com/a/i/us/per/gr/gp/rel_interstitial_loading.gif" />');
  this.map = new GMap2(document.getElementById(elementid));
  this.map.setCenter(new GLatLng(latlng[0], latlng[1]), DEFAULT_ZOOM);
  
  this.map.addControl(new GMapTypeControl(),
                      new GControlPosition(G_ANCHOR_TOP_RIGHT,
                                           new GSize(10,10)));
  this.map.addControl(new GLargeMapControl());
  if (this.options.wheelzoom) {
    this.map.enableScrollWheelZoom();
  }
  if (this.options.show_waitpanel) {
    this.waitpanel.render(document.body);
    cbck = new GEvent.callbackArgs(marker, hide_waitpanel, this.waitpanel);
    GEvent.addListener(this.map, 'tilesloaded', cbck);
  }
  this.markers = [];
  this.icon = new GIcon(G_DEFAULT_ICON);
  icon_opts = this.options.index_icons ? INDEXED_ICON_OPTIONS
                                       : DEFAULT_ICON_OPTIONS;
  this.icon.iconSize = new GSize(icon_opts.size[0],
                                 icon_opts.size[1]);
  this.icon.shadowSize = new GSize(icon_opts.shadowSize[0],
                                   icon_opts.shadowSize[1]);
  this.icon.iconAnchor = new GPoint(icon_opts.iconAnchor[0],
                                    icon_opts.iconAnchor[1]);
  this.icon.infoWindowAnchor = new GPoint(icon_opts.infoAnchor[0],
                                          icon_opts.infoAnchor[1]);
  this.icon.imageMap = icon_opts.imageMap;
  if (!this.options.index_icons) {
    this.icon.image = icon_opts.image;
  }

  var markerIcon = this.icon;
  // Create markers
  for (var i=0; i<properties.length; i++) {
    var point = new GLatLng(properties[i].latitude, properties[i].longitude);
    if (this.options.index_icons) {
      var indexIcon = new GIcon(this.icon);
      indexIcon.image = "/static/images/markers/" + zeroPad(i+1, 3) + ".png";
      var marker = new GMarker(point, { icon: indexIcon });
    } else {
      var marker = new GMarker(point, { icon: markerIcon });  
    }    

    show_info = new GEvent.callbackArgs(marker,
                                        show_property_info,
                                        this.map, properties[i]);
    GEvent.addListener(marker, this.options.show_info_event, show_info);
    if (this.options.cluster) {
      this.markers.push(marker);
    } else {
      this.map.addOverlay(marker);
    }
  }
  if (this.options.show_info_event=='mouseover') {
	GEvent.addListener(this.map, 'mousemove', function(latlng) {
		infowindow = this.getInfoWindow();

		if (!infowindow.isHidden()) {
			infowindowxy = this.fromLatLngToContainerPixel(infowindow.getPoint())
			mousexy = this.fromLatLngToContainerPixel(latlng);
			if (mousexy.x > infowindowxy.x + 200 || mousexy.x < infowindowxy.x - 80){
				this.closeInfoWindow();
			}
			if (mousexy.y > infowindowxy.y + 12 || mousexy.y < infowindowxy.y - 162) {
				this.closeInfoWindow();
			}
		}
	});
  }
  if (this.options.cluster) {
    var clstr_opts = {
      maxZoom: DEFAULT_ZOOM + this.options.clicks_to_uncluster,
      styles: [CLUSTER_STYLE, CLUSTER_STYLE, CLUSTER_STYLE, CLUSTER_STYLE]
    };
    this.clusterer = new MarkerClusterer(this.map, this.markers, clstr_opts);
  }
}
