var fKeys  = [];
var fIds   = [];
var hotelIds = [];

(function($) {

  $.fn.hotel_search = function() {
	return $(this);
  };

  //
  // initialize
  //
  $.fn.hotel_search.init = function(options) {
	$opts = $.extend({}, $.fn.hotel_search.defaults, options);
    var $this = $(this);
    // search form change
    $('div#hotel_s_1').find('input,select').change(function() {
      $('#hotel_search').find('#search_status').hide();
      $('#search_button').show();
    });

	// load state from browser
	//$(this).hotel_search.load_state();
	//$(window).bind('hashchange', function(e) {
	//	$this.hotel_search.load_state();
	//});
  };

  //
  // data stores
  //
  $.fn.hotel_search.count = 0;
  $.fn.hotel_search.last_search = false;
  $.fn.hotel_search.last_rates = false;
  $.fn.hotel_search.url_cache = {};
  
  //
  // get object of current state
  // 
  $.fn.hotel_search.current_state = function() {
	//window.console.log('current_state()');
	var state = {
	 'h_s_query':	$('#h_s_query').val()
	,'check_in':	$('#check_in').val() 
	,'check_out':	$('#check_out').val()
	,'adults':		$('#adults').val() 
	,'children':	$('#children').val()
	,'child_ages':  []
	}
	//window.console.dir(state);
	return state;
  };

  //
  // get el of current cache
  // 
  //$.fn.hotel_search.cached_el = function() {
  //  // already loaded in the DOM?
  //  var url = window.location.href.split("#")
  //  var hash = false;
  //  if (url[1]) {
  //  	hash = url[1].replace(/[^a-zA-Z0-9]+/g, "");
  //  }
  //  // nada
  //  if(!hash) return $('#hotel_s_r');
  //};


  //
  // push current state to browser history
  // 
  $.fn.hotel_search.push_state = function() {
	//window.console.log('push_state()');
	var state = $(this).hotel_search.current_state();
	jQuery.bbq.pushState(state);
  };

  //
  // trigger search, rating, and filtering from browser state object
  //
  $.fn.hotel_search.load_state = function() {
	//window.console.log('load_state()');
	var cur_state = jQuery.bbq.getState();
	for(var key in cur_state) {
		var val = cur_state[key];
		$('#'+key).val(val);
		if(key == 'h_s_query') $('#'+key).trigger("liszt:updated");	
	}

	// run the search
	// TODO - cache the DOM
	$(this).hotel_search.load();
  };


  //
  // load matching hotels from server
  //
  $.fn.hotel_search.load = function() {
    // get query 
    var data = $(this).find('.hotel_s_load').serialize();
    if($(this).hotel_search.last_search == data) {
      // no change, trigger rating only
      return $(this).hotel_search.get_hotel_rates();
    }
    $(this).hotel_search.last_search = data;
    // reset vars
    fKeys = [];
    fIds  = [];
    hotelIds = [];
    // update state
    $(this).find('#search_button').hide();
    $(this).find('#search_status').hide().html('<h3>Searching...</h3>').fadeIn();
    $.ajax({
      url: '/tornado/hotel/search',
      data: data,
      cache: true,
      success: function(data) {

		// hide existing search results, assign for later use
		// var el = $('#hotel_s_r').hide().attr('id', hash);

		// add new div, show results in it
		//$('#hotel_search').append('<div id="hotel_s_r"></div>');
        $('div#hotel_s_r').html(data).show();

		// use current setting for ordering
		if( $('#h_s_order').val() != 'stars' ) {
			$(this).hotel_search.change_order( $('#h_s_order').val() );
		}

      }
    });
  };

  //
  // change filter tab
  //
  $.fn.hotel_search.filter_tab = function(rel, el) {
    $(this).find('div.h_s_filter').hide();
    $(this).find('div.h_s_filter.' + rel).fadeIn();
    $(this).find('div.h_s_menu a').removeClass('sel');
    $(el).addClass('sel');
  };

  //
  // Update rating
  //
  $.fn.hotel_search.get_hotel_rates = function() {
    // get rates via ajax and push into 
    var check_in = $('#check_in').val();
    var check_out = $('#check_out').val();
    if(!check_in || !check_out) {
      return;
    };
    // get adults
    var ages = [];
    var adults = Number($('#adults').val());
    for(var i=0; i<adults; i++) {
      ages.push('19'); 
    }
    // get kid ages
    for(var i=1; i<= Number($('#children').val()); i++) {
      var v = $('#child_age_' + i).val();
      if(v) ages.push(v);
    }
    
    // get the data, check for change since last server request
    var params = {hotel_ids: hotelIds.join(','), check_in:check_in, check_out:check_out, ages:ages.join(','), raw:1};
    if($(this).hotel_search.last_rates === params) {
      // update state
      return;
    }
    $(this).hotel_search.last_rates = params;
    
    // update state
    $(this).find('#search_button').hide();
    $(this).find('#search_status').html('<h3>getting rates...</h3>').show();

    var tt = $(this);

    // get the rates
    $.ajax({
      url: '/tornado/hotel/rate_many_hotels',
      dataType: "json",
      type: 'POST',
      data: params,
	  cache: true,
      success: function(json) { 
		// load values
        var rs = json['results'];
        var allocations = json['allocations'];
        var nosells = json['nosells'];
        // update state
        $('#hotel_search').find('#search_status').hide();
        $('#hotel_search').find('#search_button').show();
        // show all rates
        for(var i in rs) {
          var el = $('#' + i);
          var best_rate = Number(rs[i].best_rate);
          if(best_rate) {
            el.attr('rate', best_rate);
            el.find('h1.lowest_rate').html('$' + rs[i].best_rate);
            var rEl = el.find('p.rooms');
            rEl.html('').show();

           // url for booking form
            var url =	'/hotel/reserve/' + i + 
						'?check_in=' + check_in + 
						'&check_out=' + check_out + 
						'&adults=' + rs[i].adults +
						'&children=' + rs[i].children +
						'&infants=' + rs[i].infants;

			// update urls
			var hash =  '#' + check_in +
						'|' + check_out +
						'|' + rs[i].adults +
						'|' + rs[i].children;
			el.find('a.profile').each(function() {
				var uri = $(this).attr('href');
				if(!uri.match("#")) $(this).attr('href', $(this).attr('href') + hash);
				$(this).attr('target','_blank');
			})

            // add the rooms html
            for(var ii in rs[i].rooms) {
              if(rs[i].rooms[ii].rates && rs[i].rooms[ii].rates.total) {
                $('#hotel_room_tmpl').tmpl({
                  id:i,
                  room:rs[i].rooms[ii], 
                  rate: rs[i].rooms[ii].rates,
                  total: Math.round(rs[i].rooms[ii].rates.total),
                  url:url + '&room_id=' + rs[i].rooms[ii].room_id
                }).appendTo($(rEl));
              }
            }
          }

          // adjust min-height of center div so
          // border reaches bottom
          var mid = $(el).find('div.middle');
          mid.height( mid.next().height() );
        }
        // update counters/pricing display
        tt.hotel_search.filter_refresh();
      }
    });
  }

  //
  // setup a filter listener
  //
  $.fn.hotel_search.filter_listen = function(type, key, ids) {
    // array and listener setup
    if(typeof fKeys[type] == "undefined") {
      fKeys[type] = [];
      fIds[type] = [];
      // setup the listener for this type
      var tt = $(this);
      $(this).find('input.h_s_f.' + type).change(function() {
        var checked = $(this).attr('checked');
        var key = $(this).val();
        tt.hotel_search.filter_change(type, key, checked);  

        // additional region stuff
        if(type == 'region') {
          $.fn.regions($(this)); 
        }
      }, tt);
    }
    // add key to type and ids to key
    fKeys[type].push(key);
    fIds[type].push(ids);
  };

  //
  // region selection changed
  //
  $.fn.regions = function(el) {
    // hide all thumbs
    $('img.region_thumb').hide();
    // reveal selected thumb
    if(el.attr('checked')==true) {
      var region = el.val().replace(' ','');
      $('img.region_thumb.' + region).show();
    }
  };

  //
  // filter changed
  //
  $.fn.hotel_search.filter_change = function(type, key, is_checked) {
    var hiddenIds = $.fn.hotel_search.get_ids(':hidden');
    var visibleIds = $.fn.hotel_search.get_ids(':visible');
    var checkedInputs = $('input.h_s_f:checked');
    if (checkedInputs.length==0) {
      // everything should be showing and selectable
      // nothing checked
      $(this).hotel_search.filter_clear();
    } else {
      // One filter was removed and some rows are presently hidden.
      // For each hidden row, show, then hide if all conditions not met.
      // Get ids to consider (presently hidden rows)
      // hold list of lists of valid ids
      var validIds = [];
      // loop through types, get invalid ids 
      for(var type in fKeys) {
        // get selected filters applied for current type
        var keysToCheck = [];
        $('input.h_s_f.'+type+':checked').each(function(){ 
          keysToCheck.push($(this).val());
        });
        // have any filters been selected?
        if(keysToCheck.length > 0) {
          for(var ii in keysToCheck) {
            // get the valid ids for each selected filter
            var keyId = fKeys[type].indexOf(keysToCheck[ii]);
            validIds.push(fIds[type][keyId]);
            //window.console.log('valid ids for ' + type + ' and key ' + keysToCheck[ii] + ' : '+ fIds[type][keyId]);
          }
        }
      }
      // now should have a list with valid ids for the checked options
      // loop on each hidden id (row)
      for(var id in hotelIds) {
        // consider each list of valid ids
        var valid = true;
        id = Number(id);
        for(var i in validIds) {
          // is the current row in this list of valid ids?
          if(validIds[i].indexOf(id) == -1) {
            // no, still hidden 
            valid = false;
            break;
          }
        }
        //window.console.log('# ' + id + 'valid? ' + valid + ' - ' + hotelIds[id]);
        // everything passed for this row
        if(valid==true) {
          $('#' + hotelIds[id]).show();
          // window.console.log('Show #' + id + " : " + hotelIds[id]);  
        } else {
          $('#' + hotelIds[id]).hide();
        } 
      }
    }

    $(this).hotel_search.filter_refresh();

    // nothing to do
    if (checkedInputs.length==0) return;

    // done hiding and unhiding rows
    // consider each unselected filter control to see if 
    // still matches any visible rows
    // Get ids to consider (presently visible rows)
    var visibleIds = $.fn.hotel_search.get_ids(':visible');
    // Loop on each filter type
    for(var type in fKeys) {
      // Loop on each non-selected filter control
      $('input.h_s_f.'+type).each(function() {
        if($(this).attr('checked') !== true)  {

          var keyId = fKeys[type].indexOf($(this).val());
          var validIds = fIds[type][keyId];
          validIds.indexOf('x');
          // window.console.log('fIds[' + type + '][' + keyId + ']' + ' for key: ' + $(this).val());
          var is_on = $.fn.hotel_search.filter_find_one_match(visibleIds, validIds);
          if(is_on) {
            $(this).attr('disabled', false).next().removeClass('off');
          } else {
            $(this).attr('disabled', true).next().addClass('off');
          }
          
        }
      });
    }

    //
    // change region thumb?
    //
    if(typeof fKeys['region'] == "undefined") {
      // window.console.log('region type not present');
    } else if ($("input.region:checked").length == 0) {
      // nothing checked
      // only one visible
      var en = $("input.h_s_f.region:not(:disabled)");
      if(en.length == 1) {
        // hide all thumbs 
        $('img.region_thumb').hide();
        // reveal only remaining region thumb
        var el = en[0];
        var region = $(el).val().replace(' ','');
        $('img.region_thumb.' + region).show();
      }
    }
  };

  //
  // test if list one contains a matching value in list two
  //
  $.fn.hotel_search.filter_find_one_match = function(ids, validIds) {
    for(var id in ids) {
      var id = Number(ids[id]);
      if(validIds.indexOf(id) != -1) return true;
    }
    return false;
  };

  //
  //  get row ids
  //
  $.fn.hotel_search.get_ids = function(selector) {
    var ids = [];
    $('.hotel-row' + selector).each(function() {
      var id = hotelIds.indexOf($(this).attr('id'));
      ids.push(id); 
    });
    return ids;
  };

  //
  // test a row id against one type, key filter
  //
  $.fn.hotel_search.filter_one = function(type, key, id) {
    var keyId = fKeys[type].indexOf(key);
    var validIds = fIds[type][keyId];
    var id = Number(id);
    //window.console.log(type + ', ' + key + ', ' + id + ': ' + ' keyId: ' + keyId + ' '+ validIds);
    if(validIds.indexOf(id) == -1) {
      return false;
    } else {
      return true;
    }
  };

  //
  // clear all filters, show all hotels
  //
  $.fn.hotel_search.filter_clear = function() {
    $('input.h_s_f').each(function() {
      $(this).attr('checked',false).attr('disabled',false).next().removeClass('off');  
    });
    $('.hotel-row:hidden').each(function() {
      $(this).show(); 
    });
    $(this).hotel_search.filter_refresh();
  };

  //
  // sorting key changed
  //
  $.fn.hotel_search.change_order = function(val) {
    var mylist = $('#hotel_s_r');
    var listitems = mylist.find('.hotel-row').get();
    listitems.sort(function(a, b) {
       var compA = Number($(a).attr(val));
       var compB = Number($(b).attr(val));
       if(val=='rate') {
        // ascending
        return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
       } else {
        // descending
        return (compA > compB) ? -1 : (compA < compB) ? 1 : 0;
       }
    });
    $.each(listitems, function(idx, itm) { mylist.append(itm); });
  };

  //
  // post-filter update statuses, counters
  //
  $.fn.hotel_search.filter_refresh = function() {
    var c_vis = Number($('.hotel-row:visible').length);
    var c_ttl = Number($('.hotel-row').length);
    if(!c_vis || c_vis==0) {
      // nothing remains visiblej
      $('span.count_visible').html('<u>0</u> of ');
      $('div#h_s_nomatch').fadeIn();
      $('a.h_s_all').show().next().hide();
    } else if (c_vis === c_ttl) {
      // all visible
      $('span.count_visible').html('');
      $('div#h_s_nomatch').hide();
      $('a.h_s_all').hide().next().show();
    } else {
      // partial visible
      $('span.count_visible').html(c_vis + ' of ');
      $('div#h_s_nomatch').hide();
      $('a.h_s_all').show().next().hide();
    }
    // update lowest rate visible
    var lowest_rate = false;
    $('.hotel-row:visible').each(function() {
      var cur = Number($(this).attr('rate'));
      if(cur && cur > 1 && (!lowest_rate || lowest_rate > cur)) lowest_rate = cur;
    });
    $('h1.h_s_lowest').html('$' + Math.round(lowest_rate));
  };
  
  //
  // config defaults
  //
  $.fn.hotel_search.defaults = {
  	'url': '',
  	'required_fields': []
  };

}) (jQuery);


function change_ages(i) {
	var i = Number(i);
	if(i == 0) {
	  $('#ages').hide();
	} else {
	  $('#ages').show();
	  var ii = 1;
	  while(ii<7) {
		if( ii <= i) {
		  $("span#child_" + ii).show(); 
		} else {
		  $("span#child_" + ii).hide(); 
		}
		ii += 1;
	  }
	} 
}

