
var map; var geocoder; var custMarker; var baseMarker; var imageDirectory; var baseIcon; 
var custImage; var placeImage; var dealers; var xmlDoc; var directionsPanel; var directions;
var curMarker; var toDealer; var contextmenu; var sortedPlaces; var googleMapKey; var afterLoadCallBack;
var locationsPath; var defaultLatitude; var defaultLongitude; var defaultZoom;

//define custom object to represent a place
function Place(){
	this.mainhead = "";
	this.description = "";
    this.name = "";
    this.address = "";
	this.subaddress = "";
    this.city = "";
    this.state = "";
    this.zip = "";
    this.phone = "";
	this.web = "";
    this.lat = "";
    this.lon = "";
    this.toString = toString;
}
//define a custom toString() method for our Place object
function toString(){
    return this.state + " " + this.name;
}

function configureMap(){
    var confXML;
    var req;
    try{
        var browserName=navigator.appName; 
        if (browserName=="Netscape"){           
            req = new XMLHttpRequest;            
            req.open("GET", "user/config.xml", false);
            req.send(null);              
        }
        else if (browserName=="Microsoft Internet Explorer") {                
            req = new ActiveXObject("Msxml2.XMLHTTP");            
            req.open("GET", "user/config.xml", false);
            req.send(null);         
        }
        else {
            alert("Your browser is not compatible with this page");
            return;
        }
        
        confXML = req.responseXML;
        var x = confXML.getElementsByTagName('mapkey');
        if(x.length > 0){
            googleMapKey = x[0].firstChild.data;
        }   
        var mapsource = "http://maps.google.com/maps?file=api&v=2.140&key=" + googleMapKey;
        document.write('<script type="text/javascript" src="' + mapsource + '"></script>'); 
        
        x = confXML.getElementsByTagName('locationspath');
        if(x.length > 0){
            locationsPath = x[0].firstChild.data;
        }   
        
        //now we want to create the center GLatLng for the map
        var lat; var lng;
        x = confXML.getElementsByTagName('defaultlatitude');        
        if(x.length > 0){
            lat = x[0].firstChild.data;
        } 
        
        x = confXML.getElementsByTagName('defaultlongitude');        
        if(x.length > 0){
            lng = x[0].firstChild.data;
        }
        if(lat != null){
            defaultLatitude = lat;
        }
        if(lng != null){
            defaultLongitude = lng;
        }
        
        //now get the map zoom level
        x = confXML.getElementsByTagName('defaultzoom');
        defaultZoom = 5;
        if(x.length > 0){
            defaultZoom = parseInt(x[0].firstChild.data);
        }
        
        //get the image directory
        x = confXML.getElementsByTagName('imagedirectory'); 
        imageDirectory = "";
        if(x.length > 0){
            imageDirectory = x[0].firstChild.data;
        }      
        
    } catch (e) {        
	alert("Error in configureMap().... " + e.name + " " + e.message);        
    }    
}

