/* search.js */

// Search form
document.observe('dom:loaded', search_setup);
var drink_cost_slider = null;
var meal_cost_slider = null;
var cover_cost_slider = null;
var updated_filters = new Array();

function search_setup() {
  // capture search form submits, but only on search page, not home page
  if ($('results') != null) {
    $('search_form').action='/search/search' // we override the default search destination of /
    $('search_form').observe('submit', search_form_submit);
  }
  
  // observe all the tag checkboxes and the already-active tags
  $$('ul.active-filters li').each(search_sidebar_observe);
  $$('.filter-checklist').each(search_tag_select_observe);
  $$('.filter-trigger').each(filter_trigger_observe);
  $$('.close_button').each(filter_trigger_observe);
  
  // set up the cost sliders
  if ($('drink_cost_display') != null)
    drink_cost_slider = new Control.Slider('drink_cost_handle', 'drink_cost_track', {
      onSlide: function(value, slider) {$('drink_cost_display').innerHTML = value.toFixed(2)},
      onChange: submit_drink_cost,
      sliderValue: $('drink_cost_display').innerHTML,
      minimum: 0,
      alignX: -200,
      range: $R(0,20)
    });
  if ($('meal_cost_display') != null)
    meal_cost_slider = new Control.Slider('meal_cost_handle', 'meal_cost_track', {
      onSlide: function(value, slider) {$('meal_cost_display').innerHTML = value.toFixed(2)},
      onChange: submit_meal_cost,
      sliderValue: $('meal_cost_display').innerHTML,
      minimum: 0,
      alignX: -200,
      range: $R(0,500)
    });
  if ($('cover_cost_display') != null)
    cover_cost_slider = new Control.Slider('cover_cost_handle', 'cover_cost_track', {
      onSlide: function(value, slider) {$('cover_cost_display').innerHTML = value.toFixed(2)},
      onChange: submit_cover_cost,
      sliderValue: $('cover_cost_display').innerHTML,
      minimum: 0,
      alignX: -200,
      range: $R(0,100)
    });
  if ($('direct_link_url') != null) {  // no direct link url on home page
    $('direct_link_url').observe('click', direct_link_observer);
  }
}

function direct_link_observer(event) {
  event.stop();
  Modalbox.show($('direct_link_content'), {
    title: "Link to this search",
    width: 500,
    afterLoad: function() {$('direct_link_field').focus(); $('direct_link_field').select()}
  });
}

function search_sidebar_observe(a_elem) {
  a_elem.observe('click', search_sidebar_observer);
}

function search_tag_select_observe(span) {
  span.observe('click', search_tag_observer);
}

function filter_trigger_observe(a_elem) {
  a_elem.observe('click', filter_trigger_observer);
}

function search_tag_observer(event) {  
  var span = Event.element(event);
  if (span.tagName == "IMG")  // if a checkbox was clicked, select the parent span
    span = span.up('span.tag');
  else if (span.tagName != "SPAN")  // if something other than a span or img was clicked, we're not interested
    return;
  // Determine the name of the span's context
  var context = span.down('input').name;
  var tag_value = span.down('input').value;
  
  if (!span.hasClassName('selected')) {  // Tag is not yet selected
    // Update the tag's appearance
    span.addClassName('selected');
    if (!search_is_calendar(span))
      span.down('img').src = '/images/checkbox-selected.png';

    // Add the tagname to the list of active tag filters
    var new_li = "<li id=\""+span.id+"_active\" style=\"display: none\" title=\"click to remove\">" + tag_value + "</li>"
    $(context+'_active_filters').insert({bottom: new_li});
    // $(span.id+"_active").appear().highlight(); - highlight overrides element background, causing red x's not to appear
    $(span.id+"_active").appear();
    if (!$(context+'_active_filters').previousSiblings()[0].visible())
      $(context+'_active_filters').previousSiblings()[0].appear(); // show section header

    // Add the uncheck observer to this new link
    $(span.id+"_active").observe('click', search_sidebar_observer);

    // Add this tag to the list of values that need to be updated when the black box is closed
    add_filter(context, tag_value);
  } else {
    // change appearance
    deselect_tag(span);
    remove_filter(context, tag_value);
    // Remove this tag from the list of active tags in the left sidebar
    var li = $(span.id+'_active');
    if (li.up().childElements().size() == 1)  // remember, this li still exists
      li.up().previousSiblings()[0].fade();  // hide section title if we are removing the last li    
    li.remove();
  }
}

function deselect_tag(span) {
  span.removeClassName('selected');
  if (!search_is_calendar(span))
    span.down('img').src = '/images/checkbox-unselected.png';
}

function exists_open_box() {
  return ($$('.selected-filter-trigger').size() > 0);
}

