// Global Classes
function Address() {
	return {
		streetAddress : "",
		streetAddress2 : "",
		firm : "",
		city : "",
		countrySubDivision : "",
		postalCode : "",
		country : new Country(),
		airportCode : "",
		
		reset : function() {
			this.streetAddress = "";
			this.streetAddress2 = "";
			this.firm = "";
			this.city = "";
			this.countrySubDivision = "";
			this.postalCode = "";
			this.country = new Country();
			this.airportCode= "";
		}
	}
}

function Point() {
	return {
		latitude : "0",
		longitude : "0"
	}
}

function LocatorLocation() {
	return {
		address : new Address(),
		point : new Point(),
		attributes : new Array(),
		distance : 0.0,
		distanceUnit : "mi",
		id : 0,
		name: ""
	}
}

function Country() {
     return {
        countryCode : "",
		name : "",
		supportsStreetLevelGeocoding : false 
	}
}

function Category() {
	return {
		id : "",
		name : ""
	}
}

// Global Variables
var locatorCountryList = new Array();
var locatorLocationList = new Array();
var locatorBrowseCityResultsArray;
var locatorCategoryList = new Array();
var locatorCategories =  "";
var currentQueryString = "";
var lastResultsQueryString = "";
var offset = 0;
var home = "";
var results = "";
var details = "";
var locatorDistanceUnitMiles = "miles";
var locatorDistanceUnitKilometers = "km";
var locatorUseResultsFilter = true;
var locatorUseSmallMapControls = false;
var searchATMType = "";

// Global State Variables
var lastPageLoadTime = new Date();
var currentPageLoadTime = new Date();
var pageLoadedFromHistory = false;
var currentPage = "home";
var previousPage = "home";
var newPageLoaded = true;
var locatorFormState;
var locatorCommon = new Array();

// Default Settings
var locatorMainLocation = "/interactivelocator/";
var locatorClientLocation = locatorMainLocation + "clients/merchant-default/";
var locatorHome = locatorClientLocation + "home.html";
var locatorResults = locatorClientLocation + "results.html";
var locatorDetails = locatorClientLocation + "details.html";
var locatorServiceHome = "/locationmanagementservice/services/"
var locatorLocale = "en_US";
var locatorLocationType = "paypass";
var locatorContentDivId = "locator-content";
var locatorDefaultCountry = "usa";
var locatorLocationsPerPage = 10;
var locatorCitiesPerPage = 20;
var locatorShowSMS = true;
var locatorDefaultDistanceUnit = "";
var locatorUseAutoSubmit = false;
var locatorAlwaysShowCities = "";

// Global Functions
function ServiceClient(serviceName, itemId, parameters) {
	var xhr = getXhr();
	var request = locatorServiceHome + serviceName + '/' + itemId + '?' + parameters;
	return {
		send : function(callbackObj) {
		 xhr.open("GET", request, true);
		 xhr.onreadystatechange=function() {
		  if (xhr.readyState==4) {
		   callbackObj.callback(xhr.responseXML);
		   
		  }
		 }
		 xhr.send(null);
	 }
  }
}

function loadCountryList(selectedCountryCode) {
	var callbackObj = {
		callback: function(responseXml) {
			var countryNodes = responseXml.getElementsByTagName("country");
			for (var i = 0; i < countryNodes.length; i++) {
				var country = new Country();
				country.countryCode = countryNodes[i].getElementsByTagName("countryCode")[0].firstChild.nodeValue.toLowerCase();
				if (locatorCommon[country.countryCode]) {
					country.name = locatorCommon[country.countryCode];
				} else {
					country.name = countryNodes[i].getElementsByTagName("name")[0].firstChild.nodeValue.toTitleCase();
				}
				if (countryNodes[i].attributes.getNamedItem("supportsStreetLevelGeocoding").value == "true") {
					country.supportsStreetLevelGeocoding = true;
				} else {
					country.supportsStreetLevelGeocoding = false;
				}
				locatorCountryList[i] = country;
			}
						
			displayCountries(selectedCountryCode);
			
		}
	}

	if (locatorCountryList.length <= 0) {
		var service = new ServiceClient("CountryListService", "", "locationType=" + locatorLocationType);
		service.send(callbackObj);
	} else {
		displayCountries(selectedCountryCode);
	}
}

