function gupFrom(name, location) {
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( location );
  if( results == null )
    return "";
  else
    return results[1];
}

function gup(name) {
  return gupFrom(name, window.location.href);
}

function reloadPageData() {
  var activeModuleId = getActiveModuleId();
  if(activeModuleId != null) {
    var radius = $("#radius").val();
    $(".calendar_include").html("<p class='searching'>Loading...</p>");
    $.get("/includes/calendar_module.jsp", {
      'module_id': activeModuleId,
      't': new Date().getTime(),
      'radius': radius,
      'lower_month': $("#lower_month").val() || 0,
      'upper_month': $("#upper_month").val() || 11
    },
    function(data) {
      $(".calendar_include").html(data);
      populateCalendarEvents();
      populateLocations($("#StateID").val(), activeModuleId);
    });
  }
  else {
    $(".calendar_include").html("");
  }
}
 
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}
 
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
 
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function populateCalendarEvents() {
  var monthVal = $(".calendar_controls input.current_month").val();
  var yearVal = $(".calendar_controls input.current_year").val();
  $.getJSON("/includes/ajax/getSearchRanges.jsp", {
    'modules': getActiveModuleId(),
    'month': monthVal != undefined ? monthVal : 0,
    'year': yearVal != undefined ? yearVal : -1,
    'radius': $("#radius").val(),
    't': new Date().getTime()
  },
  function(data) {
    if(data.ranges) {
      for(var i=0; i < data.ranges.length; i++) {
        var range = data.ranges[i];
        var start = parseDate(range[0]);
        var end = parseDate(range[1]);
        addCalendarRange(start, end);
      }
    }
  });
}

function reloadCalendarData() {
  var calendar = $(this);
  var pickedDate = parseDate($(this).find(".calendar_controls input.picker_date").val());
  $.get("/includes/calendar_picker.jsp", {
    'picked_month': pickedDate.month,
    'picked_day': pickedDate.day,
    'picked_year': pickedDate.year,
    'calendar_month': new Number($(this).find(".calendar_controls input.current_month").val()),
    'calendar_year': new Number($(this).find(".calendar_controls input.current_year").val())
  },
  function(newCalendar) {
    calendar.replaceWith(newCalendar);
  });
}

