/* 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 Fuse JS Library
 * @depends YUI Calendar Control
 * @author A Evans
 */

/* Constants */
var DF_DAYS = new Array(
    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
);

var DF_MONTHS = new Array(
    "January", "February", "March", "April", "May", "June", "July", "August",
    "September", "October", "November", "December"
);


/* Fields */
var departCal = null;
var returnCal = null;
var departureDate = "";
var departureDateObj = null;
var departureDisplayDate = "";
var returnDate = "";
var returnDateObj = null;
var returnDisplayDate = "";


/* 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 ddmmyyyyyString 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;

  var day = ddmmyyyyString.substring(0,2);
  var month = ddmmyyyyString.substring(3,5);
  var year = ddmmyyyyString.substring(6);
  return new Array(day, month, year );
}


/* 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
    };

    if($(departId)!=null) {
        departCal = new YAHOO.widget.CalendarGroup(null,departId,config);
        departCal.hide();
        departCal.render();
        departCal.selectEvent.subscribe(function() {
          departCal.hide();
          if($(returnCal)!=null) returnCal.hide();
          handleDate(departCal.getSelectedDates()[0],'departureDate');
        });

        // handle case where date field is preset - copy to date object
        departureVal = $F('departure');
        if(departureVal!="" && departureVal!=null && departureVal!=undefined && departureVal!="dd/mm/yyyy") {
            departureVals = extractDateVals(departureVal);
            departureDate = departureVal;
            departureDateObj = new Date(departureVals[2],departureVals[1]-1,departureVals[0]);
            departureDisplayDate = formatQuoteDate(departureDateObj);
        }
    }

    if($(returnId)!=null) {
        returnCal = new YAHOO.widget.CalendarGroup(null,returnId,config);
        returnCal.hide();
        returnCal.render();
        returnCal.selectEvent.subscribe(function() {
            if($(departCal)!=null) departCal.hide();
            returnCal.hide();
            selectedDate = returnCal.getSelectedDates()[0];
            handleDate(selectedDate,'returnDate');
        });


        // handle case where date field is preset - copy to date object
        returnVal = $F('return');
        if(returnVal!="" && returnVal!="dd/mm/yyyy") {
            returnVals = extractDateVals(returnVal);
            returnDate = returnVal;
            returnDateObj = new Date(returnVals[2],returnVals[1]-1,returnVals[0]);
            returnDisplayDate = formatQuoteDate(returnDateObj);
        }
    }
};


/* Displays one of the calendars whilst hiding the other.
 *
 * @param the id of the date field that is to have it's calendar shown.
 */
function showCalendar(id) {
    if(id=="departureDate") {
        if(returnCal!=null) returnCal.hide();
        departCal.show();
    } else if(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 the 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();
    }
};


/* 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) {
    month = (newDate.getMonth()+1);
    formDate = newDate.getDate() + "/" + (month<10? "0"+month:month) + "/" + newDate.getFullYear();

    if(fieldId=='departureDate') {
        departureDateObj = newDate;
        departureDate = formDate;
        departureDisplayDate = formatQuoteDate(newDate);
        $('departureDate').setAttribute("value",departureDisplayDate);
        if ($('departureDate').value !== 'dd/mm/yyyy') $('departureDate').className='text whitebg';

        if($('returnDate') && (returnDateObj==null || departureDateObj.getDOY()>returnDateObj.getDOY())) {
            $('returnDate').setAttribute("value",departureDisplayDate);
            if ($('returnDate').value !== 'dd/mm/yyyy') $('returnDate').className='text whitebg';
            returnDate = departureDate;
            returnDateObj = newDate;
            returnCal.setMonth(newDate.getMonth());
            returnCal.setYear(newDate.getFullYear());
        }

        if($('returnDate')) {
          returnCal.cfg.setProperty('mindate',newDate,false);
          returnCal.render();
        }
    } else if(fieldId=='returnDate') {
        returnDate = formDate;
        returnDateObj = newDate;
        returnDisplayDate = formatQuoteDate(newDate);
        $('returnDate').setAttribute("value",returnDisplayDate);
        if ($('returnDate').value !== 'dd/mm/yyyy') $('returnDate').className='text whitebg';
    }
};


/* 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;
};


/* 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(!$F('airport')) {
        alert("Please select an airport.");
        $('airport').focus();
        return false;
    }

    if(departureDateObj==null && (departureDate=="dd/mm/yyyy" || departureDate=="")) {
        alert("Please enter a departure date.");
        $('departureDate').focus();
        departCal.show();
        return false;
    }

    if(bothFields && returnDateObj==null && (returnDate=="dd/mm/yyyy" || returnDate=="")) {
        alert("Please enter a return date.");
        $('returnDate').focus();
        returnCal.show();
        return false;
    }

    var dtNow = new Date();
    if(isValidDate(departureDateObj)) {
        if(departureDate < dtNow) {
            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(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 isValid;
};


/*
 * 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;
        }
    }
};


/*
 * 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
 */
function submitQuoteRequest(formId, lightBoxId) {
    if(!validate(true)) return false;

    $("departure").setAttribute("value", departureDate);
    $("return").setAttribute("value", returnDate);

    if(lightBoxId) {
        displayLightbox(lightBoxId);
    }
    
    return true;
};
