jQuery(document).ready(function($) {
    try {
    console.assert(1);
} catch(e) {
    if (typeof loadFirebugConsole == 'function') {
         loadFirebugConsole();
    }  else {
        console = {
            log: function() {},
            debug: function() {},
            info: function() {},
            warn: function() {},
            assert: function() {}
        }
    }
}
    initSearchableMap();
});
var options = {
    maxDistance     : 1000, // distance in miles, filtered results will not display on map if they are further away
    startLat        : 40.759829, // on load the map will center at this latitude
    startLng        : -73.975049, // on load the map will center at this longitude
    cssThumb        : "thumb", // CSS class on item that wraps thumbnail image
    cssName            : "name", // CSS class on item that wraps location Name information
    cssAddress        : "address", // CSS class that wraps location Address
    cssDescription    : "description", // CSS class that wraps location Description
    cssService        : "service" // CSS class that wraps location Services
}
function initSearchableMap() {
    
    parseHTML();
    initGoogleStuff();
    buildFilterControls();
    
    // Added By Jim Faulkner
    preloadGoogleMarkers();
    
    var zip = getQueryString("zip");
    if(zip) {
        SubmitQuery(zip);
        //addMarkers(true);
    }
}

var locCounter = 0;
var curFilterLocs = new Array();
//--------------------------------------------------------------------------------
// BEGIN CODE ADDED
//--------------------------------------------------------------------------------
var MARKER_LETTERS   = new Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J");
var MarkerLetterIcon = new Array(MARKER_LETTERS.length);
var ZipCodePoint     = null;
//--------------------------------------------------------------------------------
// preloadGoogleMarkers - function to preload and cache the Google A-J markers   
//--------------------------------------------------------------------------------
function preloadGoogleMarkers() {
    var shadowIcon = new GIcon(G_DEFAULT_ICON);
    
    shadowIcon.shadow           = 'http://www.google.com/mapfiles/shadow50.png';
    shadowIcon.iconSize         = new GSize(20, 34);
    shadowIcon.shadowSize       = new GSize(37, 34);
    shadowIcon.iconAnchor       = new GPoint(9, 34);
    shadowIcon.infoWindowAnchor = new GPoint(9, 2);
                    
    for (var index = 0; index < MARKER_LETTERS.length; index++) {
        var letterIcon = new GIcon(shadowIcon);
        
        letterIcon.image = 'http://www.google.com/mapfiles/marker' + MARKER_LETTERS[index] + '.png';    
        
        MarkerLetterIcon[index] = letterIcon;
    }
}
//--------------------------------------------------------------------------------
// END CODE ADDED
//--------------------------------------------------------------------------------

var locationLookup = new Array();
var filters = new Array();
// pass in a parameter with the querystring to retrieve
// parse url and return value of query
function getQueryString(arg) {
    var qsParm = new Array();
    var query = window.location.search.substring(1);
    var parms = query.split('&');
    for (var i=0; i<parms.length; i++) {
        var pos = parms[i].indexOf('=');
        if (pos > 0) {
            var key = parms[i].substring(0,pos);
            var val = parms[i].substring(pos+1);
            qsParm[key] = val;
        }
    }
    
    return qsParm[arg];
}
// Build form controls used to filter results
function buildFilterControls() {
    var f = $("#filters");
    // add filter options
    for(var filter in filters) {
        id = "filter-"+filter;
        displayName = filters[filter].displayName;
        f.append("<label class='btn"+id+"'><input id='"+id+"' name='filter' type='radio' />" + displayName + "</label>");
        $("#filters input:first").attr("checked", "checked")
    }
}
// Determine which locations should be added to the map
function addMarkers(all, localOnly) {
    all       = false || all;
    localOnly = false || localOnly;
    
    curFilterLocs = new Array();
    
    // Add new markers
    if(all) {    
        for (var i in locationLookup) {
            curFilterLocs.push(locationLookup[i]);
        }    
    }
    else {
        if($(":radio:checked").length > 0) {
            $(":radio:checked").each(function() {
                x = $(this).attr("id").replace("filter-", "");
                curFilterLocs = filters[x].getLocations();
            });
        }
        else {
            for (var i in locationLookup) {
                curFilterLocs.push(locationLookup[i]);
            }
        }
    }
    
    gMap.clearOverlays();
    locCounter = 0;
    // If local, we need to grab the closest 10 locations and show them
    if (localOnly && gCGeo) {
        callNextDistance();
    }
    else {        
        callNextAddress();
    }
}
function callNextDistance() {
    if (locCounter < curFilterLocs.length) {
        
        var point = curFilterLocs[locCounter].point;
        if (point) {
            var distance = gMap.getCenter().distanceFrom(point);
            curFilterLocs[locCounter].setDistanceFromZip(distance);
        }
        
        locCounter++;
        callNextDistance();
    }
    else {
        // Here we need to show the 10 closest locations
        curFilterLocs.sort(function(a,b){return a.distanceFromZip - b.distanceFromZip});
        
        var maxResults   = (curFilterLocs.length > 9 ? 10 : curFilterLocs.length); 
        var leftColHTML  = '';
        var rightColHTML = '';
        
        for (var x = 0; x < maxResults; x++) {
            setAddressForDistanceMarker(curFilterLocs[x], x);
        }
    }
}
function setAddressForDistanceMarker(loc, markerLetterIndex) {
    markerOptions = {icon: MarkerLetterIcon[markerLetterIndex]}
    var marker = new GMarker(loc.point, markerOptions);
            
    GEvent.addListener(marker, "click", function() {
            var html = buildInfoHTML(loc, userAddress)
            this.openInfoWindowHtml(html, {maxWidth : 350});
        }
    );
    
    gMap.addOverlay(marker);
    
}
function callNextAddress() {
    if(locCounter < curFilterLocs.length) {
        setAddress(curFilterLocs[locCounter]);
    }
}
// Given an address convert to latLng()
// call addMarker
function setAddress(loc) {
    if(loc.point) {
        var marker = new GMarker(loc.point);
        
        GEvent.addListener(marker, "click", function() {
                var html = buildInfoHTML(loc, userAddress)
                this.openInfoWindowHtml(html, {maxWidth : 350});
            }
        );
        
        gMap.addOverlay(marker);
        
    }
    locCounter++;
    callNextAddress();
}

