$(document).ready(function(){
  hotelDetails();
  hotelForm();
  eventDetails();
  hotelSearch();
  eventSearch();
  hotelSearchResults();
  packageSearch();
});

function hotelDetails() {
  if (! $('.hotelDetails')[0] ) return;
  
  // Datepicker Options
	var startDateOptions = datepickerOptions({
	  minDate: 0,
	  onSelect: updateBookingStayDays
  });
	var	endDateOptions = datepickerOptions({
	  beforeShow: customRange,
	  onSelect: updateBookingStayDays
	});
		
	$("#bookingArrival").datepicker(startDateOptions);
  $('#bookingDeparture').datepicker(endDateOptions);
  initDates($("#bookingArrival"), $('#bookingDeparture'));
  
  var roomButtons = {};
  roomButtons[lang['cancel']] = function() {
    $(this).dialog('close');
  };
  roomButtons[lang['addRoom']] = function() {
    var room = $(this).find('input:radio:checked');
    if ( room.length ) { 
      var roomText = room.prev('label').html();
      var roomCount = $('.rooms li').length;
      var li = $('#roomAdder').parent();
      li.before('<li class="roomRow clearfix"><select id="room_'+roomCount+'_count" name="room_'+roomCount+'_count"><option value="1">1</option><option value="2">2</option></select><label for="room_'+roomCount+'_count">'+roomText+'</label></li>');
      li.prev().find('strong').before('<a title="'+lang['removeRoom']+'" class="roomDelete" href="#"><img src="http://www.wien.info/++resource++wir/img/iconTrash.png" alt="'+lang['removeRoom']+'" /></a>');
      updateRoomRows();
    }
    $(this).dialog('close');
  };
  
  var serviceButtons = {};
  serviceButtons[lang['cancel']] = function() {
    $(this).dialog('close');
  };
  serviceButtons[lang['addService']] = function() {
    var services = $(this).find('input:checkbox:checked');
    services.each(function() {
      var serviceText = $(this).prev('label').html();
      var serviceCount= $('.rooms li').length;
      var li = $('#roomAdder').parent();
      li.before('<li class="roomRow clearfix"><select id="service_'+serviceCount+'_count" name="service_'+serviceCount+'_count"><option value="1">1</option><option value="2">2</option></select><label for="service_'+serviceCount+'_count">'+serviceText+'</label></li>');
      li.prev().find('strong').before('<a title="'+lang['removeService']+'" class="roomDelete" href="#"><img src="http://www.wien.info/++resource++wir/img/iconTrash.png" alt="'+lang['removeService']+'" /></a>');
       updateRoomRows();
    });
    $(this).dialog('close');
  };
  
  // Room Dialogue
  $('#roomDialogue').dialog({
    autoOpen: false,
    modal: true,
    width: 600,
    buttons: roomButtons,
    close: function() {
      $(this).find('input').attr('checked', false);
    }
  });
  
  // Service Dialogue
  $('#serviceDialogue').dialog({
    autoOpen: false,
    modal: true,
    width: 600,
    buttons: serviceButtons,
    close: function() {
      $(this).find('input').attr('checked', false);
    }
  });
  
  $('#moreInfo').hide().before('<p id="moreInfoShower"><a href="#">'+lang['moreInfo']+'</a></p>');
  $('#roomPriceDetails').hide();
  $('#actualStays').append('<br /><a href="#">'+lang['priceDetails']+'</a>');
  
  
  // Event Handlers
  $('#moreInfoShower a').click(function() {
    $('#moreInfo').slideDown(300);
    $(this).parent().slideUp(300);
  return false;
  });
  $('#roomAdder').click(function(){
    $('#roomDialogue').dialog('open');
    return false;
  });
  $('#serviceAdder').click(function(){
    $('#serviceDialogue').dialog('open');
    return false;
  });
  $('#actualStays a').click(function() {
    $('#roomPriceDetails').slideToggle(500);
    return false;
  });
  
  // Room Row Enhancements
  function updateRoomRows() {
    var deleteLinks = $('.roomDelete');
    var roomSelects =  $('.roomRow select');
    roomSelects.each(updateRoomMulti);
    roomSelects.change(updateRoomMulti);
    deleteLinks.click(function() {
      $(this).parents('.roomRow').slideUp(300, function() {
        $(this).remove();
        updateRoomPrices();
      });
      return false;
    });
  }
  updateRoomRows();
   
  /*--- Tab Interface ---*/
  
  $('#mainTabs').tabs();
  $('#accomTabs').tabs();
  
  // we need this to initialize the Slideshow
  $('#accomTabs').tabs('select', 2);
  ImageSlideshow();
   $('#accomTabs').tabs('select', 0);
  
   // Event Handlers
  $('#bookButton').click(function() {
    $('#mainTabs').tabs('select', 1);
    return false;
  });
  
  $('.hotelDetails .address a').click(function() {
    $('#mainTabs').tabs('select', 0);
    return false;
  });
  
  // Fix bad behaviour (scrolling too far down) when linking to anchor (Tab)
  // Seen in Firefox
  if ( window.location.hash ) {
    window.location = window.location;
  }
}

