(function(){
	/*
	 * Google Maps, store locator
     * Places a Google map with several options, among which displaying of route directions
	 *
	 * @author Lee Boonstra, <lee.boonstra@efocus.nl>
	 * @since 12 jul 2011
	 * @version 1.0
	 * @copyright eFocus
	 *
	 * @uses jQuery 1.2.6, <http://www.jquery.com> or higher
	 * @uses Google Maps V3 API
	 */
	$.fn.StoreLocator = function(obj){
		var options = {};
		if(obj){
			options = obj;
		} else {
			options = {
				ajaxPath : '/storelocator/ajax_sl.php',
				el: $(this).attr('class'),
				geolocation: false,
				gpsImage: '/fileadmin/templates/img/gps.png',
				getInput: '#city',
				idDataHolder: '#data',
				idMapsHolder: '#maps',
				idRouteHolder: '#route',
				idRange: '#range',
				idPostal: '#postal',
				idFilter: '#retailer',
				idGetStoresBtn: '#submitStores',
				idRouteBtn: '#submitRoute',
				markerImage: 'http://maps.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png',
				zoom: 7
			}
		}	
		GoogleMaps(options);
	};
	
})(jQuery);

/*
 * Debug, if debugmode is enabled.
 */
var isDebugMode = true;
function debug(str,isError){
	if(isDebugMode && isError === true ){ 
		console.error(str);
	} else if(isDebugMode) {
		console.log(str);
	}
}

/*
 * This function tries to load the Google API in your page.
 * Incase the API is already loaded, then go further with the
 * Google Maps function. Else try every second...
 * After 10 tries, quit.
 */
function GoogleMaps(options){
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = "http://maps.google.com/maps/api/js?sensor="+options.geolocation+"&language="+$('html').attr('lang')+"&callback=GoogleMaps.prototype.init";
	GoogleMaps.options = options;
	document.body.appendChild(script);
}

