/*
 GxMarker version 2.0

 SYNOPSIS
    This version is compatible only with Google Maps API Version 2

    GxMarker is merely an extended marker that allows styled tooltip events.
   
    To setup a tooltip, pass in a third parameter (after the icon) to the
    GxMarker class:
        var marker = new GxMarker(new GPoint(lat,lng),icon,"My Tooltip",?opts?);
        map.addOverlay(marker);
    Or:
        var marker = new GxMarker( new GPoint(lat,lng) );
        marker.setTooltip("My Tooltip", ?opts?);
        map.addOverlay(marker);

    The opts should be a hash (var opts = { "field1": "value" }) that contains
    the configuration for the marker.  This allows a user to specify the
    offset, a "isStatic" boolean flag, and an alternative className to use
    intead of the default "markerTooltip"

    (This is a complete, 100% rewrite of GxMarker Version 1)

    TESTED PLATFORMS:
        Google Maps API V2 with:
        Linux: Firefox
        Windows: Firefox, IE6
        Mac OS X (Panther): Safari

    There is no warranty of functionality of this code, if you wish to use it
    and it does not work for you, I recommend you submit a patch.  This software
    is licensed under the GNU Lesser General Public License (LGPL):
    the full text at: http://opensource.org/licenses/lgpl-license.php
*/

var __singleLabel;
var __singleLabelRefCount = 0;

// track whether or not the streetview has been shown AT LEAST once.  Calling checkResize() on it when it hasn't
// been shown yet causes problems
var __streetViewShown = false;

// track whether or not the streetview has been inited with a location (be it the default location or otherwise)
// if it hasn't, it will always try to check streetview data for the default location
var __gPanoInit       = false;

function GxLabel( content, opts ) {
    if ( typeof opts != "object" ) throw "Invalid GxLabel configuration";

    this.content = content;

    if ( opts.offset && typeof opts.offset.width != "undefined" ) 
        this.offset = opts.offset
    else
        this.offset = new GSize(0,0);

    this.className = opts.className || "markerTooltip";
    if ( opts.marker && typeof opts.marker.getPoint != "undefined" ) {
        this.marker = opts.marker;
        this.anchor = opts.marker.getPoint();
        if ( opts.isStatic ) {
            this.isStatic = true;
        } else {
            __singleLabelRefCount++;

            GEvent.addListener(this.marker, "mouseover",
                this.createSingletonClosure(this.show, this.anchor, this.offset, this.content));
            GEvent.addListener(this.marker, "mouseout",
                this.createSingletonClosure(this.hide, this.anchor, this.offset, this.content));
            if ( !__singleLabel )
                __singleLabel = this;
            return __singleLabel;
        }
    }
    else if ( opts.anchor && typeof opts.anchor.lat != "undefined" ) {
        if ( opts.isStatic ) {
            this.isStatic = true;
        }
        if ( opts.moveHandle ) {
            this.moveHandle = true;
        }
        if ( opts.deleteHandle ) {
            this.deleteHandle = true;
        }
        this.anchor = opts.anchor
    }

    if ( opts.pane ) this.pane = opts.pane;
    if ( !this.anchor ) throw "Invalid label configuration: no anchor point";
}

GxLabel.prototype = new GOverlay();

GxLabel.prototype.initialize = function(map) {
    var t = this;
    if ( __singleLabel && !this.isStatic )
        t = __singleLabel;
    t.map = map;
    t.pane = map.getPane(t.pane || G_MAP_MARKER_SHADOW_PANE) ||
        map.getPane(G_MAP_MARKER_SHADOW_PANE);

    if ( !t.container ) {
        t.container = document.createElement("div");
        t.container.className = t.className;
        t.container.style.position = "absolute";
        
        if ( t.moveHandle && !t.moveHandleNode ) {
            t.moveHandlePanel = t.pane;
            t.contentNode    = document.createElement("div");
            t.moveHandleNode = document.createElement("div");
            with ( t.moveHandleNode.style ) {
                background = "#ccc";
                width      = "8px";
                height     = "100%";
                cssFloat   = "left";
                fontWeight = "bold";
                textAlign  = "center";
                borderRight = "1px solid #555";
            }
            t.contentNode.style.marginLeft = "10px";
            t.moveHandleNode.innerHTML = ":";

            t.container.appendChild(t.moveHandleNode);
            t.container.appendChild(t.contentNode);

            t.insertPoint     = t.contentNode;

            GEvent.bindDom(t.moveHandleNode, "mousedown", this, this.mouseDown);
        } else {
            t.insertPoint = t.container;
        }

        t.setContent(t.content);

        t.pane.appendChild(t.container);
        var b = t.container;
        // removed the stopEvent(e) so URLs could be clicked
        GEvent.addDomListener(b, "click",
            function(e) { GEvent.trigger(t, "click", e); });
        GEvent.addDomListener(b, "mouseup", function(e) {
            stopEvent(e); t.mouseUp(e); GEvent.trigger(t, "mouseup", e);
        });
        GEvent.addDomListener(b, "mousedown",
            function(e) { stopEvent(e); GEvent.trigger(t, "mousedown", e); });
    }
}