function hotelForm () {
  if (! $('.hotelBooking')[0] ) return;
  
  var dates = $('#dates');
  var lateSpan = $('.infoBoxLeft span', dates);
  var lateOption = $('.option', dates);
  
  lateOption.hide();
  lateSpan.append('<br /><a href="#">'+lang['lateArrivalQ']+'</a>');
  
  $('.infoBoxLeft a', dates).click(function() {
    lateOption.slideDown(300);
    $(this).slideUp(300);
    return false;
  });
  
  // Room Row Enhancements
  var roomSelects =  $('.roomRow select');
  roomSelects.each(updateRoomMulti);
  roomSelects.change(updateRoomMulti);
}

function eventDetails () {
  if (! $('.eventDetails')[0] ) return;
  
  var smallDate = $('.infoBoxDates:first');
  var extendedDates = $('.extendedDates');
  var extendLink = $('<a href="#">'+lang['allTimes']+'</a>').insertAfter('.infoBoxDates:first ul');
  
  //Initialize
  extendedDates.hide();
  
  // Event Handlers
  extendLink.click(toggleTimes);
  
  function toggleTimes () {
    var text = extendLink.text() == lang['allTimes'] ? lang['currentTimes'] : lang['allTimes'];
    extendedDates.slideToggle(500, function() {
      extendLink.text(text);
    });
    return false;
  }
}

