// -----------------------------------------------------------------------------

/*
 * General utility functions.
*/

// correctly handle PNG transparency in Win IE 5.5 & 6.
$(document).bind("load", function correctPNG() {
   var arVersion = navigator.appVersion.split("MSIE")
   var version = parseFloat(arVersion[1])
   if ((version >= 5.5) && (document.body.filters))
   {
      for(var i=0; i<document.images.length; i++)
      {
         var img = document.images[i]
         var imgName = img.src.toUpperCase()
         if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
         {
            var imgID = (img.id) ? "id='" + img.id + "' " : ""
            var imgClass = (img.className) ? "class='" + img.className + "' " : ""
            var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
            var imgStyle = "display:inline-block;" + img.style.cssText
            if (img.align == "left") imgStyle = "float:left;" + imgStyle
            if (img.align == "right") imgStyle = "float:right;" + imgStyle
            if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
            var strNewHTML = "<span " + imgID + imgClass + imgTitle
            + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
            + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
            + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
            img.outerHTML = strNewHTML;
            i = i-1;
         }
      }
   }
});


document.onkeypress = function(evt) {
    if (evt.keyCode == 13) {
        evt.returnValue=false;
        evt.cancel = true;
        return false;
    }
    return true;
}


// simple lightbox for progress bars and page loads
function displayLightbox(lightBoxId) {
    var lightBoxDivId = "#lightbox_div_" + lightBoxId;
    var lightBoxDiv = $(lightBoxDivId);
    if(lightBoxDiv!=null && lightBoxDiv!="undefined") {
        $("#lightbox_glassPane").css("display","block");
        lightBoxDiv.fadeIn("fast");
    }
    document.location.hash = "lightbox_div_" + lightBoxId;
    
}
function hideLightbox(lightBoxId) {
    var lightBoxDivId = "#lightbox_div_" + lightBoxId;
    var lightBoxDiv = $(lightBoxDivId);
    if(lightBoxDiv!=null && lightBoxDiv!="undefined") {
        $("#lightbox_glassPane").css("display","none");
        lightBoxDiv.fadeOut("fast");
    }

}

// behaviour for header drop down menus
$(this).bind("load", function() {
  $.each(["#parking-services","#airport-parking","#travel-advice","#faq"],
     function(idx,itemId) {
       var item = $(itemId + "-nav");
       var submenu = $(itemId + "-submenu");

       item.bind("mouseover", function(evt) {
           submenu.css("display","block");
       });

       item.bind("mouseout", function(evt) {
           submenu.css("display","none");
       });
     }
  );
});


// -----------------------------------------------------------------------------

/*
 * Utility functions for use with ClickTale recording of Javascript activity.
*/

/* Simulation identification codes */
SIMULATION_NONE = 0;
SIMULATION_SUCCESS = 1;
SIMULATION_FAILURE = 2;
SIMULATION_HTTP_ERROR = 3;


/* Set up handling of ClickTale playback */
$(this).bind("load",function() {
    if(isInClickTalePlayback() && !parent.P2SIDs) {
        displayAllPanels();
    }
});


/* Determine if ClickTale playback is occurring */
function isInClickTalePlayback() {
    try {
        return parent && parent.WebPlayer;
    }
    catch(e) {
        return false;
    }
}


/* Display all panels for use when viewing Link and/or form Analytics */
function displayAllPanels() {
    //TODO: this will have problems since the different panels are fixed at
    //certain positions which will make them look bad when all displayed together
}


/* Returns true if ClickTale is recording, i.e. during normal user activity. */
function isClickTaleRecording() {
    return isClickTale("recording");
}


/* Returns true if ClickTale is performing the given action */
function isClickTale(clickTaleAction) {
    var topLocation = top.location;

    if(clickTaleAction == "recording" && window.location == topLocation) {
        return true;
    } else if(clickTaleAction == "recording" || window.location == topLocation) {
        return false;
    }

    switch(clickTaleAction.toLowerCase()) {
        case "report":
            var fn = arguments.callee;
            return fn("scroll-heatmap") || fn("click-heatmap") || fn("form-analytics");
        case "scroll-heatmap":
            var regex = new RegExp("Heatmap.aspx\?", "i");
            return regex.test(topLocation);
        case "click-heatmap":
            var regex = new RegExp("ClickHeatMap.aspx\?", "i");
            return regex.test(topLocation);
        case "form-analytics":
            var regex = new RegExp("FormAnalytics.aspx\?", "i");
            return regex.test(topLocation);
        case "playback":
            var regex = new RegExp("Player.aspx\?", "i");
            return regex.test(topLocation);
    }
}


