//*********** Debugging code ***********
var reportStatus = new Array();
function report ( msg ) {
    reportStatus.push ( msg );
}
function showReport () {
		if( reportStatus[0].indexOf("Error loading script") != -1 )
			return;
    alert ( "javascript reporting an error: " + reportStatus.join ( "\n" ) );
}
window.onerror = function ( err, url, line ) {
    report ( err + " [" + url + " - line " + line + "]" );
    showReport();
}

//*********** Utility functions ***********
String.prototype.replaceAll = function(strTarget, strSubString) {
var strText = this;
var intIndexOfMatch = strText.indexOf( strTarget );
while (intIndexOfMatch != -1) {
	strText = strText.replace( strTarget, strSubString )
	intIndexOfMatch = strText.indexOf( strTarget );
}
return( strText );
}


//*********** Create icons ***********
		var dollaricon = new GIcon();
		dollaricon.image = "images/dollar.png";
		dollaricon.shadow = "images/dollarshadow.png";
		dollaricon.iconSize = new GSize(19, 28);
		dollaricon.shadowSize = new GSize(30, 28);
		dollaricon.iconAnchor = new GPoint(10, 27);
		dollaricon.infoWindowAnchor = new GPoint(12, 3);
		
		var targetLocationIcon = new GIcon();
		targetLocationIcon.image = "images/dollar2.png";
		targetLocationIcon.shadow = "images/dollar2shadow.png";
		targetLocationIcon.iconSize = new GSize(20, 24);
		targetLocationIcon.shadowSize = new GSize(28, 24);
		targetLocationIcon.iconAnchor = new GPoint(14, 24);
		targetLocationIcon.infoWindowAnchor = new GPoint(16, 3);
		
		var chickenicon = new GIcon();
		chickenicon.image = "images/chicken.png";
		chickenicon.shadow = "images/chickenshadow.png";
		chickenicon.iconSize = new GSize(25, 26);
		chickenicon.shadowSize = new GSize(34, 26);
		chickenicon.iconAnchor = new GPoint(11, 23);
		chickenicon.infoWindowAnchor = new GPoint(7, 4);
		
		var gunicon = new GIcon();
		gunicon.image = "images/gun.png";
		gunicon.shadow = "images/gunshadow.png";
		gunicon.iconSize = new GSize(28, 21);
		gunicon.shadowSize = new GSize(37, 21);
		gunicon.iconAnchor = new GPoint(19, 19);
		gunicon.infoWindowAnchor = new GPoint(3, 3);
		
		var liquoricon = new GIcon();
		liquoricon.image = "images/wine.png";
		liquoricon.shadow = "images/wineshadow.png";
		liquoricon.iconSize = new GSize(11, 32);
		liquoricon.shadowSize = new GSize(24, 32);
		liquoricon.iconAnchor = new GPoint(5, 31);
		liquoricon.infoWindowAnchor = new GPoint(6, 3);
		
		var pawnicon = new GIcon();
		pawnicon.image = "images/pawn.png";
		pawnicon.shadow = "images/pawnshadow.png";
		pawnicon.iconSize = new GSize(21, 16);
		pawnicon.shadowSize = new GSize(29, 16);
		pawnicon.iconAnchor = new GPoint(10, 15);
		pawnicon.infoWindowAnchor = new GPoint(15, 2);
		
//*********** Basefinder Data ***********