function loadMap(callBack) {    
    try {        
	if (GBrowserIsCompatible()) {          
	    // Create and Center a Map
	    map = new GMap2(document.getElementById("map"));
	    map.setCenter(new GLatLng(defaultLatitude,defaultLongitude), defaultZoom);
	    map.addControl(new GLargeMapControl(),new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10, 20)));
	    map.addControl(new GMapTypeControl());
	    map.addControl(new GScaleControl());         
	    map.enableDoubleClickZoom();
            map.enableContinuousZoom();
            map.enableScrollWheelZoom(); 
            
            //add a listener to disable page scrolling while scroll zooming on the map
            GEvent.addDomListener(map.getContainer(), "DOMMouseScroll", wheelevent);
            map.getContainer().onmousewheel = wheelevent;
	    
	    //initialize some variables
            placeImage = imageDirectory + "darkgreen_MarkerD.png";
            custImage = imageDirectory + "red_MarkerY.png";            
	    geocoder = new GClientGeocoder();
	    directionsPanel = document.getElementById("route");     
	    directions = new GDirections(map,directionsPanel);
            baseMarker = new GMarker(new GLatLng(39.821103,-77.657794));
            baseIcon = baseMarker.getIcon();           
            dealers = new Array();
            toDealer = true;
            afterLoadCallBack = callBack;
            
            // === create the context menu div ===
            contextmenu = document.createElement("div");          
            contextmenu.style.visibility="hidden";
            contextmenu.style.background="#ffffff";
            contextmenu.style.border="1px solid #8888FF";
            contextmenu.style.padding="2px";
  
            contextmenu.innerHTML = '<a href="javascript:placeMarker(true);"><div width="50" class="context">Directions from here</div></a>'
                              + '<a href="javascript:placeMarker(false);"><div width="50" class="context">Directions to here</div></a>'
                              + '<a href="javascript:zoomIn()"><div width="50" class="context">Zoom in</div></a>'
                              + '<a href="javascript:zoomOut()"><div width="50" class="context">Zoom out</div></a>'
                              + '<a href="javascript:zoomInHere()"><div width="50" class="context">Zoom in here</div></a>'
                              + '<a href="javascript:zoomOutHere()"><div width="50" class="context">Zoom out here</div></a>'
                              + '<a href="javascript:centreMapHere()"><div width="50" class="context">Center map here</div></a>';  
            map.getContainer().appendChild(contextmenu);

	    
	    //add a load listener to the GDirections object
	    GEvent.addListener(directions, "load", function() {
                try{
                        var miles = directions.getSummaryHtml();                         
                        document.getElementById('miles').innerHTML = miles;
                        
                        if(toDealer == true){                        
                                directions.getRoute(0).getStartGeocode().address = custMarker.getTitle();
                                directions.getRoute(0).getEndGeocode().address = curMarker.getTitle();                                
                        }else{
                                directions.getRoute(0).getStartGeocode().address = curMarker.getTitle();
                                directions.getRoute(0).getEndGeocode().address = custMarker.getTitle();    
                        }
                        
                } catch (er) {
                        alert(er.name + " " + er.message);
                }	 
	    });
            
            //add "addoverlay" listener to hide directions markers
            GEvent.addListener(directions, "addoverlay", function(){               
                for(i=0; i < directions.getNumRoutes() + 1; i++){
                        var m = directions.getMarker(i);
                        map.removeOverlay(m);                                             
                }  
                //BUG WORKAROUND - hide the images in the route dive for now because they come back as null
                $("#route IMG").hide();                
            });    
	    
	    //call funtion to import xml file and load the dealer markers
	    importXML();  	    
	    
	    GEvent.addListener(map, "singlerightclick", function(point, src, marker) {
                try{
                        clickedPixel = point;
                        var x=point.x;
                        var y=point.y;
                        if (x > map.getSize().width - 120) { x = map.getSize().width - 120 }
                        if (y > map.getSize().height - 100) { y = map.getSize().height - 100 }
                        var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x,y));  
                        pos.apply(contextmenu);
                        contextmenu.style.visibility = "visible";                    
                        
                } catch (er) {
                        alert(er.name + " " + er.message);
                }	 
            });
            
            // === If the user clicks on the map, close the context menu ===
            GEvent.addListener(map, "click", function() {
                contextmenu.style.visibility="hidden";
            });
            
            GEvent.addListener(map, "mouseout", function() {
                contextmenu.style.visibility="hidden";
            });            
	}
	else{
	    alert("Your browser is not compatible!");
	}
    } catch (e) {
	alert("Error in loadMap().... " + e.name + " " + e.message);
    }	 
}

///prevent page scroll
function wheelevent(e) {
    if (!e){
        e = window.event;
    }
    if (e.preventDefault){
        e.preventDefault();
    }
    e.returnValue = false;    
} 

function placeMarker(toDlr){
        try{
                contextmenu.style.visibility="hidden";
                toDealer = toDlr;
                var p = map.fromContainerPixelToLatLng(clickedPixel);           
                showAddress(p.toUrlValue());
                
        } catch (e) {
	    alert(e.name + " " + e.message);
        }
       	 
}

function importXML() {
    try{
        var req = GXmlHttp.create();
        req.onreadystatechange = function () {                        
                if (req.readyState == 4){                       
                        xmlDoc = req.responseXML;
                        loadDealers();   
                }                 
        };       
        req.open("GET", locationsPath, true);
        req.send("");
    } catch (e) {
	   alert("Error in importXML().... " + e.name + " " + e.message);
    }	
}