/* Handles recording of a Javascript function call but only if ClickTale is
 * enabled and in recording mode.
 */
function clickTaleRecord(code) {
    if(typeof ClickTaleExec != 'undefined' && isClickTaleRecording()) {
        ClickTaleExec(code);
    }
}


/* Returns a null-safe value of the simulate code for asynchronous calls. */
function getSimulateCode(code) {
    if(code==null || code==undefined || code<SIMULATION_NONE || code>SIMULATION_HTTP_ERROR) {
        return SIMULATION_NONE;
    }
    return code;
}


/* Creates an AJAJ parameter block with optional ClickTale simulated playback parameters.
 *
 * paramObj is the main parameter block to pass.
 * simulateCode is an optional value denoted by the constants at the top of this file, or null if not required.
 * simulateErrorMessage is an optional error message that the server needs to return as part of simulation.
 * simulateResponseCode is an optional response code that the server needs to return as part of simulation.
 *
 * If any of the simulateX parameters are an event object which may occur when the calling function
 * is an event handler as well as being callable by ClickTale, then the parameter is excluded, as it is
 * if null or undefined.
 */
function getAjajParams(paramObj, simulateCode, simulateErrorMessage, simulateResponseCode) {
    if(paramObj==null) paramObj = new Object();

    if(isAjajParameter(simulateCode)) paramObj.simulateCode = getSimulateCode(simulateCode);
    if(isAjajParameter(simulateErrorMessage)) paramObj.simulateErrorMessage = simulateErrorMessage;
    if(isAjajParameter(simulateResponseCode)) paramObj.simulateResponseCode = simulateResponseCode;

    return paramObj;
}


/* Tests the given parameter value for null, undefined, or an event object.
 *
 * Returns true if it is none of the above and can therefore be used as an AJAJ
 * parametr, false otherwise.
 */
function isAjajParameter(paramValue) {
    if(paramValue==null || paramValue==undefined || paramValue.type) {
        return false;
    }
    return true;
}


// -----------------------------------------------------------------------------

/* Purple Parking Calendar control for Quote forms.
 *
 * The id of the departure date field must be "departureDate" and that of the
 * return date field "returnDate".  This may be fixed in a future release.
 *
 * @depends JQuery
 * @depends YUI Calendar Control
 */

/* Constants */
var DF_DAYS = new Array(
    "Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"
);

var DF_MONTHS = new Array(
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
    "Sep", "Oct", "Nov", "Dec"
);

/* Fields */
var departCal = null;
var returnCal = null;
var departureDateObj = null;
var returnDateObj = null;
var notChanged = true;
var noCalendars = false;
var mouseInDepart = false;
var mouseInReturn = false;

/* Attach the get day of year function to date objects.*/
Date.prototype.getDOY = function() {
  var onejan = new Date(this.getFullYear(),0,1);
  return Math.ceil((this - onejan) / 86400000);
}


/* Extract the day of month, month, and full year from the given date string
 * in the format dd/mm/yyyy.
 *
 * @param ddmmyyyyString the date in the dd/mm/yyyy format.
 * @return an array comprising the day of month at index 0, month at index 1,
 *         and full year at index 2.
 */
function extractDateVals(ddmmyyyyString) {
  if(ddmmyyyyString.length==9) ddmmyyyyString = "0" + ddmmyyyyString;
  if(ddmmyyyyString.length!=10) return null;

  var day = ddmmyyyyString.substring(0,2);
  var month = ddmmyyyyString.substring(3,5);
  var year = ddmmyyyyString.substring(6);
  return new Array(day, month, year );
}


/*
 * Initialises validation when calendar is not being used and instead drop
 * downs are used.
 */
function initNoCalendars() {
    noCalendars = true;
}


/* Calendar initialisation method
 *
 * @param departId is the id of the div element in which the departure date
 *        calendar is to be rendered.
 * @param returnId is the id of the div element in which the departure date
 *        calendar is to be rendered.
 */
