﻿//  Minimum exit offset, comparing serialised date-times (e.g. entry "200905010300", exit "200905010400")
// Months and days are one based, i.e. the above examples are for 1st of May 2009

var minExitOffset = 100;  // If you change this, also change the relevant error message!

//  Set as global, for later setting and reference
var minEntryDateTime = "";

// debug boolean. if set set to true, messages are logged to the console log
var debug = false;

// How many days do months have? Note: zero-based!
// Have included 3 letter month code for debugging purposes
var daysInMonth = [
        [31, "Jan"],
        [28, "Feb"],
        [31, "Mar"],
        [30, "Apr"],
        [31, "May"],
        [30, "Jun"],
        [31, "Jul"],
        [31, "Aug"],
        [30, "Sep"],
        [31, "Oct"],
        [30, "Nov"],
        [31, "Dec"]
    ];

var errors = new Array();

/**
*  Dropdown Date-Time
*  Takes date and time obj refs and then concatenates their
*  values into a simple "CCYYMMDDHHmm" string.
*  Last modified: 2011-07-20 {dn}
*/
function dropdownDateTime(textDate, dropdownTime) {

    var textDateArr = textDate.split('/');
    var dropdownTimeArr = dropdownTime.split(':');

    var dropdownDateTime = textDateArr[2] + textDateArr[1] + textDateArr[0] + dropdownTimeArr[0] + dropdownTimeArr[1];

    return dropdownDateTime;
}

/**
* Takes string created by dropdownDateTime ("CCYYMMDDHHmm")
* and works out whether this date is valid (i.e. exists).
* Returns true if valid, false if not.
*
*/
function checkValidDate(dateStr) {
    // extract year, month and date from date string
    var dateYear = parseInt(dateStr.substr(0, 4), 10);
    var dateMonth = parseInt(dateStr.substr(4, 2), 10);
    var dateDay = parseInt(dateStr.substr(6, 2), 10);

    //if (debug) { console.log("year, month, day = " + dateYear + ' | ' + dateMonth + ' | ' + dateDay); }

    if (isNaN(dateYear) || isNaN(dateMonth) || isNaN(dateDay)) {
        //if (debug) { console.log("Date is NOT valid"); }
        return false;
    }
    else {
        // Adjust daysInMonth array for leap years. This needs to be calculated 
        // every time the date is checked to be valid, as it's only really relevant (and 
        //    correct!) if the date that is being checked is in February
        if (dateYear % 4 == 0) {
            daysInMonth[1][0] = 29;
            if (dateYear % 100 == 0 && dateYear % 400 != 0) {
                daysInMonth[1][0] = 28;
            }
        }

        // What is the last day of the month being checked
        var lastDay = daysInMonth[(dateMonth - 1)][0];

        //if (debug) { console.log("last day for month " + lastDay); }

        // is the day in dateStr earlier or the same as last valid day
        if (dateDay <= lastDay) {
            //if (debug) { console.log("Date is valid"); }
            return true;
        }
        else {
            //if (debug) { console.log("Date is NOT valid"); }
            return false;
        }
    }
}

/**
*  Takes a date in string format "CCYYMMDDHHmm"
*  and returns the day start datetime.
*/
function calculateTodayDayStart(today) {
    var year = today.substr(0, 4);
    var month = today.substr(4, 2);
    var day = today.substr(6, 2);

    //if (debug) { console.log("calculated today date: " + day + ' / ' + month + ' / ' + year); }

    return year + month + day + '0000';
}

/**
*  Compare Date-Times
*  Compares one date-time string to another, returns the offset.
*  Last modified: 2011-07-20 {dn}
*/
function compareDateTimes(lowerDateTime, upperDateTime) {

    var lowerInt = parseInt(lowerDateTime);
    var upperInt = parseInt(upperDateTime);
    var diffInt = (upperInt - lowerInt);

    return (diffInt);

}

