function MapController()
{
    this.default_zooms = {"5":11, "10":10, "25":9, "50":8, "100":7};
    this.closeup_zoom = 16;
    this.directions = null;

    // set CustomControls elements
    this.zoomOut_id = "msMap_zoomout";
    this.zoomIn_id = "msMap_zoomin";
    this.zoomKnob_id = "msMap_knob";
    this.zoomBar_id = "msMap_slidebar";
    this.zoomBar_left = 26;
    this.zoomBar_width = 57;
    this.zoomBar_height = 2;
    this.panLeft_id = "msMap_panLeft";
    this.panRight_id = "msMap_panRight";
    this.panUp_id = "msMap_panUp";
    this.panDown_id = "msMap_panDown";
    this.startAddress_id = "start_address";
    this.directionsDiv_id = "mapFoundStores2";
	this.hasDirections = false;
}
MapController.prototype.initialize = function(map_div, latitude, longitude, zoom)
{ 
    if (GBrowserIsCompatible()) 
    {
        this.map = new GMap2(document.getElementById(map_div));
 //       this.map.setCenter(new GLatLng(latitude, longitude ), zoom);
		var thisObj = this;
//		setTimeout(thisObj.initControls, 500);
        this.geocoder = new GClientGeocoder();
//	}
//}
//MapController.prototype.initControls = function() {
        this.controls = new CustomControls(this.map, "msMap_toolbar");
        this.controls.createZoomControl(this.zoomOut_id, this.zoomIn_id, this.zoomKnob_id, this.zoomBar_id, this.zoomBar_left, this.zoomBar_width, this.zoomBar_height, G_NORMAL_MAP);
        this.controls.createPanControl(this.panLeft_id, this.panRight_id, this.panUp_id, this.panDown_id);
	}
}
MapController.prototype.addMarker = function(pt, index) {
    var latitude = pt.latitude;
    var longitude = pt.longitude;
    var name = pt.retailer;
    var point = new GLatLng(latitude, longitude);
	var icon = new GIcon(MapController.default_icon);
	if (MapController.icon_src[name]) {
		var src = AppController.imagesURL + this.getIconFile(name);
		icon.image = src;
		icon.printImage = src.replace("png", "gif");
	}
    var marker = new GMarker(point, icon);
    var thisObj = this;
    GEvent.addListener(marker, "click", function() {
        var text = app_controller.map_controller.buildInfoWindow(pt, index); 
        marker.openInfoWindowHtml(text);
    });
    GEvent.addListener(marker, "mouseover", function() {
            app_controller.highlightStore(marker.pointsIndex);
            app_controller.scrollIntoView(marker.pointsIndex);
    });
    GEvent.addListener(marker, "mouseout", function() {
            app_controller.unHighlightStore(marker.pointsIndex);
    });
    this.map.addOverlay(marker);
    return marker;
}

MapController.prototype.centerOnAddress = function(point, radius) {
    var zoom = this.default_zooms[radius];
	this.homeLatLng = point;
    this.map.setCenter(point, zoom);
    if (this.controls) this.controls.updateZoom(zoom);
}
MapController.prototype.clearMap = function()
{
    this.map.clearOverlays();
}

MapController.prototype.selectMarker = function(marker) {
	GEvent.trigger(marker, "click");
}

MapController.prototype.deSelectMarker = function(marker) {
	marker.closeInfoWindow();
}

MapController.prototype.getDirections =  function(index, id)
{
    this.currentStoreIndex = index;
    var from_address = document.getElementById(id).value;
    if (from_address == "" || (from_address.indexOf("start street address") >= 0)) {
	alert ("Please enter a starting address");
	return;
    }
    var to_address = app_controller.getStoreAddress(index);

    this.doDirectionsQuery(from_address, to_address);
}

MapController.prototype.doDirectionsQuery =  function(from_address, to_address)
{
    var dirDiv = document.getElementById(this.directionsDiv_id);
    if (!this.directions) {
	var gDir = new GDirections(this.map, dirDiv);
	GEvent.bind(gDir, "load", this, this.handleDirectionsLoad);
	GEvent.bind(gDir, "addoverlay", this, this.handleDirectionsComplete);
	GEvent.bind(gDir, "error", this, this.handleDirectionsErrors);
        this.directions = gDir;
    }
    else this.directions.clear();

    var queryStr = "from: " + from_address + " to: " + to_address;
    this.directions.load(queryStr);
    // save the query in case we have to print
    this.directions_query = queryStr;
	// close the info window
	this.map.closeInfoWindow();
}

MapController.prototype.detailsZoom = function(latitude, longitude) {
    this.map.closeInfoWindow();
    this.map.setCenter(new GLatLng(latitude, longitude), this.closeup_zoom);
}

MapController.prototype.handleDirectionsLoad = function() {
    // store details on left directions on right
    app_controller.setUpDirections();
    app_controller.showDetailsHtml(this.currentStoreIndex);
    this.clearMap();
    var dirDiv = document.getElementById(this.directionsDiv_id);
    dirDiv.style.width = "315px";
    dirDiv.style.height = "161px";
//    document.getElementById(this.directionsDiv_id).innerHTML = "";
}