//bases is array of arrays, with subarray of form [search string, display text, number of nearby lenders]
var defaultBase = 0;
var bases = new Array();
bases.push( new Array("Maxwell-Gunter AFB,Al", "Maxwell-Gunter AFB (Alabama)", 40) ); //verified
bases.push( new Array("Little Rock AFB,AR", "Little Rock AFB (Arkansas)", 60) ); //xx
bases.push( new Array("Fort Irwin, CA", "Fort Irwin (California)", 45) ); //xx
bases.push( new Array("McConnell AFB,KS", "McConnell AFB (Kansas)", 90) ); // 
bases.push( new Array("Fort Riley, KS", "Fort Riley (Kansas)", 45) ); // 
bases.push( new Array("Fort Dix, NJ", "Fort Dix (New Jersey)", 45) ); // 
bases.push( new Array("West Point, NY", "West Point (New York)", 45) ); // 
bases.push( new Array("Fort Bragg, NC", "Fort Bragg (North Carolina)", 45) ); // 
bases.push( new Array("Kelly AFB,TX", "Kelly AFB (Texas)", 90) ); //
bases.push( new Array("Fort Lewis, WA", "Fort Lewis (Washington)", 45) ); // 
bases.push( new Array("Fort Benning, GA", "Fort Benning (Georgia)", 45) ); // 
//bases.push( new Array("29 Palms, CA", "29 Palms Marine Corps Air Ground Combat Center (California)", 45) ); 
//bases.push( new Array("Camp Pendleton, CA", "Camp Pendleton (California)", 45) ); // 
bases.push( new Array("Peterson AFB, CO", "Peterson AFB (Colorado)", 45) ); // 
bases.push( new Array("Dover AFB, DE", "Dover AFB (Delaware)", 45) ); // 
bases.push( new Array("NAS Jacksonville, FL", "NAS Jacksonville (Florida)", 45) ); // 
bases.push( new Array("Mountain Home AFB, ID", "Mountain Home AFB (Idaho)", 45) ); // 
bases.push( new Array("Fort Campbell, KY", "Fort Campbell (Kentucky)", 45) ); // 
bases.push( new Array("Barksdale AFB, LA", "Barksdale AFB (Louisiana)", 45) ); // 
bases.push( new Array("Fort Leonard Wood, MO", "Fort Leonard Wood (Missouri)", 45) ); // 
bases.push( new Array("Seymour Johnson AFB, NC", "Seymour Johnson AFB (North Carolina)", 45) ); // 
bases.push( new Array("Wright-Patterson AFB, OH", "Wright-Patterson AFB (Ohio)", 45) ); // 
bases.push( new Array("Tinker AFB, OK", "Tinker AFB (Oklahoma)", 45) ); // 
bases.push( new Array("Fort Gordon, GA", "Fort Gordon (Georgia)", 45) ); // 
bases.push( new Array("Shaw AFB, SC", "Shaw AFB (South Carolina)", 45) ); // 
bases.push( new Array("Ellsworth AFB, SD", "Ellsworth AFB (South Dakota)", 45) ); // 
//bases.push( new Array("Shepphard AFB, TX", "Shepphard AFB (Texas)", 45) ); // 
bases.push( new Array("NAS Corpus Christi, TX", "NAS Corpus Christi (Texas)", 45) ); // 
bases.push( new Array("Fort Bliss, TX", "Fort Bliss (Texas)", 45) ); // 
bases.push( new Array("Langley AFB, VA", "Fort Eustis, Langley AFB (Virginia)", 45) ); // 
//bases.push( new Array("Bremerton Navy Sites, WA", "Bremerton Navy Sites (Washington)", 45) ); //  
bases.push( new Array("Fairchild AFB, WA", "Fairchild AFB (Washington)", 45) ); //  
bases.push( new Array("Fort Rucker, AL", "Fort Rucker (Alabama)", 45) ); //  
//bases.push( new Array("NAME", "NAMESTATE", 45) );  


//*********** GMap2 Prototype ***********
		GMap2.prototype.initted = false;
		GMap2.prototype.controlsAdded = false;
		
		GMap2.prototype.goTo = function(point, zoom) {
				this.setCenter(point, zoom);
				if (!this.controlsAdded) {
					this.addControl(new GSmallMapControl());
					this.controlsAdded = true;
				}
		}
		
		GMap2.prototype.plotMarkers = function( results ) {
			for (var i=0; i<results.length; i++) {
				this.addOverlay( results[i].marker() );
			}			
		}
		
		GMap2.prototype.setToBounds = function (bounds) {
			var center_lat = ( bounds.getNorthEast().lat() + bounds.getSouthWest().lat() ) / 2.0; 
			var center_lng = ( bounds.getNorthEast().lng() + bounds.getSouthWest().lng() ) / 2.0; 
			var center = new GLatLng( center_lat, center_lng );
			var zoom = this.getBoundsZoomLevel( bounds, this.getSize() ); 
			this.goTo( center, Math.min(zoom, 14) ); 
		}


//*********** geocoding code ***********
/*function announceDestination(point){
		if (!point) { 
			alert(address + " not found"); 
		} 
		else { 
			alert("got: " + point.lat() + ", " + point.lng() );
		}    
}
var geocoder = new GClientGeocoder();
var destination = geocoder.getLatLng( bases[defaultBase][0], announceDestination );*/

