/**
 * bookingForm.js
 * 
 * Adds a behaviour layer to the booking forms.
 * Note that the forms are designed to provide basic functionality
 * without JavaScript.
 * These functions prepare the forms on page load, and add additional
 * functionality (form switching, dynamic airport listings, 
 * date calendar) and prepare the data to be sent to the 
 * Premier booking engine.
 */

/**
 * Basic Booking Engine Settings
 */

// The minimum number of days after today that a client can book online
var bf_min_days_start = 7;
// The maximum number of months after today that a client can book online (except accommodation only) 
var bf_max_months_end = 11;
// The maximum number of months after today that a client can book accommodation online 
var bf_max_months_end_accom = 15;

/**
 * Booking Engine URLs
 * specific URLs are areas of the booking engine that require and accommodation code
 */
var bf_flight_url = 'http://ecom.premierholidays.co.uk/ecom/AtopWeb/Live/En/Inclusive/InclusiveSearchCriteria.asp';
var bf_ferry_url  = 'http://ecom.premierholidays.co.uk/ecom/AtopWeb/Live/En/Inclusive/InclusiveFerrySearchCriteria.asp';
var bf_hotel_url  = 'http://ecom.premierholidays.co.uk/ecom/atopweb/live/En/accomOnly/accomSearchCriteria.asp';

var bf_specific_flight_url = 'http://ecom.premierholidays.co.uk/ecom/AtopWeb/live/en/inclusive/inclusiveCriteria.asp';
var bf_specific_ferry_url  = 'http://ecom.premierholidays.co.uk/ecom/AtopWeb/live/en/inclusive/inclusiveFerryCriteria.asp';
var bf_specific_hotel_url  = 'http://ecom.premierholidays.co.uk/ecom/AtopWeb/live/en/accomOnly/accomOnlyCriteria.asp';

/*
 * List of Low Cost Carrier Airports
 * On submit, these airports should redirect user to the Holiday Quote form (w/ a special message)
 */
var bf_airports_lowcost = new Array("");
var bf_airports_lowcost_redirect  = document.location.protocol + '//'
    bf_airports_lowcost_redirect += document.location.host + '/holiday_quote?message=9524';

var bf_booking_unavailable_redirect  = document.location.protocol + '//'
    bf_booking_unavailable_redirect += document.location.host + '/holiday_quote?message=9523';

var bf_airports_default = Array();
bf_airports_default["0"] = "Select an airport...";

var bf_airports = Array();
bf_airports["0"] = "Select an airport...";
bf_airports["BHD"] = "Belfast City";
bf_airports["BFS"] = "Belfast International";
bf_airports["BHX"] = "Birmingham";
bf_airports["BLK"] = "Blackpool";
bf_airports["BRS"] = "Bristol";
bf_airports["EMA"] = "East Midlands";
bf_airports["EDI"] = "Edinburgh";
bf_airports["GLA"] = "Glasgow";
bf_airports["GLO"] = "Gloucester";
bf_airports["INV"] = "Inverness";
bf_airports["JER"] = "Jersey";
bf_airports["LBA"] = "Leeds Bradford";
bf_airports["LVP"] = "Liverpool";
bf_airports["LCY"] = "London City";
bf_airports["LGW"] = "London Gatwick";
bf_airports["LTN"] = "Luton";
bf_airports["MAN"] = "Manchester";
bf_airports["NCL"] = "Newcastle";
bf_airports["SOU"] = "Southampton";

var bf_ports = Array();
bf_ports["0"] = "Select a port...";
bf_ports["LP"] = "Liverpool";
bf_ports["HY"] = "Heysham";

// Set up global booking_cal variable
var booking_cal;

/**
 * Change the basic functionality for JS functionality
 */ 
