var storeLocator = {
	form : {
		countries : [
			'Republic of Ireland',
			'UK'
			],
		ids : {
			country : '#search_country',
			form: '#search_form',
			input : '#search_input',
			submit : '#search_submit'
		},
		inputText : 'Type in your location',
		getAddress : function () {
			addressEntered = jQuery.trim($(storeLocator.form.ids.input).val());
			countrySelected = $(storeLocator.form.ids.country).val();
			countryRegex = new RegExp(this.countries[countrySelected] + '$', 'i');
			if ( addressEntered == this.inputText || addressEntered == '' ) {
				return '';
			} else if (countryRegex.test(addressEntered) || this.isPostcode(addressEntered) ) {
				 return addressEntered;
			} else {
				return addressEntered + ', ' + this.countries[countrySelected];
			}
		},
		initialize : function () {
			$(this.ids.submit).click( function() {
				storeLocator.search(storeLocator.form.getAddress(), storeLocator.map.defaults.zoomLevel);
				return false;
			} );			
			$(this.ids.form).submit( function() {
				$(storeLocator.form.ids.form).click();
				return false;
			} );
			$(this.ids.input).keypress( function(event) {
				if (event.keyCode == 13) {
					storeLocator.search(storeLocator.form.getAddress(), storeLocator.map.defaults.zoomLevel);
					return false;
				}
				return true;
			});
			$(this.ids.input).focus( function() {
				if ( $(storeLocator.form.ids.input).val() == storeLocator.form.inputText ) {
					$(storeLocator.form.ids.input).val('');
				}
			} );		
			$(this.ids.input).blur( function() {
				if ( $(storeLocator.form.ids.input).val() == '' ) {
					$(storeLocator.form.ids.input).val(storeLocator.form.inputText);
				}
			} );
		},
		isPostcode : function(address) {
			var regexPattern = /^[A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}$/i
			var regexNorthernIreland = /^BT/i;
			return regexPattern.test(address) && !regexNorthernIreland.test(address);
		},
		setAddress : function (address) {
			$(this.ids.input).val(address);
		},
		submit : function () {
			$(this.ids.submit).click();
		}
	},
	
	initialize : function() {
		$.ajaxSetup ( { cache: false } );		
		this.form.initialize();
		if (  this.form.getAddress() != '' ) {
			this.search(this.form.getAddress(), this.map.defaults.zoomLevel);
		} else {			
			this.map.display({});
		}
	},
	
	map : {
		defaults : {
			mapOptions : {
				zoom: 5,
				center: new google.maps.LatLng(55.3781, -3.4360),
				navigationControl: true,
				scaleControl: true,
				scrollwheel: false,
				mapTypeControl: false,
				mapTypeId: google.maps.MapTypeId.ROADMAP
			},
			zoomLevel : 10
		},
		display : function (specificOptions) {
			mapOptions = $.extend(this.defaults.mapOptions, specificOptions);
			this.image = new google.maps.Map($(this.id).get(0), mapOptions);
			
			// set listeners if user changes map
			
		//	$.each(['zoom_changed', 'resized', 'dragend'], function(index, event) {
		//		google.maps.event.addListener(storeLocator.map.image, event, function() {
		//			var image = storeLocator.map.image;
		//			re = /^.(.*).$/;
		//			storeLocator.search(re.exec(image.getCenter())[1], image.getZoom(), true);
		//			return false;
		//		} );
		//	});
		
		},	
		infoWindow : {
			lastOpened : null,
			openOnClick : function (location)
			{
				return google.maps.event.addListener(location.marker, 'click', function() {
					var infoWindow = storeLocator.map.infoWindow;
					if ( infoWindow.lastOpened != null ) {
						infoWindow.lastOpened.infoWindow.close() ;
					}
					infoWindow.lastOpened = location ;    
					location.infoWindow.open(storeLocator.map.image,location.marker) ;    
				});
			}
		},
		you : {
			display : function(lat, lng, moveMap) {
				if ( moveMap == null) {
					this.location = new google.maps.LatLng(lat,lng);
				}
	
				var marker = new google.maps.Marker({
					position: this.location,
					map: storeLocator.map.image,
					clickable: true,
					title: 'You',
					icon: this.images.marker,
					zIndex : 0
//					draggable: true,
				});
	
				google.maps.event.addListener(marker, 'drag', function() {
					storeLocator.map.you.location = marker.getPosition();
				} );
			},
			images : {
				marker : '/img/markers/you.gif'
			},
			location : null 
		},
		image : null,
		id : '#canvas'
	},
	
	results : {
		data: [],
		id : '#search_serp',
		images : {
			location_base : '/img/markers/'
		},
		displayAddress : function(location) {
			var addresses = this.getAddress(location);
			address = [];
			addressIndex = 0;
			address[addressIndex++] = '<span class="name">' + location["Location"]["name"] + '</span>';
			if ( null != location["LocationName"]["name"] ) {
				address[addressIndex++] = '<span class="store">' + location["LocationName"]["name"] + '</span>';
			}
			address[addressIndex++] = addresses.join(', ');
			if ( null != location["Location"]["telephone"] ) {
				address[addressIndex++] = location["Location"]["telephone"];
			}
			if ( null != location["Location"]["email"] ) {
				address[addressIndex++] = '<a href="mailto:' + location["Location"]["email"] + '">' + location["Location"]["email"] + '</a>';
			}
			return address.join("<br />\n") + this.openingTime(location);
		},
		getAddress : function (location) {
			var addressFields = ['address_1', 'address_2', 'address_3', 'postcode'];
			var addresses = [];
			addressIndex = 0;
			for (var field in addressFields) {
				if ( '' != jQuery.trim(location["Location"][addressFields[field]]) ) {
					addresses[addressIndex] = jQuery.trim(location["Location"][addressFields[field]]);
					addressIndex++;
				}
			}
			return addresses;
		},
		openingTime : function(location) {
			var days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
			var openingTimes = '';
			openingTimes += '<div class="openingTime">';
			openingTimes += '<h3>Opening Times</h3>';
			openingTimes += '<table>';
			for(var dayIndex in days) {
				openingTimes += '<tr>';
				openingTimes += '<th>' + days[dayIndex] + '</th>';
				openingTimes += '<td>' + location['Location'][days[dayIndex].toLowerCase()] + '</td>';
				openingTimes += '</tr>';
			}
			openingTimes += '</table>';
			openingTimes += '</div>';
			return openingTimes;
		},
		displayMarker : function(location, resultIndex) {
			var companyLatLng = new google.maps.LatLng(location["Location"]["latitude"], location["Location"]["longitude"]);
			var directionInfo = location["Location"]["address_1"] + ' ' + location["Location"]["address_2"] + location["Location"]["address_3"] + ' ' + location["Location"]["postcode"] + ' @' + companyLatLng;
			var infoData = new Object;
			infoData.html =
				'<span class="infoWindow">' +
					'<span class="name">' + location["Location"]["name"] + "</span><br />" + 
					this.getAddress(location).join("<br />\n") + "<br />\n" + 
					'<a href="javascript:directions(\'' + directionInfo + '\');">Get directions</a>' +
				'</span>';

			infoData.marker = new google.maps.Marker({
				position: companyLatLng,
				map: storeLocator.map.image,
				title: location["Location"]["name"],
				icon: storeLocator.results.images.location_base + resultIndex + '.gif',
				zIndex : 1
			});
			infoData.infoWindow = new google.maps.InfoWindow({
				content: infoData.html
			});
			infoData.listener = storeLocator.map.infoWindow.openOnClick(infoData) ;
			
		},
		displayKey : function (location) {
			if ( location['LocationTypes'].length == 0 ) {
				return '&nbsp;';
			}
			var key = '';
			for (var typeIndex in location['LocationTypes'] ) {
				key += '<img src="/img/key/' + location['LocationTypes'][typeIndex][0] + '" alt="' + location['LocationTypes'][typeIndex][1] +'" />';
			}
			return key;
		},
		displayLocations : function (originalData) {
			var data = JSON.parse(originalData);
			var result = '';
			result += '<h2>Search results for your area</h2>';
			result += '<ul class="results">';
			for (var resultIndex in data) {
				storeLocator.results.displayMarker(data[resultIndex], resultIndex);
				result +=
					'<li id="result-' + resultIndex + '">' +
						'<div class="key">' + storeLocator.results.displayKey(data[resultIndex]) + '</div>' +
						'<div class="details">' + storeLocator.results.displayAddress(data[resultIndex]) + '</div>' +
					'</li>';
			}
			result += '</ul>';
			$(this.id).html('');
			$(this.id).html(result);
			$('.openingTime').addClass('closed');
			$('.openingTime h3').toggle(  function() { $(this).parent().removeClass('closed');$(this).parent().addClass('open');}, function() { $(this).parent().addClass('closed');$(this).parent().removeClass('open');} );
		},
		displayMessage : function (message, type) {
			message = '<div class="' + type + '">' + message + '</div>';
			$(this.id).html('');
			$(this.id).html(message);
		},
		process : function(address, zoomLevel, moveMap) {
			if ( storeLocator.geocode.results == null || storeLocator.geocode.results.length == 0 ) {
				storeLocator.results.displayMessage('Sorry, your search returned no results. Please try again but include more of your address in the search box above', 'error');
			} else if ( storeLocator.geocode.results.length == 1  || moveMap ) {
				$.ajax(
					{
						type: "POST",
						url: '/locations/search/',
						data: { lat: storeLocator.geocode.lat, lng: storeLocator.geocode.lng },
						success: function(data) {
							storeLocator.map.display({zoom: zoomLevel, center: new google.maps.LatLng(storeLocator.geocode.lat,storeLocator.geocode.lng)});
							storeLocator.map.you.display(storeLocator.geocode.lat, storeLocator.geocode.lng, moveMap);
							storeLocator.results.displayLocations(data);
						},
						error: function(data) {
							storeLocator.results.displayMessage('<p>Sorry there appears to have been an error, please try again</p>', 'error');
						}
					}
				);
	
			// if there are multiple matches for a search term
			} else {
				var others = "<p>We have found a number of possible matches for that address. If you can't see the one you want then you might need to add more detail and search again:</p>";
				others += '<ul class="options">';
				for (var result in storeLocator.geocode.results) {
					others += '<li><a>' + storeLocator.geocode.results[result].formatted_address + '</a></li>';
				}
				others += "</ul>";
				storeLocator.map.display({});
				storeLocator.results.displayMessage(others, 'info');
	
				// if user clicks another result then re-search
				$(".options LI").live("click", function(event){
					var result = storeLocator.geocode.results[$(".options LI").index(this)];
					storeLocator.form.setAddress($(this).text());
					storeLocator.search(result.geometry.location.lat() + ',' + result.geometry.location.lng(), storeLocator.map.defaults.zoomLevel);
					return false;
				});
			}
			storeLocator.results.log(address, moveMap);
		},
		log : function (address, moveMap) {
			$.ajax(
				{
					type: "POST",
					url: '/search_log_items/search_log/',
					data: {
						address : address,
						geocoder : storeLocator.geocode.geocoder,
						status : storeLocator.geocode.status,
						results : (moveMap ? '1' : storeLocator.geocode.results.length.toString())
					}
				}
			);			
		}
	},
	
	
	geocode : {
		geocoder : null,
		status : null,
		results : null,
		lat : null,
		lng : null,
		google : function (address, zoomLevel, moveMap) {
			this.geocoder = 'Google';
			var geocoder = new google.maps.Geocoder();
			if ( geocoder ) {
				geocoder.geocode(
					{ 'address': address },
					function(results, status) {
						storeLocator.geocode.status = status.toString();
						storeLocator.geocode.results = results;
						if ( status == google.maps.GeocoderStatus.OK && results.length == 1) {
							var result = results[0];
							storeLocator.geocode.lat = result.geometry.location.lat();
							storeLocator.geocode.lng = result.geometry.location.lng();
						}
						storeLocator.results.process(address, zoomLevel, moveMap);
					}
				);
			}
		},
		mapMove : function (address, zoomLevel, moveMap) {
			this.geocoder = 'Map move';
			this.status = 'OK';
			this.results = [''];
			re = /^(.*),(.*)$/;			
			this.lat = re.exec(address)[1];
			this.lng = re.exec(address)[2];
			storeLocator.results.process(address, zoomLevel, moveMap);
		},
		postcode : function (postcode, zoomLevel, moveMap) {
			this.geocoder = 'Postcode';
			$.ajax(
				{
					type: "POST",
					url: '/postcodes/search/',
					data: { postcode : postcode},
					success: function(data) {
						data = JSON.parse(data);
						if ( data.length > 0 )  {
							storeLocator.geocode.status = 'OK';
							storeLocator.geocode.results = data;
							storeLocator.geocode.lat = data[0]['Postcode']['latitude'];
							storeLocator.geocode.lng = data[0]['Postcode']['longitude'];
						} else {
							storeLocator.geocode.status = 'ZERO_RESULTS';
							storeLocator.geocode.results = [];
							storeLocator.geocode.lat = null;
							storeLocator.geocode.lng = null;
						}
						storeLocator.results.process(postcode, zoomLevel, moveMap);
					},
					error: function(data) {
						storeLocator.geocode.status = 'ERROR';
						storeLocator.geocode.results = [];
						storeLocator.geocode.lat = null;
						storeLocator.geocode.lng = null;
						storeLocator.results.process(postcode, zoomLevel, moveMap);
					}
				}
			);
		}
	},
	
	search : function(address, zoomLevel, moveMap) {
		if ( address == '' ) {
			this.results.displayMessage('<p>Our store locator is the easiest way to find your nearest store in the UK and Ireland. Just enter the town or postcode you would like to search for in the box above.</p>', 'error');
		} else if (moveMap) {
			this.geocode.mapMove(address, zoomLevel, moveMap);
		} else if ( this.form.isPostcode(address) ) {
			this.geocode.postcode(address, zoomLevel, moveMap);
		} else {
			this.geocode.google(address, zoomLevel, moveMap);
		}
		return true;
	}
};


function directions(address) {
	window.open('http://www.google.com/maps?source=uds&daddr=' + escape(address) + '&iwstate1=dir%3Ato&saddr=' + escape(storeLocator.map.you.location));	
}


$(document).ready(storeLocator.initialize());
