/*
Map and form funcionality definition for ride/search_form view
	
*/
$().ready(function(){

	// Enable the JQuery UI Components for the date and timepicker
	//$('#time').timepickr({convention:12,suffix:['AM','PM']});

	$('#date').datepicker();
	
	// Core JS validation and error feedback
	$('#ride_search_form').validate({showErrors: function(errorMap, errorList){
		$('.error').removeClass('error').children('p.errors').remove();
		
		pageTracker._trackPageview('/ride_search_form/errors');
		
		for(error in errorList)
		{		$(errorList[error].element).qtip({content:errorList[error].message,show: 'mouseover',
		   hide: 'mouseout',
		show:{ready:true},
			 position: {
			                  corner: {
			                     tooltip: 'leftMiddle', // Use the corner...
			                     target: 'rightMiddle' // ...and opposite corner
			                  }
			               },
			
		     style: {
			                  border: {
			                     width: 5,
			                     radius: 10
			                  },
			                  padding: 10, 
			                  textAlign: 'center',
			                  tip: true, // Give it a speech bubble tip with automatic corner detection
			                  name: 'red' // Style it according to the preset 'cream' style
			               }
			
		
		   });
			//$(errorList[error].element).parents('.element').addClass('error').append('<p class="errors">'+errorList[error].message+'</p>');
		}
		
	}});

	// This enables the alternating sections for single-occurrence and recurring rides
	$('#element_days').hide();
	
	$("input[name='type']").click(checkType)	
	
	
	function checkType()
	{		if($("input[name='type']:checked").val() == 'single')
		{
			$('#date').addClass('required');
			$('#days').removeClass('required');
			$('#element_days').hide();
			$('#element_date').fadeIn();			
		}
		else
		{
			$('#days').addClass('required');
			$('#date').removeClass('required');
			$('#element_days').fadeIn();
			$('#element_date').hide();			
		}
	}
	
	function initSearchForm()
	{
		initMap();
		$("#to_name, #from_name").blur(updateMap)
		$("#co2").insertAfter("#element_to_name");
		
		// This way we prent focus/blur (no change) events from needlessly re-loading map data
		$("#to_name, #from_name").focus(function(){previousValue = $(this).val();})
		pageTracker._trackPageview('/ride_search_form/initForm');
	}

	//--------------------------------------------------------------------
	
	var previousValue;

	var toPolygon
	var toMarker;
	var fromPolygon;
	var fromMarker;
	
	
	// reset status and re-draw the map
	function initMap()
	{
		$('#map').jmap('init', {'mapEnableScrollZoom':true,'mapShowjMapsIcon':false});
		$('#map').corner();
		
		positionMap();
		$(window).resize(positionMap);
		pageTracker._trackPageview('/ride_search_form/initMap');
	}

	// orient the map to completely occlude the #home_content (x,y/w,h)
	function positionMap() 
	{
		var pos =  $('#home_content').offset();
		var width = $('#home_content').width();
		var height = $('#home_content').height()	
		var left = pos.left + "px";
		var top =  pos.top + "px";
		
		$('#map').css( {
			position: 'absolute',
			zIndex: 2,
			width: width,
			height: height,
			left: left,
			top: top
		} );
	}
	
	function redrawMap()
	{		
		positionMap();
		$('#map').fadeIn();
		$('#map').jmap('CheckResize');
	
		if(fromMarker || toMarker)
		{
			var bounds = new GLatLngBounds();
			
			if(fromMarker)
				bounds.extend(fromMarker.getLatLng());
			
			if(toMarker)
				bounds.extend(toMarker.getLatLng());

			var map = Mapifies.MapObjects.Get($('#map'));
			map.setCenter(bounds.getCenter(),map.getBoundsZoomLevel(bounds)-5);
		}
	};

	var updatingFields = false;
	// This clears the map state and then updates it based on the current values
	function updateMap()
	{
		//console.log("Updating Fields... ", updatingFields);
		
		if($(this).val() == previousValue)
		{
			previousValue = null;
			return;
		} 
		
		redrawMap(); //This allows the 'centered' content to show up correctly
		
		
		toValue = $("#to_name").val() != "";
		fromValue = $("#from_name").val() != "";
		from_lat = $("#from_lat").val() != "";
		from_lon = $("#from_lon").val() != "";
		to_lat = $("#to_lat").val() != "";
		to_lon = $("#to_lon").val() != "";
		
		
		pageTracker._trackPageview('/ride_search_form/updateMap?to_value='+toValue+'&from_value='+fromValue);
		// updating the map, so clear previous co2 data
		$('#co2').hide();
		
		// Directions draws points,radii, and polyline
		if(toValue && fromValue &&  from_lat && to_lat)
		{
			updatingFields = false;
			$('#map').jmap('ClearMap');
			pageTracker._trackPageview('/ride_search_form/getDirections');
			getDirections();
		}
		else if(updatingFields)
		{
			setTimeout(updateMap,500);
		}	
		else
		{

			updatingFields = fromValue && toValue; // only if checking for BOTH values do we try again.			
			
			$('#map').jmap('ClearMap');
			if(fromValue)
			{
				pageTracker._trackPageview('/ride_search_form/getFromGeocode');
				fromMarker = null;
				$('#from_lat').val('');
				$('#from_lon').val('');
				$('#map').jmap('SearchAddress', { 'query': $('#from_name').val(), 'returnType': 'getLocations', location:'from'}, onAddressResult);
			}
		
			if(toValue)
			{
				pageTracker._trackPageview('/ride_search_form/getToGeocode');
				toMarker = null;
				$('#to_lat').val('');
				$('#to_lon').val('');
				$('#map').jmap('SearchAddress', { 'query': $('#to_name').val(), 'returnType': 'getLocations', location:'to'}, onAddressResult);	
			}
			
		}
		
		
		if(!toValue && !fromValue) $('#map').hide();
	}
	
	function getDirections()
	{
		jQuery('#map').jmap('SearchDirections', 
					{
						'query':'from:'+$("#from_name").val()+' to:'+$("#to_name").val()+'',
						'panel':'#directions'
			        }, 
					directionsResult);
	}
	
	function directionsResult(directions, options)
	{
			
			if(directions.getNumRoutes() > 0)
			{
				var route = directions.getRoute(0);
				displayCO2(directions)
				//$("#from_name").val(route.getStartGeocode().address);
				//$("#to_name").val(route.getEndGeocode().address);
				var start = route.getStep(0).getLatLng();
				var end = route.getEndLatLng();
				onMarkerAdd(new GMarker(start),{location:'from'});
				onMarkerAdd(new GMarker(end),{location:'to'});		
			}
			else
			{
				$("#ride_search_form").validate().showErrors({
													'from_name':'Bad route: from '+$('#from_name').val()+' to '+$('#to_name').val(), 
													'to_name':'Bad route: from '+$('#from_name').val()+' to '+$('#to_name').val()
													});

			}
			redrawMap();	
	}
		
	function onAddressResult(result, options) 
	{
		var valid = Mapifies.SearchCode(result.Status.code);
		if (valid.success) {
			var mapCenter;
			jQuery.each(result.Placemark, function(i, point){
				markerOptions = {
					'pointLatLng':[point.Point.coordinates[1], point.Point.coordinates[0]],
					'centerMap':true,
					'location':options['location']
				}
				$('#map').jmap('AddMarker',markerOptions,onMarkerAdd);
						$('#'+options['location']+'_name').val(point.address);
			});
			if(updatingFields) updateMap();
			redrawMap();
			
		} else {		
			var field = options['location']+'_name';
			if(field == 'from_name')
				$("#ride_search_form").validate().showErrors({'from_name':"Location not found on the map: "+$("#"+options['location']+"_name").val()});
			else
				$("#ride_search_form").validate().showErrors({'to_name':"Location not found on the map: "+$("#"+options['location']+"_name").val()});
			$('#'+options['location']+'_name').val('');
			$('#'+options['location']+'_lat').val('');
			$('#'+options['location']+'_lon').val('');
			redrawMap();
		}
	}
	
	function onMarkerAdd(marker,options)
	{
		switch(options['location'])
		{
			case "to":
				toMarker = marker;
				drawRadii(marker.getLatLng().lat(),marker.getLatLng().lng(),null,'to');
				break;
			case "from":
				fromMarker = marker;
				drawRadii(marker.getLatLng().lat(),marker.getLatLng().lng(),null,'from');
				break;
		}

		$('#'+options['location']+'_lat').val(marker.getLatLng().lat());
		$('#'+options['location']+'_lon').val(marker.getLatLng().lng());
	}

	function drawRadii(lat,lng,miles,location)
	{
		if(!miles) miles = 1.5
	
		point = new GLatLng(lat, lng);
		polygonPoints =  getCirclePoints(point,miles);
		$('#map').jmap('AddPolygon', {
						'polygonPoints':polygonPoints,
						'polygonFillOpacity': 0.25,
						'location': location
					},onPolygonAdd);	
	}
	
	function onPolygonAdd(polygon,polygonOptions, options)
	{
		switch(options['location'])
		{
			case "to":
				toPolygon = polygon;
				break;
			case "from":
				fromPolygon = polygon;
				break;			
		}
	}

	//http://maps.forum.nu/gm_sensitive_circle2.html
	function getCirclePoints(point, circleRadius)
	{
		var circlePoints = Array();
		with (Math) {
			var d = circleRadius/3963.189;	// miles to radians		
			var lat1 = (PI/180)* point.lat(); // radians
			var lng1 = (PI/180)* point.lng(); // radians

			for (var a = 0 ; a < 361 ; a++ ) {
				var tc = (PI/180)*a;
				var y = asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc));
				var dlng = atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(y));
				var x = ((lng1-dlng+PI) % (2*PI)) - PI;
				var point = new GLatLng(parseFloat(y*(180/PI)),parseFloat(x*(180/PI)));
				circlePoints.push([point.lat(),point.lng()]);
			}
			return circlePoints;
		}
	}	

	function displayCO2(directions)
	{
		var miles = directions.getDistance().meters / 1609.344;
		$('#co2').html("<p>Sharing this ride will save " + Math.round(miles * .8127753) + " pounds of CO2</p>").show();
	}

	initSearchForm();
	
});