
// locations_xml = "../path/to/locations.xml"
// home_lat = home position latitude
// home_lng = home position longitude
// home_zoom = home position zoom level
function init_gmap(locations_xml, home_lat, home_lng, home_zoom) {
    if (GBrowserIsCompatible()) {
    
        // this variable will collect the html which will eventualkly be placed in the side_bar
        var side_bar_html = "";
    
        // arrays to hold copies of the markers used by the side_bar
        // because the function closure trick doesnt work there
        var gmarkers = [];
        var htmls = [];
        var i = 0;
        // arrays to hold variants of the info window html with get direction forms open
        var to_htmls = [];
        var from_htmls = [];
        var info_window_showing = false;
    
    
        // A function to create the marker and set up the event window
        function createMarker(point,name,html) {
            var marker = new GMarker(point);
    
            // === store the name so that the tooltip function can use it ===
            marker.tooltip = '<div class="tooltip"><span style="font-weight: bold"><nobr>'+name+'</nobr></span></div>';
    
            // The info window version with the "to here" form open
            to_htmls[i] = html + 'Directions: <b>To here</b> - <a href="javascript:fromhere(' + i + ')">From here</a>' +
                 '<br><br>Start address:<br /><form style="display: inline" action="javascript:getDirections()">' +
                 '<input type="text" SIZE=40 MAXLENGTH=40 name="saddr" id="saddr" value="" /><br>' +
                 '<INPUT value="Get Directions" TYPE="SUBMIT">' +
                 '<input type="hidden" id="daddr" value="'+name+"@"+ point.lat() + ',' + point.lng() + 
                 '"/>';
            // The info window version with the "to here" form open
            from_htmls[i] = html + 'Directions: <a href="javascript:tohere(' + i + ')">To here</a> - <b>From here</b>' +
                    '<br><br>End address:<br /><form style="display: inline" action="javascript:getDirections()">' +
                 '<input type="text" SIZE=40 MAXLENGTH=40 name="daddr" id="daddr" value="" /><br>' +
                 '<INPUT value="Get Directions" TYPE="SUBMIT">' +
                 '<input type="hidden" id="saddr" value="'+name+"@"+ point.lat() + ',' + point.lng() +
                 '"/>';
            // The inactive version of the direction info
            html = html + 'Directions: <a href="javascript:tohere('+i+')">To here</a> - <a href="javascript:fromhere('+i+')">From here</a>';
    
            GEvent.addListener(marker, "click", function() {
                marker.openInfoWindowHtml(html);
                tooltip.style.visibility="hidden";
            });
    
            GEvent.addListener(marker, "infowindowopen", function() {
                info_window_showing = true;
            });
    
            GEvent.addListener(marker, "infowindowclose", function() {
                info_window_showing = false;
            });
    
    
            //  ======  The new marker "mouseover" and "mouseout" listeners  ======
            GEvent.addListener(marker,"mouseover", function() {
                        if (!info_window_showing)
                showTooltip(marker);
            });        
            
            GEvent.addListener(marker,"mouseout", function() {
                        tooltip.style.visibility="hidden";
            });   
    
            // ====== This function displays the tooltip ======
            // it can be called from an icon mousover or a side_bar mouseover
            function showTooltip(marker) {
                tooltip.innerHTML = marker.tooltip;
                var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
                var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
                var anchor=marker.getIcon().iconAnchor;
                var width=marker.getIcon().iconSize.width;
                var height=tooltip.clientHeight;
                var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height)); 
                pos.apply(tooltip);
                tooltip.style.visibility="visible";
            }
    
            // save the info we need to use later for the side_bar
            gmarkers[i] = marker;
            // add a line to the side_bar html
            side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '</a><br>';
            i++;
            return marker;
        }
    
        // ===== request the directions =====
        getDirections = function() {
            var saddr = document.getElementById("saddr").value
            var daddr = document.getElementById("daddr").value
            gdir.load("from: "+saddr+" to: "+daddr);
        }
    
        // This function picks up the click and opens the corresponding info window
        myclick = function(i) {
            GEvent.trigger(gmarkers[i], "click");
        }
    
        // functions that open the directions forms
        tohere = function(i) {
            gmarkers[i].openInfoWindowHtml(to_htmls[i]);
        }
        fromhere = function(i) {
            gmarkers[i].openInfoWindowHtml(from_htmls[i]);
        }
    
    
        // create the map	
    
        var map = new GMap2(document.getElementById("map"));
        map.addControl(new GLargeMapControl());
        //map.addControl(new GMapTypeControl());
        //map.setCenter(new GLatLng(-33.894357, 151.029053), 9);
        map.setCenter(new GLatLng(home_lat, home_lng), home_zoom)
    
        // ====== set up marker mouseover tooltip div ======
        var tooltip = document.createElement("div");
        map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
        tooltip.style.visibility="hidden";
    
        // === create a GDirections Object ===
        var gdir=new GDirections(map, document.getElementById("directions"));
    
        GEvent.addListener(gdir, "load", function () {
            document.getElementById("directions").style.border = "#cc9900 1px solid";
            document.getElementById("directions_wrapper").style.display = "block";
        });
    
        // === Array for decoding the failure codes ===
        var reasons=[];
        reasons[G_GEO_SUCCESS]            = "Success";
        reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
        reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
        reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
        reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
        reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
        reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
        reasons[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
        reasons[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
        reasons[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";
    
        // === catch Directions errors ===
        GEvent.addListener(gdir, "error", function() {
            var code = gdir.getStatus().code;
            var reason="Code "+code;
            if (reasons[code]) {
                reason = reasons[code]
            } 
    
            alert("Failed to obtain directions, "+reason);
        });
    
        // Read the data from example.xml
        var request = GXmlHttp.create();
        request.open("GET", locations_xml, true);
        request.onreadystatechange = function() {
            if (request.readyState == 4) {
                var xmlDoc = GXml.parse(request.responseText);
                // obtain the array of markers and loop through it
                var markers = xmlDoc.documentElement.getElementsByTagName("marker");
                
                for (var i = 0; i < markers.length; i++) {
                    // obtain the attribues of each marker
                    var lat = parseFloat(markers[i].getAttribute("lat"));
                    var lng = parseFloat(markers[i].getAttribute("lng"));
                    var point = new GLatLng(lat,lng);
                    var html = GXml.value(markers[i]);
                    var label = markers[i].getAttribute("label");
                    // create the marker
                    var marker = createMarker(point,label,html);
                    map.addOverlay(marker);
                }
                // put the assembled side_bar_html contents into the side_bar div
                //document.getElementById("side_bar").innerHTML = side_bar_html;
            }
        }
        request.send(null);
    }
}