map_mgr = {
  mm : null,
  map : null,
  icon : null,
  gd : null,
  container : null,
  loaded : false,
  options : {},
  initialize : function(opts) {
    if (this.loaded) {
      this.unload();
    }
    this.loaded = true;
    this.options = $.extend({
      map: '#map',
      zoom: 11
    }, opts);

    
    var map = new GMap2($(this.options.map).get(0));
    
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(this.options.center[0], this.options.center[1]), this.options.zoom);
    
    this.map = map;
    this.mm = new MarkerManager(map);   
    
    // Set up the icons
    //this.icon = new GIcon();
    // this.icon.image = "_media/splash/images/map-icon.png"
    // this.icon.iconAnchor = this.icon.infoWindowAnchor = new GPoint(25,25);
    // this.icon.iconSize = this.icon.shadowSize = new GSize(50,50);
    //this.iconA = new GIcon(this.icon);
    // this.iconA.image = "_media/splash/images/map-icon-a.png"
    
    this.container = $(this.options.holder).get(0);
    var self = this;
    $(this.options.holder + ' ' + this.options.buttons).each(function(idx){
      var target = $(self.options.holder + ' ' + self.options.containers).get(idx);
      map_mgr.doDirections(this,target,$(this).attr('rel'));
    });
  },
  unload : function() {
    // Clear all the html
    $(this.options.holder + ' ' + this.options.containers).html('<div class="holder"></div>');
  },
  _point : function(ll) {
    var marker = new GMarker(new GLatLng(ll[0],ll[1]), { icon: this.icon });
    this.mm.addMarker(marker, 11);
    return marker;
  },
  addPoint : function(name, ll) {
    
  },
  doDirections : function(target, container, ll) {
    var start = null;
    if (typeof ll == "string") {
      if (ll.indexOf(':')) {
        start = ll.split(':')[1];
        ll = ll.split(':')[0];
      }
      ll = ll.split(',');
    }
    var pt = this._point(ll);
    GEvent.bind(pt,'click',{data:{'target' : target, 'container' : container, 'll' : ll, 'start': start }},this.doClick);
    $(target).bind('click',{'target' : target, 'container' : container, 'll' : ll, 'start': start},this.doClick);
  },
  doClick : function(ev) {
    if (ev.preventDefault) { ev.preventDefault(); }
    data = {};
    if (this.data) {
      data = this.data;
    } else {
      data = ev.data;
    }
    var base_node = data.target;
    var container = data.container;
    
    if ($(container).attr('open') != 'true') {
      if (data.start) {
        var placemark = [
          {'address': data.start}
        ];
        map_mgr._clearDirections(data.container);
        map_mgr._doDirections({ target: data.target, container: data.container, placemark: placemark, ll: data.ll});
      } else {
        var geo = new GClientGeocoder();
        geo.setBaseCountryCode("US");
        geo.getLocations(new GLatLng(data.ll[0], data.ll[1]),function(result){
          map_mgr._clearDirections(data.container);
          map_mgr._doDirections({ target: data.target, container: data.container, placemark: result.Placemark, ll: data.ll});
        });
      }
    }
  },
  _doDirectionsRequest: function(address) {
    this.gd.load("from: " + address + " to: " + $(this.container).find('.to-address').text().replace(/to:\s+/i,''), {
      getSteps: true,
      travelMode: ( $(this.container).find('.active select[name=direction-type]').val() == 'driving' ? G_TRAVEL_MODE_DRIVING : G_TRAVEL_MODE_WALKING )
    });
  },
  _doDirections : function(data) {
    var self = this;
    $(data.container).attr('open','true');
    $(data.container).parents('li').addClass('active');
    $(data.container).hide();
    var form = $('<form action="">' +
      '<select name="direction-type" style="float: right">' +
        '<option value="driving">Driving</option>' +
        '<option value="walking">Walking</option>' +
      '</select>' +
      '<label>From: <input name="from" type="text" class="text"></label><br>' +
      '<label><span class="to-address">To: <strong>' + data.placemark[0].address + '</strong></span><br>' +
      '<input type="submit" value="Get Directions"></label>' +
    '</form>');
    $(data.container).prepend(form);
    $(data.container).slideDown('normal');
    
    $(data.container).find('form').submit(function(ev){
      ev.preventDefault();
      if ($(this.container).find('.active select[name=direction-type]').val() == 'transit') {
        var to = $(this.container).find('.to-address').text().replace(/to:\s+/gi,'');
        var from = $(this.container).find('input[name=from]').val();
        if (from) {
          var ser = $.param({
            'daddr' : to,
            'saddr' : from
          }).replace(/%20/g,'+');
          window.open("http://maps.google.com/maps?f=d&source=s_d&"+ser+"&hl=en&geocode=&mra=ls&dirflg=r&ttype=dep&noexp=0&noal=0&sort=&tline=&ie=UTF8&z=17&start=0",'google-map');
        }
        return false;
      }
      
      
      // http://maps.google.com/maps?f=d&source=s_d&saddr=10024&daddr=145+W+84th+St.+NY,+NY,+USA&hl=en&geocode=&mra=ls&dirflg=r&ttype=dep&noexp=0&noal=0&sort=&tline=&ie=UTF8&z=17&start=0
      
      if (self.gd) { 
        self.gd.clear(); 
        for (var i = 0; i < self.listeners.length; i++) {
          GEvent.removeListener(self.listeners[i])
        }
      }
      self.gd = new GDirections(map_mgr.map, $(this).next('.holder').get(0));
      self.listeners = new Array();
      var node = this;
      self.listeners.push(GEvent.addListener(self.gd,'error',function(ev){
        // Ambiguous results ... great
        if (this.getStatus().code == 602) {
          var geo = new GClientGeocoder();
          geo.setBaseCountryCode("US");
          geo.getLocations($(node).find('input[name=from]').val(),function(result){
            map_mgr.didYouMean(result.Placemark, data);
          })
        }
      }));
      
      self.listeners.push(GEvent.addListener(self.gd,'addoverlay',function(ev){
        // Do all the style fixes
        var holder = $(self.container).find('.holder');
        holder.find('div[jsdisplay=walking]').filter(function(){
          return ($(this).css('display') != 'none')
        }).removeAttr('style').addClass('walking');
        
        
        
        // Do stuff to get the markers all looking nice
        // var marker = self.gd.getMarker(1);
        // marker.remove();
        // // This is an interal hack and not part of the API.  MIGHT BREAK IN FUTURE
        // marker.Ua = self.icon;
        // marker.initialize(self.map);
        // marker.redraw(true);
        // 
        // marker = self.gd.getMarker(0);
        // marker.remove();
        // // This is an interal hack and not part of the API.  MIGHT BREAK IN FUTURE
        // marker.Ua = self.iconA;
        // marker.initialize(self.map);
        // marker.redraw(true);
        
        // holder.find('div[jsselect=Placemark][jsinstance=0] > table img').attr('src',self.iconA.image)
        // holder.find('div[jsselect=Placemark][jsinstance=*1] > table img').attr('src',self.icon.image)
        
        // window.setTimeout(function(){
        //           holder.find('div[jsselect=Placemark][jsinstance=0] > table img').attr('src',self.iconA.image)
        //           holder.find('div[jsselect=Placemark][jsinstance=*1] > table img').attr('src',self.icon.image)
        //         },600);
      }));
      self._doDirectionsRequest($(this.container).find('input[name=from]').val());
      return false;
    })
  },
  didYouMean : function(placemarks, data) {
    var self = this;
    var str = '';
    for ( var i = 0; i < placemarks.length; i++) {
      str += '<a href="" rel="' + placemarks[i].address + '">' + placemarks[i].address + '</a><br>';
    }
    if ($(data.container).find('.did-you-mean').length > 0) {
      $(data.container).find('.did-you-mean').html(str);
    } else {
      $(data.container).append('<div class="did-you-mean"><h3>Did you mean?</h3>' + str + '</div>'); 
    }
    $(data.container).find('.did-you-mean a').click(function(ev){
      ev.preventDefault();
      self._doDirectionsRequest($(this).attr('rel'));
      $(data.container).find('.did-you-mean').remove();
    });
  },
  _clearDirections: function(already_open) {
    $(this.container).find('.directions').each(function() {
      if (this != already_open) {
        $(this).parents('li').removeClass('active');
        $(this).removeAttr('open');
        $(this).slideUp('normal',function(){
          $(this).html('<div class="holder"></div>');
        })
      }
    })
  }
};

$(function(){
    if (GBrowserIsCompatible()) {
      var node = $('#main-content');
      var target = $('#map-directions a:first');
      var ll = target.attr('rel').split(':')[0];
      map_mgr.initialize({
        holder: '#main-content',
        buttons: '.direction-button',
        containers: '.directions',
        center: [ll.split(',')[0],ll.split(',')[1]],
        zoom: 14
      });
      $('#map-directions a:first').click()
    }

    // display a warning if the browser was not compatible
    else {
      alert("Sorry, the Google Maps API is not compatible with this browser");
    }
})