com.bezurk.namespace('com.bezurk.flights');
com.bezurk.namespace('com.bezurk.hotels');
com.bezurk.namespace('com.bezurk.flights.autocomplete');
com.bezurk.namespace('com.bezurk.calendar');

/** Event handlers. **/
YAHOO.util.Event.onDOMReady(function() {

  // Flights autocomplete.
  var flights_server = '/p/flights/locations/search';
  var flights_schema = ['results', 'name', 'code', 'c_name', 's_code', 'iata_code', 'icao_code', 'type', 'multi_airport'];

  var ds = new YAHOO.widget.DS_XHR(flights_server, flights_schema);
  ds.responseType = YAHOO.widget.DS_XHR.TYPE_JSON;
  ds.scriptQueryParam = 'q';
  ds.scriptQueryAppend = 'limit=50&format=js';
  ds.queryMatchContains = true;
  ds.queryMatchSubset = true;

  var originAc = new YAHOO.widget.AutoComplete('origin', 'origin-results', ds);
  originAc.minQueryLength = 2;
  originAc.maxResultsDisplayed = 20;
  originAc.forceSelection = true;
  originAc.queryDelay = 0.1;
  originAc.useIFrame = true;
  originAc.allowBrowserAutocomplete = false;
  originAc.formatResult = function(result, query) {
    return com.bezurk.flights.autocomplete.constructLocationDisplay(result, query, true);
  };
  originAc.itemSelectEvent.subscribe(function(type, args) {
    com.bezurk.flights.autocomplete.itemSelect(type, args, 'from');
  });
  originAc.textboxBlurEvent.subscribe(com.bezurk.flights.autocomplete.textboxBlur);
  originAc.dataReturnEvent.subscribe(function(type, args) {
    com.bezurk.flights.autocomplete.dataReturn(type, args, 'origin');
  });

  var destinationAc = new YAHOO.widget.AutoComplete('destination', 'destination-results', ds);
  destinationAc.minQueryLength = 2;
  destinationAc.maxResultsDisplayed = 20;
  destinationAc.forceSelection = true;
  destinationAc.queryDelay = 0.1;
  destinationAc.useIFrame = true;
  destinationAc.allowBrowserAutocomplete = false;
  destinationAc.formatResult = function(result, query) {
    return com.bezurk.flights.autocomplete.constructLocationDisplay(result, query, true);
  };
  destinationAc.itemSelectEvent.subscribe(function(type, args) {
    com.bezurk.flights.autocomplete.itemSelect(type, args, 'to');
  });
  destinationAc.textboxBlurEvent.subscribe(com.bezurk.flights.autocomplete.textboxBlur);
  destinationAc.dataReturnEvent.subscribe(function(type, args) {
    com.bezurk.flights.autocomplete.dataReturn(type, args, 'destination');
  });


  // Hotels autocomplete.
  var acResultTemplate = new Template('<div class="location-result">#{name}#{state}, #{country}</div>');
  var acPlainResultTemplate = new Template('#{name}#{state}, #{country}');

  var hotels_server = '/p/hotelr/locations/search';
  var hotels_schema = ['results', 'name', 'code', 'c_name', 's_code'];

  var ds = new YAHOO.widget.DS_XHR(hotels_server, hotels_schema);
  ds.responseType = YAHOO.widget.DS_XHR.TYPE_JSON;
  ds.scriptQueryParam = 'q';
  ds.scriptQueryAppend = 'limit=50&format=js';
  ds.queryMatchContains = true;
  ds.queryMatchSubset = true;

  var ac = new YAHOO.widget.AutoComplete('location', 'location-results', ds);
  ac.minQueryLength = 2;
  ac.maxResultsDisplayed = 20;
  ac.forceSelection = true;
  ac.queryDelay = 0.1;
  ac.useIFrame = true;
  ac.allowBrowserAutocomplete = false;
  ac.formatResult = function(result, query) {
    return this.constructLocationDisplay(result, query, true);
  };
  ac.itemSelectEvent.subscribe(function(type, args) {
    var result = args[2];
    var textbox = args[0]._oTextbox;
    var query = textbox.value;

    textbox.value = this.constructLocationDisplay(result, query, false);
    $('locationCode').value = result[1];
  });
  ac.textboxBlurEvent.subscribe(function(type, args) {
    var autoComplete = args[0];
    if (!autoComplete._bItemSelected) {
      var listItems = autoComplete.getListItems();
      if (listItems && listItems[0] && autoComplete.getListItemData(listItems[0])) {
        autoComplete._selectItem(listItems[0]);
      }
    }
  });
  ac.dataReturnEvent.subscribe(function(type, args) {
    var results = args[2];
    var content = args[0]._oContainer._oContent;

    // Hack to enforce max-height in IE.
    if (results.length > 10) {
      var listElements = content.getElementsByTagName('li');
      var first = listElements[0];
      content.style.height = (10 * first.offsetHeight) + 'px';
    }

    if (results.length == 0) {
      args[0].setBody('<div class="error">No matching locations</div>');
    }
  });

  ac.constructLocationDisplay = function(result, query, withMarkup) {
    if (withMarkup) {
      return acResultTemplate.evaluate({
        name: this.highlightNeedle(result[0], query, '<strong>', '</strong>'),
        state: result[3] ? ', ' + result[3] : '',
        country: this.highlightNeedle(result[2], query, '<strong>', '</strong>')
      });
    } else {
      return acPlainResultTemplate.evaluate({
        name: result[0],
        state: result[3] ? ', ' + result[3] : '',
        country: result[2]
      });
    }
  };
  ac.highlightNeedle = function(str, needle, prefix, suffix) {
    var regex = new RegExp('('+needle+')', 'gi');
    return str.replace(regex, prefix + '$1' + suffix);
  }


  // Initialize calendars.
  var today = new Date();

  var defaultDepartDate = new Date();
  defaultDepartDate.setDate(today.getDate()+21);
  var defaultDepartDay = defaultDepartDate.getDate(), defaultDepartMonth = defaultDepartDate.getMonth()+1, defaultDepartYear = defaultDepartDate.getFullYear();
  var defaultReturnDate = new Date();
  defaultReturnDate.setDate(today.getDate()+25);
  var defaultReturnDay = defaultReturnDate.getDate(), defaultReturnMonth = defaultReturnDate.getMonth()+1, defaultReturnYear = defaultReturnDate.getFullYear();

  // Set the textbox date values.
  $('outboundDate').value = defaultDepartYear+'-'+defaultDepartMonth+'-'+defaultDepartDay;
  $('inboundDate').value = defaultReturnYear+'-'+defaultReturnMonth+'-'+defaultReturnDay;

  com.bezurk.calendar.calDepart = new YAHOO.widget.Calendar('calDepart', 'calDepartContainer', {
    pagedate : defaultDepartMonth+'/'+defaultDepartYear,
    selected : defaultDepartMonth+'/'+defaultDepartDay+'/'+defaultDepartYear,
    mindate : today,
    title : 'Depart:',
    close: true,
    iframe : true,
    LOCALE_WEEKDAYS : '1char',
    HIDE_BLANK_WEEKS : true
  });
  com.bezurk.calendar.calDepart.selectEvent.subscribe(com.bezurk.calendar.handleDepartSelect, com.bezurk.calendar.calDepart, true);
  com.bezurk.calendar.calDepart.render();

  com.bezurk.calendar.calReturn = new YAHOO.widget.Calendar('calReturn', 'calReturnContainer', {
    pagedate : defaultReturnMonth+'/'+defaultReturnYear,
    selected : defaultReturnMonth+'/'+defaultReturnDay+'/'+defaultReturnYear,
    mindate : today,
    title : 'Return:',
    close: true,
    iframe : true,
    LOCALE_WEEKDAYS : '1char',
    HIDE_BLANK_WEEKS : true
  });
    com.bezurk.calendar.calReturn.selectEvent.subscribe(com.bezurk.calendar.handleReturnSelect, com.bezurk.calendar.calReturn, true);
  com.bezurk.calendar.calReturn.render();


  var defaultCheckInDate = new Date();
  defaultCheckInDate.setDate(today.getDate()+7);
  var defaultCheckInDay = defaultCheckInDate.getDate(), defaultCheckInMonth = defaultCheckInDate.getMonth()+1, defaultCheckInYear = defaultCheckInDate.getFullYear();
  var defaultCheckOutDate = new Date();
  defaultCheckOutDate.setDate(today.getDate()+9);
  var defaultCheckOutDay = defaultCheckOutDate.getDate(), defaultCheckOutMonth = defaultCheckOutDate.getMonth()+1, defaultCheckOutYear = defaultCheckOutDate.getFullYear();

  // Set the textbox date values.
  $('fromDate').value = defaultCheckInYear+'-'+defaultCheckInMonth+'-'+defaultCheckInDay;
  $('toDate').value = defaultCheckOutYear+'-'+defaultCheckOutMonth+'-'+defaultCheckOutDay;

  com.bezurk.calendar.calCheckIn = new YAHOO.widget.Calendar('calCheckIn', 'calCheckInContainer', {
    pagedate : defaultCheckInMonth+'/'+defaultCheckInYear,
    selected : defaultCheckInMonth+'/'+defaultCheckInDay+'/'+defaultCheckInYear,
    mindate : today,
    title : 'Check-in:',
    close: true,
    iframe : true,
    LOCALE_WEEKDAYS : '1char',
    HIDE_BLANK_WEEKS : true
  });
  com.bezurk.calendar.calCheckIn.selectEvent.subscribe(com.bezurk.calendar.handleCheckInSelect, com.bezurk.calendar.calCheckIn, true);
  com.bezurk.calendar.calCheckIn.render();

  com.bezurk.calendar.calCheckOut = new YAHOO.widget.Calendar('calCheckOut', 'calCheckOutContainer', {
    pagedate : defaultCheckOutMonth+'/'+defaultCheckOutYear,
    selected : defaultCheckOutMonth+'/'+defaultCheckOutDay+'/'+defaultCheckOutYear,
    mindate : today,
    title : 'Check-out:',
    close: true,
    iframe : true,
    LOCALE_WEEKDAYS : '1char',
    HIDE_BLANK_WEEKS : true
  });
    com.bezurk.calendar.calCheckOut.selectEvent.subscribe(com.bezurk.calendar.handleCheckOutSelect, com.bezurk.calendar.calCheckOut, true);
  com.bezurk.calendar.calCheckOut.render();
}); // YAHOO.util.Event.onDOMReady

