    var map;
    var mgr;
    var weatherWindow;
    var pointsWithMarker = {};
    var groundOverlay = new GGroundOverlay("http://dev.keyhole.com/clouds/clouds_2048_alphaed.png", new GLatLngBounds(new GLatLng(-88,-177), new GLatLng(88,177)));
    var cloudsVisible = false;

    var iclear = new GIcon();
    iclear.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/clear.png";
    iclear.iconSize = new GSize(36,36);
    iclear.iconAnchor = new GPoint(18,18);
    iclear.infoWindowAnchor = new GPoint(36,0);

    var isunny = new GIcon();
    isunny.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/sunny.png";
    isunny.iconSize = new GSize(36,36);
    isunny.iconAnchor = new GPoint(18,18);
    isunny.infoWindowAnchor = new GPoint(36,0);

    var isunnyintervals = new GIcon();
    isunnyintervals.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/sunnyintervals.png";
    isunnyintervals.iconSize = new GSize(36,36);
    isunnyintervals.iconAnchor = new GPoint(18,18);
    isunnyintervals.infoWindowAnchor = new GPoint(36,0);

    var ilightrain = new GIcon();
    ilightrain.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/lightrain.png";
    ilightrain.iconSize = new GSize(36,36);
    ilightrain.iconAnchor = new GPoint(18,18);
    ilightrain.infoWindowAnchor = new GPoint(36,0);

    var idrizzle = new GIcon();
    idrizzle.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/lightrain.png";
    idrizzle.iconSize = new GSize(36,36);
    idrizzle.iconAnchor = new GPoint(18,18);
    idrizzle.infoWindowAnchor = new GPoint(36,0);

    var icloudy = new GIcon();
    icloudy.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/cloudy.png";
    icloudy.iconSize = new GSize(36,36);
    icloudy.iconAnchor = new GPoint(18,18);
    icloudy.infoWindowAnchor = new GPoint(36,0);

    var ipartlycloudy = new GIcon();
    ipartlycloudy.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/cloudy.png";
    ipartlycloudy.iconSize = new GSize(36,36);
    ipartlycloudy.iconAnchor = new GPoint(18,18);
    ipartlycloudy.infoWindowAnchor = new GPoint(36,0);

    var iheavyrain = new GIcon();
    iheavyrain.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/heavyrain.png";
    iheavyrain.iconSize = new GSize(36,36);
    iheavyrain.iconAnchor = new GPoint(18,18);
    iheavyrain.infoWindowAnchor = new GPoint(36,0);

    var ilightshowers = new GIcon();
    ilightshowers.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/lightshowers.png";
    ilightshowers.iconSize = new GSize(36,36);
    ilightshowers.iconAnchor = new GPoint(18,18);
    ilightshowers.infoWindowAnchor = new GPoint(36,0);

    var iheavyshowers = new GIcon();
    iheavyshowers.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/heavyshowers.png";
    iheavyshowers.iconSize = new GSize(36,36);
    iheavyshowers.iconAnchor = new GPoint(18,18);
    iheavyshowers.infoWindowAnchor = new GPoint(36,0);

    var ithunderyshowers = new GIcon();
    ithunderyshowers.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/thunderyshowers.png";
    ithunderyshowers.iconSize = new GSize(36,36);
    ithunderyshowers.iconAnchor = new GPoint(18,18);
    ithunderyshowers.infoWindowAnchor = new GPoint(36,0);

    var ithunderstorm = new GIcon();
    ithunderstorm.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/thunderstorm.png";
    ithunderstorm.iconSize = new GSize(36,39);
    ithunderstorm.iconAnchor = new GPoint(18,18);
    ithunderstorm.infoWindowAnchor = new GPoint(36,0);

    var imisty = new GIcon();
    imisty.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/misty.png";
    imisty.iconSize = new GSize(36,36);
    imisty.iconAnchor = new GPoint(18,18);
    imisty.infoWindowAnchor = new GPoint(36,0);

    var ihazy = new GIcon();
    ihazy.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/hazy.png";
    ihazy.iconSize = new GSize(36,36);
    ihazy.iconAnchor = new GPoint(18,18);
    ihazy.infoWindowAnchor = new GPoint(36,0);

    var ifoggy = new GIcon();
    ifoggy.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/foggy.png";
    ifoggy.iconSize = new GSize(36,36);
    ifoggy.iconAnchor = new GPoint(18,18);
    ifoggy.infoWindowAnchor = new GPoint(36,0);

    var isandstorm = new GIcon();
    isandstorm.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/sandstorm.png";
    isandstorm.iconSize = new GSize(36,36);
    isandstorm.iconAnchor = new GPoint(18,18);
    isandstorm.infoWindowAnchor = new GPoint(36,0);

    var iduststorm = new GIcon();
    iduststorm.image = "http://www.bluwavedesign.co.uk/tests/weather/icons/duststorm.png";
    iduststorm.iconSize = new GSize(36,36);
    iduststorm.iconAnchor = new GPoint(18,18);
    iduststorm.infoWindowAnchor = new GPoint(36,0);

      function showLoadingDiv()
      {
       document.getElementById('loading').className="block";
      }

      function hideLoadingDiv()
      {
       document.getElementById('loading').className="hidden";
      }

      function createMarker(point,id,weather) {

        var opts;

        switch(weather)
        {
         case "clear":
              opts = { icon:iclear };
              break;
         case "sunny":
              opts = { icon:isunny };
              break;
         case "sunnyintervals":
              opts = { icon:isunnyintervals };
              break;
         case "lightrain":
              opts = { icon:ilightrain };
              break;
         case "drizzle":
              opts = { icon:idrizzle };
              break;
         case "partlycloudy":
              opts = { icon:ipartlycloudy };
              break;
         case "cloudy":
              opts = { icon:icloudy };
              break;
         case "heavyrain":
              opts = { icon:iheavyrain };
              break;
         case "lightshowers":
              opts = { icon:ilightshowers };
              break;
         case "heavyshowers":
              opts = { icon:iheavyshowers };
              break;
         case "thunderyshowers":
              opts = { icon:ithunderyshowers };
              break;
         case "thunderstorm":
              opts = { icon:ithunderstorm };
              break;
         case "misty":
              opts = { icon:imisty };
              break;
         case "hazy":
              opts = { icon:ihazy };
              break;
         case "foggy":
              opts = { icon:ifoggy };
              break;
         case "sandstorm":
              opts = { icon:isandstorm };
              break;
         case "duststorm":
              opts = { icon:iduststorm };
              break;
         default:
                 opts = null;
                 break;
         }


        var marker = new GMarker(point,opts);
        GEvent.addListener(marker, "click", function() {
          var zoom = map.getZoom();
          try{map.removeOverlay(weatherWindow);}
          catch(err){};
          weatherWindow = new WeatherWindow(id,zoom,point);

          var overlayEventListener = GEvent.bind(map,"moveend",this,function(){ map.addOverlay(weatherWindow); GEvent.removeListener(overlayEventListener);});

          map.panTo(point);
        });
        return marker;
      }

      function loadXmlMarkers()
      {
            showLoadingDiv();
            var bounds = map.getBounds();
            var zoom = map.getZoom();
            var request = GXmlHttp.create();
            var n = bounds.getNorthEast().lat();
            var e = bounds.getNorthEast().lng();
            var s = bounds.getSouthWest().lat();
            var w = bounds.getSouthWest().lng();

            request.open("GET", "weather/weatherxml.php?n="+n+"&s="+s+"&e="+e+"&w="+w+"&zoom="+zoom, true);
            request.onreadystatechange = function()
            {
              if (request.readyState == 4)
              {

                var xmlDoc = GXml.parse(request.responseText);
                // obtain the array of markers and loop through it
                var locations = xmlDoc.documentElement.getElementsByTagName("location");

                for (var i = 0; i < locations.length; i++)
                {
                  // obtain the attribues of each marker
                  var lat = parseFloat(locations[i].getAttribute("lat"));
                  var lng = parseFloat(locations[i].getAttribute("lng"));
                  var minzoom = locations[i].getAttribute("minzoom");
                  if((lat + "," + lng) in pointsWithMarker || locations[i].getAttribute("weather") == "N/Ax")
                  {}
                  else
                  {
                  var point = new GLatLng(lat,lng);
                  var weather = locations[i].getAttribute("weather");
                  var id = locations[i].getAttribute("id");
                  var photosfrmid = "photos"+id;
                  var tweetsfrmid = "tweets"+id;

                  // create the marker
                  //var marker = createMarker(point,[new GInfoWindowTab("dev",id), new GInfoWindowTab("Forecast","<iframe class=\"iwframe\" src=\"http://bluwavedesign.co.uk/tests/weather/getweather.php?id="+id+"\" width=\"400\" height=\"195\"></iframe>"),new GInfoWindowTab("Photos","<iframe class=\"iwframe\" id=\""+photosfrmid+"\" src=\"http://bluwavedesign.co.uk/tests/weather/getphotos.php?lat="+lat+"&lng="+lng+"&weather="+weather.replace("/","")+"\" width=\"400\" height=\"195\"></iframe>"),new GInfoWindowTab("Tweets","<iframe  id=\""+tweetsfrmid+"\" class=\"iwframe\" src=\"http://bluwavedesign.co.uk/tests/weather/gettweets.php?lat="+lat+"&lng="+lng+"&weather="+weather.replace("/","")+"\" width=\"400\" height=\"195\"></iframe>")],weather);
                  var marker = createMarker(point,id,weather);
                  mgr.addMarker(marker,minzoom);
                  mgr.refresh();
                  pointsWithMarker[lat+","+lng]='';
                  }
                }
              hideLoadingDiv();
              }
            }
            request.send(null);
      }

    function getPhotosHtml(lat,lng,weather,divId)
    {
        document.getElementById(divId).innerHTML = ("<iframe src=\"http://bluwavedesign.co.uk/tests/weather/getphotos.php?lat="+lat+"&lng="+lng+"&weather="+weather+"\" width=\"375\" height=\"150\"></iframe>");

    }

    function getTweetsHtml(lat,lng,weather,divId)
    {
        document.getElementById(divId).innerHTML = ("<iframe src=\"http://bluwavedesign.co.uk/tests/weather/gettweets.php?lat="+lat+"&lng="+lng+"&weather="+weather+"\" width=\"375\" height=\"150\"></iframe>");
    }

    function load() {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"),{ googleBarOptions:{onMarkersSetCallback:function(results){ map.setZoom(8); loadXmlMarkers(); findNearestLocation(results); }}} );

        map.addControl(new GLargeMapControl());
        map.addMapType(G_PHYSICAL_MAP);
        map.addControl(new GHierarchicalMapTypeControl());
        map.enableContinuousZoom()
        map.setMapType(G_PHYSICAL_MAP);


        //toggleClouds();

        //Go to home
        homeId = readCookie("home_id");
        homeZoom = readCookie("home_zoom");
        homeLatLng = new GLatLng(parseFloat(readCookie("home_lat")),parseFloat(readCookie("home_lng")));

        if(homeId != null && homeZoom != null && homeLatLng.lat() != NaN && homeLatLng.lng() != NaN)
        {
         map.setCenter(homeLatLng,parseInt(homeZoom));
         weatherWindow = new WeatherWindow(homeId,homeZoom,homeLatLng);
         map.addOverlay(weatherWindow);
        }
        else
        {
         map.setCenter(new GLatLng(10,4), 2);
        }
        map.enableGoogleBar();

        mgr = new GMarkerManager(map);
        loadXmlMarkers();
        GEvent.addListener(map,"moveend",function(){ loadXmlMarkers(); });
        GEvent.addListener(map,"movestart",function(){ map.removeOverlay(weatherWindow); });
        GEvent.addListener(map,"zoomend",function(){ map.removeOverlay(weatherWindow); });
      }
    }

    function toggleClouds()
    {
       if(cloudsVisible)
          map.removeOverlay(groundOverlay);
       else
           map.addOverlay(groundOverlay);

        cloudsVisible = !cloudsVisible;
    }

    function setHomeLocation(id,zoom,lat,lng)
    {
     document.cookie = 'home_id='+id+'; expires=Sun, 17 Jan 2038 19:14:05 GMT; path=/';
     document.cookie = 'home_zoom='+zoom+'; expires=Sun, 17 Jan 2038 19:14:05 GMT; path=/';
     document.cookie = 'home_lat='+lat+'; expires=Sun, 17 Jan 2038 19:14:05 GMT; path=/';
     document.cookie = 'home_lng='+lng+'; expires=Sun, 17 Jan 2038 19:14:05 GMT; path=/';
    }

    function findNearestLocation(googleSearchMarkers)
    {
      var lat = googleSearchMarkers[0]['marker'].getLatLng().lat();
      var lng = googleSearchMarkers[0]['marker'].getLatLng().lng();
      map.removeOverlay(googleSearchMarkers[0]['marker']);

      var request = GXmlHttp.create();

      request.open("GET", "weather/locationsearch.php?lat="+lat+"&lng="+lng, true);
      request.onreadystatechange = function()
      {
        if (request.readyState == 4)
        {
                var xmlDoc = GXml.parse(request.responseText);
                var locations = xmlDoc.documentElement.getElementsByTagName("location");
                var resultLat = locations[0].getAttribute("lat");
                var resultLng = locations[0].getAttribute("lng");
                var resultId = locations[0].getAttribute("id");

                var point = new GLatLng(parseFloat(resultLat),parseFloat(resultLng));

                try
                {
                 map.removeOverlay(weatherWindow);
                }
                catch(err)
                {}

                weatherWindow = new WeatherWindow(resultId,8,point);
                //var overlayEventListener = GEvent.bind(map,"moveend",this,function(){ map.addOverlay(weatherWindow); GEvent.removeListener(overlayEventListener);});
                map.setCenter(point);

                map.addOverlay(weatherWindow);
        }
      }
      request.send(null);
    }

    ///CUSTOM INFOWINDOW STUFF
    function WeatherWindow(id,zoom,latlng) {
      this.id = id;
      this.zoom = zoom;
      this.latlng = latlng;
    }
    WeatherWindow.prototype = new GOverlay();


    WeatherWindow.prototype.initialize = function(map) {
      var div = document.createElement("div");
      div.setAttribute("id","weatherWindow");
      div.style.position = "absolute";
      div.style.width = "415px";
      div.style.height = "440px";

      var pixel = map.fromLatLngToDivPixel(this.latlng);
      div.style.top=""+(pixel.y-220)+"px";
      div.style.left=""+pixel.x+"px";

      var homeLink =  ('<a href="#" onclick="setHomeLocation(\''+this.id+'\',\''+this.zoom+'\',\''+this.latlng.lat()+'\',\''+this.latlng.lng()+'\'); return null;">Set as home</a>');

      var request = GXmlHttp.create();

      request.open("GET", "weather/weatherwindow.php?id="+this.id+"&zoom="+this.zoom+"&lat="+this.latlng.lat()+"&lng="+this.latlng.lng(), true);
      request.onreadystatechange = function()
      {
        if (request.readyState == 4)
        {
         div.innerHTML = request.responseText;
         div.innerHTML += homeLink;
        }
      }
      request.send(null);

      map.getPane(G_MAP_FLOAT_PANE).appendChild(div);

      this.map_ = map;
      this.div_ = div;
    }

    // Remove the main DIV from the map pane
    WeatherWindow.prototype.remove = function() {
      this.div_.parentNode.removeChild(this.div_);
    }

    // Redraw the rectangle based on the current projection and zoom level
    WeatherWindow.prototype.redraw = function(force) {
    return;
    }

    if(document.addEventListener)
    {
            document.addEventListener('keydown',handleKeyDown,false);
    }
    else if (document.attachEvent)
    {
            document.attachEvent('onkeydown',handleKeyDown);
    }
    else
    {
            document.onkeydown = handleKeyDown;
    }

    function handleKeyDown(e) {
           switch(e.keyCode)
           {
                   case 27:
                           map.removeOverlay(weatherWindow);
                           break;
           }
    }

    function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
                var c = ca[i];
                while (c.charAt(0)==' ') c = c.substring(1,c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    }