/**
*  Check Date-Times
*  Compiles the two user-input date-times into integers and checks
*  them against various mandatory conditions (min entry, min exit).
*  Last modified: 2011-07-20 {dn}
*/
function checkDateTimes() {

    var userEntryDateTime = dropdownDateTime($('#carParkEntry input:text').val(), $('#carParkEntry select').val());
    var userExitDateTime = dropdownDateTime($('#carParkExit input:text').val(), $('#carParkExit select').val());
    var userDateTimeDiff = compareDateTimes(userEntryDateTime, userExitDateTime);

    //if (debug) { console.log("userEntryDateTime: " + userEntryDateTime); }
    //if (debug) { console.log("userExitDateTime: " + userExitDateTime); }
    //if (debug) { console.log("userDateTimeDiff: " + userDateTimeDiff); }
    //if (debug) { console.log("userDateTimeDiff: " + minEntryDateTime); }
    
    var today = calculateTodayDayStart(minEntryDateTime);
    //if (debug) { console.log("calculated today string: " + today); }

    // check entry date
    
    if ($('#carParkEntry input:text').val() != '') {
        // Is it a valid date?
        if (checkValidDate(userEntryDateTime)) {
            // Is it before today?
            if (userEntryDateTime < today) {
                errors.push("Please select an entry date after today's date.");
            }
            else {
                // if entry date is today
                if (userEntryDateTime < minEntryDateTime) {
                    errors.push("Bookings cannot be made for an arrival less than 3 hours from now. However, spaces are available on the day at the drive-up price.\n\nYou also cannot book for a time earlier than now.");
                }
            }
        }
        else {
            errors.push("Please enter a valid entry date.");
        }
    }
    else {
        // no entry date selected
        errors.push("Please select the date when you wish to enter the car park.");
    }

    // check exit date

    // is an exit date selected?
    if ($('#carParkExit input:text').val() != '') {
        // is the exit date valid?
        if (checkValidDate(userExitDateTime)) {
            // Is it before today?
            if (userExitDateTime < today) {
                errors.push("Please select an exit date after today's date.");
            }
            else {
                // is it an hour later than entry time?
                if (userDateTimeDiff < minExitOffset) {
                    errors.push("Please select an exit date that is after the entry date.");
                }
            }
        }
        else {
            errors.push("Please enter a valid exit date.");
        }
    }
    else {
        // no exit date selected
        errors.push("Please select the date when you wish to exit the car park.");
    }

    if ($('#carParkExit select').val() == '') {
        // no exit time selected
        errors.push("Please select the time when you wish to exit the car park.");
    }


    var len = errors.length;

    if (debug) { console.log("number of errors: " + len); }

    // if there are no errors, submit the form
    if (len == 0) {
        return true;
    }
    else {
        // if there are errors, concatenate them & alert them 
        var errorStr = '';
        for (var i = 0; i < len; i++) {
            errorStr += errors[i] + '\n\n';
        }
        alert(errorStr);

        // Clear out the array so the same errors don't keep being
        // shown even after you've corrected them.
        for (var j = 0; j < len; j++) {
            errors.pop();
        }
        errorStr = '';

        // and stop form from submitting
        return false;
    }
}

//  Bind onload [jQuery]
$(function() {
    var entryDate = $('#carParkEntry input:text');
    var exitDate = $('#carParkExit input:text');
    
    entryDate.val(entryDate.attr('title'));
    exitDate.val(exitDate.attr('title'));
    
    entryDate.click(function() {
        if (entryDate.val() == entryDate.attr('title')) {
            entryDate.val('');
        }
    });
    
    exitDate.click(function() {
        if (exitDate.val() == exitDate.attr('title')) {
            exitDate.val('');
        }
    });
    
    if ($('#airportParking .control input:submit')) {

        //  Get min date-time as set by server-side code in hidden input
        minEntryDateTime = $(':input.carParkMinEntry').val();

        //  Validate and then compare entry and exit date-times on attempted form submission
        $('#airportParking .control input:submit').click(function(ev) {
            return checkDateTimes();
            ev.preventDefault();
        });
    }

});