GxLabel.prototype.setContent = function(content) {
    var t = this;
    if ( __singleLabel && !this.isStatic )
        t = __singleLabel;

    if ( content ) {
        var point = t.insertPoint || t.container;
        point.innerHTML = "";
        if ( typeof content == "object" ) {
            point.appendChild(content);
            t.content = point.innerHTML;
        } else {
            t.content = content;
            point.innerHTML = t.content;
        }
        if ( t.deleteHandle ) {
            var img = document.createElement("img");
            img.src = "/static/images/close.png";
            img.alt = "";
            img.style.padding = "0px 2px";
            GEvent.bindDom(img, "click", this, this.remove);
            point.appendChild(img);

        }
    }
}

GxLabel.prototype.setAnchor = function(anchor) {
    try {
        if ( anchor.lat() && anchor.lng() ) {
            this.anchor = anchor;
            this.redraw();
        }
    } catch(E) {}
}

GxLabel.prototype.remove = function() {
    if ( this.isStatic || --__singleLabelRefCount <= 0 ) {
        this.container.parentNode.removeChild(this.container);
        GEvent.trigger(this, "remove");
    }
}

GxLabel.prototype.copy = function() {
}

GxLabel.prototype.redraw = function(force) {
    if ( this.isStatic ) {
        this.show();
    } else {
        /* Show dynamic tooltips only on events, not on redraws */
        this.hide();
    }
}

GxLabel.prototype.createSingletonClosure = function(fn, p, o, c) {
    var _t = this; var obj = fn;
    var _p = p; var _o = o; var _c = c;
    p = null; fn = null; o = null; c = null;
    return function() {
        _t.setContent(_c);
        obj.apply(_t, [ _p, _o ] );
    };
}

GxLabel.prototype.show = function(point, offset) {
try {
    var t = this;
    if ( __singleLabel && !this.isStatic )
        t = __singleLabel;
    var p = point  || t.anchor;
    var o = offset || t.offset || new GSize(0,0);
    if ( p && p.lat ) {
        t.anchor = p; t.offset = o;
        var pix = t.map.fromLatLngToDivPixel(p);
        t.container.style.left = ( pix.x + o.width ) + "px";
        t.container.style.top  = ( pix.y + o.height ) + "px";
        t.container.style.display = "";
    }
} catch(e) { }
}

/* Pointless Params! */
GxLabel.prototype.hide = function(point, offset) {
    var t = this;
    if ( __singleLabel && !this.isStatic )
        t = __singleLabel;
    t.container.style.display = "none";
}

GxLabel.prototype.mouseUp = function(e) {
    if ( this.mouseUpListener )
        GEvent.removeListener(this.mouseUpListener);
    if ( this.mouseMoveListener )
        GEvent.removeListener(this.mouseMoveListener);
    if ( this.startDrag ) {

    }
    GEvent.trigger(this, "moveend", this.anchor);
    this.startDrag = false;
}

GxLabel.prototype.mouseMove = function(e) {
    if ( !this.startDrag ) {
        if ( this.mouseUpListener )
            GEvent.removeListener(this.mouseUpListener);
        if ( this.mouseMoveListener )
            GEvent.removeListener(this.mouseMoveListener);
        return false;
    }

    var point = new GPoint(
        e.clientX - this.topLeftPoint.x, e.clientY - this.topLeftPoint.y);
    var anchor = this.map.fromDivPixelToLatLng(point);
    this.anchor = anchor;
    this.redraw();
}