function prepareBookingForm() {

  // Do we have DOM?  Is the Form there?
  if (!document.getElementById || !document.getElementById('booking-form')) { return; }

  // get the destination code for use later in the script
  var bookingFormType = getBookingFormType();

  // Add Radio Buttons (Form Navigation)
  if (document.getElementById("booking-nav")) {

    var bnav = document.getElementById("booking-nav");
    removeChildren(bnav);

    //set default states for booking-nav radio buttons
    var bnav_flight_checked = true;
    var bnav_ferry_checked  = false;
    var bnav_hotel_checked  = false;

    //get the name of the top directory (or page)
    //and set selected states for booking-nav radio buttons
    if (document.location.pathname) {
      var locpath = document.location.pathname;
      // match the top directory in the webpath
      var matches = locpath.match(/^\/([^/]+)\/?/);
      if (matches) {
        var thisPageTopDir = matches[1];
        if (thisPageTopDir == 'hotels') {
          bnav_flight_checked = false;
          bnav_ferry_checked  = false;
          bnav_hotel_checked  = true;    
        }
      }
    }

    var flh = appendRadio(bnav, 'booking-nav-select', false, 'booking-nav-flight', bnav_flight_checked);
    flh.onclick = bookingNavSwitch;
    appendTextNode(bnav, " ");
    var flhlabel = appendLabel(bnav, 'booking-nav-flight', 'Flight + Hotel');
    if (bnav_flight_checked) {
      setClass(flhlabel, "active");
    }
    flhlabel.setAttribute('id', 'booking-nav-flight-label');

    appendTextNode(bnav, " ");

   
    var frh = appendRadio(bnav, 'booking-nav-select', false, 'booking-nav-ferry', bnav_ferry_checked);
    frh.onclick = bookingNavSwitch;
    appendTextNode(bnav, " ");
    var frhlabel = appendLabel(bnav, 'booking-nav-ferry', 'Ferry + Hotel');
    if (bnav_ferry_checked) {
      setClass(frhlabel, "active");
    }
    frhlabel.setAttribute('id', 'booking-nav-ferry-label');

    appendBr(bnav);
    

    var hot = appendRadio(bnav, 'booking-nav-select', false, 'booking-nav-hotel', bnav_hotel_checked);
    hot.onclick = bookingNavSwitch;
    appendTextNode(bnav, " ");
    var hotlabel = appendLabel(bnav, 'booking-nav-hotel', 'Hotel Only');
    if (bnav_hotel_checked) {
      setClass(hotlabel, "active");
    }
    hotlabel.setAttribute('id', 'booking-nav-hotel-label');

  }

  //if the hotels booking-nav radio button is checked by default
  // hide the Dep Airport div and select list
  if (document.getElementById('DepAirport') && bnav_hotel_checked) {
    document.getElementById('DepAirport').parentNode.style.display = 'none';
  }

  // Add onsubmit bahaviour to booking form
  if (document.getElementById('booking-form')) {
    document.getElementById('booking-form').onsubmit = submitBooking;
  }

  // set the start date and prepare the calendar
  if(document.getElementById('booking-dates')) {
    bookingSetStartDate();
    prepareBookingCalendar();
  }

}// end prepareBookingForm()


/**
 * Test whether a date is a Premier formatted date, should we do date and month checking?
 *
 * @parameter string datestring Premier formatted datestring (dd/mm/yy)
 *
 * @return boolean
 */
function isPremDate(datestring) {

  var pattern = /^\d{2}\/\d{2}\/\d{2}$/;
  return pattern.test(datestring);

}//end isPremDate()


/**
 * convertDatePremToJs
 * convert a Premier Booking System formatted string 
 * JavaScript Date object
 *
 * @parameter string datestring Premier formatted date string (dd/mm/yy)
 *
 * @return object JS Date object
 */
function convertDatePremToJs(datestring) {

  if (!isPremDate(datestring)) return false;

  var datearray = datestring.split('/');
  var day   = Number(datearray[0]);
  var month = Number(datearray[1]) - 1;
  var year  = Number('20' + datearray[2]);

  var jsdate = new Date();
  jsdate.setDate(day);
  jsdate.setMonth(month);
  jsdate.setFullYear(year);

  return jsdate;

}// end convertDatePremToJs()


/**
 * convertDateJsToPrem
 * convert a JavaScript Date object to a Premier Booking System formatted string 
 *
 * @parameter object dateobj JS Date object
 *
 * @return string Premier formatted date string (dd/mm/yy)
 */
function convertDateJsToPrem(dateobj) {

  if (!dateobj.getDate) return false;

  var day   = dateobj.getDate();
  var month = dateobj.getMonth() + 1 ;
  var year  = dateobj.getFullYear();

  var daystr  = (day.toString().length == 1) ? '0' + day.toString() : day.toString();
  var monstr  = (month.toString().length == 1) ? '0' + month.toString() : month.toString();
  var yearstr = year.toString().substr(2,2);
  var premdate = daystr + '/' + monstr + '/' + yearstr;

  return premdate;

}// end convertDateJsToPrem()