//*********** Basefinder map and search code ***********

// Constants
		var BASEMAP = 1;
		var POORMAP = 2;
		var BOTHMAPS = 3;

// Our global state
		var app;
		var locationList;
		var poorzip;
		var poorResultSetsReturned = 0;
		var selectedResultIndex = 0;
    var gLocalSearch;
    var baseMap;
    var poorMap;
    var activeMap; //which map is receiving data from localsearch (1 or 2)
    var gSelectedResults = [];
    var gBaseResults = [];
    var gPoorResults = [];
    var gSearchControl;		
    var gSearchForm;
		var baseQuery="cash OR advance OR payday -registers -union -public -mortgage -auto";
		var encodedBaseQuery=baseQuery.replaceAll(" ","+");
		var poorQuery1='gun OR ammo OR firearms OR pawn -against';
		var poorQuery2='liquor store';
					
		function MyApp() {
		}

    // Set up the map and the local searcher.
    function initMaps( mapsToCreate, mapToSelect ) { //if both maps created, 2nd param needed to choose which is active
			app = new MyApp();
			
      gSearchForm = new GSearchForm(false, document.getElementById("searchform"));
      gSearchForm.setOnSubmitCallback(null, CaptureForm);
			
      // Initialize the local searcher
      gLocalSearch = new GlocalSearch();
			gLocalSearch.setSearchCompleteCallback(null, OnLocalSearch);
			gLocalSearch.setResultSetSize(GSearch.LARGE_RESULTSET);
			
			//set the local search to the correct center
			activeMap = mapToSelect;
			if ( activeMap == BASEMAP || mapsToCreate == BASEMAP ){		
				initBaseMap();
			}
			else if ( activeMap == POORMAP || mapsToCreate == POORMAP ){		
				initPoorMap();
			}
    }
		
		function initBaseMap() {
				activeMap = BASEMAP;
				if (baseMap) return;
				
				//init DOM handles for elements used by the base map
				locationList = document.getElementById("locationlist");
				updateBaseFinderUI(defaultBase);
				
				// Initialize the map
				baseMap = new GMap2(document.getElementById("base-map"));
				
				//launch initial search
				gLocalSearch.setCenterPoint( bases[defaultBase][0] );
				gSearchForm.execute(baseQuery);
		}
		function initPoorMap() {
				activeMap = POORMAP;
				if (poorMap) return;
				
				//init DOM handles for elements used by the poor map
				poorzip = document.getElementById("poorzip");
	
				// Initialize the map
				poorMap = new GMap2(document.getElementById("poor-map"));
				
				// Execute the initial search
				poorResultSetsReturned = 0;
				gLocalSearch.setCenterPoint("Houston, TX");
				gSearchForm.execute(poorQuery1);
				gSearchForm.execute(poorQuery2);
		}
		
		MyApp.prototype.navigateBaseFinder = function(baseID) {
			activeMap = BASEMAP;
			clearResults( gBaseResults, baseMap ); // Clear the map
			gBaseResults = []; //clear the array
			gLocalSearch.setCenterPoint(bases[baseID][0]);
      gSearchForm.execute(baseQuery);
			updateBaseFinderUI(baseID);
    }
		
		MyApp.prototype.navigatePoorFinder = function(zip) {
			activeMap = POORMAP;
			poorResultSetsReturned = 0;
			selectedResultIndex = 0;
			clearResults( gPoorResults, poorMap ); // Clear the map		
			gPoorResults = []; //clear the array
			gLocalSearch.setCenterPoint(zip);
      gSearchForm.execute(poorQuery1);
      gSearchForm.execute(poorQuery2);
    }

    // Called when Local Search results are returned
    function OnLocalSearch() {
      if (!gLocalSearch.results) return;

      if ( activeMap == BASEMAP ) {		
			
				for (var i = 0; i < gLocalSearch.results.length; i++) {
					gBaseResults.push(new LocalResult(gLocalSearch.results[i]));
				}

				// move the map to the first result
				var first = gLocalSearch.results[0];
				var firstpoint = new GLatLng(parseFloat(first.lat), parseFloat(first.lng));
				baseMap.goTo(firstpoint, 12);
				baseMap.plotMarkers(gBaseResults);
			}
      else if ( activeMap == POORMAP ) {
				poorResultSetsReturned++;
				//alert("got " + gLocalSearch.results.length + " results in set: " + poorResultSetsReturned + ".  Adding to " + gPoorResults.length + "existing results");
				for (var i = 0; i < gLocalSearch.results.length; i++) {
					gPoorResults.push(new LocalResult(gLocalSearch.results[i]));
				}
				if (poorResultSetsReturned == 2){ //only reposition map after all results returned (2 sets)
					//generate recommended lending locations
					gPoorResults.push(generateLocalResult(gPoorResults, 0, 8)); 
					gPoorResults.push(generateLocalResult(gPoorResults, 8, 8));
					//center and zoom to results
					var bounds = findBounds(gLocalSearch.results);
					poorMap.setToBounds( bounds );
					poorMap.plotMarkers(gPoorResults);
				}
			}
    }

		function findBounds(results) {
			var bounds = new GLatLngBounds();
			for (var i=0; i<results.length; i++) {
				bounds.extend( new GLatLng(parseFloat(results[i].lat), parseFloat(results[i].lng)) );
			}			
			return bounds;
		}

		function clearResults ( results, map ) {
			for (var i = 0; i < results.length; i++) {
				map.removeOverlay(results[i].marker());
			}
		}

		function updateBaseFinderUI(baseID) {
			var string = bases[baseID][0].replace(" ", '+')			
			var shortBaseName = bases[baseID][1].substr( 0, bases[baseID][1].indexOf( " (" ) );
			
			//check for large basefinder UI text
			var baseFinderUILarge = document.getElementById("base-finder-UI-large")
			if (baseFinderUILarge != null) {	
				if (baseID == defaultBase ) {
					baseFinderUILarge.innerHTML = '<strong>Q:</strong> Are ' + (Math.floor(bases[baseID][2]/20)*10) + ' payday locations near one military base too many?<br /><strong>A:</strong> No. Here we see ' + shortBaseName + ' with <strong>' + bases[baseID][2] + '</strong> active lenders. <br /> The first 8 are shown below. <a target="_blank" href="http://maps.google.com/maps?f=l&hl=en&ie=UTF8&q=' + encodedBaseQuery + '&near=' + string + '">Click here to see more</a> on Google Maps.';
				}
				else {
					baseFinderUILarge.innerHTML = 'The first 8 lenders near ' + shortBaseName + ' are shown below. <a target="_blank" href="http://maps.google.com/maps?f=l&hl=en&ie=UTF8&q=' + encodedBaseQuery + '&near=' + string + '">Click here to see more</a> on Google Maps.';
				}
			}
			//check for small basefinder UI text
			var baseFinderUISmall = document.getElementById("base-finder-UI-small")
			if (baseFinderUISmall != null) {	
				baseFinderUISmall.innerHTML = 'The first 8 lenders near ' + shortBaseName + ' are shown below. <a target="_blank" href="http://maps.google.com/maps?f=l&hl=en&ie=UTF8&q=' + encodedBaseQuery + '&near=' + string + '">Click here to see more</a> on Google Maps.';
			}
		}

    // Cancel the form submission, executing an AJAX Search API search.
    function CaptureForm(searchForm) {
      gLocalSearch.execute(searchForm.input.value);
      return false;
    }

    // A class representing a single Local Search result returned by the
    // Google AJAX Search API.
    function LocalResult(result) {
      this.result_ = result;
      this.resultNode_ = this.resultBody();

      if ( activeMap == BASEMAP ) {
				//baseMap.addOverlay(this.marker(dollaricon));
				this.marker(dollaricon) //generate the marker but don't plot it
			}
      else if ( activeMap == POORMAP ) {		
				var temp = this.result_.titleNoFormatting;
				var iconToUse = null;
				
				if ( temp.indexOf("KFC") != -1 || temp.indexOf("K F C") != -1 || temp.indexOf ("chicken") != -1 || temp.indexOf ("Chick") != -1 ) 
					iconToUse = chickenicon; 
				else if ( temp.indexOf("Liquor") != -1 || temp.indexOf ("Beer") != -1 || temp.indexOf ("Wine") != -1 || temp.indexOf ("Tasting") != -1 || temp.indexOf ("Spirits") != -1 || temp.indexOf ("Vino") != -1 || temp.indexOf ("Bar Supply") != -1 ) 
					iconToUse = liquoricon;
				else if ( temp.indexOf("Gun") != -1 || temp.indexOf ("Ammo") != -1 || temp.indexOf ("Arms") != -1 || temp.indexOf ("Firearms") != -1 ) 
					iconToUse = gunicon;
				else 
					iconToUse = pawnicon; 
  
				this.marker(iconToUse) //generate the marker but don't plot it
	    	//poorMap.addOverlay(this.marker(iconToUse));
			}
    }
		
		function generateLocalResult(results, start, span) { //averages span positions, beginning at start in the array
			var lat = 0;
			var lng = 0;
			for (var i=start; i < results.length && i < (start+span); i++) {
				lat += parseFloat(results[i].marker().getPoint().lat())/span;
				lng += parseFloat(results[i].marker().getPoint().lng())/span;
			}
			return new TargetLocalResult(new GLatLng(lat, lng), targetLocationIcon);
		}
			
		function TargetLocalResult( latlng, icon ) {
			this.marker_ = new GMarker( latlng, icon );
								
      var container = document.createElement("div");
			container.innerHTML = '<DIV class="gs-localResult gs-result"><DIV class=gs-title>Recommended Payday Location</DIV><DIV class=gs-citystate>This location has a high concentration of</DIV><DIV class=gs-citystate>working poor with few existing lenders.</DIV></DIV>';
      this.resultNode_ = container;
			
			GEvent.bind(this.marker_, "click", this, function() {
        this.marker_.openInfoWindow(container);
      });
			
	    //poorMap.addOverlay(this.marker_);
    }		
		
		//added for parity with localresults, but requires that marker already be generated
		TargetLocalResult.prototype.marker = function() {
      if (this.marker_) return this.marker_;
		}

    // Returns the baseMap marker for this result, creating it with the given
    // icon if it has not already been created.
    LocalResult.prototype.marker = function(opt_icon) {
      if (this.marker_) return this.marker_;
      var marker = new GMarker(new GLatLng(parseFloat(this.result_.lat),
                                         parseFloat(this.result_.lng)),
                               opt_icon);
      GEvent.bind(marker, "click", this, function() {
        marker.openInfoWindow(this.resultBody());
      });
      this.marker_ = marker;
      return marker;
    }

    // Returns the HTML we display for a result before it has been "saved"
    LocalResult.prototype.resultBody = function() {
      if (this.resultNode_) return this.resultNode_;
      var container = document.createElement("div");
			var content = '<DIV class="gs-localResult gs-result"><DIV class=gs-title><A class=gs-title href="' + this.result_.url + '" target=_blank>' + this.result_.titleNoFormatting + '</A></DIV>';
			content += '<DIV class=gs-address><DIV class=gs-street>' + this.result_.streetAddress + '</DIV>';
			content += '<DIV class=gs-citystate>' + this.result_.city + ', ' + this.result_.region + '</DIV>';
			if ( this.result_.phoneNumbers && this.result_.phoneNumbers.length ){
				for (var i=0; i<this.result_.phoneNumbers.length; i++) {
					if (this.result_.phoneNumbers[i].type == "main" || this.result_.phoneNumbers[i].type == "")
						content += '<DIV class=gs-phone>' + this.result_.phoneNumbers[0].number + '</DIV>';
				}
			}
			content += '</DIV></DIV>';
			container.innerHTML = content;
      return container;
    }

		/*function selectNextResult() {
			selectedResultIndex++;
			selectedResultIndex = ( selectedResultIndex >= gPoorResults.length ) ? 0 : selectedResultIndex;
			//open info window of selected marker
			gPoorResults[selectedResultIndex].marker().openInfoWindow(gPoorResults[selectedResultIndex].resultNode_);		
		}
		
		function selectPreviousResult() {
			selectedResultIndex--;
			selectedResultIndex = ( selectedResultIndex < 0 ) ? (gPoorResults.length - 1) : selectedResultIndex;
			//open info window of selected marker
			gPoorResults[selectedResultIndex].marker().openInfoWindow(gPoorResults[selectedResultIndex].resultNode_);			
		}*/

    GSearch.setOnLoadCallback(OnLoad);