function loadDealers(){
    try{        
	// create the icon we will user dealers
	var icon = new GIcon(baseIcon);        
	icon.image = placeImage;
	var x = xmlDoc.getElementsByTagName('dealer');
        sortedPlaces = new Array();
	       
	//loop through the nodes
	for (i=0;i<x.length;i++) {
	    //list the variables we will be using to create our markers
	    var mainhead= ""; var name=""; var address="";  var subaddress=""; var city=""; var state=""; var zip=""; var phone = ""; var description = ""; var web=""; var lat=""; var lon="";
	    
	    //loop through the child nodes and put markers on the map
	    for (j=0;j<x[i].childNodes.length;j++) {
		if (x[i].childNodes[j].nodeType != 1){
		    continue;
		}	
                
		var node = x[i].childNodes[j];
		
		if(node.nodeName == "mainhead" && node.firstChild) {
		    mainhead = node.firstChild.data;
		}
		else if(node.nodeName == "name" && node.firstChild) {                        
		    name = node.firstChild.data;
		}
		else if(node.nodeName == "address" && node.firstChild) {
		    address = node.firstChild.data;
		}
		else if(node.nodeName == "subaddress" && node.firstChild) {
		    subaddress = node.firstChild.data;
		}
		else if(node.nodeName == "city" && node.firstChild) {
		    city = node.firstChild.data;
		}
		else if(node.nodeName == "state" && node.firstChild) {
		    state = node.firstChild.data;
		}
		else if(node.nodeName == "zip" && node.firstChild) {
		    zip = node.firstChild.data;
		}
		else if(node.nodeName == "phone" && node.firstChild) {
		    phone = node.firstChild.data;
		}
		else if(node.nodeName == "description" && node.firstChild) {
		    description = node.firstChild.data;
		}
		else if(node.nodeName == "web" && node.firstChild) {
		    web = node.firstChild.data;
		}
		else if(node.nodeName == "lat" && node.firstChild) {
		    lat = node.firstChild.data;
		}
		else if(node.nodeName == "long" && node.firstChild) {
		    lon = node.firstChild.data;                    
		}               
	    }
            
            var place = new Place();
			place.mainhead = mainhead;
            place.name = name;
            place.address = address;
			place.subaddress = subaddress;
            place.city = city;
            place.state = state;
            place.zip = zip;
            place.phone = phone;
			place.description = description;
            place.web = web;
            place.lat = lat;
            place.lon = lon;
            sortedPlaces[i] = place;
	    
	    //we have the data for a mark so create it
	    var point = new GLatLng(lat,lon);                 
	    dealers[i] = new GMarker(point,{icon: icon, clickable: true, title: name});              
	    map.addOverlay(dealers[i]);                
	    dealers[i].bindInfoWindowHtml("<div class=\"balloon\">" + mainhead + "<br />" + name + "<br />" + address + "<br />" + subaddress + "<br />" + city + ", " + state + " " + zip + "<br />" + phone + "<br />" + description +"<br /><a href=\"http://" + web + "\" target=\"_blank\">" + web + "</a><br />" +
					  "Get Directions:<br><a id=\"" + i + "\" title=\"Click to get directions to this point\" href=\"#\" onclick=\"javascript: setCurrentMarker(this.id); getDirections(true);\">To Here</a>" +
					  " - <a id=\"" + i + "\" title=\"Click to get directions from this point\" href=\"#\" onclick=\"javascript: setCurrentMarker(this.id); getDirections(false);\">From Here</a></div>");
            
            //this listener will cause a "click" event on the marker causing it to display it's info window
            GEvent.addListener(dealers[i], "mouseover", function(){
                GEvent.trigger(this,"click");
            });
            
            
            GEvent.addListener(dealers[i], "dblclick", function(){
                map.zoomIn();
            });           
	}   
         
        //this calls the function that was passed in with the loadMap function - mostly that will be used to display
        //the places on a div after all the places are added to the map
        if(afterLoadCallBack){
            afterLoadCallBack();
        }
        
    } catch (e) {
	   alert(e.name + " " + e.message);
    }	 
}

