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)
{
	var alertMessage = document.getElementById("alert-message");
    alertMessage.style.display = "none";
    alertMessage.style.display = "block";
    this.currentStoreIndex = index;
    var from_address = document.getElementById(id).value;
    if (from_address == "" || (from_address.indexOf("start street address") >= 0)) {
	alertMessage.innerHTML = "Please enter a starting address";
	return;
    }
    var to_address = app_controller.getStoreAddress(index);
	alertMessage.style.display = "none";
    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();
    document.getElementById(this.directionsDiv_id).className = 'driving-directions';
    document.getElementById("mapFoundStores").className = 'driving-store';
    document.getElementById("results").className = 'driving-results';
    document.getElementById("numStoreLocations").className = 'driving-locations';
    var onlineStores = document.getElementById("numOnlineStores");
 	onlineStores.style.display = 'none';
//    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;
    var alertMessage = document.getElementById("alert-message");
    alertMessage.style.display = "none";
    alertMessage.style.display = "block";
    
    if (code == G_GEO_UNKNOWN_ADDRESS)
    
	alertMessage.innerHTML = "Sorry, your starting address could not be found as entered. Please check the format, ex: 601 West 26th Street, New York City, NY";

    else if (code == G_GEO_SERVER_ERROR)
        alertMessage.innerHTML = "Sorry, the directions request could not be successfully processed, yet the exact reason for the failure is not known.";
	   
    else if (code == G_GEO_MISSING_QUERY)
        alertMessage.innerHTML = "Sorry, no query was specified in the input.";

//    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)
        alertMessage.innerHTML = "Sorry, there is a problem with the Google key for this site.";

    else if (code == G_GEO_BAD_REQUEST)
        alertMessage.innerHTML = "Sorry, the directions request could not be understood.";
	    
    else if (code == G_GEO_UNKNOWN_DIRECTIONS)
        alertMessage.innerHTML = "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.";
	    
    else if (code == G_GEO_TOO_MANY_QUERIES)
        alertMessage.innerHTML = "Sorry, this site has exceeded its limit for directions requests today.";
	    
    else alertMessage.innerHTML = "An unknown error occurred.";
}


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

MapController.prototype.printDirections = function() {
    var print = window.open("http://marthastewart.com/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\"); return false;' name='directions-form'><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='' value='submit' style='padding-left:5px;vertical-align:bottom;cursor:pointer;' /></form><div id='alert-message'></div></div></div>";
    return html;
 
}

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

MapController.prototype.getSmallIconFile = function(name) {
	if (MapController.icon_src[name]) return MapController.icon_src[name] + "_s.png";
	else return "lowes_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":"lowes",
	"2":"lowes",
	"4":"lowes",
	"3":"lowes",
	"5":"lowes"
}

MapController.default_icon = new GIcon();
MapController.default_icon.image = AppController.imagesURL + "lowes.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 + "lowes.gif";
MapController.default_icon.mozPrintImage = AppController.imagesURL + "lowes.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];



