lanaudiere_js = lanaudiere_js || {};
lanaudiere_js.gmap = lanaudiere_js.gmap || {};

/**
 * Object constructor
 * Merge options and defines DOM objects
 */
lanaudiere_js.gmap = function(obj, options) {
	defaults = {
		markerDefault: false,
		markers: false, // default markers to show, i.e. no GET query
		mode: "full",
	  zoom: 7,
		forceCenter: false, // forces center to default coords, not to first marker
		latitude: 45.971197,
		longitude: -73.545227,
		controls: ["GSmallMapControl", "GMapTypeControl"],
		token: {results: heap.labels['default']['shared_result']+'s', result: heap.labels['default']['shared_result']}
	};
	this.options = jQuery.extend({}, defaults, options);

	/* defines objects */
	this.target = $(obj);
	this.filterElem = ".cbox";
	this.resultListId = "service_results_list";
	this.pager = $("#service_pager");
	this.pagerCurrentpage = $("#pager_currentpage");
	this.pagerTotalpage = $("#pager_totalpage");
	this.resultCount = $("#service_results_count");
	this.resultListWrap = $("#service_results");
	this.resultPager = $(".pager");
	this.pagecurrent = 1;
	
	this.filterAlias = new Array();
	this.filterAlias['service_all']          = 'cat_all';
	this.filterAlias['service_hebergement']  = 'cat_hebergement';
	this.filterAlias['service_activites']    = 'cat_activite';
	this.filterAlias['service_restauration'] = 'cat_restauration';
	this.filterAlias['service_evenements']   = 'cat_festival';
	
	return this.init();
};

/**
 * function init()
 */
lanaudiere_js.gmap.prototype = {
	init: function() {

		this.gmapOptions = {
		  	zoom:         this.options.zoom,
		    controls:     this.options.controls,
		    scrollwheel:  false,
		    maptype:      G_NORMAL_MAP,
		    html_prepend: '<div class="gmap_marker">',
		    html_append:  '</div>'
		};

		if (this.options.mode == 'full') {

			var $this = this;
			// bind onchange handler on checkboxes and pager
			$($this.filterElem).change(function() {
			
				// special behavior depending on checkbox
				// 1. checkbox #service_all unchecks all other
				// 2. other checkbox unchecks #service_all
				switch($(this).attr("id")) {
					case "service_all": 
						if ($(this).not(':checked')) {
							$($this.filterElem).attr('checked', false);
							$(this).attr('checked', true);
						}
						break;
					default:
						$("#service_all").attr('checked', false);
						break;
				}
				return $this.filter();
			});
		}
		if (!this.options.markers && this.options.mode !== 'single') {
			// we don't have any marker to show,
			// launch first filter on page load and proceed to GET request
			return this.filter();
		} else {

			// we already have everything we need to show
			// show map rightaway
			this.populate({results: this.options.markers});
		}

	},
	
	/**
	 * function getIcon()
	 */
	getIcon: function(params) {
		var path = { markers: heap.urlmap['static']+"/images/markers/" };
		var filename = params.defaultm !== undefined && params.defaultm ? "marker_default.png" : params.type + "/marker_"+params.number+".png";

		var icon = {
			image:              path.markers + filename,
	    iconsize:           [34, 28],
	    iconanchor:         [5, 20],
	    infowindowanchor:   [17, 1],
			type: params.type // custom property
		};
		return icon;
	},
	
	/**
	 * function setDefaultMarker()
	 */
	setDefaultMarker: function(params) {
		params.defaultm = true;
		return {latitude: params.latitude, longitude: params.longitude, icon: lanaudiere_js.gmap.prototype.getIcon(params), title: params.title, url: params.url};
		
	},
	
	/**
	 * function filter()
	 * filter members by service
	 */
	filter: function(params) {
		
		var params = params || {};
		
		//perform GET request
		var getparams = new Object();
		getparams['ajax'] = 1;
		if (params.page) getparams['page'] = params.page;
		
		// grab checked filters
		$(this.filterElem+':checked').each( function() { getparams[$(this).attr("id")] = 1; } );

		var $this = this;		
		$.get(window.location.pathname, getparams,
		   function(data){
				data.results = $this.prepareResults(data.resultset);	
			 	return $this.populate(data);
		   }
		);
		return false;
	},
	
	/**
	 * function prepareResults()
	 * takes resultset object and populate new clean results object
	 */
	prepareResults: function(rawresults) {
		var results = new Array();
		var count = 1;
		$.each(rawresults, function() {
			
			var classAlias = new Array();
			classAlias['HEAPM_LAN_Lodging']        = 'hebergement';
			classAlias['HEAPM_LAN_Restaurant']     = 'restauration';
			classAlias['HEAPM_LAN_Activity']       = 'activites';
			classAlias['HEAPM_LAN_Event']          = 'evenements';

			var classAlias = classAlias[this['class']] || 'default';
			results.push({
				latitude: this.latitude,
				longitude: this.longitude,
				icon: lanaudiere_js.gmap.prototype.getIcon({type: classAlias, number:count}), // grab correct get_class to show correct color
				title: this._member[0].title,
				url: this.url
			});
			count++;
		});
		
		return results;
	},
	
	/**
	 * function populate()
	 * populate results, refresh googleMap
	 */
	populate: function(data) {

		var $this = this;
		if (this.options.mode == "full") {

			// show result count in html div
			this.resultCount.html(data.totalrows + ' ' + (data.totalrows > 1 ? this.options.token.results : this.options.token.result));

			if (!data.totalrows || !data.results.length) {
				$("#"+this.options.resultListId).remove();
				this.pager.hide();
			} else {
				// remove list if exists
				if ($("#"+this.options.resultListId).length) {
					$("#"+this.options.resultListId).html("");
				} else {
					this.resultListWrap.prepend('<ol id="'+this.options.resultListId+'" />');
				}
	
				// populate verbose list: write ol > li result elements
				var list = $("#"+this.options.resultListId);
				$.each(data.results, function() {
					list.append('<li><img class="marker" src="'+this.icon.image+'" /><a href="'+this.url+'">'+this.title+'</a></li>');
				});
	
				// feed pager and create li elements
				this.pagerCurrentpage.html(data.page);
				this.pagerTotalpage.html(data.pages);
				this.pager.show();
				var pagerlist = this.pager.children('ul');
				pagerlist.html("");
				for (i=1; i<=data.pages; i++) {
					pagerlist.append('<li><a href="#" rel="'+i+'" class="js-pager'+(i==data.page?' selected':'')+'">'+i+'</a></li>');
				}
				// bind click on page links
				pagerlist.find('a').click(function(){ $this.filter({page: $(this).attr("rel")}); return false; });
			}
		}
		
		//
		
		// populate gmap markers
		this.gmapOptions.markers = data.results || [];
		
		// we unshift defaultMarker, populate googleMap
		if (this.options.markerDefault) this.gmapOptions.markers.unshift(this.options.markerDefault); // show marker in gmap

		// if no markers, center to default point
		if (!this.gmapOptions.markers.length || this.options.forceCenter) {
			this.gmapOptions.latitude = this.options.latitude;
			this.gmapOptions.longitude = this.options.longitude;
		}

		// show the magic!
		this.target.gMap(this.gmapOptions);
	}

};