// selectEvent handlers for calendars.
com.bezurk.calendar.handleDepartSelect = function(type, args, obj) {
  var selectedDate = args[0][0]; // First (and only) selected date.
  var year = selectedDate[0], month = selectedDate[1], day = selectedDate[2];
  $('outboundDate').value = year+'-'+month+'-'+day;

  // If inbound date is earlier than outbound, change it to outbound + 7 days.
  var outboundDate = com.bezurk.calendar.parseDate($('outboundDate').value);
  var inboundDate = com.bezurk.calendar.parseDate($('inboundDate').value);

  if (inboundDate <= outboundDate) {
    var aWeekLater = YAHOO.widget.DateMath.add(outboundDate, YAHOO.widget.DateMath.DAY, 7);
    com.bezurk.calendar.calReturn.select(aWeekLater);
    com.bezurk.calendar.calReturn.cfg.setProperty('pagedate', aWeekLater);
    com.bezurk.calendar.calReturn.render();
    $('inboundDate').value = aWeekLater.getFullYear()+'-'+(aWeekLater.getMonth()+1)+'-'+aWeekLater.getDate();
  }

  obj.hide();
}
com.bezurk.calendar.handleReturnSelect = function(type, args, obj) {
  var selectedDate = args[0][0]; // First (and only) selected date.
  var year = selectedDate[0], month = selectedDate[1], day = selectedDate[2];
  $('inboundDate').value = year+'-'+month+'-'+day;
  obj.hide();
}
com.bezurk.calendar.handleCheckInSelect = function(type, args, obj) {
  var selectedDate = args[0][0]; // First (and only) selected date.
  var year = selectedDate[0], month = selectedDate[1], day = selectedDate[2];
  $('fromDate').value = year+'-'+month+'-'+day;

  // If check out date is earlier than check in, change it to check in + 2 days.
  var checkInDate = com.bezurk.calendar.parseDate($('fromDate').value);
  var checkOutDate = com.bezurk.calendar.parseDate($('toDate').value);
  if (checkOutDate <= checkInDate) {
    var twoDaysLater = YAHOO.widget.DateMath.add(checkInDate, YAHOO.widget.DateMath.DAY, 2);
    com.bezurk.calendar.calCheckOut.select(twoDaysLater);
    com.bezurk.calendar.calCheckOut.cfg.setProperty('pagedate', twoDaysLater);
    com.bezurk.calendar.calCheckOut.render();
    $('toDate').value = twoDaysLater.getFullYear()+'-'+(twoDaysLater.getMonth()+1)+'-'+twoDaysLater.getDate();
  }

  obj.hide();
}
com.bezurk.calendar.handleCheckOutSelect = function(type, args, obj) {
  var selectedDate = args[0][0]; // First (and only) selected date.
  var year = selectedDate[0], month = selectedDate[1], day = selectedDate[2];
  $('toDate').value = year+'-'+month+'-'+day;
  obj.hide();
}

