GMapLoader = new Object({
      mapId: null,
      mapWindow: null,
      source: null,
      map: null,
      markers: null,
      goeCoder: null,
      icons: null,
      markers: null,
      xml: null,
      defaultZoom: 13,
      load: function(map, source)
      {
            if (GBrowserIsCompatible()) {
                  this.source = source;
                  this.map = map;
              this.geocoder = new GClientGeocoder();
              this.loadData();
            }
      },
      sleep: function(timeout) {
        var loop = true;
        var current = new Date();
        var now;
        var cTimestamp = current.getTime();

        while(loop) {
            now = new Date();
            nTimestamp = now.getTime();

            if(nTimestamp - cTimestamp > timeout) {
                    loop = false;
            }
        }

      },
      unload: function()
      {
            GUnload();
      },
      loadData: function()
      {
            var mapObj = this;
            GDownloadUrl(this.source, function(data) {
                        mapObj.xml = GXml.parse(data);
                        mapObj.loadMap();
                        mapObj.loadIcons();
                        mapObj.loadMarkers();
                  }
            );
      },    
      loadMap: function()
      {
            if ( this.xml != null ) 
            {
                  var xmlMaps = this.xml.documentElement.getElementsByTagName("map");
                  var xmlMap = xmlMaps.item(0);
                  if (  xmlMap.getAttribute("defaultZoom") != null &&  xmlMap.getAttribute("defaultZoom") != 'undefined')
                        this.defaultZoom = parseInt(xmlMap.getAttribute("defaultZoom"));
                if ( xmlMap.getAttribute("address") != null && xmlMap.getAttribute("address") != 'undefined' )
                {
                  var mapper = this;
                    this.geocoder.getLocations(xmlMap.getAttribute("address"), 
                          function(response)
                             {
                                   if (response && response.Status.code == 200) 
                                         mapper.map.setCenter(new GLatLng(response.Placemark[0].Point.coordinates[1], response.Placemark[0].Point.coordinates[0]), mapper.defaultZoom);
                             }
                        );
                  }
                  else if ( xmlMap.getAttribute("lat") != null && xmlMap.getAttribute("lng") != null )
                    this.map.setCenter(new GLatLng(xmlMap.getAttribute("lat")),new GLatLng(xmlMap.getAttribute("lng")), this.defaultZoom);
                else
                        this.map.setCenter(new GLatLng(0, 0), this.defaultZoom);
                  if ( xmlMap.getAttribute("smallMapControl") != null && xmlMap.getAttribute("smallMapControl") != 'undefined' && xmlMap.getAttribute("smallMapControl") != 0 )
                        this.map.addControl(new GSmallMapControl());
            if ( xmlMap.getAttribute("mapTypeControl") != null && xmlMap.getAttribute("mapTypeControl") != 'undefined' && xmlMap.getAttribute("mapTypeControl") != 0 )
                        this.map.addControl(new GMapTypeControl());
                  
        }
      },
      loadIcons: function()
      {
            if ( this.xml != null ) 
            {
                  var xmlIcons = this.xml.documentElement.getElementsByTagName("icon");
                  this.icons = [];
                  for (var i = 0; i < xmlIcons.length; i++) 
                      if ( xmlIcons.item(i).hasChildNodes() )
                      {
                              var icon = new GIcon(); 

                              for ( var j = 0; j < xmlIcons.item(i).childNodes.length; j++ )
                              {
                              if ( xmlIcons.item(i).childNodes[j].tagName == 'image' )
                              {
                                    icon.image = xmlIcons.item(i).childNodes[j].getAttribute("src");
                                    icon.iconSize = new GSize(
                                          xmlIcons.item(i).childNodes[j].getAttribute("width"), 
                                          xmlIcons.item(i).childNodes[j].getAttribute("height")
                                    );
                              }
                              else if ( xmlIcons.item(i).childNodes[j].tagName == 'shadow' )
                              {
                                    icon.shadow = xmlIcons.item(i).childNodes[j].getAttribute("src");
                                    icon.shadowSize = new GSize(
                                          xmlIcons.item(i).childNodes[j].getAttribute("width"), 
                                          xmlIcons.item(i).childNodes[j].getAttribute("height")
                                    );
                              }
                              else if ( xmlIcons.item(i).childNodes[j].tagName == 'iconAnchor' )
                              {
                                    icon.iconAnchor = new GPoint(                              
                                          xmlIcons.item(i).childNodes[j].getAttribute("x"), 
                                          xmlIcons.item(i).childNodes[j].getAttribute("y")
                                    );
                              }
                              else if ( xmlIcons.item(i).childNodes[j].tagName == 'infoWindowAnchor' )
                              {
                                    icon.infoWindowAnchor = new GPoint(                              
                                          xmlIcons.item(i).childNodes[j].getAttribute("x"), 
                                          xmlIcons.item(i).childNodes[j].getAttribute("y")
                                    );
                              }
                        }
                              this.icons[parseInt(xmlIcons.item(i).getAttribute("id"))] = icon;
                        }
            }
      },
      loadMarkers: function()
      {
            if ( this.xml != null ) 
            {
                  var xmlMarkers = this.xml.documentElement.getElementsByTagName("marker");
                  var mapper = this;
                  mapper.next = true;
                  for (var i = 0; i < xmlMarkers.length; i++) 
                  {
                  var name = xmlMarkers.item(i).getAttribute("name");
                  var address = xmlMarkers.item(i).getAttribute("address");
                  var type = xmlMarkers.item(i).getAttribute("icon");
                  var lat = xmlMarkers.item(i).getAttribute("lat");
                  var lng = xmlMarkers.item(i).getAttribute("lng");
                  var description = xmlMarkers.item(i).firstChild.nodeValue;
                  if ( lat != null && lng != null )
                  {
                        mapper.createMarkerByPoint(name, lat, lng, description, this.icons[type]);
                  }
                  else 
                  {
                        mapper.createMarker(name, address, description, this.icons[type]);
                  }
            }
            }
      },
      createMarkerByPoint:  function(name, x, y, description, icon) {
            mapper = this;
            point = new GLatLng(x, y);
            
            var marker;
            if ( icon != null )
            {
                  icon.infoWindowAnchor.x = parseFloat(icon.infoWindowAnchor.x);
                  icon.infoWindowAnchor.y = parseFloat(icon.infoWindowAnchor.y);
                  marker = new GMarker(point, icon);
            }
            else
                  marker = new GMarker(point);
                  
            GEvent.addListener(marker , 'click', function() {
                  marker.openInfoWindowHtml(description);
            });
            mapper.map.addOverlay(marker);

    },
      createMarker:  function(name, address, description, icon) {
            mapper = this;
        mapper.geocoder.getLocations(address, 
                  function(response)
                  {
                        if (response && response.Status.code == 200) {
                             place = response.Placemark[0];
                             point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                             
                             var marker;
                             if ( icon != null )
                             {
                                   icon.infoWindowAnchor.x = parseFloat(icon.infoWindowAnchor.x);
                                   icon.infoWindowAnchor.y = parseFloat(icon.infoWindowAnchor.y);
                                   marker = new GMarker(point, icon);
                             }
                             else
                                   marker = new GMarker(point);
                             
                             GEvent.addListener(marker , 'click', function() {
                                   marker.openInfoWindowHtml(description);
                             });
                             mapper.map.addOverlay(marker);
                        }
                  }
            );
    }
}
);

