
var map; var geocoder; var custMarker; var baseMarker; var imageDirectory; var baseIcon;
var custImage; var placeImage; var sites; var xmlDoc; var directionsPanel; var directions;
var curMarker; var toSite; var contextmenu; var sortedPlaces; var googleMapKey;
var locationsPath; var defaultLatitude; var defaultLongitude; var defaultZoom; var primarySites;

//define custom object to represent a place
function Place(){
    this.name = "";
    this.address = "";
    this.city = "";
    this.state = "";
    this.zip = "";
    this.phone = "";
    this.web = "";
    this.lat = "";
    this.lon = "";
    this.photo = "";
    this.primary = false;
    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", "./config2.xml", false);
            req.send(null);
        }
        else if (browserName=="Microsoft Internet Explorer") {
            req = new ActiveXObject("Msxml2.XMLHTTP");
            req.open("GET", "./config2.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.85&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";
			homeImage = imageDirectory + "red_MarkerY.png";
	    geocoder = new GClientGeocoder();
	    directionsPanel = document.getElementById("route");
	    directions = new GDirections(map,directionsPanel);
            baseMarker = new GMarker(new GLatLng(40.235457,-76.247797));
            baseIcon = baseMarker.getIcon();
            sites = new Array();
            primarySites = new Array();
            toSite = 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(toSite == 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 site 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(toSt){
        try{
                contextmenu.style.visibility="hidden";
                toSite = toSt;
                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;
                        loadPoints();
                }
        };
        req.open("GET", locationsPath, true);
        req.send("");
    } catch (e) {
	   alert("Error in importXML().... " + e.name + " " + e.message);
    }
}

function loadPoints(){
    try{
	//get all the site elements from the xml doc
	var x = xmlDoc.getElementsByTagName('site');
        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 name=""; var address=""; var city=""; var state=""; var zip=""; var phone = "";
            var web=""; var lat=""; var lon=""; var photo=""; var primary="false";

	    //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 == "name" && node.firstChild) {
				name = node.firstChild.data;
			}
			else if(node.nodeName == "address" && node.firstChild) {
				address = 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 == "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;
			}
			else if(node.nodeName == "photo" && node.firstChild) {
				photo = node.firstChild.data;
			}
                        else if(node.nodeName == "primary" && node.firstChild) {
                                primary = node.firstChild.data;
                        }

	    }

		var place = new Place();
		place.name = name;
		place.address = address;
		place.city = city;
		place.state = state;
		place.zip = zip;
		place.phone = phone;
		place.web = web;
		place.lat = lat;
		place.lon = lon;
		place.photo = photo;
                place.primary = primary;
		sortedPlaces[i] = place;

	    //we have the data for a mark so create it
	    var point = new GLatLng(lat,lon);
            var divString = "";

            // create the icon we will user sites
            var icon = new GIcon(baseIcon);
            if(primary == "true"){
                icon.image = homeImage;
            }else{
                icon.image = placeImage;
            }
	    sites[i] = new GMarker(point,{icon: icon, clickable: true, title: name});
            //if this is a primary location add it to the primary location array
            if(primary == "true"){
                primarySites.push(sites[i]);
            }
	    map.addOverlay(sites[i]);
		divString = "<div class=\"balloon\">";
		if(photo != ""){
			divString = divString + "<a href=\"http://" + web + "\" target=\"_blank\"><img src=\"./portfolio/images/thumbs/" + photo + "\" title=\"" + name + "\" height=\"65\" width=\"80\" border=\"0\" /></a><br />";
		}
		divString = divString + name;
		if(address != ""){
			divString = divString + "<br />" + address;
		}
		divString = divString + "<br />" + city + ", " + state;
		if(zip != ""){
			divString = divString + "<br />" + " " + zip;
		}
		if(phone != ""){
			divString = divString + "<br />" + phone;
		}
		if(web != ""){
			divString = divString + "<br />" + "<a href=\"http://" + web + "\" target=\"_blank\">View Portfolio Entry</a>";
		}
	    sites[i].bindInfoWindowHtml(divString +
					  "<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(sites[i], "mouseover", function(){
                GEvent.trigger(this,"click");
            });


            GEvent.addListener(sites[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);
    }
}

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

function setCurrentMarker(id){
        curMarker.show();
        curMarker = sites[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);
                        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 Site:<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 site
                        var closest = 0;
                        var d = 0;
                        var pnt = custMarker.getPoint();

                        var sitesToLoop;
                        if(primarySites.length > 0){
                            sitesToLoop = primarySites;
                        }else{
                            sitesToLoop = sites;
                        }

                        for (var x = 0; x < sitesToLoop.length; x++) {
                            var distance = pnt.distanceFrom(sitesToLoop[x].getPoint());
                            if(x == 0){
                               closest = distance;
                               d = x;
                            }

                            if(distance < closest){
                                closest = distance
                                d = x;
                            }
                        }

                        //set closest site as the current marker
                        curMarker = sitesToLoop[d];

                        //now load the directions
                        getDirections(toSite);

                        //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(toSt) {
    try{
        toSite = toSt;
	directions.clear();
	if(custMarker != null){

                if(toSite){
                    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";
}