MapController.prototype.handleDirectionsComplete = function() {
    this.controls.updateZoom();
	this.hasDirections = true;
}

MapController.prototype.handleDirectionsErrors =  function() {
    var code = this.directions.getStatus().code;
    if (code == G_GEO_UNKNOWN_ADDRESS)
	alert("Sorry, no corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + code);
    else if (code == G_GEO_SERVER_ERROR)
        alert("Sorry, the directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + code);
	   
    else if (code == G_GEO_MISSING_QUERY)
        alert("Sorry, no query was specified in the input.\n Error code: " + code);

//    else if (code == G_UNAVAILABLE_ADDRESS)  <--- Doc bug... this is either not defined, or Doc is wrong
//        alert("Soryy, the given directions query cannot be returned due to legal or contractual reasons.\n Error code: " + code);
	     
    else if (code == G_GEO_BAD_KEY)
        alert("Sorry, there is a problem with the Google key for this site. \n Error code: " + code);

    else if (code == G_GEO_BAD_REQUEST)
        alert("Sorry, the directions request could not be understood.\n Error code: " + code);
	    
    else if (code == G_GEO_UNKNOWN_DIRECTIONS)
        alert("Sorry, we could not compute directions between the two points, either because there is no route available or we do not have data for routing in that region.\n Error code: " + code);
	    
    else if (code == G_GEO_TOO_MANY_QUERIES)
        alert("Sorry, this site has exceeded its limit for directions requests today.\n Error code: " + code);
	    
    else alert("An unknown error occurred.");
}


MapController.prototype.showingDirections = function() {
	return this.hasDirections;
}

MapController.prototype.printDirections = function() {
    var print = window.open("/storelocator/print_directions.jsp?lt=" + this.homeLatLng.lat() + "&ln=" + this.homeLatLng.lng() + "&zm=" + this.default_zooms[app_controller.radius] + "&q=" + this.directions_query, "printWindow");
}

MapController.prototype.buildInfoWindow = function(store, index) {
    var html = "<div id='msMap_infoWin'><span style='font-weight:bold;font-size:larger;'>" + store.storeName + "</span><br />" +
				"<span id='store_street'>" + store.address + "</span><br />" +
				/* location details + "<br />" + */
				"<span id='store_cityStateZip'>" + store.city + ", " + store.state + " " + store.postCode + "</span><br />" + 
				store.tel + "<br />";
    html += "<input id='get_details' type='image' style='margin:8px 0;cursor:pointer;' src='" + AppController.imagesURL + "button_details.gif' alt='' onclick='app_controller.getStoreDetails(" + index + ");' />";
    html += "<br /><b>Get Directions</b><br /><div style='height:22px; width:238px'><form onsubmit='app_controller.map_controller.getDirections(" + index + ", \"start_address\")'><input type='text' name='start_address' id='start_address' value='start street address, city, state' size=26 onfocus='this.value=\"\"' valign='top' style='padding:0px; margin:0px;' /><input id='go_get_directions' type='image' src='" + AppController.imagesURL + "button_go.gif' alt='' onclick='app_controller.map_controller.getDirections(" + index + ", \"start_address\")' style='padding-left:5px;vertical-align:bottom;cursor:pointer;' /></form></div></div>";
    return html;
}

MapController.prototype.getIconFile = function(name) {
	if (MapController.icon_src[name]) return MapController.icon_src[name] + ".png";
	else return "other.png";
}

MapController.prototype.getSmallIconFile = function(name) {
	if (MapController.icon_src[name]) return MapController.icon_src[name] + "_s.png";
	else return "other_s.png";
}

// NOTE the icon source doesn't contain the filetype anymore, so we can choose the larger or smaller version - HM
MapController.icon_src = {
	"1":"costco",
	"2":"kmart",
	"4":"macys",
	"3":"lowes",
	"5":"michaels"
}

MapController.default_icon = new GIcon();
MapController.default_icon.image = AppController.imagesURL + "other.png";
MapController.default_icon.iconSize = new GSize(22,22);
MapController.default_icon.iconAnchor = new GPoint(11,11);
MapController.default_icon.infoWindowAnchor = new GPoint(11,1);
MapController.default_icon.printImage = AppController.imagesURL + "other.gif";
MapController.default_icon.mozPrintImage = AppController.imagesURL + "other.gif";
MapController.default_icon.transparent = AppController.imagesURL + "transparent.png";
/*
MapController.default_icon.imageMapType = "circle";
MapController.default_icon.imageMap = [11,0,11];
*/
MapController.default_icon.imageMap = [10,1,8,2,7,3,6,4,5,5,4,6,3,7,2,8,1,10,1,12,2,14,3,15,4,16,5,17,6,18,7,19,8,20,10,21,12,21,14,20,15,19,16,18,17,17,18,16,19,15,20,14,21,12,21,10,20,8,19,7,18,6,17,5,16,4,15,3,14,2,12,1];


