/*
 * CLUBBING MAP
 *
 *  Author: David Pratt
 *  Date: 18/03/10
 *
 *
 *  TODO:
 *    RHN - Make it scalable so that it can take up to a 1000 clubs on the map. Clever use of AJAX.
 *    Auto fit pins to map - Zoom to an appropriate zoom level so that the pins on the map can be displayed resonably
 *    Use custom pins with numbering so that they match up to the side nav items - http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=A|FF0000|000000
 *
 *
 *  IDEAS:
 *    Media
 *       Podcasts - ? itunes
 *       Pictures - ? Flickr, facebook
 *       Videos - ? YouTube
 *    Events - ? timeout, dontstayin, lastfm
 *    Add a club
 *    Reviews - ? tripadvisor, timeout, mixmag
 *
 *
 *  FIELDS:
 *    capacity, website, telephone, rating, open on nights, opening times
 *
 *
 *  SEXY CODE
 *    Click to "hide" the blocks from view
 *    Dragable, resizable blocks
 *    Autocomplete on the search box
 *    Customise the marker pin popups with non-default styling
 *    Create a mobile version that accepts their geolocation as an input.
 *    Filter:
 *     by music type.
 *     by open tonight.
 *     by open now.
 *     by near to me.
 *    Club pin in wrong place - drag to move it and add to a moderation queue
 *
 */

/*
 *  FLICKR
 *     Key:
 *     e7b632042bb236b6d16d56b6275051a8
 *     Secret:
 *     4543892a056de2c3
 *
 *     http://www.wait-till-i.com/2009/11/02/getting-a-list-of-flickr-photos-by-location-andor-search-term-with-a-yql-open-table/
 *     http://developer.yahoo.com/yql/console/?q=select%20*%20from%20flickr.photos.search%20where%20text%3D%22panda%22#h=select%20*%20from%20flickr.photos.search%20where%20text%3D%22fabric%20nightclub%22
 *     http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20flickr.photos.search%20where%20text%3D%22fabric%20nightclub%22&format=xml
 */