function hotelSearch () {
  if (! $('#hotelSearchForm')[0] ) return;
  
  // Datepicker Options
	var startDateOptions = datepickerOptions({
	  minDate: 0,
	  onSelect: updateSearchStayDays
  });
	var	endDateOptions = datepickerOptions({
	  beforeShow: customRange,
	  onSelect: updateSearchStayDays
	});
		
	$("#hotelArrival").datepicker(startDateOptions);
  $('#hotelDeparture').datepicker(endDateOptions);
  
  // Insert/Remove Stuff we don't need when JS is not on
  $('#hotelRooms').before('<p class="hint stays"><strong></strong></p>');
  $('#hotelExtended').append('<h3 class="clearfix"><a href="#" id="hotelExtender">'+lang['expand']+'</a></h3>');
  $('p', '.types, .stars').after('<a href="#">'+lang['all']+'</a>');
  $('.maxprice').append('<a href="#">'+lang['without']+'</a>');
  $('.currency').append('<a href="#">EUR</a>');
  $('.facilities').append('<a id="facExtender" href="#">'+lang['moreAmenities']+'</a>');
  $('#hotelRooms').append('<a id="roomAdder" href="#">'+lang['addRoom']+'</a>');
  $('#closeToSelect').before('<input type="text" name="closeTo" class="hint" id="closeTo" value="'+lang['limitSelection']+'" title="'+lang['limitSelection']+'" />');
  
  // Define vars for DOM Elements we need more often
  var extender = $('#hotelExtender');
  var extendedBox = $('#hotelExtended');
  var changing = $('.types .option, .stars .option, .facilities, .closeto, .maxprice input, .currency select, #hotelExtended .submit');
  var extendLinks = $('a', '.types, .stars, .maxprice, .currency');
  var moreFacs = $('.evenMoreFacs');
  var closeToOptions = $('#closeToSelect option');
  
  // Initialize
  initDates($("#hotelArrival"), $('#hotelDeparture'));
  updateSearchStayDays.call($("#hotelArrival"));
  initializeRooms();
  changing.hide();
  moreFacs.hide();
  setTypes();
  setStars();
  setMaxprice();
  setCurrency();
  $('#closeTo').keyup(closeToFilter);
  
  // Event Handler
  extender.click(toggleSearch);
  extendLinks.click(toggleSearch);
  $('#closeTo').focus(function() {deleteContent($(this), lang['limitSelection']);});
  $('#closeTo').blur(function() {restoreContent($(this), lang['limitSelection']);});
  $('#roomAdder').click(addRoom);
  $('#facExtender').click(function() {
    if ( moreFacs.hasClass('open') ) {
      moreFacs.hide().removeClass('open');
      $(this).text(lang['moreAmenities']);
    } else {
      moreFacs.show().addClass('open');
      $(this).text(lang['lessAmenties']);
    }
    return false;
  });
  
  // Contract / Extend  Search
  function toggleSearch () {
    if ( extendedBox.hasClass('open') ) // Contract
    {
      changing.hide();
      $('.evenMoreFacs.open').hide();
      $('a', '.maxprice, .currency').show();

      setTypes();
      setStars();
      setMaxprice();
      setCurrency();
      
      extendedBox.removeClass('open');
      extender.text(lang['expand']);
    }
    else // Extend
    {
      changing.show();
      $('.evenMoreFacs.open').show();
      $('a', '.maxprice, .currency').hide();
      
      $('a', '.types, .stars')
        .text(lang['allNone'])
        .unbind('click')
        .click(markAllCheckboxes);
      
      extendedBox.addClass('open');
      extender.text(lang['reduce']);
    }
    return false;
  }
  
  function closeToFilter (e) {
    if ( e.which == 27) $(this).val('');
        
    var string = $(this).val().toLowerCase();
    var updateField = $('#closeToSelect');
    var allOptions = closeToOptions;
    
    updateField.empty().append(allOptions);
    
    if ( string == '' ) {
      allOptions.each(function() {
        var strong = $(this).children('strong');
        strong.replaceWith(strong.text());
      });
      return;
    }
    
    allOptions.each(function(i) {
      var origText = $(this).text();
      var lowerText = origText.toLowerCase();
      var foundIndex = lowerText.indexOf(string);
      
      if ( foundIndex >= 0 ) {
        var foundText = origText.substr(foundIndex, string.length);
        var highlightText = origText.replace(foundText, '<strong>'+foundText+'</strong>');
        
        $(this).html(highlightText).show();
      } else {
        $(this).remove();
      }
    });
  }
  
  function initializeRooms () {
    var rooms = $('#hotelRooms .roomRow');
    
    $('input', rooms).each(function() {
      if (  $(this).val() == '0' || $(this).val() == '' ) {
        $(this).parent().remove();
      }
    });
    rooms.not(':first').each(function() { addRoomDelete($(this)); });
  }
  
  function addRoom () {
    var roomNumber = $('#hotelRooms .roomRow').length + 1;
    var addString = '<div class="roomRow clearfix"><input type="text" name="hotelRoomsNumber_'+roomNumber+'" id="hotelRoomsNumber_'+roomNumber+'" value="1" maxlength="1" /><select name="hotelRoomkind_'+roomNumber+'" id="hotelRoomkind_'+roomNumber+'" size="1" title="Zimmertyp"><option value="double">Doppelzimmer</option><option value="single">Einzelzimmer</option></select></div>';
    $(this).before(addString);
    addRoomDelete($(this).prev());
    return false;
  }
  
  function addRoomDelete (room) {
    room.append('<a title="'+lang['removeRoom']+'" href="#" class="roomDelete"><img alt="'+lang['removeRoom']+'" src="http://www.wien.info/++resource++wir/img/iconTrash.png"/></a>');
    $('a', room).click(function() {
      $(this).parent().remove();
      return false;
    });
  }
  
  function setTypes () {
    var checkboxes = $('.types input:checkbox');
    var checked = $('.types input:checkbox:checked');
    var unchecked = $('.types input:checkbox:not(:checked)');
    var value = '';
    
    if ( checked.length > 1 && unchecked.length != 0 ) {
      value = lang['different'];
    } else if ( unchecked.length == 0 || checked.length == 0 ) {
      value = lang['all'];
    } else {
      value = checked.prev('label').text();
    }
    updateExtendedLinks($('.types a'), value);
  }
  
  function setStars () {
    var checkboxes = $('.stars input:checkbox');
    var checked = $('.stars input:checkbox:checked');
    var unchecked = $('.stars input:checkbox:not(:checked)');
    var value = '';
    
   if ( checked.length > 1 && unchecked.length != 0 ) {
      value = lang['different'];
    } else if ( unchecked.length == 0 || checked.length == 0 ) {
      value = lang['all'];
    } else {
      value = checked.prev('label').children('img').length ? checked.prev('label').children('img').attr('alt') : checked.prev('label').text();
    }
    updateExtendedLinks($('.stars a'), value);
  }
  
  function setMaxprice () {
    var string = $.trim($('.maxprice input').val());
    var value =  string == '' ? lang['without'] : string;
    updateExtendedLinks($('.maxprice a'), value);
  }
  
  function setCurrency () {
    var value = $('.currency select').val();
    updateExtendedLinks($('.currency a'), value);
  }
  
  function updateExtendedLinks (element, value) {
    element.text(value).unbind('click').click(toggleSearch);
  }
}

