var sDIVName = 'VenuesMap';                  // Default name of the <div> in the calling form in case one is not supplied
var gLatValue;                              // Latitude co-ordinate - global so that all routines can access it
var gLongValue;                             // Longitude co-ordinate - global so that all routines can access it
var mapObject;                              // This is the Google Map object itself
var aryMarkerItems = new Array();           // An array of the marker points that will end up on the map


var bMapScrolling = false;                  // Just an on/off variable so we know whether the map is in motion later on


// Called from the main ASP page to set the name of the <div> object that contains the map
function SetDIVName(DIVName)
    {
        sDIVName = DIVName;
    }

// Sets the centre of the map, but adds event handlers to listen for scrolling of the map		
function SetLatLongWithMovement(gLat, gLong)
    {
    
        gLatValue = gLat;
        gLongValue = gLong;

	    load(1, false);
    }

// The main creation function for the Map ... The IsArtist parameter is OzLeisure-specific and can be removed. If so, just remember to 
// change all of the calls to it so that they don't pass a value to that parameter
function load(TrackMovement, IsArtist) 
    {

        // Built-in Google Map function to make sure the browser is compatible
        if (GBrowserIsCompatible()) 
            {

            // Locate the <div> on the page that contains the map
            if (document.getElementById(sDIVName)) 
	            {
		            mapObject = new GMap2(document.getElementById(sDIVName));
            
                    // Adds the Google map controls for zoom and switch between map/satellite etc
		            mapObject.addControl(new GMapTypeControl());
		            mapObject.addControl(new GLargeMapControl());
		            
                    // Centre the map and set the zoom level
		            var iZoomLevel = (IsArtist == true) ? 12 : 9
		            mapObject.setCenter(new GLatLng(gLatValue, gLongValue), iZoomLevel);

                    // Are we tracking the movement of the map? If so, add event handlers to deal with it all                        		        
    		        if (TrackMovement == 1)
    		            {
		                    // Add the event handlers that we need for moving (mapListenerAfterMove is a JavaScript function that is further down
		                    // it re-loads all of the data etc)
                            GEvent.addListener(mapObject, "moveend", mapListenterAfterMove);

                            // Show the first bunch of data
                            getMapData(mapObject);
                        }
	            }
            }
    }