function initCalendars(departId, returnId) {
    config = {
        mindate: new Date(),
        close: true,
        START_WEEKDAY: 1,
        strings: {
            previousMonth : "",
            nextMonth : "",
            close : ""
        }
    };

    $("#calendarDepartureDate").mouseover(function(){mouseInDepart=true});
    $("#calendarDepartureDate").mouseout(function(){mouseInDepart=false});
    $("#calendarReturnDate").mouseover(function(){mouseInReturn=true});
    $("#calendarReturnDate").mouseout(function(){mouseInReturn=false});

    $(document).mousedown(function() {
        if(departCal && !mouseInDepart) departCal.hide();
        if(returnCal && !mouseInReturn) returnCal.hide();
    });
    
    if($("#"+departId)!=null) {
        departCal = new YAHOO.widget.CalendarGroup(null,departId,config);
        departCal.hide();
        departCal.render();
        departCal.selectEvent.subscribe(function() {
          departCal.hide();
          if(returnCal) returnCal.hide();
          handleDate(departCal.getSelectedDates()[0],"#departureDate");
        });

        // handle case where date field is preset on server - copy to date object
        departureVal = $("#departure").val();
        if(departureVal!="" && departureVal!=null && departureVal!=undefined && departureVal!="dd/mm/yyyy") {
            departureVals = extractDateVals(departureVal);
            departureDateObj = new Date(departureVals[2],departureVals[1]-1,departureVals[0]);
        }

        // handle case where no date is present - set to today
        else {
            departureDateObj = new Date();
            $("#departure").val(createFormDate(departureDateObj));
        }

        $("#departureDate").val(formatQuoteDate(departureDateObj));
    }

    if($("#"+returnId)!=null) {
        returnCal = new YAHOO.widget.CalendarGroup(null,returnId,config);
        returnCal.hide();
        returnCal.render();
        returnCal.selectEvent.subscribe(function() {
            returnCal.hide();
            if(departCal) departCal.hide();
            selectedDate = returnCal.getSelectedDates()[0];
            handleDate(selectedDate,"#returnDate");
        });

        // handle case where date field is preset - copy to date object
        returnVal = $("#return").val();
        if(returnVal!="" && returnVal!="dd/mm/yyyy") {
            returnVals = extractDateVals(returnVal);
            returnDateObj = new Date(returnVals[2],returnVals[1]-1,returnVals[0]);
        }

        // handle case where no date is present - set to today + 7 days
        else {
            returnDateObj = new Date();
            returnDateObj.setDate(returnDateObj.getDate() + 7);
        }

        $("#return").val(createFormDate(returnDateObj));
        $("#returnDate").val(formatQuoteDate(returnDateObj));
    }
}


/* Displays one of the calendars whilst hiding the other.
 *
 * @param id of the date field that is to have it's calendar shown.
 */
function showCalendar(id) {
    if(id=="#departureDate" || id=="departureDate") {
        if(returnCal!=null) returnCal.hide();
        departCal.show();
    } else if(id=="#returnDate" || id=="returnDate") {
        if(departCal!=null) departCal.hide();
        returnCal.show();
    }
}


/**
 * Hides one or both calendars.  If a field id is provided then it's associated
 * calendar is hidden, if no id is specified then both calendars are hidden.
 *
 * @param id of the date field that is to have it's calendar hidden.
 */
function hideCalendar(id) {
    if(id=="#departureDate") {
        if(departCal!=null) departCal.hide();
    } else if(id=="#returnDate") {
        if(returnCal!=null) returnCal.hide();
    } else if(id==null || id==undefined || id=="") {
        if(departCal!=null) departCal.hide();
        if(returnCal!=null) returnCal.hide();
    }
}


function createFormDate(dateObj) {
    month = (dateObj.getMonth()+1);
    date = dateObj.getDate();
    return (date<10? "0"+date:date) + "/" + (month<10? "0"+month:month) + "/" + dateObj.getFullYear();
}


/* Renders the selected date from a calendar into the associated form field
 * in a nice display format, while retaining the values within this object's
 * fields.
 *
 * @param newDate the date that was selected in the calendar.
 * @param fieldId the id of the field in which the nice date is to be rendered.
 */
function handleDate(newDate, fieldId) {
    if(fieldId=="#departureDate") {
        departureDateObj = newDate;
        $("#departure").val(createFormDate(departureDateObj));
        $("#departureDate").val(formatQuoteDate(departureDateObj));

        if($("#returnDate") && (notChanged || departureDateObj.getDOY()>returnDateObj.getDOY())) {
            returnDateObj = new Date(departureDateObj);
            returnDateObj.setDate(returnDateObj.getDate()+7);

            $("#return").val(createFormDate(returnDateObj));
            $("#returnDate").val(formatQuoteDate(returnDateObj));

            returnCal.setMonth(returnDateObj.getMonth());
            returnCal.setYear(returnDateObj.getFullYear());
        }

        if($("#returnDate")) {
          returnCal.cfg.setProperty('mindate',departureDateObj,false);
          returnCal.render();
        }
    } else if(fieldId=="#returnDate") {
        returnDateObj = newDate;
        $("#return").val(createFormDate(returnDateObj));
        $("#returnDate").val(formatQuoteDate(returnDateObj));
        notChanged = false;
    }
}