function eventSearch () {
  if (! $('#eventSearchForm')[0] ) return;  
  
  // Datepicker Options
	var startDateOptions = datepickerOptions({
	  minDate: 0,
	  onSelect: resetEnd
  });
  
	var	endDateOptions = datepickerOptions({
	  beforeShow: customRange
	});
		
	// Initialize Datepickers
	$("#eventFrom").datepicker(startDateOptions);
  $('#eventTo').datepicker(endDateOptions);
  initDates($("#eventFrom"), $("#eventTo"), 1);
  
  // Insert stuff we don't need without JS
  $('#eventSearchForm').append('<h3 id="eventExtenderHeading" class="clearfix"><a id="eventExtender" href="#" class="open">'+lang['expand']+'</a></h3>');
  $('#catGroup legend').after('<a href="#">'+lang['allNone']+'</a>');
  addSimpleCategorySelect();
  
  // Define vars for DOM Elements we need more often
  var form = $('#eventSearchForm');
  var extender = $('#eventExtender');
  var reduceHide = $('#catGroup, #sortGroup');
  var catGroup = $('#catGroup');
  var catSelect = $('#catSelect');
  var eventCats = $('#eventCats');
  
  var checkboxCount = $('input', catGroup).length;
  var checkedCheckboxCount = $('input:checked', catGroup).length;
  
  // Initialize
  if ( checkedCheckboxCount == 0 || checkedCheckboxCount == checkboxCount ) 
  { // if all are none checboxes are checked
    reduceHide.hide();
    catSelect.show();
    catSelect.find('option[value="eventAll"]').attr('selected', 'selected');
  }
  else if ( checkedCheckboxCount == 1 )
  { // if exactly one checkbox is checked
    reduceHide.hide();
    catSelect.show();
    var findIt = 'option[value="'+$('#catGroup input:checked').attr('id')+'"]';
    catSelect.find(findIt).attr('selected', 'selected');
  }
  else
  {
    reduceHide.hide();
    catSelect.show();
    eventCats.prepend('<option value="eventMany" selected="selected">'+lang['selection']+'</option>');
  }
  
  /*---
    Resolve a Firefox Bug with Radiobuttons
    see http://www.ryancramer.com/journal/entries/radio_buttons_firefox/
    Bugzilla Report https://bugzilla.mozilla.org/show_bug.cgi?id=394782
  --- */
  if ( $.browser.mozilla ) {
    form.attr("autocomplete", "off");
  }
  
  // Event Handlers
  extender.click(toggleSearch);
  
  $('#catGroup a').click(function() {
    markAllCheckboxes.call($(this));
    // Also set the Selectbox to 'Alle'
    catSelect.find('option[value="eventAll"]').attr('selected', 'selected');
    return false;
  });
  
  form.submit(function() {
    eventCats.attr('disabled', 'disabled');
  });
  
  eventCats.change(function() {
    var selected = $(this).find('option:selected').val();

    if ( selected == 'eventAll' ) {
      markAllCheckboxes.call($('#catGroup a'));
    } else {
      markAllCheckboxes.call($('#catGroup a'), null, false);
      $('#'+selected).attr('checked', true);
    }
    catSelect.find('option[value="eventMany"]').remove();
  });
  
  // Contract / Extend  Search
  function toggleSearch () {
    if ( form.hasClass('extended') ) // Contract
    {
      if ( $('#catGroup input:checked').length == 1 ) {
        var findIt = 'option[value="'+$('#catGroup input:checked').attr('id')+'"]';
        catSelect.find(findIt).attr('selected', 'selected');
      } else if ( $('#catGroup input:checked').length == $('#catGroup input').length ) {
        catSelect.find('option[value="eventAll"]').attr('selected', 'selected');
      } else {
        eventCats.prepend('<option value="eventMany" selected="selected">'+lang['selection']+'</option>');
      }
      reduceHide.hide();
      catSelect.show();
      form.removeClass('extended');
      extender.text(lang['expand']);
    }
    else // Extend
    {
      catSelect.hide();
      catSelect.find('option[value="eventMany"]').remove();
      reduceHide.show();
      form.addClass('extended');
      extender.text(lang['reduce']);
    }
    return false;
  }
  
  // Add the Category Select Box 
  function addSimpleCategorySelect () {
    var html = '<div class="input" id="catSelect"><label for="eventCats">'+lang['category']+'</label><select name="eventCats" id="eventCats">';
    html += '<option value="eventAll">'+lang['all']+'</option>';
    $('#catGroup .option').each(function() {
      html += '<option value="'+$(this).children('input').attr('id')+'">'+$(this).children('label').text()+'</option>';
    });
    html += '</select></div>';
    $('#catGroup').before(html);
    $('#catSelect').hide();
  }
}