// Load the data for the map that we have on the screen        
function getMapData(MapItem)
    {  
                    
        // Work out the min/max lat/long for the map shown in both X and Y axis                    
        var MapBounds = MapItem.getBounds()
        var gTRLat = MapBounds.getNorthEast().lat();
        var gTRLong = MapBounds.getNorthEast().lng(); 
        var gBLLat = MapBounds.getSouthWest().lat();
        var gBLLong = MapBounds.getSouthWest().lng();
        
        
        // This is the main set up for the AJAX call and is pretty standard        
        var xmlHttp;
        try
            {    // Firefox, Opera 8.0+, Safari    
                 xmlHttp=new XMLHttpRequest();    
            }
        catch (e)
            {    
                 // Internet Explorer    
                 try
                    {      
                        xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");      
                    }
                catch (e)
                    {      
                        try
                            {        
                                xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");        
                            }
                        catch (e)
                            {        
                                alert("Your browser does not support AJAX!");        
                                return false;        
                            }      
                     }    
             }

        // This is the bit that is called when the AJAX call is completed. readyState = 4 means completed/finished
        xmlHttp.onreadystatechange=function()
            {
                if(xmlHttp.readyState==4)
                    {
                        // Process the results that we get from our call
                        // responseText will contain the HTML output from the AJAX page
                        var sResultText = xmlHttp.responseText;

                        // Trim off the spurious script block from the reply
                        if (sResultText.indexOf("/script")  > -1)
                            {
                                sResultText = sResultText.substr(sResultText.indexOf("/script") + 8);
                            }
                            
                        // Trim off the spaces and things
                        var sResultText = sResultText.replace(/^\s+|\s+$/g, '')

                        // Split the result up into the individual items (each record is separated using a | character)
                        var asItemList = sResultText.split('|')

                        // Remove any overlay data (pushpins) that we may already have so that they don't get duplicated
                        mapObject.clearOverlays();
                        aryMarkerItems = new Array();
                        
                        // Our records are now in the array (asItemList) - loop through that and add the pushpins to the map
                        var iLoop;

                        for (iLoop = 0; iLoop < asItemList.length; iLoop++)
                            {
                                // Split up the individual item (ID~Title~Lat~Long~Synopsis~ImagePath)
                                // Fields in records are separated using the ~ character
                                asSingleItem = asItemList[iLoop].split('~');
                                
                                // This checks to make sure that a lat/long exist in the array item that we are checking (just error-checking really)
                                if (asSingleItem[2] && asSingleItem[3])
                                    {
                                        // asSingleItem[2] contains the Latitide
                                        // asSingleItem[3] contains the Longitude
                                    
                                        // Create the pushpin item and shove it onto the map
                                        var markerPoint = new GLatLng(asSingleItem[2], asSingleItem[3]);
                                        var markerItem = new GMarker(markerPoint)
                                        mapObject.addOverlay(markerItem);

                                        // Add the marker to the array - just so that we know what is on the map. We will use this information
                                        // further down when we handle the pushpin click. Once a pushpin is on the map, it is a bugger to find 
                                        // out from it what it actually is - the only reliable information it can give back is lat/long. So, I 
                                        // store all of the pins I add in an array, then when the pin is clicked, I can whizz through the array
                                        // of displayed items and match the lat/longs to find the right one. Seeing as I am returning in my original
                                        // query all of the information I would want in the information window, I store that in the array too in 
                                        // order to make the process of showing the window that much quicker and avoiding the need to do more
                                        // database queries.
                                        var arySingleMarker = new Array();

                                        // **************************************************************************************
                                        // ** Make sure that the number of elements in the array here matches up to the number **
                                        // ** of fields that are coming back from te AJAX page. In JavaScript, when dealing    **
                                        // ** with arrays, you don't need to declare the size of them at the outset, just keep **
                                        // ** on adding elements (the numbers in sqare brackets [] - starting with 0)          **
                                        // **                                                                                  **
                                        // ** Here we have 6 elements but it could just as easily be 2 or 20                   **
                                        // **************************************************************************************
                                        arySingleMarker[0] = asSingleItem[2] // Lat
                                        arySingleMarker[1] = asSingleItem[3] // Long
                                        arySingleMarker[2] = asSingleItem[0] // ID
                                        arySingleMarker[3] = asSingleItem[1] // Title
                                        if (asSingleItem[4]) { arySingleMarker[4] = asSingleItem[4]; }
                                        if (asSingleItem[5]) { arySingleMarker[5] = asSingleItem[5]; }
                                        
                                        aryMarkerItems[iLoop] = arySingleMarker;
                                    }
                            }
                        // Create the listener for clicking a marker item - mapListenterMarkerClick is a JavaScript function that appears 
                        // later in this file
                        GEvent.addListener(mapObject, "click", mapListenterMarkerClick);
                        
                    }
            }

        // This is the main AJAX call ... you point the request at the ASP page that will get the data from the database 
        // along with all of the necessary variables that you will need. Most likely Top, Bottom, Left and Right of
        // the visible map, and any other stuff that you may need. Exactly as you would with any other call to a page.
        // The ms= parameter appends the current time (in milliseconds) so that each request is different and therefore doesn't
        // get taken from the browser cache. ie, every call results in live (not cached) data.
        if (!bMapScrolling) 
            {
                // Make the main request - pass the map bounds (split out) to the read page
                xmlHttp.open('GET','/googlemapsajax.asp?L=' + gBLLong + '&R=' + gTRLong + '&T=' + gTRLat + '&B=' + gBLLat + '&ms=' + new Date().getTime(),true);
                xmlHttp.send(null);  
            }

        bMapScrolling = false;
    }          

  
                    
// Once the map has moved, the event handler that was created points to this function which re-loads the data into the map with new pushpins
function mapListenterAfterMove(MapItem)
    {
		getMapData(mapObject);
    }