GoogleMaps.prototype = {
	/*
	 * Initialize Google Maps
	 */
	init: function(){
		var arrMaps = $("." + GoogleMaps.options.el);
		
		return arrMaps.each(function(i){
			GoogleMaps.arrMarkers = new Array();
			GoogleMaps.prototype.setMap(this);
			GoogleMaps.prototype.setMapStyles(this);
			
			if (GoogleMaps.options.getStreet || GoogleMaps.options.getPostal || GoogleMaps.options.getCity) GoogleMaps.prototype.getAddress();
		});
	},
	getPosFromGoogleObj: function(position){
		var counter = 0;
		var pos = {};
		pos.latitude = "52";
		pos.longitude = "5";
		
		for (var entry in position) {
			if (counter === 0) 
				pos.latitude = position[entry];
			if (counter === 1) 
				pos.longitude = position[entry];
			counter++;
		}
		
		return pos;
	},
	/*
	 * Call Data
	 */
	getUserInput: function(){
		var address = $(GoogleMaps.options.idPostal).val() + " " + $(GoogleMaps.options.getInput).val();
		if (address.length > 1) {
			GoogleMaps.prototype.searchQueryString(address, function(pos, status){
				var position = GoogleMaps.prototype.getPosFromGoogleObj(pos[0].geometry.location);
				if (status === "OK") {
					var props = {
						dist: $(GoogleMaps.options.idRange).val(),
						filter: $(GoogleMaps.options.idFilter).val(),
						lat: position.latitude,
						long: position.longitude
					}
					if (GoogleMaps.options.getStreet || GoogleMaps.options.getPostal || GoogleMaps.options.getCity) {
						//no ajax call
					} else {
						GoogleMaps.prototype.getData(props);
					}
						
				}
				else {
					alert("Google can't locate the address.")
				}
			});
		}
	},
	getAddress: function(){
		var elStreet = $(GoogleMaps.options.getStreet)[0];
		var elPostal = $(GoogleMaps.options.getPostal)[0];
		var elCity = $(GoogleMaps.options.getCity)[0];
		var elCountry = $('.country');
		
		var s = $(elStreet).text() + ", " + $(elCity).text() + ", " + elCountry.text();
				
		if(s.indexOf('Theresialaan') > -1) GoogleMaps.strAddress = 'Vilvoorde, Belgie'; else GoogleMaps.strAddress = s;
		
		GoogleMaps.prototype.searchQueryString(GoogleMaps.strAddress, 
			function(results){
				if(results.length > 0){
					var position = GoogleMaps.prototype.getPosFromGoogleObj(results[0].geometry.location);
					GoogleMaps.prototype.setMarkerToMap(position, GoogleMaps.strAddress);
					GoogleMaps.MapObj.setCenter(results[0].geometry.location);	
				}
			}
		);
	},
	getData: function(props){
		var arrData = new Array();
		$.getJSON('/storelocator/ajax_sl.php',
		props,
		function(results) {
			if(results.stores === false){
				var elStrong = document.createElement('strong');
				$(elStrong).addClass("error");
				$(elStrong).text(results.status.status[0]);
				$(GoogleMaps.options.idDataHolder).html(elStrong);
			} else {
				$.each(results.stores, function(i, obj){
					arrData.push(obj);
				});
	
			  	GoogleMaps.prototype.setData(arrData);
			}  	
		});
	},
	setData: function(arrData){
		$(GoogleMaps.options.idDataHolder).html("");
		$.each(arrData, function(i, obj){
			/*
			 * Generate input radio's with address data and a marker image
			 * After this, load the same markers in the map.
			 */
			
			//make address data
			var elDiv = document.createElement('div');
			var elOption = document.createElement('input');
			var elLabel =  document.createElement('label');
			var elHr = document.createElement('hr');
			var elMarker = document.createElement('img');
			
			var strAddress = "";
			if(obj.city !== "" && obj.street !== "") {
				strAddress = obj.city +', ' + obj.street + ' ' +  obj.house_number + obj.house_number_suffix;
			} else if(obj.city !== ""){
				strAddress = obj.city;
			}
			
			$(elDiv).addClass('field');
			$(elLabel).addClass('inline');
			$(elMarker).addClass('marker');		
			$(elOption).attr('type','radio');
			$(elOption).attr('name',obj.uid);
			$(elOption).attr('name','name_' + obj.uid);
			$(elLabel).attr('for','name_' + obj.uid);
			$(elLabel).html('<strong>'+obj.name+'</strong>' + strAddress);
			$(elMarker).attr('src',GoogleMaps.prototype.getMarkerImage());
			
			$(elDiv).append(elOption);
			$(elDiv).append(elLabel);
			$(elDiv).append(elMarker);
	
			$(GoogleMaps.options.idDataHolder).append(elDiv);
			$(GoogleMaps.options.idDataHolder).append(elHr);
			
			GoogleMaps.prototype.setMarkerToMap(this, strAddress);
		});
		var latlng = new google.maps.LatLng(arrData[0].latitude, arrData[0].longitude);
		GoogleMaps.MapObj.setCenter(latlng);	
	},
	resetData: function(){
		this.setMap(null);
		$(GoogleMaps.options.idDataHolder).html("");
	},
	getMarkerImage: function(){
		var image = null;
		if(GoogleMaps.options.markerImage){
			var image = GoogleMaps.options.markerImage;
			var counter = GoogleMaps.arrMarkers.length+1;
			if(counter < 10) {
				counter = "0" + counter;
 			}
			image = image + counter + ".png";
		}
		return image;
	},
	setMarkerToMap: function(item, strAddress){
		var image = GoogleMaps.prototype.getMarkerImage();
		var myLatLng = new google.maps.LatLng(item.latitude, item.longitude);
		var googleMarker = new google.maps.Marker({
		      position: myLatLng,
		      map: GoogleMaps.MapObj,
		      draggable: true,
		      icon: image,
		      title: ''+item.name
		});

		GoogleMaps.arrMarkers.push(googleMarker);
		GoogleMaps.prototype.setMarkerEvents(googleMarker, strAddress);
	},
	
	/*
	 * Display Map functions
	 */
	setMap: function(el){
		var latlng = new google.maps.LatLng(52.4, 4.8);

		var mapOptions = {
  			zoom: GoogleMaps.options.zoom,
  			center: latlng,
  			mapTypeId: google.maps.MapTypeId.ROADMAP
		};		

		if(GoogleMaps.options.idMapsHolder) el = $(GoogleMaps.options.idMapsHolder)[0];
			
    	GoogleMaps.MapObj = new google.maps.Map(el, mapOptions);
    	GoogleMaps.MapObj.setCenter(latlng);
    	
    	GoogleMaps.prototype.setMapEvents();

	},
	setMapStyles: function(el){
		if(GoogleMaps.options.idMapsHolder) el = $(GoogleMaps.options.idMapsHolder)[0];
		$(el).css({
			height: GoogleMaps.options.cssHeight,
			width: GoogleMaps.options.cssWidth
		});
	},
	/*
	 * Set Map Events
	 */
	setMapEvents: function(){
		//enable geolocation
		GoogleMaps.prototype.getCurrentPosition();
		//enable clicks
		$(GoogleMaps.options.idGetStoresBtn).click(function(){
			GoogleMaps.prototype.resetData();
			GoogleMaps.prototype.getUserInput();
		});
		$(GoogleMaps.options.idRouteBtn).click(function(){
			GoogleMaps.prototype.resetData();
			GoogleMaps.prototype.getRoute();
		});
		$(GoogleMaps.options.getInput).keydown(function(e){
			 if (e.keyCode === '13') {
				GoogleMaps.prototype.resetData();
				GoogleMaps.prototype.getUserInput();
			}
		});
	},
	/*
	 * Set Marker Events
	 */
	setMarkerEvents: function(marker, strAddress){
		var infowindow = new google.maps.InfoWindow({
			content: '<p class="address"><strong>' + marker.title + '</strong><br/>' + strAddress + '</p>'
		});
		google.maps.event.addListener(marker, 'click', function() {
			 infowindow.open(GoogleMaps.MapObj, marker);
		});
	},
	/*
	 * Geolocation
	 */
	getCurrentPosition: function(){
		if(GoogleMaps.options.geolocation){
			GoogleMaps.geolocation = navigator.geolocation.watchPosition(function(position){
				GoogleMaps.prototype.setCurrentPosition(position);
			}, 
	        debug,
	        { 
	        	enableHighAccuracy: true,
	        	maximumAge: 1000, 
	        	timeout: 50000
	       	});
	   } else {
	   		//debug("Geolocation is disabled.");
	   }
	},
	setCurrentPosition: function(position){
		if(position){
			var mapCenter = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
			GoogleMaps.prototype.setPosMarker(position);
			GoogleMaps.MapObj.setCenter(mapCenter);
			navigator.geolocation.clearWatch(GoogleMaps.geolocation);
		}	
	},
	setPosMarker: function(position){
		var image = GoogleMaps.options.gpsImage;
		var myLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
		var marker = new google.maps.Marker({
	      position: myLatLng,
	      map: GoogleMaps.MapObj,
	      icon: image
	  	});
	},
	
	getRoute: function(){
		if(GoogleMaps.options.idRouteHolder){
			var el = $(GoogleMaps.options.idRouteHolder)[0];
			$(el).empty();
			
			var startPos = $(GoogleMaps.options.getInput).val();
  			var endPos = GoogleMaps.strAddress;

  			GoogleMaps.directionsService = new google.maps.DirectionsService();
			GoogleMaps.directionsDisplay = new google.maps.DirectionsRenderer();

			GoogleMaps.prototype.resetData();

			GoogleMaps.directionsDisplay.setMap(GoogleMaps.MapObj);
				    			
  			var request = {
			    origin: startPos,
			    destination: endPos,
			    travelMode: google.maps.TravelMode.DRIVING
			 };
			 
			GoogleMaps.directionsService.route(request, function(result, status) {
			    if (status == google.maps.DirectionsStatus.OK) {
			      	GoogleMaps.directionsDisplay.setDirections(result);
					GoogleMaps.directionsDisplay.setPanel($(GoogleMaps.options.idRouteHolder)[0]);
			    }
			 });
			 
		}	
	},
		
	/*
	 * GeoCoder function
	 * @param address string
	 */
	searchQueryString: function(address,fn){
    	new google.maps.Geocoder().geocode({'address': address}, function(results, status){
    		fn(results,status);
    	})
	}
}