/**
 * insert the first day that a client can book into the date field
 */
function bookingSetStartDate() {

  if (!document.getElementById) return;
  if (!document.getElementById('StartDate')) return;

  var datenode = document.getElementById('StartDate');

  // is datenode an text input element?
  if (datenode.nodeName != 'INPUT' || datenode.getAttribute('type') != 'text') return;

  // don't overwrite a date if we have a valid one
  if (isPremDate(datenode.value)) return;

  // generate a date x days in advance of today
  var dt = new Date();
  dt.setDate(dt.getDate() + bf_min_days_start);
  var start_date = convertDateJsToPrem(dt);

  datenode.value = start_date;

}// end bookingSetStartDate()


/**
 * set the end date based on the start date and duration
 */
function bookingSetEndDate() {

  if (!document.getElementById) return;
  if (!document.createElement) return;
  if (!document.appendChild) return;
  if (!document.getElementById('booking-form')) return;
  if (!document.getElementById('StartDate')) return;
  if (!document.getElementById('Duration')) return;
  
  var startdate = document.getElementById('StartDate').value;
  if (!isPremDate(startdate)) return;

  var duration  = document.getElementById('Duration')[document.getElementById('Duration').selectedIndex].value;
  // check if duration is numeric?

  // create the enddate
  var dateobj = convertDatePremToJs(startdate);
  dateobj.setDate(dateobj.getDate() + Number(duration));
  var enddate = convertDateJsToPrem(dateobj);

  if (!document.getElementById('EndDate')) {

    var enddatenode = document.createElement('input');
    enddatenode.setAttribute('type', 'hidden');
    enddatenode.setAttribute('id', 'EndDate');
    enddatenode.setAttribute('name', 'EndDate');

    var bookingform = document.getElementById('booking-form');
    bookingform.appendChild(enddatenode);

    enddatenode.value = enddate;

  } else {

    var enddatenode = document.getElementById('EndDate');
    if (enddatenode.nodeName != 'INPUT') return;

    enddatenode.value = enddate;

  }
}


/**
 * getBookingFormType
 * if the booking-form-type (hidden value) is declared return the form type
 * otherwise return 'default'
 *
 * @return string
 */
function getBookingFormType() {

  if (!document.getElementById) return '';

  var formtype = 'default';
  if (document.getElementById('booking-form-type')) {
    formtype = document.getElementById('booking-form-type').getAttribute('value');
  }

  return formtype;

}// end getBookingFormType


/**
 * Switch between different booking modes when user clicks
 * one of the navigation radio buttons (onclick).
 * We need to change the colour of the label when this happens
 */ 
function bookingNavSwitch() {

  if (!document.getElementById) return;
  if (!document.getElementsByTagName) return;

  var nsid = this.getAttribute('id');
  var nslabels = this.parentNode.getElementsByTagName('label');
  var nsform = document.getElementById('booking-form');
  var nsdeparture = document.getElementById('DepAirport');
  var nsdest_value = '';
  var dsformtype = getBookingFormType();

  // Set all labels to no class
  for (var i = 0; i < nslabels.length; i++) {
    setClass(nslabels[i], '');
  }

  // Set this label to active
  var thislabel = document.getElementById(nsid + '-label');
  setClass(thislabel, 'active');

  // replace the destination section with the correct
  // airport / port or remove the div
  // and replace the form action with the correct URL
  switch (nsid) {
    case 'booking-nav-ferry':
       if (dsformtype == 'hotel-specific') {
         nsform.setAttribute('action', bf_specific_ferry_url);
       } else {
         nsform.setAttribute('action', bf_ferry_url);
       }
       nsdeparture.parentNode.style.display = 'block';
       replaceSelect(nsdeparture, bf_ports);
       break;
    case 'booking-nav-flight':
       if (dsformtype == 'hotel-specific') {
         nsform.setAttribute('action', bf_specific_flight_url);
       } else {
         nsform.setAttribute('action', bf_flight_url);
       }
       nsdeparture.parentNode.style.display = 'block';
       replaceSelect(nsdeparture, bf_airports); //NEW
       break;
    case 'booking-nav-hotel':
       if (dsformtype == 'hotel-specific') {
         nsform.setAttribute('action', bf_specific_hotel_url);
       } else {
         nsform.setAttribute('action', bf_hotel_url);
       }
       nsdeparture.parentNode.style.display = 'none';  
       break;
  }

}// end bookingNavSwitch()


