DAY = 24*60*60*1000;
WEEKDAYS = [ "Sunday", "Monday", "Tuesday", "Wedsday", "Thursday", "Friday", "Saturday" ];
MONTHS   = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];

function onMapReady () {
  createMarkerForSearchLocation();
  getEvents(0);
}

function onBeforeMapChanged () {
  hideInfoWindows();
}

function onMapChanged () {
  getEvents(window.index);
}

function onGeoLocationError () {
  $("#message-title").html('No Location Found');
  $("#message-text").html('That\'s awkward. Try entering a specific address or check out <a href="?q=rome">Rome, Italy</a>.');
}

function createMarkerForSearchLocation () {
  var marker = createMarker(window.map, window.options.map.center, { icon: "/images/search-pin.png", shadow: "/images/search-pin-shadow.png" });
  createInfoWindow(window.map, marker, $.extend({ }, { content: window.options.infoWindow.searchContent }, window.options.infoWindow.options));
}

function inRome () {
  var center = window.options.map.center;  
  var ne = unserializePoint(42.1606919, 12.9945619);
  var sw = unserializePoint(41.6291333,11.9700867);

  return (center.lat() > sw.lat() && center.lat() < ne.lat()) &&
         (center.lng() > sw.lng() && center.lng() < ne.lng());
}

function createMarkersForEvents (index) {
  if ( (events = $(".event-element")) && events.length > 0 ) {
    $(".event-element").each(function() {
      var marker = createMarkerForEvent(this, index);

      $(this).click(function() {
        google.maps.event.trigger(marker, "click");
        return false;
      }, false);
    });
    $("#helper-list-container").show();
    $("#message").hide();
  } else {
    if (inRome()) {
      $("#message-title").html('No L&#299;ve Music Found');
      $("#message-text").html('Boops. Try changing the date by using the slider on the bottom of the map.');
    } else {
      $("#message-title").html('No L&#299;ve Music Found');
      $("#message-text").html('Boops. Try entering a different address or check out <a href="?q=rome">Rome, Italy</a>.');
    }
  }
}

function createMarkerForEvent (element, index) {
  var element = $(element);
  var point   = unserializePoint(element.attr("data-lat"), element.attr("data-lng"));

  if ( (found = jQuery.inArray(serializePoint(point), window.markersPoints[index])) && found != -1 ) {
    window.markers[index][found].setVisible(true);
    return window.markers[index][found];
  }

  var marker  = createMarker(window.map, point, { icon: "/images/pin.png", shadow: "/images/pin-shadow.png" }, index);
  cacheMarker(marker, index);
  createInfoWindow(window.map, marker, $.extend({ },
    { content: infoWindowContentForEvent(window.options.infoWindow.content, element) },
    window.options.infoWindow.options));

  return marker;
}

function createInfoWindow(map, marker, options) {
  var infoWindow = new InfoBox(options);
  window.infoWindows.push(infoWindow);

  google.maps.event.addListener(marker, 'click', function() {
    hideInfoWindows();
    infoWindow.open(map, marker);
  });

  return infoWindow;
}

function hideInfoWindows () {
  $.each(window.infoWindows, function() { this.close(); });
}

function infoWindowContentForEvent (template, element) {
  var element  = $(element);
  var text     = element.find(".helper-list-event-name").text();
  var distance = element.find(".helper-list-event-distance").text();
  var startAt  = element.attr("data-start-at");
  var imageSrc = element.attr("data-image-src");
  var href     = element.find(".helper-list-event-name a").attr("href");

  var recommendationsCount = element.attr("data-recommendations-count");
  var attendancesCount     = element.attr("data-attendances-count");

  return template.replace("{{title}}", text).replace("{{title}}", text).replace("{{distance}}", distance).replace("{{start_at}}", startAt).replace("{{recommendations_count}}", recommendationsCount).replace("{{attendances_count}}", attendancesCount).replace("{{image_src}}", imageSrc).replace("{{href}}", href).replace("{{href}}", href);
}

function showLoadingMessage () {
  $("#message-title").html("Finding L&#299;ve Music");
  $("#message-text").html("");
  $("#message").show();
}

function toggleShowLinks() {
  $("#show-more").toggle();
  $("#show-less").toggle();
  $("#list").toggleClass("unfolded");
}

function localizedDate (index) {
  var date = new Date(window.date + ( index * DAY ));
  return WEEKDAYS[date.getDay()] + ", " + date.getDate() + " " + MONTHS[date.getMonth()] + " " + date.getFullYear();
}

function getEvents(index) {
  hideInfoWindows();
  showLoadingMessage();
  var bounds = window.map.getBounds();
  $("#helper-list-container").hide();

  $.ajax({
    type: "GET",
    url: "/map.js",
    data: {
      ne: serializePoint(bounds.getNorthEast()),
      sw: serializePoint(bounds.getSouthWest()),
      origin: getSearchLocation(),
      start: index
    },
    // TODO handle errors
    // TODO handle timeout
    success: function(data) {
      data = data["html"];
      $("#list").replaceWith(data);
      createMarkersForEvents(index);
    }
  });
}

$(document).ready(function() {
  var options = {
    infoWindow: {
      options: {
        pixelOffset: new google.maps.Size(-150, -240),
        infoBoxClearance: new google.maps.Size(1, 1),
        closeBoxURL: "/images/close-box.png",
        pane: "floatShadow",
        boxStyle: {
          background: "url(/images/bubble.png) no-repeat",
          width: "300px",
          height: "181px",
        }
      },
      searchContent: '\
<div id="searchloc-infowindow-container">\
  <div id="searchloc-infowindow">\
    Search Location\
  </div>\
</div>',
      content: '\
<div id="infowindow-container">\
  <div id="infowindow">\
    <a href="{{href}}" id="infowindow-title">{{title}}</a>\
    <div id="infowindow-content-container">\
      <a href="{{href}}" id="infowindow-photo">\
         <img src="{{image_src}}" alt="{{title}}"/>\
      </a>\
      <div id="infowindow-content-subcontainer">\
        <div class="infowindow-content">\
          time:<br/>\
          distance:<br/>\
          <img src="/images/star-icon-white.png" alt="recommendations" /><br/>\
          <img src="/images/person-icon-white.png" alt="people attending" />\
        </div>\
      </div>\
      <div class="infowindow-content">\
      {{start_at}}<br/>\
      {{distance}}<br/>\
      {{recommendations_count}}<br/>\
      {{attendances_count}}\
      </div>\
    </div>\
  </div>\
</div>'
    }
  };

  $.extend(window.options, options);
  $("#date").text(localizedDate(window.index));

  $("#slider").slider({ min: 0, max: 7 });
  $("#slider").bind("slidestart", function(event, ui) {
    hideInfoWindows();
  });
  $("#slider").bind("slidechange", function(event, ui) {
    hideInfoWindows();
    hideMarkers();
    window.index = ui.value;

    $("#date").text(localizedDate(window.index));
    getEvents(window.index);
  });

  $("#show-more").live("click", function() {
    $("#list").attr("style", "height: 300px");
    toggleShowLinks();
  });

  $("#show-less").live("click", function() {
    $("#list").attr("style", "height: 30px").find("li:first").focus();
    toggleShowLinks();
  });
});