GxLabel.prototype.mouseDown = function(e) {
    stopEvent(e);
    this.startDrag = true;
/*
    var mapBounds = this.map.getBounds();
    var topleft = new GLatLng(
        mapBounds.getSouthWest().lat(),
        mapBounds.getNorthEast().lng());
    this.topLeftPoint = this.map.getCurrentMapType().getProjection().fromLatLngToPixel(topleft, this.map.getZoom());
    this.topLeftPoint = this.map.fromLatLngToDivPixel(topleft);
*/
    this.topLeftPoint = new GPoint(
                dojo.html.getAbsoluteX(document.getElementById("map")),
                dojo.html.getAbsoluteY(document.getElementById("map")));
    if ( !this.mouseUpListener ) {
        this.mouseUpListener = GEvent.bindDom(document.getElementById("map"),
            "mouseup", this, this.mouseUp);
    }
    if ( !this.mouseMoveListener ) {
        this.mouseUpListener = GEvent.bindDom(document.getElementById("map"),
            "mousemove", this, this.mouseMove);
    }
}

/* 
 * Kills an event's propagation and default action.  Not sure who the original
 * author of this function is, but I love it.
  */
function stopEvent(eventObject) {
    if (eventObject && eventObject.stopPropagation) {
        eventObject.stopPropagation();
    }
    if (window.event && window.event.cancelBubble ) {
        window.event.cancelBubble = true;
    }
                                      
    if (eventObject && eventObject.preventDefault) {
        eventObject.preventDefault();
    }
    if (window.event) {
        window.event.returnValue = false;
    }
}

/*
 * GxMarker
*/

function GxMarker(point, icon, tooltip, opts) {
    if ( tooltip ) {
        var oldInit  = this.initialize;
        var _t = this;
        var offset   = ( typeof opts == "object" ) ?
            (opts.offset || new GPoint(22,0)) : new GPoint(22,0);
        var isStatic = ( typeof opts == "object" ) ?
            (opts.isStatic || false ) : false;
        this.initialize = function(map) {
            var l = new GxLabel(tooltip, {
                "marker":   _t,
                "offset":   offset,
                "isStatic": isStatic
            });
            map.addOverlay(l);
            oldInit.apply(_t, [ map ]);
        }
    }
    GMarker.apply(this, [ point, icon ]);
}

GxMarker.prototype = new GMarker(new GLatLng(1,1));

function debug(msg) {
    var d = document.getElementById("debug") ?
        document.getElementById("debug") : document.body;
    d.appendChild(document.createTextNode("[" + new Date() + "] "));
    d.appendChild(document.createTextNode(msg));
    d.appendChild(document.createElement("br"));
}
/**************** End GxMarker code *************************/

/**************** Begin printMapControl code *************************/
function printMapControl(catID, areaID) {
	this._catID = catID;
	this._areaID = areaID;
}

printMapControl.prototype = new GControl();

printMapControl.prototype.initialize = function(map) {
	var t = this;
	var printDiv = document.createElement("div");
	printDiv.className = 'gmapPrintDiv';
	printDiv.appendChild(document.createTextNode("Printable Version"));
	GEvent.addDomListener(printDiv, "click", function() {
		url = '/print/areamap/' + t._catID + '/' + t._areaID + '/' +
			map.getCenter().toUrlValue(4) + '/' + map.getZoom() + '/';
		MM_openBrWindow(url,'print','scrollbars=yes,resizable=yes,width=910,height=680,menubar=yes,toolbar=yes');
	});

	map.getContainer().appendChild(printDiv);
	return printDiv;
}

printMapControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(272, 7));
}
/****************** End printMapControl code *************************/

var map;
var panoClient;
var houseMarker;
var tsvcDiv;
var initializeWithDefault = false;
var svOverlay = new GStreetviewOverlay();

