/**
* Copyright (c) 2005 Andriy Bidochko. All Rights Reserved.
* http://www.mapbuilder.biz
*
* This code (including but not limited to the actual source code, documentation and database schemes) 
* is not freeware and is intended for the use of the original license purchaser according to the license agreement.
* The code all or in part may not be sold, redistributed, or included as part of another application.
* 
* THIS SOFTWARE PRODUCT IS PROVIDED "AS IS" AND LICENSOR MAKE NO WARRANTY AS TO ITS USE, PERFORMANCE, 
* OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

   // encode the things to pass back and forth
   // the escape() method in Javascript is deprecated -- should use encodeURIComponent if available
   function encode(uri) 
   {
     if (encodeURIComponent) 
     {
       return encodeURIComponent(uri);
     }

     if (escape) 
     {
       return escape(uri);
     }
   }

   var map ;
   //Marker Array
   var marar = [] ;
   // Icon Associative Array
   var iconaa = [] ;
   // Configuration array
   var conf = [];
   conf ['ShowSideNar'] = false;

   // Define MapObject class
   function MapObject (){
     //Map Container
     this.container = null;

     //XML file URL
     this.dataUrl = '';
     
     //AutoZoom
     this.autoZoom = false;
     // Number of zoom levels which we will use for zoom in/out
     this.autoZoomLevel = 3;

     // Active marker
     this.activeMarkerID = 0;

     // Marker IDs arrays
     this.markerIDs = [];

     /* ****************************************************************** */ 
     // Init Map and Load Data
     this.init = function()
     {
       map = new GMap2(this.container);
     }

     /* ****************************************************************** */ 
     this.loadMap = function(container, dataurl, locationID)
     {
       // Set container;
       this.container = container;
       
       // Remember URL
       this.dataUrl = dataurl;

       // Do Map if Compatible Browser only
       if (GBrowserIsCompatible()) 			
       {
         // Initialize Map
         this.init();
          
         if (location.search.length > 1)
         {
           // Pass ?x=y&z=x query parameters to the xml	
           this.loadData(dataurl + location.search);
         } 
         else
         {
           this.loadData(dataurl);
         }
       } 
       else
       {
         this.container.innerHTML = "<h1>Your browser is not compatible with Google Maps. You will not be able to see the map.</h1>" ;
       }
     }  // EOF LoadMap

     /* ****************************************************************** */ 
     // Reset Map with original data and state
     this.reset =  function(param, value)
     {
       this.clearOverlays();
       this.loadData (this.dataUrl)
     }

     /* ****************************************************************** */ 
     // Filter locations
     this.filter =  function(param, value)
     {
       this.clearOverlays();
       this.loadData (this.dataUrl+"?" +encode(param) + "=" + encode(value))
     }

     /* ****************************************************************** */ 
     //Removes all of the overlays from the map. 
     // Filter locations
     this.clearOverlays =  function()
     {
       map.clearOverlays();
     }

     /* ****************************************************************** */ 
     // Build Icons and Draw Polylines and Markers
     this.loadData = function(url)
     {
       var request = GXmlHttp.create();
       request.open("GET", url, true);
       request.onreadystatechange = function() 
       {
         document.getElementById("loading").innerHTML = "Loading, please wait..." ;

         if (request.readyState == 4)
         {
           var xmlDoc = request.responseXML ;
           try
           {
             mapattr = xmlDoc.getElementsByTagName("map")
             map.addControl(new GLargeMapControl());
             map.addControl(new GMapTypeControl());
             map.addControl(new GScaleControl());

             // Set Title
             try 					
             {
               document.title = mapattr[0].getAttribute("title");
             } 
             catch(e) { }

             var lng = -90 ;
             // Set Map Center Longitude
             try 					
             {
               lng = parseFloat(mapattr[0].getAttribute("lng"));
             } 
             catch(e) { }

             var lat = 35 ;
             // Set Map Center Latitude
             try 					
             {
               lat = parseFloat(mapattr[0].getAttribute("lat"));
             } 
             catch(e) { }

             var zoom = 2 ;
             // Set Initial Zoom Level
             try 					
             {
               zoom = parseInt(mapattr[0].getAttribute("zoom"));
             } 
             catch(e) { }

             map.setCenter(new GLatLng(lat, lng), zoom);


             try 					
             {
               var polyline = xmlDoc.getElementsByTagName("polyline");
               for (var i = 0; i < polyline.length ; i++)
               {
                 var color = "#0000ff" ;
                 // Set Polyline Color
                 try 					
                 {
                   color = polyline[i].getAttribute("color");
                 } 
                 catch(e) { }

                 var weight = .5 ;
                 // Set Polyline Weight
                 try 					
                 {
                   weight = parseFloat(polyline[i].getAttribute("weight"));
                 } 
                 catch(e) { }

                 var width = 1 ;
                 // Set Polyline Width
                 try 					
                 {
                   width = parseInt(polyline[i].getAttribute("width"));
                 } 
                 catch(e) { }
         
                 var points = [ ] ;
                 var point = polyline[i].getElementsByTagName("point");

                 // Get Polyline Points - Required for Polyline
                 for (j = 0 ; j < point.length ; j++)	
                 {
                   points.push(new GPoint(parseFloat(point[j].getAttribute("lng")),parseFloat(point[j].getAttribute("lat"))));
                 }
                 map.addOverlay(new GPolyline(points, color, width, weight));
               }
             } 
             // No Polylines or error in XML
             catch(e) { }				

             // Build Icons, if available
             try 					
             {
               var icons = xmlDoc.getElementsByTagName("icon");
               for (var i = 0; i < icons.length ; i++)
               {
                 // Required: icon name
                 var name = icons[i].getAttribute("name");		

                 // Test Variable
                 var x = "" ;				
                 // Test Variable
                 var y = "" ;				

                 // Check for an icon copy
                 try 					
                 {
                   x = icons[i].getAttribute("copy");
                 } 
                 catch(e) { }

                 // Make sure icon to copy has been built
                 if (x && iconaa[x])			
                 {
                   var icon = new GIcon(iconaa[x]);
                 } 
                 else
                 {
                   var icon = new GIcon();
                 }

                 // Required: Icon Image
                 icon.image = icons[i].getElementsByTagName("image")[0].getAttribute("src");	

                 x = "" ;
                 y = "" ;
                 // Check for an icon anchor
                 try 					
                 {
                   x = icons[i].getAttribute("xanchor");
                   y = icons[i].getAttribute("yanchor");
                 } 
                 catch(e) { }

                 if (x != null && y!= null && x && y)
                 {
                   icon.iconAnchor = new GPoint(parseInt(x),parseInt(y));
                 }

                 x = "" ;
                 y = "" ;

                 // Check for an icon infowindow anchor
                 try 					
                 {
                   x = icons[i].getAttribute("xiwanchor");
                   y = icons[i].getAttribute("yiwanchor");
                 } 
                 catch(e) { }

                 if (x != null && y!= null && x && y)
                 {
                   icon.infoWindowAnchor = new GPoint(parseInt(x),parseInt(y));
                 }

                 x = "" ;
                 y = "" ;

                 // Check for an icon infoshadow anchor
                 try 					
                 {
                   x = icons[i].getAttribute("xisanchor");
                   y = icons[i].getAttribute("yisanchor");
                 } 
                 catch(e) { }

                 if (x != null && y!= null && x && y)
                 {
                   icon.infoShadowAnchor = new GPoint(parseInt(x),parseInt(y));
                 }

                 x = "" ;
                 y = "" ;
                 // Check for icon image height and width
                 try 					
                 {
                   x = icons[i].getElementsByTagName("image")[0].getAttribute("width");
                   y = icons[i].getElementsByTagName("image")[0].getAttribute("height");
                 } 
                 catch(e) { }

                 if (x != null && y!= null && x && y)
                 {
                   icon.iconSize = new GSize(parseInt(x),parseInt(y));
                 }

                 x = "" ;
                 // Check for an shadow image
                 try 					
                 {
                   x = icons[i].getElementsByTagName("shadow")[0].getAttribute("src");
                 } 
                 catch(e) { }

                 if (x != null && x)
                 {
                   icon.shadow = x ;
                 }

                 x = "" ;
                 y = "" ;
                 // Check for an icon shadow dimension
                 try 					
                 {
                   x = icons[i].getElementsByTagName("shadow")[0].getAttribute("width");
                   y = icons[i].getElementsByTagName("shadow")[0].getAttribute("height");
                 } 
                 catch(e) { }

                 if (x != null && y!= null && x && y)
                 {
                   icon.shadowSize = new GSize(parseInt(x),parseInt(y));
                 }
                 
                 iconaa[name] = icon ;
               }
             } 
             catch (e) { }

             // Build Markers, if available
             try 					
             {
               var markers = xmlDoc.getElementsByTagName("marker");
               for (var i = 0; i < markers.length ; i++)
               {
                 var point = new GPoint(parseFloat(markers[i].getAttribute("lng")),parseFloat(markers[i].getAttribute("lat")));

                 var iconname ="" ;
                 // Look for Icon Name
                 try 					
                 {
                   iconname = markers[i].getAttribute("iconname");
                 } 
                 catch(e) { }
         
                 var html = "" ;
                 // Set Polyline Weight
                 try 					
                 {
                   html = markers[i].getElementsByTagName("infowindow")[0].firstChild.nodeValue;
                 } 
                 catch(e) { }

                 var marker = MapObject.createMarker(point, html, iconname);
                 marar.push(marker);
                 map.addOverlay(marker);

                 // Push markers to the array with ID as key
                 id = markers[i].getAttribute("id");
                 if (id != '')
                 {
                   MapObject.markerIDs[id] = marker;
                 }

                 // Set link
                 try					
                 {
                   html = markers[i].getElementsByTagName("link")[0].firstChild.nodeValue ;
                   if (conf ['ShowSideNar'])
                   {
                     document.getElementById("sidebar").innerHTML += "<a href='javascript:MapObject.infoLink(" + i + ");'>" + html + "</a><br>" ;
                   }
                 } 
                 catch (e) { }
               } 

             } 
             // No Markers or error in XML
             catch(e) { }				

             try 					
             {
               MapObject.showActiveMarker(MapObject.activeMarkerID);
               // Remove active marker
               MapObject.activeMarkerID = 0;
             }
             catch(e) { }				
           } 
           catch(e)
           {
             alert("Some error occured during program processing:" + e);
           }       
           document.getElementById("loading").innerHTML = "" ;
         } // if (request.readyState == 4)
       } // request.onreadystatechange = function() 

       request.send(null);

     } //this.LoadMap
      
     /* ****************************************************************** */ 
     // Create a marker at a point with an infowindow...
     this.createMarker = function(point, html, iconname) 
     {
       if (iconname && iconaa[iconname])
       {
         var marker = new GMarker(point, iconaa[iconname]);
       } 
       else
       {
         var marker = new GMarker(point);
       }
       GEvent.addListener(marker, "click", function()
       {
         // Do we use auto zoom?
         if (MapObject.autoZoom)
         {
           MapObject.centerAndZoomIn(marker.getPoint());
         }
         marker.openInfoWindowHtml(html);
       });
       return marker;
     }

     /* ****************************************************************** */ 
     // Open an Infowindow when the link is clicked in the message div...
     this.infoLink = function(i)
     {
       // Do we use auto zoom?
       if (this.autoZoom)
       {
         this.zoomIn();
       }
       GEvent.trigger(marar[i], "click");
     }

     /* ****************************************************************** */ 
     this.zoomIn = function()
     {
       // Get current zoom level
       currentZoom = map.getZoom();

       if (currentZoom != 0)
       {
         map.setZoom((currentZoom + this.autoZoomLevel) > 17 ? (currentZoom) : (currentZoom + this.autoZoomLevel));
       }
     }
     /* ****************************************************************** */ 
     this.centerAndZoomIn = function(point)
     {
       // Get current zoom level
       currentZoom = map.getZoom();

       if (currentZoom < 17)
       {
         map.setCenter(point, ((currentZoom + this.autoZoomLevel) > 17 ? (currentZoom) : (currentZoom + this.autoZoomLevel)));
       }
       
     }

     /* ****************************************************************** */ 
     this.showActiveMarker = function(id)
     {
       //alert (id);
       if (id!=0)
       {
         try 					
         {
           GEvent.trigger(this.markerIDs[id], "click"); 
         } 
         catch(e) { }
       }
     }
  } // eof MapObject class

  // Create new map object instance
  var MapObject = new MapObject();

