(function($) {


  // Why did I do this?
  //var maptab = $('#tab-map').click();



  /**
   * ArticleMap singleton object
   */
  var ArticleMap = function() {


    var element,
        tabs,
        mapContainer,
        map,
        center,
        zoom,
        vcards,
        locations = [];




    var resetMap = function() {
      map.setZoom(zoom);
      map.setCenter(center);
    };

  
    var handleClick = function(event, ui) {

      if (ui.index !== 1) {
        return; 
      }
      
      initMap();
      
    };

    /**
     * Initialize Google Map - occurs only on first click of 'Map View' tab
     */
    var initMap = function() {

      
      // Return if the map has already been initialized
      if (typeof map !== 'undefined') {
        resetMap();
        return;
      }


      // Initialize map
      map = new GMap2(mapContainer.get(0));
      map.setCenter(new GLatLng(0,0));
      map.addControl(new GSmallMapControl());

      var bounds = new GLatLngBounds();


      // Parse location data from DOM (uses vcard microformat)
      vcards.each(function() {

        $this = $(this);

        var org           = $this.find('.org').text();
        var streetAddress = $this.find('.street-address').text();
        var locality      = $this.find('.locality').text();
        var region        = $this.find('.region').text();
        var postalCode    = $this.find('.postal-code').text();
        var tel           = $this.find('.tel').text();
        var lat           = $this.find('.lat').text();
        var lng           = $this.find('.lng').text();
        var description   = $this.find('.description').text();

        var a = $this.find('.url');
        var url = a.attr('href');
        var urlText = a.text();


        var gPoint  = new GLatLng(lat, lng);  
        bounds.extend(gPoint);

        var gMarker = new GMarker(gPoint);
    
    
    
        var html = ['<span class="org"><strong>', org, '</strong></span><br/>'].join('');

        // Use description if available
        if (description !== '') {

          html = [html, '<p class="description">', description, '</p>'].join('');

        // Otherwise, assemble the address
        } else {
        
          if (streetAddress !== '') {
            html = [html, '<span class="street-address">', streetAddress, '</span><br/>'].join('');
          }

          if (locality !== '') {
            html = [html, '<span class="locality">', locality, '</span>'].join('');

            if (region !== '') {
              html = [html, ', '].join('');
            }
          }

        
          if (region !== '') {
            html = [html, '<span class="region">', region, '</span>'].join('');
          }
        
          if (postalCode !== '') {
            html = [html, ' ', '<span class="postal-code">', postalCode, '</span>'].join('');
          }

          if (tel !== '') {
            html = [html, '<br/><span class="tel">', tel, '</span>'].join('');
          }

                
        }
          if (url !== '') {
            html = [html, '<br/><a href="', url, '">', urlText, '</span>'].join('');
          }

    

        GEvent.addListener(gMarker, 'click', function() {
          gMarker.openInfoWindowHtml(html);
        });

        map.addOverlay(gMarker);

        zoom = map.getBoundsZoomLevel(bounds);
        center = bounds.getCenter();
        resetMap();

        $this.find('a').click(function() {
          GEvent.trigger(gMarker, 'click');
        });

      });

      // Unbind event after execution
      tabs.unbind('tabsselect', initMap);
    };




    /**
     * Public methods/properties
     */
    return {
    
    
      init: function(config) {



        var photoPanel,
            mapPanel,
            hasPhoto = false,
            hasMap = false;

        
        element = $(config.articleMap);

        
        if (element.size() === 0) {
          throw new Error('Invalid element.');
        }


        // Check availability of photo panel
        photoPanel = element.find('#panel-photo');
        hasPhoto = (photoPanel.size() > 0);



        // If Google Maps is available, check availability of map panel and vcards
        if (GBrowserIsCompatible()) {
        
          mapPanel = element.find('#panel-map');


          // Find vcard elements
          vcards = $(config.vcards);

          hasMap = (mapPanel.size() > 0 && vcards.size() > 0);

        }
        

        // Has either panel -> show container
        if (hasPhoto || hasMap) {
          element.show();
        }
        

        // Has both panels -> needs tabs
        if (hasPhoto && hasMap) {

          // Find tabs element
          tabs = $(config.tabContainer);
  
          if (tabs.size() === 0) {
            throw new Error('Invalid tabs element.');
          }

          // Display and initialize tab element and attach event handler
          // which will initialize map only on first click
          tabs.tabs().bind('tabsshow', initMap);
          tabs.find('li').show();
        }
        
        

        if (hasMap) {
          
          // Find map element
          mapContainer = $(config.mapContainer);
  
          if (mapContainer.size() === 0) {
            throw new Error('Invalid map element.');
          }
          
          // Display map element
          mapContainer.show();

          vcards.find('a').click(function() {

            // Focus map tab
            if (typeof tabs !== 'undefined') {
              tabs.tabs('select', 1);
            } else {
              initMap();
            }
          });
          
          if (!hasPhoto) {
            initMap();
          }
        }
      }
    };

  }();

      
      
  ArticleMap.init({
    articleMap:   'div#articleMap',
    mapContainer: 'div#googleMap',
    tabContainer: 'ul#mapTabs',
    vcards:       '#pointsOfInterest .vcard'
  });      
    
    

  

})(jQuery);