mainVenue = function() {
  return {

    // ========
    // = Vars =
    // ========

    point							  : null, 	       // [lat, lon] if doing address search
    map                 : {},            // Hash containing references to the Google Maps objects
    page                : 1,             // Default page for results
    city                : null,          // Current city
    conn                : null,          // Connection obj
    fieldData           : null,          // Event data
    perPage             : 10,            // Events per page
    categories          : null,          // List of Sports
    mapData             : null,          // List of icons for the map
    sport               : 'all',         // Default sports

    // ===========
    // = Methods =
    // ===========
    
    initVenueIndex : function() {
      
      // Init the map
      
      main.initMap(true);
      
      // Get the initial data

      main.getData();
      
      // Init Pagination
      
      $('div.eventResults div.pagination div.second p').click(function(e) {
        if (e.target.tagName != 'A') {
          return;
        }

        e.preventDefault();
        var page = $(e.target).blur().text();
        
        switch (page) {
          case 'Previous':
            main.page--;
            break;
          case 'Next':
            main.page++;
            break;
          default:
            main.page = page * 1;
        }
        
        main.getData();
      });
      
      // Init Sports drop down
      
      $('div.eventResults div.title div.second select').change(function(e) {
        var val = $(this).blur().val();
        main.sport = (val == 'all') ? val : (val * 1);
        main.page = 1;
        main.getData();
      });
      
    },
    
    initVenueShow : function() {

      // Comment delete alert
      
      $('#comments p.delete a').click(function(e) {
        if (!confirm('Are you sure you want to delete this comment?')) {
          e.preventDefault();
        }
      });

    },

    initVenueCreate : function() {
      main.initMap();
      $('#btnLocate').click(main.addressSearch);
      $('#btnDropPoint').click(main.dropPoint);
      
      // Address enter key catch
      
      $('#address').keydown(function(e) {
        if (e.keyCode == 13) {
          main.addressSearch();
        }
      });
      
      // Select All
      
      $('#selectAll').click(function(e) {
        e.preventDefault();
        $(this).blur();
        $('#sports input[type=checkbox]').attr('checked', true);
      });
      
      // Select None
      
      $('#selectNone').click(function(e) {
        e.preventDefault();
        $(this).blur();
        $('#sports input[type=checkbox]').attr('checked', false);
      });
    },

    initMap : function(indexPage) {
      if (GBrowserIsCompatible()) {
        main.map.map = new GMap2(document.getElementById((indexPage !== true) ? 'resultsMapSmall' : 'resultsMap'));
        main.map.map.setCenter(new GLatLng(main.city.latitude, main.city.longitude), 13);
        main.map.map.setUIToDefault();

        main.map.markerMgr = new MarkerManager(main.map.map, { 'trackMarkers' : true });
        main.map.geocoder = new GClientGeocoder();
        main.map.mapIcon = new GIcon(G_DEFAULT_ICON);
      }
      
      if (indexPage !== true) {
      
        // Load the point if one is already selected
      
        var lat = $('#latitude').val();
        var lng = $('#longitude').val();
        if (lat !== '' && lng !== '') {
          main.point = new GLatLng(lat, lng);
          var marker = new GMarker(main.point, { title : '', icon : main.map.mapIcon, draggable : true });
          GEvent.addListener(marker, "dragend", function() {
            $('#longitude').val(marker.getLatLng().lng());
            $('#latitude').val(marker.getLatLng().lat());
            $('#spanLongitude').text(marker.getLatLng().lng());
            $('#spanLatitude').text(marker.getLatLng().lat());
        
            // Lookup the neighborhood

            main.loadNeighborhood(marker);
          });
          main.map.markerMgr.addMarker(marker, 3);
          main.map.markerMgr.refresh();
          main.map.map.setCenter(new GLatLng(main.point.lat(), main.point.lng()), 15);
        
          $('#spanLongitude').text(marker.getLatLng().lng());
          $('#spanLatitude').text(marker.getLatLng().lat());
      
          // Lookup the neighborhood

          main.loadNeighborhood(marker);
        }

      }

    },
    
    addressSearch : function(e) {
      $('#btnLocate').attr('disabled', true).val('Searching...').blur();

      main.map.geocoder.getLatLng($('#location input[type=text]').val(), function(point) {
        $('#btnLocate').attr('disabled', false).val('Lookup the Address');
        $('#location p span.error').remove();

        if (!point) {
          $('#location p').append($('<span/>').addClass('error').html('Could not find the address'));
        } else {
          main.map.map.setCenter(new GLatLng(point.lat(), point.lng()), 15);
          main.dropPoint();
        }
      });
    },
    
    dropPoint : function(e) {
      if (e) {
        $(this).blur();
      }

      var point = main.map.map.getCenter();
      main.map.markerMgr.clearMarkers();
      var marker = new GMarker(point, { title : '', icon : main.map.mapIcon, draggable : true });
      GEvent.addListener(marker, "dragend", function() {
        $('#longitude').val(marker.getLatLng().lng());
        $('#latitude').val(marker.getLatLng().lat());
        $('#spanLongitude').text(marker.getLatLng().lng());
        $('#spanLatitude').text(marker.getLatLng().lat());
        
        // Lookup the neighborhood

        main.loadNeighborhood(marker);
      });
      main.map.markerMgr.addMarker(marker, 3);
      main.map.markerMgr.refresh();
      
      $('#longitude').val(marker.getLatLng().lng());
      $('#latitude').val(marker.getLatLng().lat());
      $('#spanLongitude').text(marker.getLatLng().lng());
      $('#spanLatitude').text(marker.getLatLng().lat());
      
      // Lookup the neighborhood
      
      main.loadNeighborhood(marker);

    },
    
    loadNeighborhood : function(marker) {
      
      var url = main.links.getNeighborhoodLink;
      var params = {
        'latitude' : marker.getLatLng().lat(),
        'longitude' : marker.getLatLng().lng()
      };
      
      if (main.conn) {
        main.conn.abort();
      }
      
      main.conn = $.getJSON(url, params, function(data) {
        if (data.results.length > 0) {
          $('#spanNeighborhood').text(data.results[0].name);
        }
      });
      
    },

    getData : function() {
      
      // Hide divs
      
      $('div.eventResults div.pagination, div.eventResults ul.results').css('display', 'none');
      $('div.eventResults h4.title').text('Loading...').addClass('loading');
      
      // Get params
      
      var params = {
        'limit' : main.perPage,
        'page' : main.page,
        'sport' : main.sport
      };
      
      var url = main.links.getVenuesLink;
      
      // Make the call
      
      if (main.conn) {
        main.conn.abort();
      }
      
      main.conn = $.getJSON(url, params, function(data) {
        if (data.error) {
          return;
        }
        main.fieldData = data;
        
        main.processPagination();
        main.processResults();
      });
      
    },
    
    processPagination : function() {
      
      // Results
      
      if (main.fieldData.totalResults === 0) {
        $('div.eventResults div.pagination div.first p').html('No fields found. <a href="' + main.links.createVenueLink + '">Create a new field now!</a>');
        $('div.eventResults div.pagination').css('display', 'block');
        return;
      }

      var start = (this.page - 1) * this.perPage + 1;
      var end = Math.min(start + this.perPage - 1, main.fieldData.totalResults);
      var title = 'Showing ' + start + '-' + end + ' of ' + main.fieldData.totalResults;
      $('div.eventResults div.pagination div.first p').html(title);
      
      // Pages

      var parts = [];
      var totalPages = Math.ceil(main.fieldData.totalResults / main.perPage);

      if (main.page === 1) {
        parts[parts.length] = '<span>Previous</span>';
      } else {
        parts[parts.length] = '<a href="#" class="previous">Previous</a>';
      }

      var i, pages = [];
      if (totalPages <= 6) { // Ex: 1, 2, 3, 4, 5
        for (i=1; i<=totalPages; i++) {
          pages[pages.length] = i;
        }
      } else if (totalPages > 6 && (main.page <= 2 || main.page >= (totalPages - 3))) { // Ex: 1, 2, 3, ... 70, 71, 72
        pages[pages.length] = 1;
        pages[pages.length] = 2;
        pages[pages.length] = 3;
        pages[pages.length] = "sep";
        pages[pages.length] = totalPages - 2;
        pages[pages.length] = totalPages - 1;
        pages[pages.length] = totalPages;
      } else { // Ex: 1, ... 13, 14, 15, ... 72
        pages[pages.length] = 1;
        pages[pages.length] = "sep";
        pages[pages.length] = main.page;
        pages[pages.length] = main.page + 1;
        pages[pages.length] = main.page + 2;
        pages[pages.length] = "sep";
        pages[pages.length] = totalPages;
      }

      for (i=0; i<pages.length; i++) {
        if (pages[i] == "sep") {
          parts[parts.length] = '<span>...</span>';
        } else {
          if (pages[i] == main.page) {
            parts[parts.length] = '<span>' + pages[i] + '</span>';
          } else {
            parts[parts.length] = '<a href="#">' + pages[i] + '</a>';
          }
        }
      }

      if (main.page == totalPages) {
        parts[parts.length] = '<span>Next</span>';
      } else {
        parts[parts.length] = '<a href="#" class="next">Next</a>';
      }
      
      if (parts.length > 3) {
        $('div.eventResults div.pagination div.second p').html(parts.join(''));
      }
      $('div.eventResults div.pagination').css('display', 'block');
    },
    
    processResults : function() {
      
      // Process the title
      
      $('div.eventResults h4.title').removeClass('loading').html(main.getResultsTitle());
      
      // Process each field
      
      $('div.eventResults ul.results').empty();
      
      main.mapData = {};
      
      main.map.markerMgr.clearMarkers();
      
      var bounds = new GLatLngBounds();
      var field, li, div, marker, point;
      for (var i=0; i<main.fieldData.results.length; i++) {
        
        field = main.fieldData.results[i];
        
        // Add to HTML
        
        li = $('<li/>').attr('id', 'field_' + field.id).addClass('clearfix');
        li.append($('<h5/>').addClass('field').append($('<a/>').attr('href', main.links.showVenueLink.replace('/ID', '/' + field.id)).text(field.name)));
        li.append($('<p/>').addClass('neighborhood').html('<strong>Neighborhood:</strong> ' + field.neighborhood.name));
        if (field.sports.length > 0) {
          li.append($('<p/>').addClass('sports').html('<strong>Sports:</strong> ' + field.sports.join(', ')));
        }
        
        $('div.eventResults ul.results').append(li);
        
        // Add marker to map
        
        point = new GLatLng(field.latitude, field.longitude);
        marker = main.addMapMarker(field, point);
				main.map.markerMgr.addMarker(marker, 3);
				bounds.extend(point);
        
      }
      
			// Show the markers, re-center and zoom out enough to show them all

      if (main.fieldData.results.length === 0) {
        main.map.map.setCenter(new GLatLng(main.city.latitude, main.city.longitude), 13);
      } else {
        main.map.markerMgr.refresh();
        main.map.map.setZoom(main.map.map.getBoundsZoomLevel(bounds) - 1);
        main.map.map.setCenter(bounds.getCenter());
      }
      
      $('div.eventResults ul.results').css('display', 'block');
      
    },
    
    getResultsTitle : function() {
      
      var title = main.fieldData.totalResults;
      title = title + ' ' + (main.sport == 'all' ? 'pickup game' : main.categories[main.sport]) + ' ' + (main.fieldData.totalResults == 1 ? 'location' : 'locations');
      title = title + ' in ' + main.city.name;
      
      return title;
      
    },
    
    addMapMarker : function(venue, point) {
			var marker = new GMarker(point, { 'title' : venue.name, 'icon' : main.map.mapIcon, 'draggable' : false });

      GEvent.addListener(marker, 'click', function() {
       var url = main.links.showVenueLink.replace('ID', venue.id);
       marker.openInfoWindow('<span class="gmap-info"><strong>' + venue.name + '</strong><br /><a href="' + url + '">&raquo; Venue Details</a></span>');
      });
			
			return marker;
		}

  };
}();

jQuery.extend(main, mainVenue);