// HTML that appears in popup info box when user clicks on a location
function buildInfoHTML(loc, from) {
    var html = loc.description;
    html = "<div class='infobox'> " + loc.thumb + loc.displayName+"<div>" + html;
//    if(userAddress != "") {
//        html += "<a href='http://maps.google.com/maps?daddr=" + loc.point.toUrlValue() + "&amp;saddr="+ from +"'>Get directions</a><br />";
//    }
//    else {
//        html += "<a href='http://maps.google.com/maps?daddr=" + loc.point.toUrlValue() + "'>directions</a><br />";
//    }
    html += "</div></div>";
    return html;
}
// Parse the existing HTML and replace with Google Map
function parseHTML() {
    buildFilters();
    $("#gmap-placeholder > #locations > li").each(function() {
        var name = $(this).children("." + options.cssName).html();
        var address = $(this).children("." + options.cssAddress).text();
        var description = $(this).children("." + options.cssDescription).html();
        var thumb = $(this).children("." + options.cssThumb).html();
        var loc = new Location(name, address, description, thumb);
        locationLookup[name] = loc;
        $(this).find("." + options.cssService).each(function() {
            var filterName = $(this).text();
            var filterId = stripSpecial(filterName);
            var f;
            
            if(filters[filterId]) {
                f = filters[filterId];
                f.addLocation(loc);
            }
        });
    });
    
    // Write the HTML that will hold the map and filters
    $("#gmap-placeholder").html(            
    "<div id='search'><div id='filters'></div><div id='searchform'></div></div><span id='redBar'></span><div id='map'></div>"
    );
}
// Reads list of services from #services-offered, then build a filter for each
function buildFilters() {
    $(".leftContent").prepend('<div id="filterDescriptions"></div>');
    $("#filterDescriptions").hide();
    $("#gmap-placeholder > #services-offered > ul > li > span.filter").each(function() {
        var filterName = $(this).text();
        var filterId = stripSpecial(filterName);
        var thisFilterDesc = $(this).next(".desc").html();
        $("#filterDescriptions").append('<li class="'+ filterId +'">' + thisFilterDesc + '</li>');
        var f;
        if(filters[filterId]) {
            f = filters[filterId]    
        }
        else {
            f = new Filter(filterName);
            filters[filterId] = f;
        }
    });
}
// Creates a new Filter object
// Each filter has a name and can contain several locations
function Filter(dName) {
    var locations = new Array();
    this.id = stripSpecial(dName);
    this.displayName = dName;
    this.addLocation = function(loc) {
        locations.push(loc);
    };
    this.getLocations = function() {
        return locations;
    };
}
// Creates a new Location object
// A location contains a name, address, and description
function Location(displayName, address, description, thumb) {
    var l = this;
    
    var latLng = address.split(',');
    var lat = latLng[0];
    var lng = latLng[1];
    
    this.address = address;
    this.displayName = displayName;
    this.description = description;
    this.thumb = thumb;
    this.distanceFromZip = 999999999;
    this.point = new GLatLng(lat, lng);
    
    this.setDistanceFromZip = function(distance) { l.distanceFromZip = distance; }
}
// Remove any crazy characters
function stripSpecial(text) {
    text = new String(text);    
    return text.replace(/[^a-zA-Z 0-9]+/g,'').replace(/ /g,'');
}

