var RosettaFossilLocator = function(){//CONSTANTS
	var INIT_VISIBLE_REGION_SW = new GLatLng(23, 58);
	var INIT_VISIBLE_REGION_NE = new GLatLng(49, 120);
	var DEFAULT_VISIBLE_REGION_SW = new GLatLng(23, 58);
	var DEFAULT_VISIBLE_REGION_NE = new GLatLng(49, 120);
	var PER_PAGE = 5;
	var DEFAULT_STORE_TITLE = 'Fossil Store;';
	var DEFAULT_STORE_URL = '#showstore;';
	var MAX_NUM_FILTERS = 3;
	var DEFAULT_FAILED_SEARCH_TEXT = 'No stores were found with the criteria entered. Please refine your search or change your address.';
	var DEFAULT_SENDSTORE_SUBJECT = 'Your Directions to Fossil';
	var DEFAULT_SENDSTORE_BODY_1 = 'I sent you the location to';
	var	DEFAULT_SENDDIRS_SUBJECT = 'Your Directions to Fossil';
	var RADIUS = 250; 	//in miles
	var MIN_LOCATIONS_TO_DISPLAY = 1;
	var MAX_LOCATIONS_TO_DISPLAY = 62; // should be a multiple of PER_PAGE
	var DEFAULT_STARTING_ADDRESS = 'KS;';
	var DEFAULT_STARTING_ZOOM_LEVEL = 3;
	var DEFAULT_USER_LOC_ZOOM_LEVEL = 7;
	var SHOW_ALL_LOCATIONS_ON_INIT = 0;

	var map;			// main map
	var myAddress;		// address string
	var myLoc;			// user location as a GLatLng
	var userLocMarker;	// marker object
	var myAddressGood=1;// bool if address returns good geocode
	var timedOutError=1;//for network connectivity issue, or empty zipcode
	var eWindow;
	var storeId;
	var getDirs;
	var dirsUrl;
	var page;			// which page of the results is displayed; 1-indexed
	var pages;			// total pages for the data returned from the service
	var pagesInCurDataset; // total number of pages for the current (filtered) dataset
	var allLocsReturned = {};	//complete dataset returned from service
	var curDataset = {};
	var numLocsReturned;
	var numLocsInCurDataset;
	var nextResultToCheck = 0;
	var filteredElems = []; // array of bools that holds an elements filter status
	var filterString = ''; // string generated by the checkboxes, pipe delimited
	var zoomLevels = [];
	var directions;
	var boundsOfResultsToDisplay = new GLatLngBounds();
	var curNumFilters = '0';
	var queryStringParams;
	var markers = {};
	var mapIcon;
	var openWindows; // Bool; if there are query string params when the page loads, open the windows; after that even if there are params, don't open the windows

	//async timeout objects
	var userLocTO;
	var dirTO;

	var dirmap;
	var directionsPanel;
	var directions;

	//public function references
	return {
		TimedOutError: isTimedOutError,
		MyAddressGood: isAddressGood,
		start: initializeApp,
		GetDirections: getDirections,
		ChangeDirections: changeDir
	}

	function initializeApp(fossilStoreDataURL) {
		StoreDataURL = fossilStoreDataURL;
		if(!GBrowserIsCompatible()){
			return false;
		}

		//pull out user address from query string
		queryStringParams = parseQueryStr();
		myAddress = myAddress || queryStringParams.loc;
		storeId="";
		storeId=queryStringParams.fossilstore;
		getDirs = queryStringParams.dirs;

		map = new GMap2(document.getElementById("map_canvas"));
		$("#address").val(myAddress);

		//reset all checkboxes to checked state
		$(".storeFilter .filter input").attr("checked", "checked");
		filterString = ""; // don't filter anything initially
		eWindow = new EWindow(map, E_STYLE_1);
		map.addOverlay(eWindow);
		map.setUIToDefault();
		if (myAddress != 0 && myAddress != null && myAddress !== undefined) {
			getUserGeo(myAddress, 1, getLocations);
		}

		$("#btn_go").click(function(){
			//if(checkAllErrors("content_div")){
				$(".storeFilter .filter input").attr('checked','checked');
				myAddress = $("#address").val();
				getUserGeo(myAddress, 1, getLocations);
				//}
			});

			$("#pageUp").click(function(){

				if(page > 1){
					page--;
					clearStoreMarkers();
					showResults(curDataset);

					$("#pageDown").css("visibility","visible");

					if(page > 1){
						$("#pageUp").css("visibility","visible");
					}
					else{
						$("#pageUp").css("visibility","hidden");
					}
				}
				else{
				}
				return false;
			});

			$("#pageDown").click(function(){
				if(page < pagesInCurDataset){
					page++;
					clearStoreMarkers();
					showResults(curDataset);

					$("#pageUp").css("visibility", "visible");

					if(page==pagesInCurDataset){
						$("#pageDown").css("visibility","hidden");
					}
					else{
						$("#pageDown").css("visibility","visible");
					}
				}

				return false;
			});

			$(".storeFilter .filter input").click(function(){
				var thisStoreType = $(this).attr("name");

				// checked; adding these types; remove string from filterlist
				if ($(this).attr("checked")) {
					curNumFilters--;

					if (filterString.indexOf(thisStoreType) >= 0) {
						// if filterlist contains the type
						// remove store type from filterlist
						filterString = filterString.removeString(thisStoreType + "|");
					}
				}

				// unchecked; removing these types; add store type to filterList
				else {

					if (filterString == '') {
						// if filterlist empty
						filterString = thisStoreType + "|";
					}
					else
					if (filterString.indexOf(thisStoreType) == -1) {
						// if filterlist doesn't contain the type add the type
						filterString = filterString.concat(thisStoreType + "|");
					}
				}

				if (eWindow) {
					eWindow.hide();
				}
				// Now that filter string has been updated...
				filterDataSet(); // synchronously
			});

			$('#locationA').keypress(function(event){
				hitEnter(event, $('#getDirections'));
			});

			$('#address').keypress(function(event){
				hitEnter(event, $('#btn_go'));
			});

			$('#print').click(function(){
				window.print();
				$(this).blur();
			});

			return;
		}

		function getUserGeo(myAddress, showMarker, callBack){
			geoCoder = new GClientGeocoder();
			userLocTO = setTimeout(userGeoTimedOut, 30000);
			geoCoder.getLatLng(myAddress,
				function(point){
					if(!point){//no geocode returned - invalid address
						myAddressGood = 0;
						checkAllErrors();
						myAddressGood = 1;
						clearTimeout(userLocTO);
					}
					else{
						clearTimeout(userLocTO);
						myAddressGood = 1;
						myLoc = point;

						map.setCenter(myLoc, DEFAULT_USER_LOC_ZOOM_LEVEL);

						var baseIcon = new GIcon(G_DEFAULT_ICON);
						baseIcon.image = "/wcsstore/Fossil/images/en_US/storeLocator/map_icon_red.png";
						baseIcon.shadow = "/wcsstore/Fossil/images/en_US/storeLocator/map_shadow.png";
						baseIcon.iconSize = new GSize(27, 28);
						baseIcon.shadowSize = new GSize(49,28);
						//offset pinpoints
						var newp = new GPoint(18,28);
						baseIcon.iconAnchor=newp;
						markerOpts = {icon:baseIcon};
						if(typeof(userLocMarker) != 'undefined'){map.removeOverlay(userLocMarker);}
						userLocMarker = new LabeledMarker(point, markerOpts);
						map.addOverlay(userLocMarker);

						if (callBack != undefined && callBack != null) {
							callBack(myLoc);
						}
					}
				}
			);
		}

		function userGeoTimedOut(){
			//alert('Request TimedOut. Please Try again');
			timedOutError = 0;
			checkAllErrors();
			timedOutError = 1;
		}

		function getLocations(center){
			options = {};
			options.dataType = "json";
			options.success = function(json, textStatus){
				allLocsReturned = json;
				numLocsReturned = 0;
				page = 1;
				boundsOfResultsToDisplay = map.getBounds();

				// counting number of results and placing markers on map
				$.each(allLocsReturned, function(i, loc){
					if (numLocsReturned >= MAX_LOCATIONS_TO_DISPLAY) {
						return; // just in case the web service misbehaves
					}
					numLocsReturned++;
				});
				calcStoreTypeTotals();
				pages = calcNumPages(numLocsReturned);
				clearStoreMarkers();
				curDataset = cloneObj(allLocsReturned);
				numLocsInCurDataset = numLocsReturned;
				pagesInCurDataset = pages;
				zoomLevels = [];
				showResults(curDataset);
			};
			options.error = function(XMLHttpRequest, textStatus, errorThrown){
				allLocsReturned = {};
				numLocsReturned = 0;
				page = 1;
				clearStoreMarkers();
				curDataset = cloneObj(allLocsReturned);
				numLocsInCurDataset = numLocsReturned;
				pagesInCurDataset = pages;
				zoomLevels = [];
				showResults(curDataset);
			};
			options.url = StoreDataURL;
			options.data = {lat: myLoc.lat(), lng: myLoc.lng(), radius: RADIUS, maxnum: MAX_LOCATIONS_TO_DISPLAY};


			$.ajax(options);
		}

		function calcStoreTypeTotals(){
			var numAcc=0;
			var numApp=0;
			var numOut=0;
			var numPar=0;
			for(loc in allLocsReturned){
				var storeType = allLocsReturned[loc].type;
				switch(storeType){
					case 'accessory':
					numAcc+=1;
					break;
					case 'apparel':
					numApp+=1;
					break;
					case 'outlet':
					numOut+=1;
					break;
					case 'partner':
					numPar+=1;
					break;
				}
			}
			// write to dom
			$('#accessory_count').html(' ('+numAcc+')');
			$('#apparel_count').html(' ('+numApp+')');
			$('#outlet_count').html(' ('+numOut+')');
			$('#partner_count').html('  ('+numPar+')');
		}

		function clearStoreMarkers(locations){
			for(var pins in markers){
				map.removeOverlay(markers[pins]);
			}
			/*if(locations.length){
			var loclen = locations.length;
			for(var i=0; i<loclen; ++i){
			var mid = locations[i].id
			if (markers[mid]) {
			map.removeOverlay(markers[mid]);
			}
			}
			}
			else{
			for(var index in locations){
			var mid = locations[index].id
			if (markers[mid]) {
			map.removeOverlay(markers[mid]);
			}
			}
			}*/

		}

		function showResults(locations){
			var thisHtml = '';
			var numInFilteredList = 0;
			var thisResult;
			var locGPoint; // local variable for current location being iterated

			if(numLocsInCurDataset < 1){
				thisHtml += '<div class="result no_result"><span class="title">' + DEFAULT_FAILED_SEARCH_TEXT + '</span></div>';
			}

			for(i = 0; i < numLocsInCurDataset; i++){

				if(locations[i]){
					thisResult = locations[i];


					//for those results that will be displayed in the list...
					if (i >= (page - 1) * PER_PAGE && i < page * PER_PAGE) {
						numInFilteredList++; // since it's being included
						var label = String.fromCharCode("A".charCodeAt(0) + numInFilteredList - 1)

						//setting left column html
						thisHtml += '<div class="result';
						if (thisResult.type) {
							thisHtml += ' ' + thisResult.type;
						}
						thisHtml += '" id="vis_result_' + (i + 1) + '"';
						if (thisResult.id) {
							thisHtml += ' storeId="' + thisResult.id + '">';
						}
						thisHtml += '<span class="title">' + label + ') <a href="';
						if (thisResult.url) {
							thisHtml += thisResult.url;
						}
						else {
							thisHtml += DEFAULT_STORE_URL;
						}
						thisHtml += '">';
						if (thisResult.title) {
							thisHtml += thisResult.title;
						}
						else {
							thisHtml += DEFAULT_STORE_TITLE;
						}
						thisHtml += '</a></span><span class="distance">';
						if (thisResult.distance) {
							thisHtml += thisResult.distance + ' mi';
						}
						else {
							thisHtml += '?? mi';
						}
						thisHtml += '</span><p class="address">';
						if (thisResult.address) {
							thisHtml += thisResult.address + '<br />';
							if (thisResult.address2) {
								thisHtml += thisResult.address2 + '<br />';
							}
						}
						if (thisResult.city) {
							thisHtml += thisResult.city;
						}
						if (thisResult.city && (thisResult.state || thisResult.zip)) { //only place a comma if state or zip are also present
							thisHtml += ', ';
						}
						if (thisResult.state) {
							thisHtml += thisResult.state;
						}
						if (thisResult.state && thisResult.zip) {
							thisHtml += ' ';
						}
						if (thisResult.zip) {
							thisHtml += thisResult.zip;
						}
						if (thisResult.phone) {
							thisHtml += '<br />' + thisResult.phone;
						}
						thisHtml += '</p></div>';

						locGPoint = new GLatLng(thisResult.lat, thisResult.lng);
						var infoWindowHtml = getInfoWindowHtml(i, thisResult)
						var marker = initMarker(locGPoint, thisResult.id, infoWindowHtml, label, "blank");
						map.addOverlay(marker);

						//check if this point is within the visible map
						//if not, enlargen the map; do not shrink the map even after paging back up
						locGPoint = new GLatLng(thisResult.lat, thisResult.lng);
						if (!boundsOfResultsToDisplay.containsLatLng(locGPoint)) {
							boundsOfResultsToDisplay.extend(locGPoint);
						}
					}

					//else add the result to the map but not to the list
					else {
						locGPoint = new GLatLng(thisResult.lat, thisResult.lng);
						var infoWindowHtml = getInfoWindowHtml(i, thisResult)
						var marker = initMarker(locGPoint, thisResult.id, infoWindowHtml, "");
						map.addOverlay(marker);
					}
				}
			}

			map.setCenter(myLoc);
			if (zoomLevels[page] != undefined && zoomLevels[page] != "" && zoomLevels[page] != null) {
				map.setZoom(zoomLevels[page]);
			}
			else{
				zoomLevels[page]=map.getBoundsZoomLevel(boundsOfResultsToDisplay);
				map.setZoom(zoomLevels[page]);
			}

			generatePagination();

			$("#pageUp").css("visibility", "hidden"); //since on first page
			if(numLocsInCurDataset > PER_PAGE){
				$("#pageDown").css("visibility", "visible");
			}
			else{
				$("#pageDown").css("visibility", "hidden");
			}

			$("#storeResults").fadeOut(800, function(){
				$(this).html(thisHtml).fadeIn(800);

				//sets the click event handler for the store titles
				$("#storeResults .result .title").click(function(){
					var thisStoreId = $(this).parent().attr("storeId");

					if (thisStoreId >= 0 && thisStoreId != undefined && thisStoreId != null) {
						GEvent.trigger(markers[thisStoreId], "click");
						return false;
					}

					return false;
				});

				// If there's a storeId in the queryString, open that store's info window
				if ( openWindows && storeId != "" && storeId > 0 && storeId != undefined && storeId != null) {
					if (getDirs) {
						GEvent.addListener(markers[storeId], "click", function(){
							setTimeout(function(){
								$("a.getDir").click();
								}, 500);
							});
						}
						GEvent.trigger(markers[storeId], "click");
					}
					openWindows = 0;
				});
			}

			function generatePagination(){
				var firstResult; // on current page
				var lastResult; // on current page
				var html;

				firstResult = (page-1) * PER_PAGE + 1;

				if (page * PER_PAGE > numLocsInCurDataset) {
					lastResult = numLocsInCurDataset;
				}
				else if(page * PER_PAGE <= numLocsInCurDataset){
					lastResult = page * PER_PAGE;
				}

				if(numLocsInCurDataset == 0)
				{
					html = "0-0 of 0"
				} else {
					html = firstResult + "-" + lastResult + " of " + numLocsInCurDataset;
				}
				$("#pageValues").fadeOut(800, function(){
					$(this).html(html).fadeIn(800);
				});
			}

			function filterDataSet(){
				var filters = filterString.split('|');
				filters.pop(); // remove the last element since it will always be the empty string
				var fl = filters.length;
				clearStoreMarkers();
				curDataset = {};
				numLocsInCurDataset = 0; //reset
				zoomLevels=[];
				//map.clearOverlays();
				map.setCenter(myLoc, DEFAULT_USER_LOC_ZOOM_LEVEL);

				var passed;

				for(var i = 0; i < numLocsReturned; i++){
					passed = 1;
					for (var j= 0; j<fl; j++){
						if (allLocsReturned[i].type.toLowerCase() == filters[j]) {
							passed = 0;
							break;
						}
					}
					if(passed){
						curDataset[numLocsInCurDataset] = allLocsReturned[i];
						numLocsInCurDataset++;
					}
				}

				page = 1;
				pagesInCurDataset = calcNumPages(numLocsInCurDataset);
				boundsOfResultsToDisplay = map.getBounds();
				showResults(curDataset);
			}

			function initMarker(point, id, html, label, iconType){
				var baseIcon = new GIcon(G_DEFAULT_ICON);
				if (iconType == "blank") {
					baseIcon.image = "/wcsstore/Fossil/images/en_US/storeLocator/map_icon.png";
				}
				else{
					baseIcon.image = "/wcsstore/Fossil/images/en_US/storeLocator/map_icon_dot.png";
				}
				baseIcon.shadow = "/wcsstore/Fossil/images/en_US/storeLocator/map_shadow.png";
				baseIcon.iconSize = new GSize(34, 31);
				baseIcon.shadowSize = new GSize(53,27);
				//offset pinpoints
				var newp = new GPoint(18,28);
				baseIcon.iconAnchor=newp;
				markerOpts = {icon:baseIcon, labelText: label};
				var marker = new LabeledMarker(point, markerOpts);
				GEvent.addListener(marker, "click", function(){
					eWindow.openOnMarker(marker, html);
					storeId = id;
					$(".storeLocatorResults #close_details").click(function(e){
						e.preventDefault();
						eWindow.hide();
					});
					return false;
				});
				markers[id] = marker;
				return marker;
			}

			function getInfoWindowHtml(i, loc){
				var html = "";
				var storeAddress = "";
				var directionsLink = "";
				var mailtoUrl;
				var sendLinkAnchor = "";
				var sendLinkMailto="";
				var urlBase = "";
				var googleMapUrl = "";
				var startAddress = "";

				//Creating the address string
				if (loc.address) {
					storeAddress += loc.address;
				}
				if (loc.city) {
					storeAddress += '%20' + loc.city;
				}
				if(loc.city && (loc.state || loc.zip) ){ //only place a comma if state or zip are also present
					storeAddress += ',%20';
				}
				if(loc.state){
					storeAddress += '%20' + loc.state;
				}
				if(loc.state && loc.zip){
					storeAddress += '%20';
				}
				if(loc.zip){
					storeAddress += loc.zip;
				}
				if(loc.zip && loc.phone){
					storeAddress += '%20';
				}
				googleMapUrl = '<a href="http://maps.google.com/maps?saddr=';

				directionsLink = '<a href="#getdir" class="getDir" onclick="RosettaFossilLocator.GetDirections(\''+$("#address").val()+'\',\''+unescape(storeAddress)+'\'); return false;">';
				mailtoUrl = buildUrl(loc.id, 1, 1, 0);
				sendLink = '<a class="send" href="mailto:?subject=' + DEFAULT_SENDSTORE_SUBJECT + '&body=' + encodeURIComponent(DEFAULT_SENDSTORE_BODY_1) +'%20'+loc.address+'%20 using Google Maps.' + '%0D%0D' + encodeURIComponent(mailtoUrl) +'" >';

				html+='<div class="point_details"';
				if (loc.type) {
					html += ' ' + loc.type;
				}
				html+='"><a href="#" id="close_details"><span>Close</span></a><h3 id="point_title">';
				if (loc.title) {
					html += loc.title;
				}
				else{
					html+= DEFAULT_STORE_TITLE;
				}
				html+='</h3><p id="point_address">';
				if (loc.address) {
					startAddress += '+'+loc.address.replace(" ","+");
					html += loc.address + '<br/>';
					if (loc.address2) {
						startAddress += '+'+loc.address2.replace(" ","+");
						html += loc.address2 + '<br/>';
					}
				}
				if (loc.city) {
					startAddress += '+'+loc.city.replace(" ","+");
					html += loc.city;
				}
				if(loc.city && (loc.state || loc.zip) ){ //only place a comma if state or zip are also present
					html += ', ';
				}
				if(loc.state){
					startAddress += '+'+loc.state.replace(" ","+");
					html += loc.state;
				}
				if(loc.state && loc.zip){
					html += ' ';
				}
				if(loc.zip){
					startAddress += '+'+loc.zip.replace(" ","+");
					html += loc.zip;
				}
				if(loc.zip || loc.state || loc.zip){
					html+= '<br/>';
				}
				if(loc.phone){
					html+=loc.phone+'<br/>';
				}

				html+='</p><p id="point_distance">';
				if(loc.distance){
					html+=loc.distance;
				}
				else{
					html+='??';
				}

				for (var i = 0; i < startAddress.length; i++)
				{
					var ch = startAddress.charAt(i);
					if(!isNaN(ch) && ch!= ' ')
					{
						startAddress = startAddress.substr(i);
						break;
					}
				}


				googleMapUrl+=myAddress;
				googleMapUrl+='&daddr='+startAddress;
				googleMapUrl+='" target="_blank">';
				html+='</p>';
				html+= googleMapUrl;
				html+='GET DIRECTIONS</a>';
				html+='        ';
				html+= sendLink ;
				html+='SEND</a></div>';
				return html;
			}

			function parseQueryStr(){
				var args = new Object();
				var query = decodeURIComponent(decodeURI(location.search.substring(1)));
				var pairs = query.split("&");

				for( var i = 0; i < pairs.length; i++){
					var pos = pairs[i].indexOf('=');
					if(pos==-1){
						continue;
					}
					var argname = pairs[i].substring(0,pos);
					var value = pairs[i].substring(pos+1);
					value = decodeURIComponent(value);
					args[argname] = value;
				}

				return args;
			}

			function buildUrl(storeId, includeUserLoc, includeStoreId, getDirs){
				var url = location.toString();
				if(url.indexOf('&loc') != -1){
					url = url.substring(0,url.indexOf('&loc'));
				}

				url += url.indexOf('?') == -1 ? '?' : '&';

				if(includeUserLoc){
					url+= "loc=" + encodeURIComponent(myAddress);
				}

				if(includeUserLoc && includeStoreId){
					url += "&";
				}

				if(includeStoreId){
					url += "fossilstore=" + storeId;
				}

				if (getDirs) {
					url += encodeURIComponent("&") + 'dirs=1';
				}
				return url;
			}

			function calcNumPages(num){
				if (num % PER_PAGE == 0) {
					return parseInt(num / PER_PAGE);
				}
				else {
					return parseInt(num / PER_PAGE) + 1;
				}
			}

			function placeMarkerOnMap(point, clickable, iconImage, iconShadow){

				var baseIcon = new GIcon(G_DEFAULT_ICON);
				baseIcon.image = iconImage;
				baseIcon.shadow = iconShadow;
				baseIcon.iconSize = new GSize(27, 28);
				baseIcon.shadowSize = new GSize(49,28);
				//offset pinpoints
				var newp = new GPoint(18,28);
				baseIcon.iconAnchor=newp;
				markerOpts = {icon:baseIcon, labelText: label};
				var marker = new LabeledMarker(point, markerOpts);
				var marker = new GMarker(point);
				map.addOverlay(marker);
			}

			function hitEnter(e, button){
				if(e.which==13){
					button.trigger('click');
				}
			}

			function getDirections(start, dest){
				tb_show(null, '#TB_inline?height=530&width=749&inlineId=modalWrapper&modal=true', false);
				$('#TB_ajaxContent').css('padding-bottom',0);
				changeDirections(start,dest);
			}

			$("#TB_closeWindowButton").bind("mousedown",function(){
				clearRosError();
			});

			function changeDir(){
				if(checkAllErrors(1,'#ddForm')) {
					changeDirections($('#locationA').val(), $('#locationB').val());
				}
			}

			function changeDirections(start, dest){
				$('#driving_directions').html('');
				$('#locationA').val('');
				$('#locationB').val('');
				myAddress = start;
				var url = buildUrl(storeId, 1, 1, 1);
				dirsUrl = 'mailto:?subject=' + DEFAULT_SENDSTORE_SUBJECT + '&body=' + encodeURIComponent(DEFAULT_SENDSTORE_BODY_1) +'%20'+ dest +'%20 using Google Maps.' + '%0D%0D' + encodeURIComponent(url);
				$("#dir_send").attr("href", dirsUrl);

				if (directions != undefined) {
					directions.clear();
				}
				//set fields and reset to driving mode
				$('#locationA').val(start);
				$('#locationB').val(dest);
				dirmap = new GMap2(document.getElementById("ddMap"));
				dirmap.clearOverlays();
				dirmap.disableDragging();
				dirmap.disableInfoWindow();
				dirmap.disableDoubleClickZoom();
				dirmap.disableScrollWheelZoom();
				dirmap.disablePinchToZoom();
				directionsPanel = document.getElementById("driving_directions");
				directions = new GDirections();

				GEvent.addListener(directions, "load", function(){
					clearTimeout(dirTO);
					// get route/steps and write to page
					var myroute = directions.getRoute(0);
					var numsteps = myroute.getNumSteps();
					var dd = $('#driving_directions');
					dd.html('');
					dd.append('<h3 id="directionsTitle" class="hBorder">Driving Directions to '+ $('#locationB').val()+'</h3>');
					dd.append('<p id="distanceInfo">'+ myroute.getSummaryHtml() +'</p>');
					dd.append('<div class="ddItem"><div class="list"><img alt="Starting Point" src="/wcsstore/Fossil/images/en_US/storeLocator/start_point.png" /></div><p class="loc">'+ $('#locationA').val()+'</p></div>');
					for(var i=0; i<numsteps; ++i){
						var step = myroute.getStep(i);
						dd.append('<div class="ddItem"><div class="list">'+ (i+1) +')'+'</div><div class="loc">'+ step.getDescriptionHtml() +'</div><p class="dist">'+ step.getDistance().html +'</p></div>');

					}
					dd.append('<div class="ddItem"><div class="list"><img alt="Destination" src="/wcsstore/Fossil/images/en_US/storeLocator/end_point.png" /></div><p class="loc">'+ $('#locationB').val()+'</p></div>');

					//map
					var start = directions.getMarker(0);
					var end = directions.getMarker(1);

					var line = directions.getPolyline();


					//points
					var baseIcon = new GIcon(G_DEFAULT_ICON);
					var offset = new GPoint(12,12);
					baseIcon.iconSize = new GSize(22, 21);
					baseIcon.shadowSize = new GSize(0,0);
					baseIcon.iconAnchor=offset;

					var startIcon = new GIcon(baseIcon, "/wcsstore/Fossil/images/en_US/storeLocator/start_point.png");
					var endIcon = new GIcon(baseIcon, "/wcsstore/Fossil/images/en_US/storeLocator/end_point.png");
					var start_marker = new LabeledMarker(start.getLatLng(), {icon: startIcon});
					var end_marker = new LabeledMarker(end.getLatLng(), {icon: endIcon});

					dirmap.addOverlay(start_marker);
					dirmap.addOverlay(end_marker);
					dirmap.addOverlay(line);

					var dirbounds = directions.getBounds();
					var dircenter = dirbounds.getCenter();
					var dirz = dirmap.getBoundsZoomLevel(dirbounds);
					dirmap.setCenter(dircenter, dirz);

					//reset vert scroll
					$("#modalContent").jScrollPane();
				});
				GEvent.addListener(directions, "error", function(){
					$('#driving_directions').html('<h3 class="error">There was a problem retrieving the directions.</h3>');
					setTimeout(function(){$("#TB_closeWindowButton").trigger('click');},5000);
				});
				dirTO = setTimeout(dirTimedOut, 30000);
				directions.load("from: "+start+" to: "+ dest, {"getSteps": true, 'getPolyline': true} );
			}

			function dirTimedOut(){
				//alert('request timed out. please try again');
				timedOutError = 0;
				checkAllErrors();
				timedOutError = 1;
			}

			function cloneObj(obj){
				if (obj == null || typeof(obj) != 'object') {
					return obj;
				}
				var temp = new obj.constructor();
				for (var key in obj) {
					temp[key] = cloneObj(obj[key]);
				}
				return temp;
			}

			function isAddressGood(){
				return myAddressGood;
			}

			function isTimedOutError() {
				return timedOutError;
			}
			}();


			String.prototype.removeString = function(stringToRemove){
				var posOfStringToRemove = this.indexOf(stringToRemove);
				var newString = '';

				if(this.length > 0 && posOfStringToRemove != -1){
					newString = this.substr(0, posOfStringToRemove);
					newString += this.substr(posOfStringToRemove + stringToRemove.length, this.length-1);
					return newString;
				}
				else{
					return null;
				}
			};