//this function builds the locations div with all the places in the xml file
function displayPlaces(){
    try{
        sortedPlaces.sort();
        //start the locations table
        var locationHTML = "<table width=\"100%\" border=\"0\" align=\"center\" cellspacing=\"5\" cellpadding=\"0\">";    
        var linksHTML = "";
        var lastState = "";
        var counter = 0;

        for (i=0; i<sortedPlaces.length; i++){
			var mainhead = "";
            var place = sortedPlaces[i];
            var newState = place.state != lastState;         

            if(newState){            
                counter++;
                var image = "<img src=\"../images/states/" + place.state.toUpperCase() + ".jpg\" border=\"0\" align=\"top\"/>";
                //its a new state so we put in a state image in the first cell and then start a second cell a put a table in that cell
                locationHTML += "<tr><td colspan=\"2\"><hr width=\"100%\"></td></tr>" +
                                "<tr><td align=\"left\" valign=\"top\"><a id=\"" + place.state.toLowerCase() + "\" name=\"" + place.state.toLowerCase() + "\"></a><font size=\"4\" color=\"#666666\">" + image + "</font></td>" +
                                "<td><table>";

                //build the shortcut header
                if(i > 0 && (counter - 1) % 4 != 0){
                    linksHTML += " :: ";
                }
                linksHTML += "<a title=\"" + place.state.toUpperCase() + "\" Store Locations href=\"#" + place.state.toLowerCase() + "\" onClick=\"javascript:toggleLayer('location',true);\">" + place.state.toUpperCase() + "</a>";
                if(counter % 4 == 0){
                    linksHTML += "<br>";
                }
            }

            var phone = "";
			var description = "";
			var web = "";
			var subaddress = "";

			if(place.mainhead){
                mainhead = "<font size=\"3\" face=\"Century Gothic, Helvetica, Arial, FontName\">"+place.mainhead + "</font><br />";
            }
			if(place.phone){
                phone = place.phone + "</font><br/>";
            }
			if(place.description){
                description = "<br /><font size=\"2\" face=\"Century Gothic, Helvetica, Arial, FontName\"><strong>"+place.description + "</strong></font><br/>";
            }
            if(place.web){
                web = "<a href=\"http://" + place.web + "\" target=\"_blank\">" + place.web + "</a><br/>";
            }

			if(place.subaddress){
                subaddress = "<br/>" + place.subaddress;
            }

            //create a new row for each place, start cell put the dealer info in it and then another cell a put the map icon to link to the map
            locationHTML += "<tr><td valign=\"top\" width=\"450\"><font size=\"3\" color=\"#993333\" face=\"Century Gothic, Helvetica, Arial, FontName\">" + mainhead + "<strong>" + place.name + "</strong>" +
                            "</font><font size=\"2\" face=\"Century Gothic, Helvetica, Arial, FontName\"><br/>" + place.address + subaddress + "<br/>" + place.city + ", " + place.state + " " + place.zip + "<br/>" + phone + description + web +
                            "<br/></td><td valign=\"top\" width=\"75\"><a href=\"javascript:centerMap('" + place.lat + "','" + place.lon + "')\"><img src=\"../images/map_icon.gif\" alt=\"Map Icon\" border=\"0\" style=\"cursor:hand\"/></a></td></tr>";

            if(newState){           
                lastState = place.state;
            }

            if(sortedPlaces.length == i + 1 || sortedPlaces[i + 1].state != place.state){
                locationHTML += "</table></td></tr>";
            }

        }    

        locationHTML += "<tr><td colspan=\"2\"><hr width=\"100%\"></tr></table>";    

        var locationDiv = document.getElementById('location');
        locationDiv.innerHTML = locationHTML; 
        var locationsLinksDiv = document.getElementById('locationlinks');
        locationsLinksDiv.innerHTML = linksHTML;
        
    }catch(error){
        alert("An error occurred in displayPlaces...." + error.name + " " + error.message);
    }
}

function centerMap(lat, lon){      
    document.getElementById('mapanchor').scrollIntoView(true);
    map.setCenter(new GLatLng(lat,lon), 11);    
}

function setCurrentMarker(id){
        curMarker.show();
        curMarker = dealers[id];        
}