function printMap(isGmap, gmapLat, gmapLng) {
	if ( isGmap ) {
		if ( GBrowserIsCompatible() ) {
			map = new GMap2(document.getElementById("gmap"));
			var latlng = new GLatLng(gmapLat, gmapLng);
			var marker = new GMarker(latlng);
			map.addControl(new GLargeMapControl3D());
			map.addControl(new GMapTypeControl());
			map.setCenter(latlng, 13);
			map.addOverlay(marker);
			if(document.getElementById('gPano')){
				map.addControl(new ToggleStreetViewControl());
				// icon drag code
				var guyIcon              = new GIcon(G_DEFAULT_ICON);
				var hn                   = window.location.hostname.replace(/^www\./, "")
				guyIcon.image            = 'http://images.' + hn + '/icons/gMapGuyIcon.png';
				guyIcon.transparent      = 'http://images.' + hn + '/icons/gMapGuyIconTransparent.png';
				guyIcon.imageMap         = [26,13, 30,14, 32,28, 27,28, 28,36, 18,35, 18,27, 16,26, 16,20, 16,14, 19,13, 22,8];
				guyIcon.iconSize         = new GSize(49, 52);
				guyIcon.iconAnchor       = new GPoint(25, 35);  // near base of guy's feet
				guyIcon.infoWindowAnchor = new GPoint(25, 5);  // top of guy's head
				var opts                 = {"icon": guyIcon, "draggable": true, "title": "Drag me to change street view location", "labelText": "X", "labelOffset": new GSize(-6, -10)};
				panoClient               = new GStreetviewClient();
				houseMarker              = new GMarker(latlng, opts);
				map.addOverlay(houseMarker); 
				GEvent.addListener(houseMarker, "dragend", function() {
					// don't even attempt to update the pano location if we haven't shown it yet, it only
					// causes problems and doesn't serve a purpose
					if ( __streetViewShown ) {
						panoClient.getNearestPanorama(houseMarker.getLatLng(), ShowPanoData);
					}
				});
				myPano = new GStreetviewPanorama(document.getElementById("gPano"));
			}
		}
	}
}

function statCount(id) {
	id = parseInt(id);
	if ( isNaN(id) ) return;
	var request = GXmlHttp.create();
	request.open('GET', '/stat/map/' + id + '/', true);
	request.send(null);
}

function createMarker(point, html, id) {
	var marker = new GMarker(point);
	GEvent.addListener(marker, "mouseover", function() {
		marker.openInfoWindowHtml(html);
		statCount(id);
	});
	return marker;
}

function printAreaMap(xmlFile,cityLat,cityLng,catID,areaID,zoom,print) {
	if ( GBrowserIsCompatible() ) {
		if ( !cityLat )
			cityLat = 0;
		if ( !cityLng )
			cityLng = 0;
		map = new GMap2(document.getElementById("gmap"));
		var bounds = new GLatLngBounds();
		var cityCenter = new GLatLng(parseFloat(cityLat),parseFloat(cityLng));
		map.setCenter(cityCenter, 12);
		map.addControl(new GLargeMapControl3D());
		map.addControl(new GMapTypeControl());
		if ( !print ) {
			map.addControl(new printMapControl(catID, areaID));
			if(document.getElementById('gPano')){
				map.addControl(new ToggleStreetViewControl());
				// icon drag code
				var guyIcon              = new GIcon(G_DEFAULT_ICON);
				var hn                   = window.location.hostname.replace(/^www\./, "")
				guyIcon.image            = 'http://images.' + hn + '/icons/gMapGuyIcon.png';
				guyIcon.transparent      = 'http://images.' + hn + '/icons/gMapGuyIconTransparent.png';
				guyIcon.imageMap         = [26,13, 30,14, 32,28, 27,28, 28,36, 18,35, 18,27, 16,26, 16,20, 16,14, 19,13, 22,8];
				guyIcon.iconSize         = new GSize(49, 52);
				guyIcon.iconAnchor       = new GPoint(25, 35);  // near base of guy's feet
				guyIcon.infoWindowAnchor = new GPoint(25, 5);  // top of guy's head
				var opts                 = {"icon": guyIcon, "draggable": true, "title": "Drag me to change street view location", "labelText": "X", "labelOffset": new GSize(-6, -10)};
				panoClient               = new GStreetviewClient();
				houseMarker              = new GMarker(cityCenter, opts);
				map.addOverlay(houseMarker); 
				GEvent.addListener(houseMarker, "dragend", function() {
					// don't even attempt to update the pano location if we haven't shown it yet, it only
					// causes problems and doesn't serve a purpose
					if ( __streetViewShown ) {
						panoClient.getNearestPanorama(houseMarker.getLatLng(), ShowPanoData);
					}
				});
				myPano = new GStreetviewPanorama(document.getElementById("gPano"));
			}
		}
		var request = GXmlHttp.create();
		request.open("GET", xmlFile, true);
		request.onreadystatechange = function() {
			if ( request.readyState == 4 ) {
				var xml = request.responseXML;
				var markers = xml.documentElement.getElementsByTagName("marker");
				for (var i = 0; i < markers.length; i++) {
					var point = new GLatLng(
						parseFloat(markers[i].getAttribute("lat")),
						parseFloat(markers[i].getAttribute("lng"))
					);
					bounds.extend(point);
					map.addOverlay( createMarker(
						point,
						markers[i].getAttribute('html'),
						markers[i].getAttribute('id')
					));
				}
				if ( markers.length == 0 ) {
					map.addOverlay(new GxLabel('<div class="gmapnoloc">No locations found</div>', {'anchor' : cityCenter, 'isStatic' : true}));
				} else {
					if ( !print ) {
						var boundZoom = map.getBoundsZoomLevel(bounds);
						if ( boundZoom > 14 ) {
							boundZoom = 14;
						}
						map.setZoom(boundZoom);
						map.setCenter(bounds.getCenter());
					} else {
						if ( zoom ) {
							map.setZoom(zoom);
						}
					}
				}
			}
		}
		request.send(null);
	}
}