// For showing calendars when text fields are clicked.
YAHOO.util.Event.addListener('outboundDate', 'click', function() {
  com.bezurk.calendar.calDepart.show();
});
YAHOO.util.Event.addListener('inboundDate', 'click', function() {
  com.bezurk.calendar.calReturn.show();
});
YAHOO.util.Event.addListener('fromDate', 'click', function() {
  com.bezurk.calendar.calCheckIn.show();
});
YAHOO.util.Event.addListener('toDate', 'click', function() {
  com.bezurk.calendar.calCheckOut.show();
});

// For hiding calendars on click away.
YAHOO.util.Event.addListener(document, 'click', function(e) {
  var target = (e && e.target) || (event && event.srcElement);
  if (target.id != 'outboundDate') {
    if ($('calDepartContainer').style.display == 'block') {
      if (!com.bezurk.calendar.checkParentIsCalendarDiv(target, 'calDepartContainer')) {
        $('calDepartContainer').style.display = 'none';
      }
    }
  }
  if (target.id != 'inboundDate') {
    if ($('calReturnContainer').style.display == 'block') {
      if (!com.bezurk.calendar.checkParentIsCalendarDiv(target, 'calReturnContainer')) {
        $('calReturnContainer').style.display = 'none';
      }
    }
  }
});
YAHOO.util.Event.addListener(document, 'click', function(e) {
  var target = (e && e.target) || (event && event.srcElement);
  if (target.id != 'fromDate') {
    if ($('calCheckInContainer').style.display == 'block') {
      if (!com.bezurk.calendar.checkParentIsCalendarDiv(target, 'calCheckInContainer')) {
        $('calCheckInContainer').style.display = 'none';
      }
    }
  }
  if (target.id != 'toDate') {
    if ($('calCheckOutContainer').style.display == 'block') {
      if (!com.bezurk.calendar.checkParentIsCalendarDiv(target, 'calCheckOutContainer')) {
        $('calCheckOutContainer').style.display = 'none';
      }
    }
  }
});
// For hiding calendars on ESC key being pressed.
YAHOO.util.Event.addListener(document, 'keypress', function(e) {
  if (e.keyCode == 27) {
    if ($('calDepartContainer').style.display == 'block') {
      $('calDepartContainer').style.display = 'none';
    }
    if ($('calReturnContainer').style.display == 'block') {
      $('calReturnContainer').style.display = 'none';
    }
  }
});
YAHOO.util.Event.addListener(document, 'keypress', function(e) {
  if (e.keyCode == 27) {
    if ($('calCheckOutContainer').style.display == 'block') {
      $('calCheckOutContainer').style.display = 'none';
    }
    if ($('calCheckInContainer').style.display == 'block') {
      $('calCheckInContainer').style.display = 'none';
    }
  }
});
com.bezurk.calendar.checkParentIsCalendarDiv = function(t, calendarDivId){
  while (t.parentNode) {
    if (t == $(calendarDivId)) {
      return true;
    }
    t = t.parentNode;
  }
  return false;
}

