google.load('maps', '2');

window.isIe6 = ((navigator.userAgent.indexOf("MSIE 6") != -1) && (navigator.userAgent.indexOf("Opera") == -1));

$(window).load(function(){
  if($('#map_canvas').length == 0)
    return;

  // Get width of map banner
  var bannerwidth = $('.skyscraper-wide').width() + 16

  // after the Googlogo is loaded, move it to the right so we don't overlap it
  var checkMoveGooglogo = function() {
    var googlogo = $('#map_canvas > div.gmnoprint:has(img)');
    if(googlogo.length == 0)
      setTimeout(checkMoveGooglogo, 100);
    else
      googlogo.css({left: '', right: bannerwidth, bottom: '35px'});
  };
  // after copyright notice is loaded, same as above
  var checkMoveCNote = function() {
    var googcnote = $('#map_canvas > div.gmnoprint:contains("Terms of Use")');
    if(googcnote.length == 0) {
      setTimeout(checkMoveCNote, 2000);
    } else {
      googcnote.css({left: '', right: bannerwidth, bottom: '25px'});
      $('#powered-by').css({paddingRight: bannerwidth})
    }
  };

  if (google.maps.BrowserIsCompatible()) {
    var map = window.map = new google.maps.Map2(document.getElementById("map_canvas"));
    map.enableContinuousZoom();
    var height = $('#header').height() + $('#search-bar').height() + 8;
    /*
    map.addControl(new google.maps.SmallMapControl, 
      new google.maps.ControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(0, height)));
    */

    // fix up position:fixed on GMap div
    $('#map_canvas').css({position: 'fixed'});
    
    checkMoveGooglogo();
    checkMoveCNote();
  }

  $(window).unload(google.maps.Unload);

  var gpListingIcon = new google.maps.Icon();
  gpListingIcon.image = 'http://national.gopickle.com/images/map_pin.png';
  gpListingIcon.shadow = 'http://national.gopickle.com/images/map_pin_shadow.png';
  gpListingIcon.iconSize = new google.maps.Size(39, 36);
  gpListingIcon.shadowSize = new google.maps.Size(39, 36);
  gpListingIcon.iconAnchor = new google.maps.Point(15, 33);
  gpListingIcon.infoWindowAnchor = new google.maps.Point(15, 33);

  window.addListingsWithBounds = function(listings, bounds) {
    function adjustBounds(bounds) {
      var min_lat = bounds[0];
      var min_lng = bounds[1];
      var max_lat = bounds[2];
      var max_lng = bounds[3];
      
      // Adjust for waste
      var _min_lat = min_lat - ((wasteBottom() / visibleY()) * (max_lat - min_lat));
      var _max_lat = max_lat + ((wasteTop() / visibleY()) * (max_lat - min_lat));
      var _min_lng = min_lng - ((wasteLeft() / visibleX()) * (max_lng - min_lng));
      var _max_lng = max_lng + ((wasteRight() / visibleX()) * (max_lng - min_lng));
      return [_min_lat, _min_lng, _max_lat, _max_lng];
    };
    function setBounds(bounds, zoom) {
      var min_lat = bounds[0];
      var min_lng = bounds[1];
      var max_lat = bounds[2];
      var max_lng = bounds[3];
      var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(min_lat, min_lng),
                                                new google.maps.LatLng(max_lat, max_lng));
      // Find zoom level if none was provided
      var zoom = zoom || window.map.getBoundsZoomLevel(bounds);
      var center = new google.maps.LatLng((min_lat+max_lat)/2.0, (min_lng+max_lng)/2.0);
      window.map.setCenter(center, zoom);
    };
    // Pixels wasted due to layout at left, right, top, and bottom of map
    // Not all of these elements might be on every page.
    function wasteTop(){
      var gpUiWaste = $("#header").height() + $("#search-bar").height();
      if ((gpUiWaste - getScrollY()) <= 0) 
        return 8;
      return gpUiWaste - getScrollY() + 8;
    }
    function wasteRight()  { return $("#listing").width(); };
    function wasteBottom() { return $("#footer").height(); };
    function wasteLeft(){
      if ($("#sidebar").length == 1) 
        return $("#sidebar").width() + $("#sidebar").offset().left;
      else 
        return 0;
    }

    function getScrollY(){
      var yScroll = 0;
      if (typeof(window.pageYOffset) == 'number') 
        //Netscape compliant
        return yScroll = window.pageYOffset;
      else 
        if (document.body && (document.body.scrollTop)) 
          //DOM compliant
          return yScroll = document.body.scrollTop;
        else 
          if (document.documentElement && (document.documentElement.scrollTop)) 
            //IE6 standards compliant mode
            return yScroll = document.documentElement.scrollTop;
      return yScroll;
    }

    function popupWidth(){
      return ( $("#gppopup_content").width() > 0) ? $("#gppopup_content").width() : 340;
    }
    function popupHeight(){
      return ( $("#gppopup_content").height() > 0) ? $("#gppopup_content").height() : 95;
    }

    // Total and visible width / height in pixels
    function totalX() { return $("#map_canvas").width(); };
    function totalY() { return $("#map_canvas").height(); };
    function visibleX() { return totalX() - (wasteLeft() + wasteRight()); };
    function visibleY() { return totalY() - (wasteTop() + wasteBottom()); };

    window.map.clearOverlays();

    // If there is only one listing, the original bounds will be a single point;
    // thus the waste-adjustment algorithm will yield a single point.
    // We let GMaps do the heavy lifting by letting it choose suitable bounds,
    // then running them through adjustBounds() again to mangle them for waste.
    if(listings.length == 1) {
      var zoom = 16;
      window.map.setCenter(new google.maps.LatLng(bounds[0], bounds[1]), zoom);
      var b = window.map.getBounds();
      var bounds = [b.getSouthWest().lat(), b.getSouthWest().lng(),
          b.getNorthEast().lat(), b.getNorthEast().lng()];
      // No idea why zoom-1 works but it does
      setBounds(adjustBounds(bounds), zoom-1);
    } else {
      setBounds(adjustBounds(bounds));
    }

    var featuredListings = [];
    
    $.each(listings, function(){
      var point = new google.maps.LatLng(this.y, this.x);
      var marker = new google.maps.Marker(point, {icon: gpListingIcon});
      var html = this.popup_html;
      var click_fcn = function() {
        show_custom_info_window(marker, html);
      }; 
      google.maps.Event.addListener(marker, 'click', click_fcn);

      $('#listing-row-' + this.id).mouseover(click_fcn);
      window.map.addOverlay(marker);

      if ($('#listing-row-' + this.id).hasClass('featured')) {
        featuredListings.push([marker, html]);
      }
    });
    

    if(featuredListings.length >= 1) {
      whichFL = featuredListings[ Math.floor(Math.random() * featuredListings.length) ];
      try{
        console.log('popupHeight() = '+popupHeight() );
        console.log('popupWidth() = '+popupWidth() );
        console.log('wasteTop() = '+wasteTop() );
        console.log('wasteLeft() = '+wasteLeft() );
      } catch(err) {}
      var setCenterLat = whichFL[0].getPoint().lat() + pxToDeg(wasteTop(), map.getZoom()) + pxToDeg(popupHeight(), map.getZoom());
      var setCenterLng = whichFL[0].getPoint().lng() - pxToDeg(wasteLeft(), map.getZoom()) + pxToDeg(popupWidth(), map.getZoom());
      window.map.setCenter( new GLatLng(setCenterLat,setCenterLng) );
      show_custom_info_window(whichFL[0], whichFL[1]);
    }
    
    function pxToDeg(px, zm){
      // Convert a distance in pixels to degrees at a particular zoom level
      var mod = new Array(
        1,
        0.1,
        0.075,
        0.048,
        0.028,
        0.015,
        0.0075,
        0.004,
        0.002,
        0.001,
        0.0005,
        0.00025,
        0.000125,
        0.0000625,
        0.00003125,
        0.00001675,
        0.000008375,
        0.0000041875,
        0.00000209375,
        0.00000104688
      );
      return px * mod[zm];
    }
    

    /*
     * Custom popup
     * 
     */
    function show_custom_info_window(marker, html){
      var gppopup = document.getElementById('gppopup');

      // Fill in the content      
      if ($('#gppopup_content #popup').length > 0) {
        $('#gppopup_content #popup').replaceWith(html);
      }
      else {
        $('#gppopup_content').append(html);
      }
      map.getPane(G_MAP_MARKER_PANE).appendChild(gppopup);
      
      // Attach the marker
      gppopup.marker = marker;
      
      // Stick it to the map where it needs to go
      gppopup.style.display = 'block';
      map_point = map.fromLatLngToDivPixel(marker.getPoint());
      gppopup.style.top = (parseInt(map_point.y) - gppopup.offsetHeight + 3) + "px";
      gppopup.style.left = (parseInt(map_point.x) - 24) + "px";
      
      // Pan the map, if on a search results page
      if (!$('body').hasClass('listings-show') && map.draggingEnabled()  ) {

        // point lat,lng, adjusted for waste and popup dims
        var panToLat = gppopup.marker.getPoint().lat() + pxToDeg(wasteTop(), map.getZoom()) + pxToDeg(popupHeight(), map.getZoom());
        var panToLng = (isIe6) ? gppopup.marker.getPoint().lng() : gppopup.marker.getPoint().lng() - pxToDeg(wasteLeft(), map.getZoom()) + pxToDeg(popupWidth(), map.getZoom());

        // pan the map to the lat,lng coordinates of the window, minus wasted UI width,height
        map.panTo( new GLatLng(panToLat,panToLng) );
      }
    }
    
    // Custom popup hide behaviors
    $('#map_canvas').click(function(event){
      if ($(event.target).hasClass('closeonclick')) 
        $('#gppopup').hide();
        
      // More features via brute-force
      if ($(event.target).attr('src').length >= 1) 
        $('#gppopup').hide();
    });

    
  }

});