/**************** Begin printMapControlByZipcodeAndRadius code *************************/
function printMapControlByZipcodeAndRadius(zip, rad, catID, areaID) {
	this._zip    = zip;
	this._rad    = rad;
	this._catID  = catID;
	this._areaID = areaID;
}

printMapControlByZipcodeAndRadius.prototype = new GControl();

printMapControlByZipcodeAndRadius.prototype.initialize = function(map) {
	var t = this;
	var printDiv = document.createElement("div");
	printDiv.className = 'gmapPrintDiv';
	printDiv.appendChild(document.createTextNode("Printable Version"));
	GEvent.addDomListener(printDiv, "click", function() {
		url = '/print/zipmap/' + t._zip.replace(/ /, '_') + '/' + t._rad + '/' + t._catID + '/' + t._areaID + '/' +
			map.getCenter().toUrlValue(4) + '/' + map.getZoom() + '/';
		MM_openBrWindow(url,'print','scrollbars=yes,resizable=yes,width=910,height=680,menubar=yes,toolbar=yes');
	});

	map.getContainer().appendChild(printDiv);
	return printDiv;
}

printMapControlByZipcodeAndRadius.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(272, 7));
}
/****************** End printMapControl code *************************/

function ShowPanoData(panoData){
	if(panoData.code != 200){
		// if the lookup failed, attempt to lookup the default (wichita) location, but only do that if we haven't
		// initialized the streetview to a valid location yet
		document.getElementById('gPanoMsg').innerHTML = "No streetview data is available here, but looking nearby may still help you find this location.<br />Drag the person icon to a street highlighted in blue for streetview.";
		if(! __gPanoInit){
			panoClient.getNearestPanorama(new GLatLng(37.686559, -97.243511), ShowPanoData); // a default start pano
			initializeWithDefault = true;
		}
		else
		{
			myPano.hide();
		}
		return;
	}

	__gPanoInit = true;
	
	if(initializeWithDefault == true){
		myPano.setLocationAndPOV(panoData.location.latlng, {yaw: 180}); // default
		var defaultMapListener = GEvent.addListener(myPano,"initialized",defaultMapHandler);
		
	}else{
		document.getElementById('gPanoMsg').innerHTML = "";
		if(myPano.isHidden())
		{
			myPano.show();
		}
		var angle = computeAngle(houseMarker.getLatLng(), panoData.location.latlng);
		myPano.setLocationAndPOV(panoData.location.latlng, {yaw: angle});
		
	}
	// only attempt to resize the pano block if this is our first time updating the coordinates (as in, we're just now showing it)
	if ( !__streetViewShown ) {
		__streetViewShown = true;
		myPano.checkResize();
	}
}