/*********************************************
    Begin Google Map Code
*********************************************/
google.load('search', '1');
google.load('maps', '2.x');
var metersInMile = 1609.344;
// Our global state
var gLocalSearch;
var gMap;
var gSelectedResults = [];
var gCurrentResults = [];
var gSearchForm;
var gCGeo;
var userAddress;
var swPoint;
var nePoint;
// Set up the map and the local searcher.
function initGoogleStuff() {
    gSearchForm = new google.search.SearchForm(false, document.getElementById("searchform"));
    gSearchForm.setOnSubmitCallback(null, CaptureForm);
//    gSearchForm.input.focus();
    // Initialize the map
    gMap = new google.maps.Map2(document.getElementById("map"));
//    gMap.enableScrollWheelZoom();
    gMap.addControl(new google.maps.LargeMapControl());
    gMap.addControl(new google.maps.MapTypeControl());
    gMap.setCenter(new google.maps.LatLng(options.startLat, options.startLng), 13);
    gCGeo = new GClientGeocoder();
    // Initialize the local searcher
    gLocalSearch = new google.search.LocalSearch();
    gLocalSearch.setCenterPoint(gMap);
    gLocalSearch.setSearchCompleteCallback(null, OnLocalSearch);
    
    $("body").unload(GUnload);
}
// Called when Local Search results are returned, we clear the old
// results and load the new ones.
function OnLocalSearch() {
    
    if (!gLocalSearch.results) return;
    // Clear the map
    for (var i = 0; i < gCurrentResults.length; i++) {
        gMap.removeOverlay(gCurrentResults[i].marker());
    }
    
    gCurrentResults = [];
    for (var i = 0; i < gLocalSearch.results.length; i++) {
        gCurrentResults.push(new LocalResult(gLocalSearch.results[i]));
    }
    // move the map to the first result
    var first = gLocalSearch.results[0];
    if(first) {
        gMap.panTo(new google.maps.LatLng(first.lat, first.lng));
    }
}
// Cancel the form submission, executing an AJAX Search API search.
function CaptureForm(searchForm) {
    userAddress = searchForm.input.value;
    gLocalSearch.setCenterPoint(userAddress);
    gLocalSearch.execute(searchForm.input.value);
    // Modified by Jim Faulkner
    if (userAddress.length < 4) {
        addMarkers();
    }
    else {
        // Here we need to get the local results
        addMarkers(false, true);
    }
        
    return false;
}
// Pass in a string and submit search request to Google
function SubmitQuery(arg) {
    userAddress = arg;
    gLocalSearch.setCenterPoint(userAddress);
    gLocalSearch.execute(arg);
    //addMarkers(false, true);
    for (var i in locationLookup) {
        curFilterLocs.push(locationLookup[i]);
    }    
    callNextDistance();
    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.unselectedHtml();
    gMap.addOverlay(this.marker());
}
// Returns the GMap 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 google.maps.Marker(new google.maps.LatLng(parseFloat(this.result_.lat),
                                       parseFloat(this.result_.lng)), opt_icon);
    GEvent.bind(marker, "click", this, function() {
      marker.openInfoWindow(this.unselectedHtml());
    });
    this.marker_ = marker;
    return marker;
}
// Returns the HTML we display for a result before it has been "saved"
LocalResult.prototype.unselectedHtml = function() {
    var container = document.createElement("div");
    container.appendChild(this.result_.html.cloneNode(true));
    return container;
}
function removeAllTabs() {
    gMap.clearOverlays();
}

$(document).ready(function(){
    $("#searchform td.gsc-search-button").append("<a id='clearAll' href='#'>Clear</a>");
    $("#clearAll").click(function(){
        removeAllTabs();
        $("#leftContentList").empty();
    })
    $("#filterSpotlight").attr("selected", "selected")
    $("#filters label").click(function(){
        $("#filters label").removeClass("active");
        $(this).addClass("active");
    })
    $("#searchform input.gsc-search-button").click(function(){
        $("#leftContentList").empty();
        var selected = $("#filters").find("input:radio:checked").attr("id").replace("filter-", "");
        var selectedLocations = filters[selected].getLocations();
        var selectedFilterDesc = $("#filterDescriptions li." + selected ).html();
        if ( selected == "Spotlight" ) {
            for(i=0; i < selectedLocations.length; i++){
                $("#leftContentList").append("<li class=\"" + selected + "\">" + selectedLocations[i].displayName + "</li>");
            }
        } else {
            $("#leftContentList").html("<li>" + selectedFilterDesc + "</li>");
        }
        layerPopLink();
    })
    function layerPopLink() {
        $("#leftContentList a").click(function(){
            var iframeURL = $(this).attr("href");
            layerPop(iframeURL);
            return false;
        })
    }
    layerPopLink();
    function layerPop(iframeURL) {
        $("#overlay").show();
        $("#profileBox").append('<iframe src="'+iframeURL+'" width="100%" height="100%" scrolling="no" frameborder="0"><p>Your browser does not support iframes.</p></iframe>');
        return false;
    }
}); // Bye-bye jQuery!