// This function is called when one of the pushpins on the map is clicked - used to display an information window of data                
function mapListenterMarkerClick(MarkerItem, Point)
    {
    
        if (MarkerItem != null)
            {
                // Find the marker that we have clicked in our list
                if (MarkerItem.getPoint())
                    {
                        var iFindMarker;
                        var objCurrentMarkerLocation = MarkerItem.getPoint();
                        var bFound = false;
                        
                        // This loops around our global array of marker points to make sure the one we have received is still valid
                        for (iFindMarker = 0; iFindMarker < aryMarkerItems.length; iFindMarker++)
                            {
                                var aryThisMarker = aryMarkerItems[iFindMarker];
                                
                                // If the lat/lng of this marker matches those of one in our global array then we know we have found the right one
                                if (aryThisMarker[0] == objCurrentMarkerLocation.lat() && aryThisMarker[1] == objCurrentMarkerLocation.lng())
                                    {
                                        // Found it, show the details
                                        // sWindowText is what we are going to display in the information window
                                        // aryThisMarker is an array that looks like this:
                                        //          [0] = Latitde co-ordinate
                                        //          [1] = Longitude co-ordinate
                                        //          [2] = ID of the activity - in your case, probably venue ID
                                        //          [3] = Title of the activity (venue for you)
                                        //          [4] = Synopsis text
                                        //          [5] = Image path
                                        //
                                        // *** Make sure you use the same number of elements in this checking and string building routine
                                        // *** are there are in the building of the array initially (done in getMapData function above)
                                        var sWindowText =  '<font class=body-text><img src="' + aryThisMarker[5] + '" align="left" style="border:none;" alt="" title="" /> <BR /> <strong>' + aryThisMarker[3] + '</strong><br />';
                                        
                                        if (aryThisMarker[4])
                                            {
                                                sWindowText += aryThisMarker[4];
                                            }
                                                                        
                                        sWindowText += '<p />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/venue.asp?venue=' + aryThisMarker[2] + '">Click for details</a> </font>'

                                        // We have now built the string of HTML that we are going to show in the info window, so show it
                                        if (MarkerItem.openInfoWindowHtml)
                                            {
                                                bMapScrolling = true; 
                                                
                                                // This next line makes the popup happen. Places the text in it, and sets the max. width of the
                                                // information window to the value shown
                                                MarkerItem.openInfoWindowHtml(sWindowText, {maxWidth:230});
                                                bFound = true;
                                                
                                            }
                                    }
                            }
                    }  
            
            }
                      
    }


// ******************************
// ** DRIVING DIRECTIONS STUFF **
// ******************************
function FindDirections(VenueName, VenueLatitude, VenueLongitude)
    {
    
        // Build up the address that we are looking to find, and pass it on to the main routine //
        // This address needs to be a comma-separated list of Street, Town, County, Postcode
        // UNITED KINGDOM goes on the end so that there is no confusion
        var sStartAddress = '';
        
        // This compiles the address from the value of text boxes on the calling ASP form, with the "name" attribute
        // set as below. txtStreet, txtTown and so on
        sStartAddress = document.frmMain.txtStreet.value + ','
        sStartAddress += document.frmMain.txtTown.value + ','
        sStartAddress += document.frmMain.txtCounty.value + ','
        sStartAddress += document.frmMain.txtPostcode.value + ', UNITED KINGDOM'
        SendDirectionsRequest(sStartAddress, VenueName, VenueLatitude, VenueLongitude);

    }    

function SendDirectionsRequest(StartingAddress, VenueName, VenueLatitude, VenueLongitude)
    {
        var directionsPanel;
        var directions;
        
        // Make sure that there is a DIV tag with the id of DrivingDirections on the main page
        directionsPanel = document.getElementById("DrivingDirections");  
        
        // Erase the contents of the panel before we start
        directionsPanel.innerHTML = '';
        
        // Center the map to a point which is shown while the directions are calculated
        mapObject.setCenter(new GLatLng(gLatValue,gLongValue), 3);  
        directions = new GDirections(mapObject, directionsPanel);  
        GEvent.addListener(directions, "load" ,function() 
            {
                
            });
        GEvent.addListener(directions, "error" ,function() 
            {
                // These are error conditions and only shown if the wheels fall off when looking up one of the addresses
                if (directions.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
                    alert("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: " + directions.getStatus().code);
	            else if (directions.getStatus().code == G_GEO_SERVER_ERROR)
	                alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + directions.getStatus().code);
	            else if (directions.getStatus().code == G_GEO_MISSING_QUERY)
	                alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + directions.getStatus().code);
	            else if (directions.getStatus().code == G_GEO_BAD_KEY)
	                alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + directions.getStatus().code);
	            else if (directions.getStatus().code == G_GEO_BAD_REQUEST)
	                alert("A directions request could not be successfully parsed.\n Error code: " + directions.getStatus().code);
	            else alert("An unknown error occurred.");    
            });

        // This is the code that actually gets the directions back and populates the directions panel
        // StartingAddress is a bunch of text with the street name and everything, VenueName is as it says
        // So, the panel will show 123 High Road, London, NW1 to ABC lakes
        directions.load(StartingAddress + " to " + VenueName, "en-GB");
    }

// ****************************
// ** ADDRESS ENCODING STUFF **
// ****************************

function GetLatLong(Address)
{
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng(Address, ShowMap);
    return 
}

function ShowMap(point)
    {
            if (!point)
                {
                    // The address is rubbish
                    alert('Address not found');
                }
            else
                {
                    // We have found the address, so pop the lat/long into an array
                }

        SetLatLongWithMovement(point.lat(),point.lng());
    }