function defaultMapHandler()
{
	if(initializeWithDefault == true){
		myPano.hide();
		initializeWithDefault = false;
		GEvent.removeListener(defaultMapListener);
		
	}
}

function computeAngle(endLatLng, startLatLng) {
	var DEGREE_PER_RADIAN = 57.2957795;
	var RADIAN_PER_DEGREE = 0.017453;
	var dlat = endLatLng.lat() - startLatLng.lat();
	var dlng = endLatLng.lng() - startLatLng.lng();
	// We multiply dlng with cos(endLat), since the two points are very closeby,
	// so we assume their cos values are approximately equal.
	var yaw = Math.atan2(dlng * Math.cos(endLatLng.lat() * RADIAN_PER_DEGREE), dlat) * DEGREE_PER_RADIAN;
	return wrapAngle(yaw);
}

function wrapAngle(angle) {
	if(angle >= 360){
		angle -= 360;
	}else if(angle < 0){
		angle += 360;
	}
	return angle;
};

function ToggleStreetViewControl(){

}

ToggleStreetViewControl.prototype = new GControl();

ToggleStreetViewControl.prototype.initialize = function(map){
	if(document.getElementById('gPano')){
		tsvcDiv           = document.createElement("div");
		tsvcDiv.className = 'gmapStreetViewButtonDiv';
		if(! document.getElementById('gPano').style.display || document.getElementById('gPano').style.display == 'none'){
			tsvcDiv.appendChild(document.createTextNode("Show Street View"));
		}else{
			tsvcDiv.appendChild(document.createTextNode("Hide Street View"));
		}
		GEvent.addDomListener(tsvcDiv, "click", function(){
			if(! document.getElementById('gPano').style.display || document.getElementById('gPano').style.display == 'none'){
				StreetView_Show();
			}else{
				StreetView_Hide();
			}
		});
		map.getContainer().appendChild(tsvcDiv);
		return tsvcDiv;
	}
}

function StreetView_Show(){
	document.getElementById('gPano').style.display = 'block';
	if(typeof(myPano) == 'object' && typeof(panoClient) == 'object'){
		// if we've already shown the street view, just go ahead and check to see if it needs resizing, otherwise, load up
		// the initial start location based on the current marker location
		if ( !__streetViewShown ) {
			panoClient.getNearestPanorama(houseMarker.getLatLng(), ShowPanoData);
		} else {
			myPano.checkResize();
		}
	}
	map.addOverlay(svOverlay);
	tsvcDiv.innerHTML = 'Hide Street View';
}

function StreetView_Hide(){
	document.getElementById('gPano').style.display = 'none';
	map.removeOverlay(svOverlay);
	tsvcDiv.innerHTML                              = 'Show Street View';
}

ToggleStreetViewControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(272, 7));
}