/* Formats the specified date into a nice format for display in the form field.
 *
 * @param date the date to format.
 * 'return the formatted date.
 */
function formatQuoteDate(date) {
    var dayOfMonth = date.getDate();
    var month = date.getMonth();
    var year = date.getFullYear();
    var dayOfWeek = date.getDay();

    return DF_DAYS[dayOfWeek] + " " + dayOfMonth + " " + DF_MONTHS[month] + " " + year;
}


function formatPrice(amount) {
    var i = parseFloat(amount);
    if(isNaN(i)) { i = 0.00; }
    var minus = '';
    if(i < 0) { minus = '-'; }
    i = Math.abs(i);
    i = parseInt((i + .005) * 100);
    i = i / 100;
    s = new String(i);
    if(s.indexOf('.') < 0) { s += '.00'; }
    if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
    s = minus + s;
    return s;
}


/* Validates the entire quote form.
 *
 * @param bothFields must be true if the departure and return date are to be
 *        validated, otherwise only the departure date will be.
 * @return true if the form is valid, false otherwise.
 */
function validate(bothFields) {
    var isValid = true;

    if($("#airport").val()=="NONE") {
        $("#airport").focus();
        return false;
    }

    if(!noCalendars) {
        return validateCalendar(bothFields);
    } else {
        handleDropDownDates();
        return true;
    }
}


/*
 * Validates the dates selected by calendar.
*/
function validateCalendar(bothFields) {
    if(departureDateObj==null && ($("#departure").val()=="dd/mm/yyyy" || $("#departure").val()=="")) {
        alert("Please enter a departure date.");
        $("#departureDate").focus();
        departCal.show();
        return false;
    }

    if(bothFields && returnDateObj==null && ($("#return").val()=="dd/mm/yyyy" || $("#return").val()=="")) {
        alert("Please enter a return date.");
        $("#returnDate").focus();
        returnCal.show();
        return false;
    }

    if(isValidDate(departureDateObj)) {
        if(before(departureDateObj, new Date())) {
            alert("Date of departure cannot be before today!");
            $("#departureDate").focus();
            departCal.show();
            return false;
        }
    } else {
        alert("Please enter a valid date of departure.");
        $("#departureDate").focus();
        departCal.show();
        return false;
    }

    if(bothFields) {
        if(isValidDate(returnDateObj)) {
            if(before(returnDateObj, departureDateObj)) {
                alert("Your return date cannot be before your departure date!");
                $("#returnDate").focus();
                returnCal.show();
                return false;
            }
        } else {
            alert("Please enter a valid date of return.");
            $("#returnDate").focus();
            returnCal.show();
            return false;
        }
    }

    return true;
}

function before(date1, date2) {
    chk1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate(),0,0,0,0);
    chk2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(),0,0,0,0);
    return chk1 < chk2;
}


/*
 * Determines if a given date value is valid.
 *
 * @param date the date to validate.
 * @return true if the date is valid, false otherwise.
 */
function isValidDate(date) {
    if(date==null) {
        return false;
    } else {
        if(date=="NaN" || date=="Invalid Date") {
            return false;
        } else {
            return true;
        }
    }
}


/**
 * Processes the dates in the drop downs and puts the appropriate date strings
 * into the proper date fields.
*/
function handleDropDownDates() {
    departDay = parseInt($("#depDay").val());
    departDay = (departDay<9? "0" + departDay : departDay);
    departMonth = parseInt($("#depMonth").val());
    departMonth = (departMonth<9? "0" + departMonth : departMonth);
    departYear = $("#depYear").val();
    $("#departure").val(departDay+"/"+departMonth+"/"+departYear);

    returnDay = parseInt($("#retDay").val());
    returnDay = (returnDay<9? "0" + returnDay : returnDay);
    returnMonth = parseInt($("#retMonth").val());
    returnMonth = (returnMonth<9? "0" + returnMonth : returnMonth);
    returnYear = $("#retYear").val();
    $("#return").val(returnDay+"/"+returnMonth+"/"+returnYear);
}


/*
 * Submits the quote form, copying the date fields that have been set from
 * the calendar into the form fields.
 *
 * @param formId references the form to be submitted
 * @param lightBoxId an optional id of a lightbox to display
 */