function hotelSearchResults () {
  if (! $('.hotelSearch #searchresults')[0] ) return;
  
  // DOM Elements we need more often
  var searchresults = $('.searchresult');
  var roomSelects =  $('.roomRow select');
  
  // Insert / Hide Stuff we (don't) need without JS
  // ### The Checkboxes need some kind of ID relating them to the Hotel ### 
  searchresults.each(function(i) {
    $(this).prepend('<div class="resultCompare"><label for="resultCompare'+i+'" class="hidden">'+$(this).find('.resultAdress h3 a').text()+ lang['remember'] +' </label><input type="checkbox" id="resultCompare'+i+'" name="resultCompare'+i+'" title="'+lang['remember']+'" /></div>');
  });
  $('#resultTopbar').prepend('<a id="compareLink" href="#">'+lang['compare']+'</a>');
  $('#hotelSearchresultSort .submit').remove();
  roomSelects.each(updateRoomMulti);
  
  // Event Handlers
  $('#compareLink').click(function()
  {
    var checked = $('.resultCompare input:checked');
    // ### Do something with the checked inputs ###
    
    return false;
  });
  roomSelects.change(updateRoomMulti);
  $('#resultSort').change(function()
  {
    // ### do we have to do something else than submit the sort form ? ###
    $(this).parents('form').submit();
  });
}