function printAreaMapByZipcodeAndRadius(xmlFile, cityLat, cityLng, zip, rad, catid, areaid, zoom, print){
	if(GBrowserIsCompatible()){
		if(! rad){rad = 1;}
		if(! areaid){areaid = "0";}
		map            = new GMap2(document.getElementById("gmap"));
		var mapSize    = map.getSize();
		var bounds     = new GLatLngBounds();
		var cityCenter = new GLatLng(parseFloat(cityLat),parseFloat(cityLng));
		map.setCenter(cityCenter, 12);
		map.addControl(new GLargeMapControl3D());
		map.addControl(new GMapTypeControl());
		if(!print) {
			map.addControl(new printMapControlByZipcodeAndRadius(zip, rad, catid, areaid));
			if(document.getElementById('gPano')){
				map.addControl(new ToggleStreetViewControl());
				// icon drag code
				var guyIcon              = new GIcon(G_DEFAULT_ICON);
				var hn                   = window.location.hostname.replace(/^www\./, "")
				guyIcon.image            = 'http://images.' + hn + '/icons/gMapGuyIcon.png';
				guyIcon.transparent      = 'http://images.' + hn + '/icons/gMapGuyIconTransparent.png';
				guyIcon.imageMap         = [26,13, 30,14, 32,28, 27,28, 28,36, 18,35, 18,27, 16,26, 16,20, 16,14, 19,13, 22,8];
				guyIcon.iconSize         = new GSize(49, 52);
				guyIcon.iconAnchor       = new GPoint(25, 35);  // near base of guy's feet
				guyIcon.infoWindowAnchor = new GPoint(25, 5);  // top of guy's head
				var opts                 = {"icon": guyIcon, "draggable": true, "title": "Drag me to change street view location", "labelText": "X", "labelOffset": new GSize(-6, -10)};
				panoClient               = new GStreetviewClient();
				houseMarker              = new GMarker(cityCenter, opts);
				map.addOverlay(houseMarker); 
				GEvent.addListener(houseMarker, "dragend", function() {
					// don't even attempt to update the pano location if we haven't shown it yet, it only
					// causes problems and doesn't serve a purpose
					if ( __streetViewShown ) {
						panoClient.getNearestPanorama(houseMarker.getLatLng(), ShowPanoData);
					}
				});
				myPano = new GStreetviewPanorama(document.getElementById("gPano"));
			}
		}
		var request = GXmlHttp.create();
		request.open("GET", xmlFile + "?zip=" + zip + "&rad=" + rad + "&catid=" + catid + "&areaid=" + areaid, true);
		request.onreadystatechange = function(){
			if(request.readyState == 4){
				var xml = request.responseXML;
				var markers = xml.documentElement.getElementsByTagName("marker");
				for(var i = 0; i < markers.length; i++){
					var point = new GLatLng(
						parseFloat(markers[i].getAttribute("lat")),
						parseFloat(markers[i].getAttribute("lng"))
					);
					bounds.extend(point);
					map.addOverlay( createMarker(
						point,
						markers[i].getAttribute('html'),
						markers[i].getAttribute('id')
					));
				}
				if(markers.length == 0){
				map.addOverlay(new GxLabel('<div class="gmapnoloc">No locations found</div>', {'anchor' : cityCenter, 'isStatic' : true}));
				}else{
					if(!print){
						var boundZoom = map.getBoundsZoomLevel(bounds);
						if(boundZoom > 14){
							boundZoom = 14;
						}
						map.setZoom(boundZoom);
						map.setCenter(bounds.getCenter());
					}else{
						if(zoom){
							map.setZoom(zoom);
						}
					}
				}
			}
		}
		request.send(null);
	}
}


/**
 * Initialize the multi-location map view
 *
 * @requires jQuery 1.3.2+
 * @requires jQuery.scrollTo
 */