var club = {
   map : null,
   geocoder : null,
   aClubName : null,
   aClubUrl : null,
   aClubAddress : null,
   aClubLatLng : null,
   aClubMarker : null,
   iCurrentMarkerIndex : null,
   iTotalNumberOfClubs : null,
   iNumberOfClubsToShow : 20,
   iNumberOfFirstClub : null,
   iNumberOfLastClub : null,
   baseIcon : null,
   xml : null,

   fInitialize : function() {
      if (GBrowserIsCompatible()) {
         club.map = new GMap2(document.getElementById("map_canvas"));
         club.map.setCenter(new GLatLng(51.51944,-0.10533), 13);
         club.map.setUIToDefault();
         club.geocoder = new GClientGeocoder();

         // Create a base icon for all of our markers that specifies the
         // shadow, icon dimensions, etc.
         club.baseIcon = new GIcon(G_DEFAULT_ICON);
         club.baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
         club.baseIcon.iconSize = new GSize(20, 34);
         club.baseIcon.shadowSize = new GSize(37, 34);
         club.baseIcon.iconAnchor = new GPoint(9, 34);
         club.baseIcon.infoWindowAnchor = new GPoint(9, 2);

         // Download the data in data.xml and load it on the map.
         // http://api.zoocha.com/getClubData.xml
         GDownloadUrl("spreadsheet.php", function(data) {
            //TODO: Showing x of y
            club.xml = GXml.parse(data);
            club.iNumberOfFirstClub = 0;
            club.fDrawPins();
         });

         // Maximised window events
         GEvent.addListener(club.map.getInfoWindow(), "maximizeclick", function(){
            club.fMoveHeader();
            club.infoWindowContent.innerHTML = "loading...";
            club.fGetTweets(club.aClubName[club.iCurrentMarkerIndex-1], club.aClubLatLng[club.iCurrentMarkerIndex][0], club.aClubLatLng[club.iCurrentMarkerIndex][1]);
         });
      }
   },
   fDrawPins : function(){
      club.map.clearOverlays();

      var m = club.xml.documentElement.getElementsByTagName("m");
      club.iTotalNumberOfClubs = m.length;
      
      if (club.iTotalNumberOfClubs < club.iNumberOfClubsToShow){
         club.iNumberOfLastClub = club.iTotalNumberOfClubs;
      }else if((club.iNumberOfFirstClub + club.iNumberOfClubsToShow) < club.iTotalNumberOfClubs){
         club.iNumberOfLastClub = club.iNumberOfFirstClub + club.iNumberOfClubsToShow;
      }else if((club.iNumberOfFirstClub + club.iNumberOfClubsToShow) > club.iTotalNumberOfClubs){
         club.iNumberOfLastClub = club.iTotalNumberOfClubs
      }else{
         club.iNumberOfLastClub = club.iNumberOfFirstClub + club.iNumberOfClubsToShow;
      }

      // If you declare them as array's up top, it will break for some reason. Fucking voodoo.
      club.aClubName = new Array();
      club.aClubUrl = new Array();
      club.aClubAddress = new Array();
      club.aClubLatLng = new Array();
      club.aClubMarker = new Array();
      

      for (var i = club.iNumberOfFirstClub; i < club.iNumberOfLastClub; i++) {
         club.aClubLatLng[i] = new Array();
         club.aClubLatLng[i][0] = parseFloat(m[i].getAttribute("lat"));
         club.aClubLatLng[i][1] = parseFloat(m[i].getAttribute("lng"));

         club.aClubName[i] = m[i].getAttribute("name");
         club.aClubUrl[i] = m[i].getAttribute("website");
         club.aClubAddress[i] = club.fFormatAddress(m[i].getAttribute("address") + ',' + m[i].getAttribute("address2") + ',' + m[i].getAttribute("town") + ',' + m[i].getAttribute("county") + ',' + m[i].getAttribute("county"));

         club.aClubMarker[i] = club.fCreateMarker(new GLatLng(club.aClubLatLng[i][0], club.aClubLatLng[i][1]), i + 1);

         club.map.addOverlay(club.aClubMarker[i]);
      }

      //Once the XML has been loaded and the marker created, add the sidebar.
      club.fSideNav();

      //Once all the AJAX business is over, show all the fruits
      $("div.pause").slideDown("slow");
   },
   fFormatAddress : function(address){
      //Format the address so that it is a bit prettier.
      address += '#';
      var sCleanAddress = address.replace(/#/g, "");
      sCleanAddress = sCleanAddress.replace(/null/g, "");
      sCleanAddress = sCleanAddress.replace(/,,/g, ",");
      sCleanAddress = sCleanAddress.replace(/,/g, ", ");
      if(sCleanAddress.charAt(sCleanAddress.length-2) == ','){ //because it ends in ', '
         sCleanAddress = sCleanAddress.substring(0, sCleanAddress.length-2); 
      }
      return sCleanAddress;
   },
   fMoveHeader : function(){
      //When a marker pin popup window is maximised, the header obstudes the window. This function slides the header to the left.
      $('#header').animate({
         margin:'0 0 0 20px',
         width:'250px'
      }, 100, function() {
         // Animation complete.
      });
   },
   fGetTweets : function(sClubName, lat, lng){
      $.ajax({
         type: 'GET',
         url: 'http://search.twitter.com/search.json',
         data: 'rpp=10&q='+sClubName+'&geocode='+lat+'%2C'+lng+'%2C100km',
         dataType: 'jsonp',
         success: function(data){
            if(data['results'][0]){
               var sOut = "";
               for (var i=0; i < 10; i++){
                  sOut += "<li><a href=\"http://twitter.com/" + data['results'][i]['from_user'] + "\" target=\"_blank\"><img src=\"" + data['results'][i]['profile_image_url'] + "\"></a> <h6><a href=\"http://twitter.com/" + data['results'][i]['from_user'] + "\" target=\"_blank\">"+data['results'][i]['from_user']+"</a></h6><p>" + data['results'][i]['created_at'] + "</p><p>" + data['results'][i]['text'] + "</p></li>";
               }
               sOut = "<ul class=\"twitter-feed\">" + sOut + "</ul>";

               club.infoWindowContent.innerHTML = sOut;
            }else{
               club.infoWindowContent.innerHTML = "No Tweets found!";
            }
         }
      });
   },
   fDisplayInfoWindow : function(marker, number){
      // Display the marker pin popup window when either the pin is clicked or a side menu item.
      var myHtml = "<div class=\"marker-popup\"><h4>" + club.aClubName[number - 1] + "</h4><p>" + club.aClubAddress[number - 1] + "</p><p><a href='" + club.aClubUrl[number - 1] + "' target='_blank'>Visit site</a></p></div>";

      club.tweetWindowContent = document.createElement("div");
      var infoTabs = [
         new GInfoWindowTab("Information", myHtml),
         new GInfoWindowTab("Tweets", club.tweetWindowContent),
         new GInfoWindowTab("Photos", "Feed from flickr")
      ];

      club.infoWindowContent = document.createElement("div");
      marker.openInfoWindowTabsHtml(infoTabs,{
         selectedTab:0,
         maxWidth:350,
         maxTitle:club.aClubName[number -1] + " details",
         maxContent:club.infoWindowContent
      });

      return marker;
   },
   fCreateMarker : function(latlng, number) {
      // Create a lettered icon for this point using our icon class
      var letter = String.fromCharCode("A".charCodeAt(0) + number - 1 - club.iNumberOfFirstClub);
      var letteredIcon = new GIcon(club.baseIcon);
      letteredIcon.image = "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + letter + "|FF0000|000000";
      // Set up our GMarkerOptions object literal
      var markerOptions = {
         id:"marker-" + number,
         icon:letteredIcon
      };
      var marker = new GMarker(latlng, markerOptions);
      marker.value = number;

      GEvent.addListener(marker,"click", function() {
         club.iCurrentMarkerIndex = number;
         marker = club.fDisplayInfoWindow(marker, number);
      });
      return marker;
   },
   fSideNav : function(){
      // Setup the side navigation.
      var sHTML = '<div class="block pause" id="club-nav">' + club.ui.fShowingMessage() + club.fPaging() + '<h3>Nightclubs</h3><ol id="side-list">';
      for (var i = club.iNumberOfFirstClub; i < club.iNumberOfLastClub; i++) {
         var j = i + 1;
         sHTML += '<li><a href="#marker-' + j + '">' + club.aClubName[i] + '</a></li>';
      }
      sHTML += "</ol></div>";
      
      $("#club-nav").slideUp("slow", function(){
         $("#club-nav").remove();
      });
      
      $("#rhn").append(sHTML);

      $("#side-list a").click(function(){
         var s = $(this).attr("href");
         var i = s.substring(8,s.length);

         club.iCurrentMarkerIndex = i;

         // Could pan it, but the fDisplayInfoWindow -> openInfoWindowTabsHtml does it for you to a certain extent.
         //club.map.panTo(new GLatLng(club.aClubLatLng[i][0], club.aClubLatLng[i][1]));
         club.fDisplayInfoWindow(club.aClubMarker[i-1], i);
      });
   },
   fShowAddress : function(address) {
      // TODO - Called directly from the search form. This should be an event.
      if (club.geocoder) {
         club.geocoder.getLatLng(address, function(point) {
            if (!point) {
               alert(address + " not found");
            } else {
               club.map.setCenter(point, 13);
               var marker = new GMarker(point);
               club.map.addOverlay(marker);
               marker.openInfoWindowHtml(address);
            }
         });
      }
   },
   fPaging : function(){
      var sPaging;

      if (club.iTotalNumberOfClubs < club.iNumberOfClubsToShow){
         //No paging
         sPaging = '<p class="paging">-</p>';
      }else{
         sPaging = '<p class="paging">';
         if((club.iNumberOfFirstClub) > 0){
            sPaging += '<a href="#" id="prev">Prev</a>';
         }else{
            sPaging += 'Prev';
         }
         sPaging += ' | ';
         if((club.iNumberOfFirstClub + club.iNumberOfClubsToShow) < club.iTotalNumberOfClubs){
            sPaging += '<a href="#" id="next">Next</a>';
         }else{
            sPaging += 'Next';
         }
      }
      return sPaging;
   },
   fPagingEvents : function(){
      $("#next").live("click", function(){        
         club.iNumberOfFirstClub += club.iNumberOfClubsToShow;
         $(this).parent().hide();
         club.fDrawPins();
      });
      $("#prev").live("click", function(){
         club.iNumberOfFirstClub -= club.iNumberOfClubsToShow;
         $(this).parent().hide();
         club.fDrawPins();
      });
   },
   ui : {
      swap_val : Array,
      init : function(){
         club.ui.fMinimise.init();
         club.ui.fSetDraggable();
         club.ui.fFormInput();
         club.fPagingEvents();
      },
      fShowingMessage : function(){
         return '<p>Showing ' + club.iNumberOfFirstClub + ' to ' + club.iNumberOfLastClub+' of ' + club.iTotalNumberOfClubs + '</p>';
      },
      fSetDraggable : function(){
         $("#rhn").draggable({
            handle:'.intro h3'
         });
         $("#like").draggable({
            handle:'legend'
         });
         $("#header").draggable();
      },
      fMinimise : {
         init : function(){
            $("#rhn").append('<a class="minimise">-</a>');
            $("a.minimise").click(function(){
               $(this).parent().find(".block").not(':first-child').slideToggle('slow');
            });

            $("a.minimise").toggle(function() {
               $(this).text("+");
            }, function() {
               $(this).text("-");
            });
         }
      },
      fFormInput : function(){
         $(".shop-header .syndication form input#edit-mail").attr("value","Newsletter signup");
         $("form input[type=text]").each(function(i){
            club.ui.swap_val[i] = $(this).val();
            $(this).focusin(function(){
               if ($(this).val() == club.ui.swap_val[i]) {
                  $(this).val("");
               }
            }).focusout(function(){
               if ($.trim($(this).val()) == "") {
                  $(this).val(club.ui.swap_val[i]);
               }
            });
         });
      }
   }
}

$(document).ready(function(){
   club.fInitialize();
   club.ui.init();
});