/**
 * Event handler called by the Calendar to set the start date field
 */
function calSetStartDate(day, mon, year, prefix) {
  if (!document.getElementById('StartDate')) return;
  var datefield = document.getElementById('StartDate');
  // zero pad the day and month, get last two digits of year
  var daystr  = (day.toString().length == 1) ? '0' + day.toString() : day.toString();
  var monstr  = (mon.toString().length == 1) ? '0' + mon.toString() : mon.toString();
  var yearstr = year.toString().substr(2,2);
  datefield.value = daystr + '/' + monstr + '/' + yearstr;
  //datefield.onchange();
}// end calSetStartDate()


/**
 * prepareBookingCalendar
 * inserts the booking calendar div into the booking forms
 */
function prepareBookingCalendar() {

  if (!document.getElementById) return;
  if (!document.getElementById('booking-dates')) return;
  if (!document.createTextNode) return;
  if (!document.createElement) return;

  var datediv = document.getElementById('booking-dates');
  var caltext = document.createTextNode('Calendar');
  var calspan = document.createElement('span');
  var callink = document.createElement('a');
  var caldiv  = document.createElement('div');

  //set up initial start date
  var dt = new Date();
  dt.setDate(dt.getDate() + bf_min_days_start);

  booking_cal = new Calendar('booking_cal', 'booking-calendar-container', '200px', '133px');
  booking_cal.prefix = "booking";
  booking_cal.fadeit = true;
  booking_cal.scrollit = false;
  booking_cal.onDayClick = calSetStartDate;
  booking_cal.day_name_length = "2";
  booking_cal.week_start = "1";
  booking_cal.popup = true;
  booking_cal.first_time = false;
  booking_cal.selday = dt.getDate();
  booking_cal.month = dt.getMonth();
  booking_cal.year = dt.getFullYear();

  setClass(calspan, 'hidden');
  calspan.appendChild(caltext);

  setClass(callink, 'calendar');
  callink.appendChild(calspan);
  if (window.event) {
    //IE
    callink.onclick = function() { booking_cal.show(window.event) };
  } else {
    //FF
    callink.setAttribute('onclick', 'booking_cal.show(event)');
  }

  datediv.appendChild(callink);

  caldiv.setAttribute('id', 'booking-calendar-container');
  caldiv.style.visibility = 'hidden';
  datediv.appendChild(caldiv);

}// end prepareBookingCalendar()


/**
 * Add behaviours on booking form submit
 * 1. If a user has selected a low cost carrier, redirect to the holiday quote page
 * 2. If a user has selected a date that they can't book online, redirect to holiday quote page
 * 3. If user has selected ferries, calculate EndDate
 */ 
function submitBooking() {

  if (!document.getElementById) { return true; }

  // 1. If a user has selected a low cost carrier, redirect to the holiday quote page
  if (document.getElementById('DepAirport')) {

    var sb_dep = document.getElementById('DepAirport');
    var sb_dep_value = sb_dep.options[sb_dep.selectedIndex].value;

    for (code in bf_airports_lowcost) {
       if (sb_dep_value == bf_airports_lowcost[code]) {
         document.location = bf_airports_lowcost_redirect;
         return false;
       } 
    }

  }

  // 2. If a user has selected a date that they can't book online, redirect to holiday quote page

  var startdate = convertDatePremToJs(document.getElementById('StartDate').value);
  // get the last date a customer can book accommodation online;
  var lastonline = new Date();
  var firstonline = new Date();
  firstonline.setDate(firstonline.getDate() + bf_min_days_start);

  if (document.getElementById('booking-nav-hotel') && document.getElementById('booking-nav-hotel').checked == true) {
    lastonline.setMonth(lastonline.getMonth() + bf_max_months_end_accom);
  } else {
    lastonline.setMonth(lastonline.getMonth() + bf_max_months_end);
  }

  if (startdate > lastonline || startdate < firstonline) {
    document.location = bf_booking_unavailable_redirect;
    return false;
  }

  // 3. If user has selected ferries, calculate EndDate and insert into form
  if (getBookingFormType() == 'ferry-only' || (document.getElementById('booking-nav-ferry')
      && document.getElementById('booking-nav-ferry').checked == true)) {

    bookingSetEndDate();

  }

  return true;

}// end submitBooking()