/*---------------
 * jQuery Findmynearest Plugin by Engage Interactive
 * Copyright (c) 2009 Engage Interactive
 * Author: Neil Charlton
 * Version: 1.0
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * Requires: 
 	1. jQuery v1.3 or later
 	2. Google Maps API
	3. A locations datasource containing id, name, latitude and longtitude
---------------*/

var iClicks = 0;
var ourLocs = [];
	
(function($) {

	var Url = {

		// public method for url encoding
		encode : function (string) {
			return escape(this._utf8_encode(string));
		},

		// public method for url decoding
		decode : function (string) {
			return this._utf8_decode(unescape(string));
		},

		// private method for UTF-8 encoding
		_utf8_encode : function (string) {
			string = string.replace(/\r\n/g,"\n");
			var utftext = "";

			for (var n = 0; n < string.length; n++) {

				var c = string.charCodeAt(n);

				if (c < 128) {
					utftext += String.fromCharCode(c);
				}
				else if((c > 127) && (c < 2048)) {
					utftext += String.fromCharCode((c >> 6) | 192);
					utftext += String.fromCharCode((c & 63) | 128);
				}
				else {
					utftext += String.fromCharCode((c >> 12) | 224);
					utftext += String.fromCharCode(((c >> 6) & 63) | 128);
					utftext += String.fromCharCode((c & 63) | 128);
				}

			}

			return utftext;
		},

		// private method for UTF-8 decoding
		_utf8_decode : function (utftext) {
			var string = "";
			var i = 0;
			var c = c1 = c2 = 0;

			while ( i < utftext.length ) {

				c = utftext.charCodeAt(i);

				if (c < 128) {
					string += String.fromCharCode(c);
					i++;
				}
				else if((c > 191) && (c < 224)) {
					c2 = utftext.charCodeAt(i+1);
					string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
					i += 2;
				}
				else {
					c2 = utftext.charCodeAt(i+1);
					c3 = utftext.charCodeAt(i+2);
					string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
					i += 3;
				}

			}

			return string;
		}

	}

	findmynearest = function( options ){
		preLoad();
		
		var geocoder = "";
		var latlng = null;
		var loglat = "";
		var loglng = "";
		var ipLatLng = [];
		var defaults = {
					dataSource: "/locations/locationsJsonList",
					ipDataSource : "",
					resultsDiv: "results",
					addressFieldId: "address",	
					ipNearest: false,
					ipAddress : "",
					ipResultDiv : "ipresult",
					searchTotal:5,
					resultsUrl: '/location/',
					logger: true,
					resultType: 'table',
					sBrand: '',
					resultTitle: '<h4>Closest restaurants...</h4>'
					};
					
		var settings = $.extend( {}, defaults, options );
		
		queryDataSource = function()
		{
		
		}

	
		/* check the inputs - we must have a datasource */
		checkInputs = function() { return ( settings.dataSource == '' ) }
	
		getResults = function( id, name, dist, data )
		{
			var km = (parseFloat(dist / 1000)).toFixed(1) + "km";
			var miles = (parseFloat(dist / 1609)).toFixed(1) + " miles";
			if( settings.resultType == 'list' ){
				return '<li><a href=\"' + settings.resultsUrl + '' + name.replace(/ /g,"-") + '" title="Click for full details about this restaurant" class="aLocation">' + name + '</a> ' + miles + '</li>';
			}
			if( settings.resultType == 'table' ){
				//console.log(data);
				return '<tr class="row_off"> \
							<td width="190"><a href="/location/' + name.replace(/ /g,"-") + '">' + name + '</a><br />' + data.telephone + '</td> \
\
							<td width="120"> \
							<address> \
							' + data.address + '</address> \
							</td> \
							<td width="160">Distance from you<br /> \
							<span class="distance">' + miles + '</span></td> \
\
						</tr>';
			}
		}
		
		printMessage = function( sMessage )
		{
			hideCurrentShowResults();
			$( "#" + settings.resultsDiv ).append( '<div id="results_content">' + sMessage + '</div>' ).slideDown( "slow" );
			$( "#search-button" ).removeAttr("disabled");
		}
	
			$this = $( this );
			if( checkInputs( ) ) { alert( "You must pass a datasource URL" ); return true; };
			
			/* UI bits and peices */
			$( "#" + settings.addressFieldId ).focus(function(){
				$( this ).attr( "value", "" );
				$( "#" + settings.resultsDiv ).slideUp( "fast" );
				$( '.search_results' ).hide();
				$( "#map" ).show();
				
			});
			
			/* on submit - meat of plugin is here */
				
				
				//$( "#search-button" ).attr( "disabled", "disabled" );
				//Loading
				//$('.locations_loading').show();
			
				$( "#" + settings.resultsDiv ).empty().slideUp( "fast" );
				
				var searchTerm = $( "#" + settings.addressFieldId ).val();
				
				if( searchTerm == '' || searchTerm.match( /Where are you/ ) ){
					printMessage( settings.sEmptyMessage );
					return false;
				}
				
				// special case for london  if( searchTerm.toLowerCase() == 'selfridges' ) searchTerm = "Selfridges, London";
				var sSt = $( "#" + settings.addressFieldId ).attr( "value" );
				if( sSt.toLowerCase() == 'london' ){
					var sStr = "<p>We have many restaurants in London, please try refining your search. </p><p class=\"bottom\">\
					 			You can search a London suburb e.g Islington, London or a landmark or postcode. <br /></p>";
					printMessage( sStr );
					return false;
				}
				
				
					/* get the locations json from the webservice  */
					$.getJSON( settings.dataSource, 
						function(data){
						if( !data ) printMessage( "We could not connect, please try again" );
					  	$.each(data.items, function(i,item){
							var address = item.address_1 + '<br />' + item.town_city + '<br />' + item.postcode;
							ourLocs[item.id] = new Array( item.lng, item.lat, item.name, item.uid, address, item.telephone );
					    });
					});
			   
					var places = [];
					if (GBrowserIsCompatible()) {
				        geocoder = new GClientGeocoder();
				    }

					geocoder.getLatLng( searchTerm + ",uk", function( point ){ 
						if( !point ){
							hideLoader();
							printMessage( settings.sEmptyMessage );
						}
						else
						{
							var centerpoint = new GLatLng( point.lat(), point.lng() )
							
							loglat = point.lat();
							loglng = point.lng();
							
							// delay the execution of this script by 100ms to give json time to populate ourLocs
							setTimeout(function() {
								
								$.each( ourLocs, function(i,n){ 

									if( this[2] != undefined )
									{
										var lat = parseFloat( this[1] );
									    var lng = parseFloat( this[0] );
									    var latlng = new GLatLng( lat, lng );
										var name = this[2];
										var id = this[4];
										if( !isNaN( lat ) ){
	                                       	places.push( { latlng:latlng , name:name, id:id, address:this[4], telephone:this[5] } );
										}
									}
								});



								/* Calculate the distances */
								for (i=0; i<places.length; i++) {
					          		places[i].dist = places[i].latlng.distanceFrom( centerpoint );
								}

								places.sort(function (a,b) {return (a.dist - b.dist)});

								var iCnt = 0;
								var sOut = ( settings.resultType == 'list' ) ? '<div id="results_content">' + settings.resultTitle + '<ul class="find_my_nearest">' : '<div id="results_content"><table class="find_my_nearest">';
								var sOutClosing = ( settings.resultType == 'list' ) ? '</ul></div>' : '</table></div>';
								for ( var key in places ) {
									if( iCnt < settings.searchTotal ){
										sOut += getResults( places[key].id, places[key].name, places[key].dist, places[key] );
									}
									iCnt++;
								}

								/* We have some results so animate the results div */

								if( places.length > 1 ){

									hideCurrentShowResults();


									$( "#" + settings.resultsDiv ).append( sOut + sOutClosing ).slideDown( "slow", function(){

										if( settings.logger ){
											$.post( "/locations/logfindmynearest", { brand: settings.sBrand, term: searchTerm, lng: loglng, lat: loglat }, function(data){
												// posted callback
											} );
										}
									});

								}
								
							}, 300);
							

						}
						
				return false;
			});
		

	};
	
	$('#address').keyup(function(e) {
		if(e.keyCode == 13) {
		}
	});

})(jQuery);