function packageSearch () {
  if (! $('#packageSearchForm')[0] ) return;
  
  // Datepicker Options
	var startDateOptions = datepickerOptions({
	  minDate: 0,
	  onSelect: setDeparture
  });
  
  var endDateOptions = datepickerOptions({
    showOn: 'focus'
  });
  
  var nights = parseInt($('.stays strong').text().split(' ')[0], 10);
  
	$("#packageArrival").datepicker(startDateOptions);
	$("#packageDeparture").datepicker(endDateOptions);
	initDates($("#packageArrival"), $("#packageDeparture"), nights);
	
	function setDeparture () {
	  var arrivalDate = $(this).datepicker('getDate');
	  var diff = Math.ceil((arrivalDate - new Date())/86400000); // 86400000 is a Day in Milliseconds
	  $('#packageDeparture').datepicker('setDate', diff+nights);
	}
}

// Utilities

function updateSearchStayDays () {
  
  if ( this.id == 'hotelArrival' ) {
    resetEnd.call($(this).get(0));
  }
  
  var message = '';
  var difference = getStayDays($("#hotelArrival"), $('#hotelDeparture'));
  
  if ( difference < 0 ) {
    message = '- ' + lang['nights'];
  } else if ( difference == 1 ) {
    message = '1 ' + lang['night'];
  } else {
    message = difference + ' ' + lang['nights'];
  }
  
  $('.stays').html('<strong>'+message+'</strong>');
}

function updateBookingStayDays () {
  
  if ( this.id == 'bookingArrival' ) {
    resetEnd.call($(this).get(0));
  }
  
  var message = '';
  var priceInfo = '';
  var difference = getStayDays($("#bookingArrival"), $('#bookingDeparture'));
  
  if ( difference < 0 ) {
    message = '- ' + lang['nights'];
    priceInfo = '- EUR';
  } else if ( difference == 1 ) {
    message = '1 ' + lang['night'];
    priceInfo = updateTotalPrice(difference);
  } else {
    message = difference + ' ' + lang['nights'];
    priceInfo = updateTotalPrice(difference);
  }

  $('#actualStays span').text(message);
  $('#actualStays strong').text(priceInfo);

}

function getStayDays (arrival, departure) {
  var difference = departure.datepicker('getDate') - arrival.datepicker('getDate');
  difference = difference/86400000; // 86400000 is a Day in Milliseconds
  return difference;
}

function updateTotalPrice (days) {
  var baseprice = $('#roomSum strong').text().split(' ')[0];
  var price = (days * baseprice).toFixed(2);
  return price + ' EUR';
}

function updateRoomPrices () {
  var price = 0;
  $('#bookingInfo .roomRow select').each(function() {
    var count = $(this).children('option:selected').val();
    var strong = $(this).parent().find('label strong');
    price += parseFloat(strong.text().split(' ')[strong.text().split(' ').length-2], 10) * count;
  });
  $('#roomSum strong').text(price.toFixed(2) + ' EUR');

  var totalPrice = updateTotalPrice(getStayDays($("#bookingArrival"), $('#bookingDeparture')));
  $('#actualStays strong').text(totalPrice);
}

function updateRoomMulti () {
  var selected = $(this).children('option:selected').val();
  var roomMulti = selected <= 1 ? '' : selected + ' x';
  var price = $(this).parent().find('label strong');
  price.children('span').remove();
  price.prepend('<span>'+roomMulti+'</span> ');
  
  // ### TODO ### we need different update Functions
  if ( $('#bookingInfo').length ) updateRoomPrices();
}

function markAllCheckboxes (event, mark) {
  if ( mark == undefined ) {
    if ( $(this).parent().find('input:checkbox').length == $(this).parent().find('input:checked').length ) {
      mark = false;
    } else {
      mark = true;
    }
  }
  $(this).parent().find(':checkbox').attr('checked', mark);
  return false;
}