function showAddress(address) {        
  if (geocoder) {       
    geocoder.getLocations(
      address,
      function(response) {
	
	if (!response || response.Status.code != 200) {
                alert("Location \"" + address + "\" not found");
	} else {
                try{              
                        var place = response.Placemark[0];
                        var point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);

                        map.setCenter(point, 6);

						if(custMarker != null){
							map.removeOverlay(custMarker);
						}                        						
	
                        var icon = new GIcon(baseIcon);
                        icon.image = custImage;               
        
                        custMarker = new GMarker(point,{icon: icon, draggable: true, clickable: true, title: place.address});                
                        map.addOverlay(custMarker);
                        custMarker.bindInfoWindowHtml("<div class=\"balloon\">" + place.address + "<br><br>Get Directions To/From Dealer:<br><a href=\"#\" onclick=\"javascript: getDirections(false);\">To Here</a>" +
					  " - <a href=\"#\" onclick=\"javascript: getDirections(true);\">From Here</a></div>");                        
                        
                                                
                        // now we want to find the closest dealer	      
                        var closest = 0;
                        var d = 0;                       
                        var pnt = custMarker.getPoint();						
        
                        for (var x = 0; x < dealers.length; x++) {
                            var distance = pnt.distanceFrom(dealers[x].getPoint());							
                            if(x == 0){
                               closest = distance;
                               d = x;
                            }
        
                            if(distance < closest){
                                closest = distance
                                d = x;
                            }
                        }						
                        
                        //set closest dealer as the current marker                        
                        curMarker = dealers[d];                                                                   
                        
                        //now load the directions
                        getDirections(toDealer);
                        
                        //listen for the custMarker "dragend" event
                        GEvent.addListener(custMarker, "dragend", function(){
                                showAddress(custMarker.getPoint().toUrlValue());                                
                        });
                        
                        //this listener will cause a "click" event on the marker causing it to display it's info window
                        GEvent.addListener(custMarker, "mouseover", function(){
                            GEvent.trigger(this,"click");
                        });
                        
                        GEvent.addListener(custMarker, "dragstart", function(){
                                custMarker.closeInfoWindow();                               
                        });
                        
                } catch (e) {
                    alert("An error occurred in showAddress...." + e.name + " " + e.message);
                }
	}
      }
    );
  }
}

function getDirections(toDlr) {
    try{
        toDealer = toDlr;
	directions.clear();
	if(custMarker != null){                
                
                if(toDealer){
                    directions.load(custMarker.getPoint().toUrlValue() + " to " + curMarker.getPoint().toUrlValue());                    
                }
                else{
                    directions.load(curMarker.getPoint().toUrlValue() + " to " + custMarker.getPoint().toUrlValue());  
                }                
                	    
	}
	else{
	    alert("Please type in your address or zip code above first!");
	}        
    } catch (e) {
	alert(e.name + " " + e.message);
    }
}    
    
function clickclear(thisfield, defaulttext) {
    if (thisfield.value == defaulttext) {
        thisfield.value = "";
    }
}

function clickrecall(thisfield, defaulttext) {
    if (thisfield.value == "") {
        thisfield.value = defaulttext;
    }
}

function toggleLayer(in_layer, show) {
        if(show){
            $("#" + in_layer).fadeIn(1750);         
            if(in_layer == "location"){
                document.getElementById("showHide").checked=true;                
            }        
        }else{        
            $("#" + in_layer).fadeOut(1750);       
        }

}

// === functions that perform the context menu options ===
function zoomIn() {
  // perform the requested operation
  map.zoomIn();
  // hide the context menu now that it has been used
  contextmenu.style.visibility="hidden";
}      
function zoomOut() {
  // perform the requested operation
  map.zoomOut();
  // hide the context menu now that it has been used
  contextmenu.style.visibility="hidden";
}      
function zoomInHere() {
  // perform the requested operation
  var point = map.fromContainerPixelToLatLng(clickedPixel)
  map.zoomIn(point,true);
  // hide the context menu now that it has been used
  contextmenu.style.visibility="hidden";
}      
function zoomOutHere() {
  // perform the requested operation
  var point = map.fromContainerPixelToLatLng(clickedPixel)
  map.setCenter(point,map.getZoom()-1); // There is no map.zoomOut() equivalent
  // hide the context menu now that it has been used
  contextmenu.style.visibility="hidden";
}      
function centreMapHere() {
  // perform the requested operation
  var point = map.fromContainerPixelToLatLng(clickedPixel)
  map.setCenter(point);
  // hide the context menu now that it has been used
  contextmenu.style.visibility="hidden";
}