function submitQuoteRequest(formId, lightBoxId) {
    if(!validate(true)) return false;

    if(lightBoxId) {
        displayLightbox(lightBoxId);
    }

    return true;
}


/*
 * Submits the quote form, copying the date fields that have been set from
 * the calendar into the form fields.
 *
 * This variant of the submitQuoteRequest() method sends a GET request in a pop-u[
 * Window.
 *
 * @param availabilityURL The URL to open in new window.
 */
function submitQuoteRequestInNewWindow(availabilityURL) {
    if(validate(true)) {
        if(availabilityURL.indexOf("?")<0) {
            availabilityURL+= "?";
        } else {
            availabilityURL+= "&";
        }

        availabilityURL+= "source=" + $("#source").val();
        availabilityURL+= "&airport=" + $("#airport").val();
        availabilityURL+= "&departure=" + $("#departure").val();
        availabilityURL+= "&return=" + $("#return").val();

        window.open(availabilityURL,"","width=1280, height=1024, status=1, toolbar=1, location=1, menubar=1, resizable=1, scrollbars=1");

        return true;
    } else {
        return false;
    }
}

/*
 * Submits the quote form, copying the date fields that have been set from
 * the calendar into the form fields.
 *
 * @param formId references the form to be submitted
 * @param parkingAndHotel denotes, if true, that there will be a return date to
 *        put into the form.
 */
function submitAPHQuoteRequest(formId, parkingAndHotel) {
    if(validate(parkingAndHotel)) {
        $("#ddd").val(departureDateObj.getDate());
        $("#ddm").val(departureDateObj.getMonth()+1);
        $("#ddy").val(departureDateObj.getFullYear());

        if(parkingAndHotel) {
            $("#rdd").val(returnDateObj.getDate());
            $("#rdm").val(returnDateObj.getMonth()+1);
            $("#rdy").val(returnDateObj.getFullYear());
        }

        $(formId).submit();
        return true;
    } else {
        alert("Please complete the form.");
        return false;
    }
}


// ----------------------------------------------------------------------------

/*
 * This lot needs removing as soon as the Fuse framework has been replaced.
 *
 * AE: 19/01/2010
 */


function setFuseAction(sAction, eTrigger)
{
    var fuseAction = eTrigger.form.elements['fuse_action'];
    if(fuseAction==null)
    {
        alert("Fuse Action is not on this form.");
    } else
    {
        fuseAction.value = sAction;
    }

    if($("#action")!=null) {
        $("#action").val(sAction);
    }
}



function setFuseActionData(sActionData, eTrigger)
{
    var fuseActionData = eTrigger.form.elements['fuse_actiondata'];
    if(fuseActionData==null)
    {
        alert("Fuse Action Data is not on this form.");
    } else
    {
        fuseActionData.value = sAction;
    }
}


function setFuseSubaction(sSubaction)
{
    var fuseSubaction = document.getElementById('fuse_subaction');
    if(fuseSubaction==null)
    {
        alert("fuse subaction is not on this page.");
    } else
    {
        fuseSubaction.value = sSubaction;
    }
}

function submitFuseForm(sActionData, eTrigger)
{
    var fuseForm = eTrigger.form;
    fuseForm.submit();
}

Fuse = {

    isValid: true,
    errorMessage: "",

    setErrorMessage: function(sErrorMessage)
    {
        Fuse.errorMessage = sErrorMessage;
    },

    setFuseAction: function(sAction, eTrigger)
    {
        var fuseAction = eTrigger.form.elements['fuse_action'];
        if(fuseAction==null)
        {
            alert("Fuse Action is not on this form.");
        } else
        {
            fuseAction.value = sAction;
        }
    },

    doAction: function(sAction, eTrigger)
    {

        if(Fuse.isValid)
        {

            var form = Fuse.getForm(eTrigger);
            var fuseAction = form.elements['fuse_action'];

            if(fuseAction==null)
            {
                alert("Fuse Action is not on this form.");
            } else
            {

                fuseAction.value = sAction;
                form.submit();
                return true;
            }

        }
        return false;
    },

    submit: function(trigger)
    {
        if(Fuse.isValid)
        {
            var form = Fuse.getForm(trigger);
            form.submit();
        }
    },

    getForm: function(element)
    {
        var parentElement = element;
        while(parentElement!=null)
        {
            if(parentElement.tagName!=null && parentElement.tagName=="FORM")
            {
                return parentElement;
            } else
            {
                parentElement = parentElement.parentNode;
            }
        }
        return null;
    }
}