function loadCategoryList() {
	var callbackObj = {
		callback: function(responseXml) {
			var categoryNodes = responseXml.getElementsByTagName("category");
			for (var i = 0; i < categoryNodes.length; i++) {
				var category = new Category();
				if (categoryNodes[i].getElementsByTagName("id")[0]) {
					category.id = categoryNodes[i].getElementsByTagName("id")[0].firstChild.nodeValue;
				}
				if (categoryNodes[i].getElementsByTagName("name")[0]) {
					if (locatorCommon['category.' + category.id]) { 
						category.name = locatorCommon['category.' + category.id]; 
					} else { 
						category.name = categoryNodes[i].getElementsByTagName("name")[0].firstChild.nodeValue.toTitleCase();
					}
				}
				locatorCategoryList[category.id] = category;
			}
		}
	}

	if (locatorCategoryList.length <= 0) {
		var service = new ServiceClient("CategoryService", "", "locationType=" + locatorLocationType);
		service.send(callbackObj);
	}
}

function getCategoryNameForId(catId) {
	var catName = "";
	if (locatorCategoryList[catId]) {
		catName = locatorCategoryList[catId].name;
	}
	return catName;
}


// Gets the XMLHTTPRequest object, with cross-browser support
function getXhr() {
	if(!xhr) {
		var xhr=false;
		// The commented block below will be run by some browser.
		// DO NOT REMOVE THIS COMMENTED BLOCK OF CODE
		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		// JScript gives us Conditional compilation, we can cope with old IE versions.
		// and security blocked creation of the objects.
		 try {
		  xhr = new ActiveXObject("Msxml2.XMLHTTP");
		 } catch (e) {
		  try {
		   xhr = new ActiveXObject("Microsoft.XMLHTTP");
		  } catch (E) {
		   xhr = false;
		  }
		 }
		@end @*/
		if (!xhr && typeof XMLHttpRequest!='undefined') {
			try {
				xhr = new XMLHttpRequest();
			} catch (e) {
				xhr=false;
			}
		}
		if (!xhr && window.createRequest) {
			try {
				xhr = window.createRequest();
			} catch (e) {
				xhr=false;
			}
		}
	}
	return xhr;
}

// Creates a cookie with the name and value passed in
// that lasts for the number of the days passed in.
function createCookie(name, value, days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

// Returns the value of a cookie by the given name.
// Returns null if the cookie doesn't exist.
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

// Erases a cookie of the given name.
function eraseCookie(name) {
	createCookie(name,"",-1);
}

// Looks for a URL parameter of the given name.
// So, if your URL ends in ?myVar=helloWorld and you call this function
// passing in the string "myVar", you'll get back the string "helloWorld".
function getURLParam(strParamName, windowObj){
  var strReturn = "";
  var strHref = windowObj.location.href;
  if ( strHref.indexOf("?") > -1 ){
    var strQueryString = strHref.substr(strHref.indexOf("?")).toLowerCase();
    var aQueryString = strQueryString.split("&");
    for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
      if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ){
		
        var aParam = aQueryString[iParam].split("=");
        strReturn = aParam[1];
        break;
      }
    }
  }
  
  return strReturn;
}

function Param() {
	return {
		name : "",
		value : ""
	}
}

// Returns all Params for a provided window
function getURLParams(windowObj) {
	var strHref = windowObj.location.href;
	var params = new Array();
	  if ( strHref.indexOf("?") > -1 ){
	    var strQueryString = strHref.substr(strHref.indexOf("?")).toLowerCase();
	    var aQueryString = strQueryString.split("&");
	    for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
	      if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ){
			var aParam = Param();
	        var aParamArr = aQueryString[iParam].split("=");
	        aParam.name = aParamArr[0];
	        aParam.value = aParamArr[1];
	        params[i] = aParam;
	      }
	    }
	  }	
}