function parseDate(date) {
  var splitDate = date.split(/\s+|\-|\:|\//);
  return {
    'month': new Number(splitDate[0]),
    'day': new Number(splitDate[1]),
    'year': new Number(splitDate[2]),
    'hour': new Number(splitDate[3]),
    'minute': new Number(splitDate[4]),
    'second': new Number(splitDate[5])
  };
}

function addCalendarRange(start, end) {
  var calDays = $("table.calendar_table tbody tr td.in_month");
  var startDay = start.day-1;
  var endDay = end.day-1;
  var currentMonth = new Number($(".calendar_controls input.current_month").val());
  var currentYear = new Number($(".calendar_controls input.current_year").val());
  if(start.month-1 < currentMonth  || start.year < currentYear) {
    startDay = 0;
  }
  if(end.month-1 > currentMonth || end.year > currentYear) {
    endDay = 30;
  }
  for(var i=startDay; i <= endDay && i < calDays.size(); i++) {
    var $calDay = $(calDays.get(i));
    if($calDay.text().match(/\d+/)) {
      $calDay.addClass("has_event");
    }
  }
}

function getVisiblePane() {
  var panes = $(".panes>div").not(".search_pane");
  for(i=0; i < panes.size(); i++) {
    if(isVisible(panes.get(i))) {
      return $(panes.get(i));
    }
  }
  return null;
}

function getActivePane() {
  if(hiddenPane != null) return hiddenPane;
  return getVisiblePane();
}

function getActiveModuleId() {
  return getActivePane().find("input.module_id").val();
}

function isVisible(elem) {
  return !isHidden(elem);
}

function isHidden(elem) {
  var $elem = $(elem);
  return $elem.css("display") == "none";
}

function changeState() {
  $.post("/includes/ajax/setState.jsp", { 'state_id': $("#StateID").val() }, function(data) {
    if(pickedYear != null) {
      performSearch({ 'from_month': pickedMonth, 'from_day': pickedDay, 'from_year': pickedYear, 'modules': getActiveModuleId(), 'radius': $("#radius").val() });
    }
    reloadPageData();
  });
  return false;
}

function changeLocation() {
  savedLocation = $("#location").val();
  $.post("/includes/ajax/setLocation.jsp", { 'location': $("#location").val() }, function(data) {
      if(pickedYear != null) {
        performSearch({ 'from_month': pickedMonth, 'from_day': pickedDay, 'from_year': pickedYear, 'modules': getActiveModuleId(), 'radius': $("#radius").val() });
      }
      reloadPageData();
  });
}

function changeRadius() {
  if(pickedYear != null) {
    performSearch({ 'from_month': pickedMonth, 'from_day': pickedDay, 'from_year': pickedYear, 'modules': getActiveModuleId(), 'radius': $("#radius").val() });
  }
  reloadPageData();
}

function clickedStateLink() {
  $.post("/includes/ajax/setState.jsp", { 'state_id': gupFrom("state_id", $(this).attr("href")) }, function(data) {
  });
  return true; // we don't want to prevent the actual linking behavior
}

function getNextMonth() {
  var currentMonthElem = $(this).find(".calendar_controls input.current_month");
  var currentYearElem = $(this).find(".calendar_controls input.current_year");
  var month = new Number(currentMonthElem.val());
  if(month == 11) {
    currentMonthElem.val(0);
    currentYearElem.val(new Number(currentYearElem.val())+1);
  }
  else {
    currentMonthElem.val(month + 1);
  }
  return currentMonthElem.val();
}

function getPreviousMonth() {
  var currentMonthElem = $(this).find(".calendar_controls input.current_month");
  var currentYearElem = $(this).find(".calendar_controls input.current_year");
  var month = new Number(currentMonthElem.val());
  if(month == 0) {
    currentMonthElem.val(11);
    currentYearElem.val(new Number(currentYearElem.val())-1);
  }
  else {
    currentMonthElem.val(month - 1);
  }
  return currentMonthElem.val();
}

function changeToNextMonth() {
  var calendar = getCalendar(this);
  changeMonth.call(calendar, getNextMonth.call(calendar));
  return false;
}

function changeToPreviousMonth() {
  var calendar = getCalendar(this);
  changeMonth.call(calendar, getPreviousMonth.call(calendar));
  return false;
}



function changeMonthSelect() {
  var monthSelect = $("#month_select");
  var newDate = parseDate(monthSelect.val());
  $(".calendar_controls input.current_Year").val(newDate.year);
  changeMonth(newDate.month);
}

function changeMonth(month) {
  var currentMonthElem = $(".calendar_controls input.current_month");
  var currentYearElem = $(".calendar_controls input.current_year");
  currentMonthElem.val(month);
  $.post("/includes/ajax/setMonth.jsp", { 'calendar_month': month, 'calendar_year': currentYearElem.val() }, function(data) {
    reloadPageData();
  });
  return false;
}

var resultsPerPage = 8;
var currentPage = 0;
var totalPages = 0;

function createPagination(resultCount) {
  currentPage = 0;
  totalPages = resultCount / resultsPerPage + (resultCount - resultCount/resultsPerPage*resultsPerPage > 0 ? 1 : 0);
  var pagesElem = $(".pagination .pages");
  pagesElem.empty().append("<span>Page:</span>");
  for(var i=0; i < totalPages; i++) {
    pagesElem.append($("<a href='#'>" + (i+1) + "</a>"));
  }
  // bind each link to its corresponding page
  pagesElem.find("a").each(function(i) { $(this).click(function() { jumpToPage(i); return false; }); });
  toggleNextAndPrev(currentPage);
}

function toggleNextAndPrev(page) {
  if(page > 0) $(".pagination .previous_page").show();
  else $(".pagination .previous_page").hide()
  if(page < totalPages-1) $(".pagination .next_page").show();
  else $(".pagination .next_page").hide();
}

function jumpToPage(pageNum) {
  var searchItems = $(".search_results_tab .search_item");
  searchItems.hide();
  for(var i=pageNum * resultsPerPage; i < (pageNum+1)*resultsPerPage && i < searchItems.size(); i++) {
    $(searchItems.get(i)).show();
  }
  var pageJumps = $(".pagination .pages a");
  pageJumps.removeClass("active");
  $(pageJumps.get(pageNum)).addClass("active");
  toggleNextAndPrev(pageNum);
  currentPage = pageNum;
}

var hiddenPane = null;
function killSearchResults() {
  $(".search_pane").hide().empty();
  if(getVisiblePane() == null && hiddenPane != null) hiddenPane.show();
  hiddenPane = null;
  pickedMonth = pickedDay = pickedYear = null;
}

// used on the calendar to differentiate between dates listed for this month and next
function getTableIndex(elem) {
  var days = $("table.calendar_table td.in_month");
  for(var i=0; i < days.size(); i++) {
    if(days.get(i) == elem) {
      return i;
    }
  }
  return -1;
}

var pickedMonth = null;
var pickedDay = null;
var pickedYear = null;

function performSearch(options) {
  options = $.extend(options, { 't': new Date().getTime() });
  var activePane = getActivePane();
  var searchPane = $(".search_pane");
  if(activePane != null) activePane.hide();
  if(hiddenPane == null) hiddenPane = activePane;
  searchPane.show().html("<div class='searching'>Searching...</div>");
  $.get("/includes/ajax/getSearch.jsp", options, function(data) {
    searchPane.html(data);
    var searchItems = searchPane.find(".search_item");
    // bind event handlers for each specific search result
    searchItems.each(function() {
      var $search_item = $(this);
      var $description = $search_item.find('.search_item_description').hide();
      $search_item.find('.details_button').click(function() {
        $description.toggle();
        return false;
      });
    });
    createPagination(searchItems.size());
    jumpToPage(0);
    scrollTo($(".search_button"));
  }, 'html');
}

// returns the calendar this element belongs to
function getCalendar(elem) {
  var $elem = $(elem);
  while($elem.parent() != null) {
    if($elem.parent().hasClass("calendar_module") || $elem.parent().hasClass("calendar_picker")) {
      return $elem.parent();
    }
    $elem = $elem.parent();
  }
  return null;
}

function clickDate(e) {
  var calendar = getCalendar(this);
  if($(this).hasClass("has_event")) {
    // get all the matching events in a list
    var clickedIndex = getTableIndex(this);
    var day = new Number($(this).text());
    var month = new Number($(".calendar_controls input.current_month").val());
    var year = new Number($(".calendar_controls input.current_year").val());
    if((clickedIndex+1) > day) {
      if(month == 11) {
        month = 0;
        year++;
      }
      else {
        month++;
      }
    }
    pickedMonth = month;
    pickedDay = day;
    pickedYear = year;
    var options = {
      'from_month': pickedMonth,
      'from_day': pickedDay,
      'from_year': pickedYear,
      'modules': getActiveModuleId(),
      'radius': $("#radius").val()
    };
    performSearch(options);
  }
}

function createCalendarPicker(month, day, year) {
  var $elem = $(this);
  $.get("/includes/calendar_picker.jsp", { 'calendar_month': month, 'calendar_year': year, 'picked_day': day }, function(data) {
    $elem.append(data);
  });
}

function adjustPicked(calendar, date) {
  var allDays = calendar.find("td.in_month");
  allDays.removeClass("picked");
  var currentMonth = calendar.find(".calendar_controls input.current_month").val();
  var currentYear = calendar.find(".calendar_controls input.current_year").val();
  if(date.month == currentMonth && date.year == currentYear) {
    $(allDays.get(date.day-1)).addClass("picked");
  }
}

function pickDate() {
  var calendar = getCalendar(this);
  var myDate = calendar.find("input.picker_date");
  var currentMonth = new Number(calendar.find(".calendar_controls input.current_month").val());
  var currentYear = new Number(calendar.find(".calendar_controls input.current_year").val());
  myDate.val(currentMonth + "-" + $(this).text() + "-" + currentYear);
  myDate.change();
  adjustPicked(calendar, parseDate(myDate.val()));
}

function changeSearchState() {
  $.post("/includes/ajax/setState.jsp", { 'state_id': $("#state_id").val() }, function(data) {
    populateLocations($("#state_id").val(), $("#program").val());
  });
}

var searched = false;
var locations = {};
var savedLocation = null;
function populateLocations(state, programs) {
  $.getJSON("/includes/ajax/getCampAreas.jsp", { 'state_id': state, 'programs': programs, 't': new Date().getTime() }, function(data) {
    $("#location option.loc").empty().remove();
    if(data.camp_areas) {
      for(var i=0; i < data.camp_areas.length; i++) {
        var campArea = data.camp_areas[i];
        $("#location").append("<option class='loc' value='" + campArea.id + "'>" + campArea.name + "</option>");
      }
    }
    var loc = gup('location');
    if(data.saved_location != undefined) savedLocation = data.saved_location;
    else savedLocation = -1;
    
    if(loc != undefined && loc != '') {
      $("#location").val(loc);
    }
    else if(savedLocation != null) {
      if(savedLocation == "" || savedLocation == -1) {
        selectFirst($("#location"));
      }
      else {
        $("#location").val(savedLocation);
      }
    }
    var op = gup('op');
    if(op != undefined && op == 'search' && !searched) {
      searched = true;
      searchCamps();
      return;
    }
    
    var options = $("#location option");
    var inList = false;
    for(var i=0; i < options.size(); i++) {
      var $option = $(options.get(i));
      if(savedLocation == $option.attr("value")) {
        inList = true;
        break;
      }
    }
    if(!inList && $("#state_id").val() != "") {
      selectFirst($("#location"));
    }
  });
}

function populatePrograms() {
  $.getJSON("/includes/ajax/getCampTypes.jsp", {}, function(data) {
    $("#program option.program").empty().remove();
    if(data.camp_types) {
      for(var i=0; i < data.camp_types.length; i++) {
        var camp_type = data.camp_types[i];
        $("#program").append("<option class='program' value='" + camp_type.id + "'>" + camp_type.name + "</option>");
      }
    }
  });
}

function searchCamps() {
  if($("#state_id").val() == "") {
    alert("Please select a state to search.");
    $("#state_id").focus();
    return;
  }
  var fromDate = parseDate($("#start_date").val());
  var toDate = parseDate($("#end_date").val());
  performSearch({ 
    'from_month': fromDate.month-1,
    'from_day': fromDate.day,
    'from_year': fromDate.year,
    'to_month': toDate.month-1,
    'to_day': toDate.day,
    'to_year': toDate.year,
    'modules': $("#program").val() != "" ? $("#program").val() : " , ",
    'location': $("#location").val(),
    'state': $("#state_id").val(),
    'radius': $("#radius").val(),
    'category_search': $("#category_search").val()
  });
}

function changeSearchLocation() {
  $.post("/includes/ajax/setLocation.jsp", { 'location': $("#location").val() }, function(data) {
    // do nothing, location cookie is set
  });
}

function changeSearchProgram() {
  var programHeader = $("#program_header").val();
  $(".subcategories").hide();
  if(programHeader != "") {
    var subCategory = $("." + programHeader + ".subcategories");
    subCategory.find("input:first").click();
    subCategory.show();
  }
  else {
    $("#program").val(" , ");
    populateLocations($("#state_id").val(), $("#program").val());
  }
}

function setProgramSelections() {
  var program = $("#program").val();
  var inputs = $(".subcategories input");
  var matchLength = 100000;
  var matchInput = null;
  for(var i=0; i < inputs.size(); i++) {
    var input = $(inputs.get(i));
    if(program != undefined && input.val().indexOf(program) != -1) {
      if(input.val().length < matchLength) {
        matchLength = input.val().length;
        matchInput = input;
      }
    }
  }
  if(matchInput != null) {
    $("#program_header").val(matchInput.attr("name")).change();
    matchInput.click();
    searchCamps();
  }
  else {
    $("#program").val(" , ");
  }
  //changeSearchProgram();
}

function clickSubcategoryButton() {
  var $this = $(this);
  if($this.attr("name") == $this.attr("id")) {
    $("#category_search").val("true");
  }
  else {
    $("#category_search").val("false");
  }
  $("#program").val($this.val());
  populateLocations($("#state_id").val(), $("#program").val());
}

function scrollTo(elem, time) {
  if(elem.size() > 0) {
    time = time || 1000;
    var y = elem.offset().top;
    $('html,body').animate({scrollTop: y}, time);
  }
}

function scrollToTabs() {
  scrollTo($('ul.tabs'), 500);
}

function selectFirst(select) {
  var $select = $(select);
  if($select.not(":select")) return;
  
  $select.find("option").each(function() {
    this.selected = false;
  });
  $select.find("option:first").each(function() {
    this.selected = true;
  });
}

function fixScrollingOnLoad() {
  var href = window.location.href;
  if(href.match(/#\w+$/)) {
    $("a[href=" + href.substring(href.lastIndexOf("#"), href.length) + "]").click();
  }
}

$(document).ready(function() {
  $('ul.tabs').tabs('div.panes > div');
  $('div.panes').append("<div class='search_pane'></div>");
  $('ul.tabs a').click(function() { killSearchResults(); setTimeout(reloadPageData,10); scrollToTabs(); });
  $(".calendar_controls .previous_month").live("click", changeToPreviousMonth);
  $(".calendar_controls .next_month").live("click", changeToNextMonth);
  $(".calendar_module table.calendar_table td.in_month").live("click", clickDate);
  $(".calendar_picker table.calendar_table td.in_month").live("click", pickDate);
  $(".start_date_picker input.picker_date").live("change", function() {
    var internalDate = parseDate($(this).val());
    $("#start_day").val(newDate.day)
    $("#start_month").val(internalDate.month+1)
    $("#start_year").val(internalDate.year)
  });
  $(".end_date_picker input.picker_date").live("change", function() {
    var internalDate = parseDate($(this).val());
    var newDate = (internalDate.month+1) + "/" + internalDate.day + "/" + internalDate.year;
    $("#end_date").val(newDate)
  });
  $(".pagination .previous_page").live("click", function() { jumpToPage(currentPage-1); return false; });
  $(".pagination .next_page").live("click", function() { jumpToPage(currentPage+1); return false; });
  $(".search_results .close").live("click", killSearchResults);
  $("#state_id, #StateID").live("load", function() { $(this).change(); }).change();
  //$("#program").each(populatePrograms);
  $(".search_button").click(searchCamps);
  $(".subcategories input").click(clickSubcategoryButton);
  setProgramSelections();
  $("a.state").live("click", clickedStateLink);
	$('a.button[rel],a.button2[rel],a.button3[rel]').overlay({expose: '#000', effect: 'apple'});
  fixScrollingOnLoad();
  //$(window).scrollTop(300);
});