function Map_InitMultiLocationMap(print){
	$(function(){
		// replace the print placeholder element with the true print button and show the map block
		checkPrint();
		$("#script_map").show();
		
		// bind the GMap cleanup function to the page unload
		$('body').unload(function(){
			GUnload();
		});
		
		// add UI handlers to the location list to allow click to focus functionality
		$("#locationList > li").hover(
			function(){
				$(this).addClass('hover');
			}, function(){
				$(this).removeClass('hover');
			}
		).find('h4 a').click(function(e){
			var $location_block = $(this).closest('li');
			$location_block.addClass('selected');
			$location_block.siblings('.selected').removeClass('selected');
			e.preventDefault();
			
			var latLng = new GLatLng( parseFloat( $location_block.attr('data-gmap-lat') ), parseFloat( $location_block.attr('data-gmap-lng') ) );
			map.setCenter(latLng, 13);
		});
		// add handler to open hours and email popups
		$("a.hours").click(function(e){
			e.preventDefault();
			MM_openBrWindow( $(this).attr('href'),'hour','scrollbars=yes,resizable=yes,width=350,height=350');
		});
		$("a.email").click(function(e){
			e.preventDefault();
			MM_openBrWindow( $(this).attr('href'),'email','scrollbars=yes,resizable=yes,width=500,height=520');
		});
		// add handler to open hours qtip (2010_rad)
		$('.hour_link').each(function(){
			var $this = $(this);
			$this.qtip({
				content: {
					url: '/hours_tip.php?id=' + $this.attr('item_id')
				},
				show: 'click',
				hide: 'unfocus',
				position: {
					corner: {
						target: 'rightMiddle',
						tooltip: 'leftMiddle'
					}
				},
				style: {
					name: 'light', // Inherit from preset style. See http://craigsworks.com/projects/qtip/docs/reference/#style to customize.
					border: {
						width: 1,
						radius: 6,
						color  : '#959984'
					},
					tip: 'leftMiddle',
					padding: 0,
					margin: 0,
					width  : 230
				}
			});
		});
		
		// initialize the actual map now
		
		// the initial lat/lng for the site are passed in via data attributes
		var $map     = $("#gmap"),
		    site_lat = $map.attr('data-gmap-lat'),
		    site_lng = $map.attr('data-gmap-lng');
			
		// internal function to create a numeric marker for a GMap
		var fn_number_marker = function( point, number ) {
			var hn     = window.location.hostname.replace(/^www\./, ""),
			    icon   = new GIcon( G_DEFAULT_ICON, 'http://images.' + hn + '/common/gmap/number_markers/marker' + number + '.png' ),
			    marker = new GMarker(point, icon);
			
			GEvent.addListener(marker, "click", function() {
				var $list     = $("#locationList"),
				    $selected = $list.find("li[data-mapIndex=" + number + "]");
				$list.scrollTo($selected);
				$selected.find('h4 a').click();
			});
			return marker;
		};
		
		if(GBrowserIsCompatible()){
			map            = new GMap2(document.getElementById("gmap"));
			var mapSize    = map.getSize();
			var bounds     = new GLatLngBounds();
			var cityCenter = new GLatLng(parseFloat(site_lat),parseFloat(site_lng));
			map.enableScrollWheelZoom();
			map.setCenter(cityCenter, 12);
			map.addControl(new GLargeMapControl3D());
			map.addControl(new GMapTypeControl());
			if(!print) {
				if(document.getElementById('gPano')){
					map.addControl(new ToggleStreetViewControl());
					// icon drag code
					var guyIcon              = new GIcon(G_DEFAULT_ICON);
					var hn                   = window.location.hostname.replace(/^www\./, "")
					guyIcon.image            = 'http://images.' + hn + '/icons/gMapGuyIcon.png';
					guyIcon.transparent      = 'http://images.' + hn + '/icons/gMapGuyIconTransparent.png';
					guyIcon.imageMap         = [26,13, 30,14, 32,28, 27,28, 28,36, 18,35, 18,27, 16,26, 16,20, 16,14, 19,13, 22,8];
					guyIcon.iconSize         = new GSize(49, 52);
					guyIcon.iconAnchor       = new GPoint(25, 35);  // near base of guy's feet
					guyIcon.infoWindowAnchor = new GPoint(25, 5);  // top of guy's head
					var opts                 = {"icon": guyIcon, "draggable": true, "title": "Drag me to change street view location", "labelText": "X", "labelOffset": new GSize(-6, -10)};
					panoClient               = new GStreetviewClient();
					houseMarker              = new GMarker(cityCenter, opts);
					map.addOverlay(houseMarker); 
					GEvent.addListener(houseMarker, "dragend", function() {
						// don't even attempt to update the pano location if we haven't shown it yet, it only
						// causes problems and doesn't serve a purpose
						if ( __streetViewShown ) {
							panoClient.getNearestPanorama(houseMarker.getLatLng(), ShowPanoData);
						}
					});
					myPano = new GStreetviewPanorama(document.getElementById("gPano"));
				}
			}
			
			// build the map markers based on the locations in the HTML
			var $locations = $("#locationList li");
			if ( $locations.length ) {
				$locations.each(function(i){
					var $this    = $(this),
					    mapIndex = $this.attr('data-mapIndex'),
					    lat      = parseFloat($this.attr('data-gmap-lat')),
					    lng      = parseFloat($this.attr('data-gmap-lng'));
					// if the location doesn't have a mapIndex, it shouldn't be plotted
					if ( mapIndex > 0 ) {
						// the location's lat/lng is also passed in via data attributes
						var point = new GLatLng(
							lat,
							lng
						);
						bounds.extend(point);
						map.addOverlay( fn_number_marker(
							point,
							mapIndex
						));
					}
				});
				
				if(!print){
					var boundZoom = map.getBoundsZoomLevel(bounds);
					if(boundZoom > 14){
						boundZoom = 14;
					}
					map.setZoom(boundZoom);
					map.setCenter(bounds.getCenter());
				}
			} else {
				map.addOverlay(new GxLabel('<div class="gmapnoloc">No locations found</div>', {'anchor' : cityCenter, 'isStatic' : true}));
			}
		}
	});
}