com.bezurk.calendar.parseDate = function(dateString) {
  var pieces = dateString.split('-');
  if (pieces.length != 3) {
    return null;
  }

  var date = new Date();
  date.setFullYear(pieces[0], pieces[1]-1, pieces[2]);
  return date;
}

com.bezurk.flights.autocomplete.acResultTemplate = new Template('<div class="location-result">#{name}#{state}, #{country}#{code}#{allAirports}</div>');
com.bezurk.flights.autocomplete.acPlainResultTemplate = new Template('#{name}#{state}, #{country}#{code}#{allAirports}');

com.bezurk.flights.autocomplete.itemSelect = function(type, args, codeElement) {
  var result = args[2];
  var textbox = args[0]._oTextbox;
  var query = textbox.value;

  textbox.value = com.bezurk.flights.autocomplete.constructLocationDisplay(result, query, false);
  var code = result[1] ? result[1] : (result[4] ? result[4] : result[5]);
  $(codeElement).value = code;
};
com.bezurk.flights.autocomplete.textboxBlur = function(type, args) {
  var autoComplete = args[0];
  if (!autoComplete._bItemSelected) {
    var listItems = autoComplete.getListItems();
    if (listItems && listItems[0] && autoComplete.getListItemData(listItems[0])) {
      autoComplete._selectItem(listItems[0]);
    }
  }
};
com.bezurk.flights.autocomplete.dataReturn = function(type, args, textbox) {
  var results = args[2];
  var content = args[0]._oContainer._oContent;

  // Hack to enforce max-height in IE.
  if (results.length > 6) {
    var listElements = content.getElementsByTagName('li');
    var first = listElements[0];
    content.style.height = (6 * first.offsetHeight) + 'px';
  }

  if (results.length == 0) {
    args[0].setBody('<div class="error">No matching locations</div>');
  }
};
com.bezurk.flights.autocomplete.highlightNeedle = function(str, needle, prefix, suffix) {
  var regex = new RegExp('('+needle+')', 'gi');
  return str.replace(regex, prefix + '$1' + suffix);
};
com.bezurk.flights.autocomplete.constructLocationDisplay = function(result, query, withMarkup) {

  var code = result[1] ? result[1] : (result[4] ? result[4] : result[5]);
  var type = result[6];

  if (withMarkup) {
    return com.bezurk.flights.autocomplete.acResultTemplate.evaluate({
      name: com.bezurk.flights.autocomplete.highlightNeedle(result[0], query, '<strong>', '</strong>'),
      state: result[3] ? ', ' + result[3] : '',
      country: com.bezurk.flights.autocomplete.highlightNeedle(result[2], query, '<strong>', '</strong>'),
      code: code ? ' (<span class="iata-code">' + com.bezurk.flights.autocomplete.highlightNeedle(code, query, '<strong>', '</strong>') + '</span>)' : '',
      allAirports: (type == 'City' && result[7]) ? ', All Airports' : ''
    });
  } else {
    return com.bezurk.flights.autocomplete.acPlainResultTemplate.evaluate({
      name: result[0],
      state: result[3] ? ', ' + result[3] : '',
      country: result[2],
      code: code ? ' (' + code + ')' : '',
      allAirports: (type == 'City' && result[7]) ? ', All Airports' : ''
    });
  }
};