function search_sidebar_observer(event) {
  var li = Event.element(event);
  var span_id = li.id.slice(0,-7); // remove the '_active' from the li's id to get the span id

  // check if this is a cost slider
  if (search_is_cost_slider(span_id)) {
    event.stop();
    remove_cost(span_id);
    return false;
  } else {
    var span = $(span_id);
  }

  // uncheck the checkbox in its old spot
  if (span != null) {
    deselect_tag(span);
    var context = span.down('input').name;
    var tag_value = span.down('input').value;
    remove_filter(context, tag_value);
  } else {  // Sometimes when we switch cities, a tag remains selected but there is actually no corresponding checkbox in the selection box
    // This is for the case where there is no corresponding checkbox for an active tag
    var context = li.up().id.slice(0, -15);  // remove _active_filters to get the tag context
    var tag = li.innerHTML; // li content = tag name
    remove_filter(context, tag);
  }

  // make the li disappear from under the active section
  // li.fade();  // doesn't seem to be working??? - probably some CSS issue - CSS overriding the style applied by the fade effect perhaps?
                 // Or perhaps simply because we're immediately removing the element  
  if (li.up().childElements().size() == 1)  // remember, this li still exists    
    li.up().previousSiblings()[0].fade();  // hide section title if we are removing the last li  
  li.remove();
  
  update_results();
}

function submit_drink_cost(value) {
  submit_cost('drink_cost', value);
}

function submit_meal_cost(value) {
  submit_cost('meal_cost', value);
}

function submit_cover_cost(value) {
  submit_cost('cover_cost', value);
}

function submit_cost(which, value) {
  value = value.toFixed(2)
  if (value == 0) {
    remove_cost(which);
  } else {
    $(which+'_active').innerHTML = which.slice(0,-5).capitalize()+": "+value;
    $(which+'_active').appear();
    if (!$('cost_header').visible())
      $('cost_header').appear(); // show section header
  }
  add_filter(which, value);
  update_results();
}

// Onchange event will trigger the appropriate submit_cost handler so we don't have to worry about calling remove_filter
function remove_cost(cost_elem) {
  // If we are not careful here, we can get into an infinite loop, where updating the innerHTML triggers the
  // slider's onChange event which calls submit_cost which calls remove_cost, etc.
  // So if innerHTML is already blank, we do nothing and break the cycle.
  if ($(cost_elem+'_display').innerHTML == '')
    return;
  $(cost_elem+'_active').innerHTML = '';
  $(cost_elem+'_active').hide();
  $(cost_elem+'_display').innerHTML = '';
  if (!$('drink_cost_active').visible() && !$('meal_cost_active').visible() && !$('cover_cost_active').visible())
    $('cost_header').fade(); // hide header if all costs removed
  switch(cost_elem) {
    case 'drink_cost':
      drink_cost_slider.setValue(0);
      break;
    case 'meal_cost':
      meal_cost_slider.setValue(0);
      break;
    case 'cover_cost':
      cover_cost_slider.setValue(0);
      break;
  }
}

function search_form_submit(event) {
  Event.stop(event);
  add_filter('q', $('search_form_input').value);
  update_results();
}

function search_is_calendar(element) {
  return element.descendantOf('calendar-container');
}

function search_is_cost_slider(elem_id) {
  return (elem_id.slice(-5) == '_cost');
}

function search_refreshing_widget(is_calendar) {
  if (is_calendar)
    return '<label><img src="/images/ajax-loader-sm-ob.gif" /></label>'
  else
    return '<label><strong>refreshing results...</strong></label>'
}

// show or hide a particular filter
function filter_trigger_observer(event) {
  var trigger = Event.element(event);
  if (!trigger.hasClassName('filter-trigger') && !trigger.hasClassName('close_button'))  // clicked on the span containing the down arrow
    trigger = trigger.up('a.filter-trigger');

  var was_open = trigger.hasClassName('selected-filter-trigger');  // was this filter already open?
  if (trigger.hasClassName('close_button'))
    was_open = true;
  $$('.filter-trigger').invoke('removeClassName', 'selected-filter-trigger'); // de-activate all active filters
  $$('.filter-checklist').invoke('hide');  // hide all open checklists
  if (!was_open) {
    trigger.addClassName('selected-filter-trigger');
    $('filters').show();
    var checklist_name = '.filter-checklist.' + trigger.getAttribute('checklist_name');
    $$(checklist_name).invoke('show'); // show appropriate checklist
  } else {
    $('filters').hide();
    update_results();
  }
  event.stop();
}

function update_results() {
  // If a black box is open, we don't update the results - that will happen when the box is closed
  // Also, don't update if nothing's changed
  if (!exists_open_box() && updated_filters.size() > 0) {
    var params_hash = new Hash();
    params_hash.set('filters[]', updated_filters);
    if ($('results') != null) { // we are on search page
      $('results').update('Refreshing results...');
      $('results-count').innerHTML = 'Refreshing results...';
      new Ajax.Updater('results', '/search/search', {
        method: 'get',
        parameters: params_hash,
        evalScripts: true,
        onComplete: function() {$('direct_link_url').observe('click', direct_link_observer);} // This element gets removed and then recreated, so we have to re-observe it
      });
    } else { // we are on home page
      params_hash.set('no_response', 'true');
      new Ajax.Request('/search/search', {  // first we send a request to update the search terms stored in the session
        method: 'get',
        parameters: params_hash,
        onComplete: function() {$('search_form').submit();}  // then we submit the search form to actually take us to the search page
      });
    }
    updated_filters = [];
  }
}

function add_filter(context, value) {
  updated_filters.push(['add', context, value]);
}

function remove_filter(context, value) {
  updated_filters.push(['remove', context, value]);
}
