function StoreLocator () {
	this.map;
	this.geocoder = new google.maps.Geocoder();
	this.markersArray = [];
	this.installFolder = "";
	
	this.addMarker = function (location, title, distance) {
		var self = this,
			marker = new google.maps.Marker({
			position: location,
			map: self.map,
			title: title
		});
		if (title.length > 0 && title != "") {
			marker.infoWindow = new google.maps.InfoWindow({
				content: title
			});
			google.maps.event.addListener(marker, "click", function() {
				for (var i = self.markersArray.length - 1; i >= 0; i--) {
					self.markersArray[i].infoWindow.close();
				}
				this.infoWindow.open(self.map, marker);
			});
		}  
		self.markersArray.push(marker);
		return self.markersArray.length - 1;
	};
	
	// Removes the overlays from the map, but keeps them in the array
	this.clearOverlays = function () {
		var self = this;
		if (self.markersArray) {
			for (i in self.markersArray) {
				if (self.markersArray.hasOwnProperty(i)) {
					self.markersArray[i].setMap(null);
				}
			}
		}
	};
	
	// Shows any overlays currently in the array
	this.showOverlays = function () {
		var self = this;
		if (self.markersArray) {
			for (i in self.markersArray) {
				if (self.markersArray.hasOwnProperty(i)) {
					self.markersArray[i].setMap(self.map);
				}
			}
		}
	};
	
	// Deletes all markers in the array by removing references to them
	this.deleteOverlays = function () {
		var self = this;
		if (self.markersArray) {
			for (i in self.markersArray) {
				if (self.markersArray.hasOwnProperty(i)) {
					self.markersArray[i].setMap(null);
				}
			}
			self.markersArray.length = 0;
		}
	};
	
	var bustcachevar = 1; //bust potential caching of external pages after initial request? (1=yes, 0=no)
	var bustcacheparameter = "";
	
	this.createRequestObject = function (){
		try	{
			xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
		}	catch(e)	{
			alert('Sorry, but your browser doesn\'t support XMLHttpRequest.');
		};
		return xmlhttp;
	};
	
	this.getMarkers = function (url){
		var self = this,
			page_request = self.createRequestObject();
	
		if (bustcachevar) bustcacheparameter=(url.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime();
		page_request.open('GET', url+bustcacheparameter, true);
		page_request.send(null);
	
		page_request.onreadystatechange = function () {
			self.resultMarkers(page_request);
		}
	};
	
	this.resultMarkers = function (page_request) {
		var self = this;
		if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)) {
			self.deleteOverlays();
			var data = page_request.responseText,
				myJsonObj = jsonParse(data),
				latlng, title, distance, arr = [], addr = [], opening_times, i, LatLngList = [];
			if (myJsonObj.length > 0) {
				for (var k in myJsonObj) {
					if (myJsonObj.hasOwnProperty(k)) {
					  latlng = new google.maps.LatLng(myJsonObj[k].lat, myJsonObj[k].lng);
					  LatLngList.push(latlng);
					  title = myJsonObj[k].name;
					  distance = myJsonObj[k].distance;
					  addr = [];
					  if (myJsonObj[k].address_1 && myJsonObj[k].address_1 !== "") {
						  addr.push(myJsonObj[k].address_1);
					  }
					  if (myJsonObj[k].address_city && myJsonObj[k].address_city !== "") {
						  addr.push(myJsonObj[k].address_city);
					  }
					  if (myJsonObj[k].address_state && myJsonObj[k].address_state !== "") {
						  addr.push(myJsonObj[k].address_state);
					  }
					  phone = "";
					  if (myJsonObj[k].phone && myJsonObj[k].phone !== "") {
					  	phone = '<br>Phone: ' + myJsonObj[k].phone;
					  }						  
					  opening_times = "";
					  if (myJsonObj[k].opening_times && myJsonObj[k].opening_times !== "") {
					  	opening_times = ['<p><strong>Opening times:</strong>', myJsonObj[k].opening_times.replace(/\r\n/g, '<br>'), '</p>'].join("");
					  }
					  i = self.addMarker(latlng, ['<div class="g-tooltip"><h3>', title, '</h3><span>', addr.join(", "), '</span>', phone, opening_times, '</div>'].join(""), distance);
					  arr.push(['<a class="sidebar_item" rel="', i, '"><abbr>', title, '</abbr><span>', addr.join(", "), '</span></a>'].join(""));
					}			  
				}
				self.showOverlays();
				//self.map.setCenter(latlng);
				var bounds = new google.maps.LatLngBounds();
				for (var j = 0, len = LatLngList.length; j < len; j++) {
					bounds.extend(LatLngList[j]);
				}
				self.map.fitBounds(bounds);
				document.getElementById("StoreSidebar").innerHTML = arr.join("");
				self.bindSidebar();
			} else {
				self.emptyResults();
			}
		}
	};
	
	this.init = function (opts) {
		var self = this,
			address = opts.default_address;
		self.installFolder = opts.install_folder;
		self.bindSearchForm();
		self.geocoder.geocode( { 'address': address}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				var myOptions = {
					zoom: opts.default_zoom_level,
					center: results[0].geometry.location,
					mapTypeId: google.maps.MapTypeId.ROADMAP
				};
				self.map = new google.maps.Map(document.getElementById("StoreCanvas"),myOptions);
			} else {
				//alert("Geocode was not successful for the following reason: " + status);
				self.emptyResults();
			}
		});
	};

	this.emptyResults = function () {
		document.getElementById("StoreSidebar").innerHTML = '<div class="StoreEmpty">No results found</div>';
	}

	this.searchLocations = function (address) {
		var self = this,
			d = window.document,
			address = d.getElementById('StoreField_Address').value;
		self.geocoder.geocode( { 'address': address}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				var radius = d.getElementById('StoreField_Radius').value,
					distance = d.getElementById('StoreField_Distance').value,
					result = self.getMarkers([self.installFolder, 'include/phpsqlsearch_genxml.php?lat=', results[0].geometry.location.lat(), '&lng=', results[0].geometry.location.lng(), '&radius=', radius, "&distance=", distance].join(""));
			} else {
				//alert("Geocode was not successful for the following reason: " + status);
				self.emptyResults();
			}
		});
	};
	
	this.bindSidebar = function () {
		var self = this,
			arr = JABB.Utils.getElementsByClass("sidebar_item", document.getElementById("StoreSidebar"), "a");
		for (var i = 0, len = arr.length; i < len; i++) {
			JABB.Utils.addEvent(arr[i], "click", function (e) {
				if (e.preventDefault) {
					e.preventDefault();
				}
				for (var j = 0, jlen = arr.length; j < jlen; j++) {
					JABB.Utils.removeClass(arr[j], "sidebar_focus");
				}
				JABB.Utils.addClass(this, "sidebar_focus");
				google.maps.event.trigger(self.markersArray[this.getAttributeNode("rel").value], 'click');
				return false;
			});
		}
	};
	
	this.bindSearchForm = function () {
		var self = this;
		document.getElementById("StoreField_Search").onclick = function (e) {
			self.searchLocations();
		};
	};
}