// -----------------------------------------------------


function LatLong(degLat, degLong) {
  this.lat = LatLong.llToRad(degLat);
  this.lon = LatLong.llToRad(degLong);
}    

LatLong.llToRad = function(brng) {
  if (!isNaN(brng)) return brng * Math.PI / 180; 

  brng = brng.replace(/[\s]*$/,'');               
  var dir = brng.slice(-1).toUpperCase();         
  if (!/[NSEW]/.test(dir)) return NaN;           
  brng = brng.slice(0,-1);                       
  var dms = brng.split(/[\s:,°º′\'″\"]/);         
  switch (dms.length) {                           
    case 3:                                       
      var deg = dms[0]/1 + dms[1]/60 + dms[2]/3600; break;
    case 2:                                       
      var deg = dms[0]/1 + dms[1]/60; break;
    case 1:                                       
      if (/[NS]/.test(dir)) brng = '0' + brng;   
      var deg = brng.slice(0,3)/1 + brng.slice(3,5)/60 + brng.slice(5)/3600; break;
    default: return NaN;
  }
  if (/[WS]/.test(dir)) deg = -deg;               
  return deg * Math.PI / 180;                     
}

LatLong.distHaversine = function(p1, p2) {
  var R = 6371;
  var dLat  = p2.lat - p1.lat;
  var dLong = p2.lon - p1.lon;

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(p1.lat) * Math.cos(p2.lat) * Math.sin(dLong/2) * Math.sin(dLong/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var d = R * c;

  return d;
}

// -----------------------------------------------------
/*
 populate gMap on load with gmap_markers smarty variable
 on ajax reload, populate using window.markers variable
*/
function populateMap(markersRaw) {
	var markersSearch = new Array();
	$.each(markersRaw, function() {
  
    /*
    var refLat = 45.971197;
    var refLon = -73.545227;
    startPoint = new LatLong(this.latitude, this.longitude);
    endPoint = new LatLong(refLat, refLon); 
    var dist = LatLong.distHaversine(startPoint, endPoint);
    console.log("Distance = "+dist+" kms");
    */
  
		markersSearch.push({
			latitude: this.latitude,
			longitude: this.longitude,
			icon: lanaudiere_js.gmap.prototype.getIcon({type:'default', number: this.counter})}
		);
	});
	var lanGmapSide = new lanaudiere_js.gmap($("#map_side"), {forceCenter: true, mode: "tiny", zoom: 8, controls: ["GSmallMapControl"], markers: markersSearch});
};
