
// map globals
var map;
var geocoder;
var locationBounds;

var perPage = 10;

var useGeoIp = (geoLat != 0 && geoLng != 0);
var defaultLocation = useGeoIp ? geoAddress : "Toronto, Ontario";
var defaultLatLng = useGeoIp ? new GLatLng(geoLat, geoLng) : new GLatLng(43.670233, -79.386755);

$(document).ready(function() {

    geocoder = new GClientGeocoder();
    map = new google.maps.Map2($('#map').get(0));
    locationBounds = new GLatLngBounds();

    // prepare locations
    $(locations).each(function(i) {

        var loc = this;
        var point = new GLatLng(loc.lat, loc.lng);
        loc.point = point;

        loc.marker = new GMarker(loc.point);
        map.addOverlay(loc.marker);
        loc.infoWindow = buildInfoWindow(loc);
        GEvent.addListener(loc.marker, "click", function() { loc.marker.openInfoWindow(loc.infoWindow); });

        locationBounds.extend(point);
        loc.id = "loc" + i;
    });

    setVisitorLocation(defaultLatLng);
    map.addControl(new GSmallMapControl());

    // wire search form
    $('.location_form').submit(handleFormSubmit);
    $('.location_form input[type=text]').val(defaultLocation);
    
    // wire popular links
    $('#popular_locations a').click(function(e) {
        e.preventDefault();
        var address = $(this).attr('title');
        if (address == null || address == 'undefined' || address.length == 0) 
            address = $(this).text();
        $('.location_form input[type=text]').val(address);
        handleFormSubmit(e);
        
    });

});

function buildInfoWindow(loc) {
    var html = '<p>';
    html += '<strong>' + loc.name + '</strong><br />';
    html += [loc.address, loc.phone].join('<br />');  
    html += '<br /><strong style="margin:10px 0;display:block;"><a href="http://www.dailychallenge.org/events/payitbackward/join.php">Join the Movement Here</a></strong>';
    html += '</p>';
	return html;
}

function showAddress(address) {
    geocoder.getLatLng(
        address,
        function(point) {
            if (!point) {
                alert(address + " not found");
            }
            else {
                map.setCenter(point, 13);
                var marker = new GMarker(point);
                map.addOverlay(marker);
            }
        }
    );
}

function handleFormSubmit(e) {
    if (e != null)
        e.preventDefault();
    var input = $('.location_form input[type=text]');
    geocoder.getLocations(input.val(), function(data) {
        if (data != null && data.Placemark != null) {
            var Point = data.Placemark[0].Point;
            var point = new GLatLng(Point.coordinates[1], Point.coordinates[0])
            input.val(data.Placemark[0].address);
            setVisitorLocation(point);
        }
        else {
            // location not found
            alert("Location could not be found.");
        }
    });
    scrollToMap();
}

function setVisitorLocation(point) {

    // calculate distance to each location
    $(locations).each(function(i) {
        var loc = this;
        var locPoint = new GLatLng(loc.lat, loc.lng);
        loc.distance = point.distanceFrom(locPoint);
        loc.distanceText = (loc.distance / 1000).toFixed(2) + ' km';
    });

    // sort by distance
    locations.sort(function(a, b) {
        if (a.distance > b.distance) return 1;
        if (a.distance < b.distance) return -1;
        return 0;
    });
    buildLocations();

    setAdjustedCenter(point);
};

function scrollToMap() {
    $.scrollTo('#map', 700);
}

function buildLocations(page) {
    
    var resultsList = $('ul.location_listings');
    resultsList.empty();

    var pages = Math.ceil(locations.length / perPage);

    page = parseInt(page) || 1;
    if (page <= 0) page = 1;
    var offset = (page - 1) * perPage;

    var count = 0;
    $(locations).each(function(i) {

        var loc = this;

        if (i < offset) return;
        count++;
        if (count > perPage) return;

        var li = $(
            '<li id="' + loc.id + '">' +
                '<h3><span class="title">' + loc.name + '</span><span class="distance">' + loc.distanceText + '</span></h3>' +
                '<p>' + loc.address + ', ' + loc.city + ', ' + loc.prov + '</p>' +
								'<p><a href="#" class="mapit"><strong>Map it</strong></a></p>' +
            '</li>'
        );
        resultsList.append(li);

        var mapItLink = li.find('a');
        mapItLink.click(function(e) {
            e.preventDefault();
            var a = $(this);
            var loc = $(locations).filter(function() { return this.id == a.parent().parent().attr('id'); }).get(0);
            map.setCenter(loc.point, 14);
            loc.marker.openInfoWindow(loc.infoWindow);
            scrollToMap();
        });
    });

    var pager = $('ul.location_nav');
    pager.empty();

    var prev = $('<li><a href="#">Prev</a></li>');
    prev.click(function(e) {
        e.preventDefault();
        buildLocations(page > 1 ? page - 1 : pages);
    });
    pager.append(prev);
    
    // build list of page links
    var pageLinks = [];
    for (var i = 1; i <= pages; i++) {
        pageLinks.push(i);
    }
    
    // trim pageLinks down to 10
    var flipper = 'pop';
    while (pageLinks.length > 10) {

	var fromStart = page;
       // var fromStart = pageLinks.indexOf(page);
	/*
			if (!Array.indexOf) {
				Array.prototype.indexOf = function (obj, start) {
					for (var i = (start || 0); i < this.length; i++) {
						if (this[i] == obj) {
							return i;
						}
					}
				}
			}
*/
        var fromEnd = pageLinks.length - fromStart;

        // balance current page
        if (fromStart <= 5 && fromEnd <= 5) return;
        if (fromStart <= 5) flipper = 'pop';
        if (fromEnd <= 5) flipper = 'shift';

        var junk = flipper == 'pop' ? pageLinks.pop() : pageLinks.shift();
        flipper = (flipper == 'pop') ? 'shift' : 'pop';
    }
       
    // turn array of links into DOM elements
    $(pageLinks).each(function(i) {
        var pageNo = this;
        var a = $('<li><a href="#">' + pageNo + '</a></li>');
        pager.append(a);
        if (pageNo == page) a.addClass('current');
        a.click(function(e) {
            e.preventDefault();
            buildLocations(pageNo);
        });
    });

    var next = $('<li><a href="#">Next</a></li>');
    pager.append(next);
    next.click(function(e) {
        e.preventDefault();
        buildLocations(page < pages ? page + 1 : 1);
    });

}


function setAdjustedCenter(point) {

    var bounds = new GLatLngBounds();

    // attempt to zoom to locations within 15km
    if (bounds.isEmpty()) {
        // find all locations within 15km, storing the farthest distance
        var count = 0;
        $(locations).each(function(i) {
            var loc = this;
            if (loc.point.distanceFrom(point) < 1000) {
                count++;
                bounds.extend(loc.point);
            }
        });
        if (count > 0) { bounds.extend(point); }
    }

    if (bounds.isEmpty()) {

        var minDistance = null;
        var nearestLoc = null;

        $(locations).each(function(i) {
            var loc = this;
            var distance = loc.point.distanceFrom(point);
            if (minDistance == null || distance < minDistance) {
                minDistance = distance;
                nearestLoc = loc;
            }
        });

        bounds.extend(point);
        bounds.extend(nearestLoc.point);
    }

    // center map on new point
    map.setCenter(
      bounds.getCenter(),
      map.getBoundsZoomLevel(bounds, new GSize(400, 300))
    );
}