// onSubmit handler for search forms.
YAHOO.util.Event.addListener('bezurk_flight_search', 'submit', function(event) {
  if (!com.bezurk.flights.searchFlights()) {
    YAHOO.util.Event.stopEvent(event);
  }
});
YAHOO.util.Event.addListener('bezurk_hotel_search', 'submit', function(event) {
  if (!com.bezurk.hotels.searchHotels()) {
    YAHOO.util.Event.stopEvent(event);
  }
});

com.bezurk.flights.searchFlights = function() {
  // Validation.
  var roundTrip = $('roundTrip').checked;

  // Validate inputs.
  if ($('origin').value.length == 0 || $('from').value.length == 0) {
    alert("Please select where you would like to depart from.");
    return false;
  }
  if ($('destination').value.length == 0 || $('to').value.length == 0) {
    alert("Please select where you would like to travel to.");
    return false;
  }
  if (!$('outboundDate').value) {
    alert("Please enter a valid departure date YYYY-MM-DD");
    return false;
  }
  if (roundTrip && !$('inboundDate').value) {
    alert("Please enter a valid return date YYYY-MM-DD");
    return false;
  }

  var totalPassengers = parseInt($F('adults'), 10) + parseInt($F('children'), 10);
  if (totalPassengers > 9) {
    alert('We\'re sorry but flight search is limited to a maximum of 9 passengers.');
    return false;
  }

  // Dates can't be in the past.
  var departDate = com.bezurk.calendar.parseDate($('outboundDate').value);

  if (departDate < new Date()) {
    alert('Your depart date can\'t be in the past');
    return false;
  }

  if (roundTrip) {

    var returnDate = com.bezurk.calendar.parseDate($('inboundDate').value);
    if (returnDate < new Date()) {
      alert('Your return date can\'t be in the past');
      return false;
    }

    // Make sure departure date is before return date.
    if (returnDate != null && departDate != null) {
      if (returnDate < departDate) {
        alert("Your departure date must be before the return date");
        return false;
      }
    }
  }

  return true;
};
com.bezurk.hotels.searchHotels = function() {
  // Validation
  if ($('locationCode').value.length == 0) {
    alert('Please enter where you would like to stay');
    return false;
  }

  if (!$('fromDate').value) {
    alert('Please enter a valid check-in date DD/MM/YYYY');
    return false;
  }
  if (!$('toDate').value) {
    alert('Please enter a valid check-out date DD/MM/YYYY');
    return false;
  }

  // Dates can't be in the past.
  var checkInDate = com.bezurk.calendar.parseDate($('fromDate').value);
  var checkOutDate = com.bezurk.calendar.parseDate($('toDate').value);

  if (checkInDate < new Date()) {
    alert('Your check-in date can\'t be in the past');
    return false;
  }
  if (checkOutDate < new Date()) {
    alert('Your check-out date can\'t be in the past');
    return false;
  }

  // Make sure check-in date is before check-out date
  if (checkOutDate != null && checkInDate != null) {
    if (checkOutDate < checkInDate) {
      alert('Your check-in date must be before the check-out date');
      return false;
    }
  }

  return true;
}

// For tab switching.
YAHOO.util.Event.addListener('flights_on', 'click', function(e) {
  $('flights_tab').show();
  $('hotels_tab').hide();

  $('flights_on').addClassName('current');
  $('hotels_on').removeClassName('current');
});
YAHOO.util.Event.addListener('hotels_on', 'click', function(e) {
  $('hotels_tab').show();
  $('flights_tab').hide();

  $('hotels_on').addClassName('current');
  $('flights_on').removeClassName('current');
});