// Finds the position of an object.  
// Use this to place another object nearby, on top, etc.
function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}


// Get a remote HTML page, and insert it into a html element using .innerHTML
// Provide the html ID, not the object itself
// The page is the url.
function loadRemotePage(htmlId, page) {
	if (document.getElementById(htmlId)) {
		var xhr = getXhr();
		 xhr.open("GET", page, true);
		 xhr.onreadystatechange=function() {
		  if (xhr.readyState==4 && document.getElementById(htmlId)) {
		   document.getElementById(htmlId).innerHTML=xhr.responseText;
		  }
		 }
		 xhr.send(null);
	}
}

// Same as above, but calls a callback function after remote content is loaded.
// Requires an object with a function named "callback"
function loadRemotePageWithCallback(htmlId, page, callbackObj) {
	if (document.getElementById(htmlId)) {
		var xhr = getXhr();
		 xhr.open("GET", page, true);
		 xhr.onreadystatechange=function() {
		  if (xhr.readyState==4) {
		   document.getElementById(htmlId).innerHTML=xhr.responseText;
		   callbackObj.callback();
		  }
		 }
		 xhr.send(null);
	}
}


var pageCache = new Array();

// Get a remote HTML page, and insert it into a 
// string variable.  Useful for pre-caching.
function cacheRemotePage(pageName, page) {
	var xhr = getXhr();
	 xhr.open("GET", page, true);
	 xhr.onreadystatechange=function() {
	  if (xhr.readyState==4) {
	   pageCache[pageName] = xhr.responseText;
	  }
	 }
	 xhr.send(null);
}

function addPageContentsToCache(pageName, pageContents) {
	pageCache[pageName] = pageContents;
}

function getCachedPage(pageName) {
	return pageCache[pageName];
}

/**	Returns a list of elements with a given class name.
	oElm is the uppermost object to look in.  Use the document object 
		to search an entire page (slower of course).
	strTagName is the actual tag name to look for, such as "a" or "div". 
		Use "*" to
	
*/
function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }   
    }
    return (arrReturnElements)
}

String.noLC = new Object
  ({the:1, a:1, an:1, and:1, or:1, but:1, aboard:1,
    about:1, above:1, across:1, after:1, against:1,
    along:1, amid:1, among:1, around:1, as:1, at:1,
    before:1, behind:1, below:1, beneath:1, beside:1,
    besides:1, between:1, beyond:1, but:1, by:1, 'for':1,
    from:1, 'in':1, inside:1, into:1, like:1, minus:1,
    near:1, of:1, off:1, on:1, onto:1, opposite:1,
    outside:1, over:1, past:1, per:1, plus:1,
    regarding:1, since:1, than:1, through:1, to:1,
    toward:1, towards:1, under:1, underneath:1, unlike:1,
    until:1, up:1, upon:1, versus:1, via:1, 'with':1,
    within:1, without:1});

function toTitleCase() {
  var parts = this.toLowerCase().split(' ');
  if ( parts.length == 0 ) return '';
  var fixed = new Array();
  for ( var i in parts ) {
    var fix = '';
    if ( String.noLC[parts[i]] )
    {
      fix = parts[i].toLowerCase();
    }
    else if ( parts[i].match(/^([A-Z]\.)+$/i) )
    { // will mess up "i.e." and like
      fix = parts[i].toUpperCase();
    }
    else if ( parts[i].match(/^[^aeiouy]+$/i) )
    { // voweless words are almost always acronyms
      fix = parts[i].toUpperCase();
    }
    else
    {
      fix = parts[i].substr(0,1).toUpperCase() +
                 parts[i].substr(1,parts[i].length);
    }
    fixed.push(fix);
  }
  fixed[0] = fixed[0].substr(0,1).toUpperCase() +
                 fixed[0].substr(1,fixed[0].length);
  return fixed.join(' ');
}

String.prototype.toTitleCase = toTitleCase;


function scrollToObj(positionObj) {
	var xy = findPos(positionObj);
	window.scrollTo(xy[0], xy[1]);
}