// This function checks the validity of a date.
// It replaces the date by a standard format of the date.

// If the optional second argument equals 1, then dates in the future are
// allowed; otherwise they are treated as an error.

// If the optional third argument is not null, then it must be a form
// control that records a code indicating partial date formats.  The
// control's value is set to 1 for a mm/dd/yyyy date, 2 for a mm/yyyy date,
// and 3 for a yyyy date.  If the third argument is not null, then a fourth
// argument must also be present, which is a control that holds the full
// date, i.e. mm/01/yyyy for a mm/yyyy date, and 01/01/yyyy for a yyyy
// date.

function DateFormat(control, future, partialDateCodeControl, partialDateHiddenControl) {
	var AllowFuture = false;
	if (arguments.length > 1 && future == 1)
		AllowFuture = true;

	var AllowPartial = false;
	var PartialCode;
	if (arguments.length > 2 && partialDateCodeControl != null)
		AllowPartial = true;

	var pdcc = null;
	var pdhc = null;
	if (AllowPartial) {
		pdcc = partialDateCodeControl;
		pdhc = partialDateHiddenControl;
	}

    var time = new Date();
	var MONTH_LENGTHS = new Array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  
    var strDate = control.value.replace(/ /g, "");

	if (strDate.length == 0) {
		if (AllowPartial) {
			pdhc.value = control.value;
			pdcc.value = 1;
		}
		return true; // Empty field is valid
	}

	// Split string at '/' characters.
  	var strDateArray = strDate.split('/');
    if (strDateArray.length > 3) {
		if (AllowPartial)
			return DateError(control, pdcc, "Please enter date as: mm/dd/yyyy, mm/yyyy or yyyy.");
		else return DateError(control, pdcc, "Please enter month, day and year as: mm/dd/yyyy.");

	}
	if (strDateArray.length != 3 && !AllowPartial)
		return DateError(control, pdcc, "Please enter month, day and year as: mm/dd/yyyy.");

	var Month, Day, Year;

	if (strDateArray.length == 3) {
		PartialCode = 1;
		Month = strDateArray[0].replace(/^0*([0-9])/, "$1");
		Day = strDateArray[1].replace(/^0*([0-9])/, "$1");
		Year = strDateArray[2].replace(/^0*([0-9])/, "$1");
	}
	else if (strDateArray.length == 2) {
		PartialCode = 2;
		Month = strDateArray[0].replace(/^0*([0-9])/, "$1");
		Year = strDateArray[1].replace(/^0*([0-9])/, "$1");
		Day = "1";
	}
	else {
		PartialCode = 3;
		Year = strDateArray[0].replace(/^0*([0-9])/, "$1");
		Month = "1";
		Day = "1";
	}

	// checks that the three elements representing month,
	// day and year are integers.
    if (!Day.match(/^\d+$/))
        return DateError(control, pdcc, "Please use only integers for the day.");

    if (!Month.match(/^\d+$/))
        return DateError(control, pdcc, "Please use only integers for the month.");

    if (!Year.match(/^\d+$/))
        return DateError(control, pdcc, "Please use only integers for the year.");

	if (PartialCode == 1)
		Year = ConvertYear(Year);  //converts to full 4 character year

	if (Year < 1800 || Year > 9999) // sql server dosn't accept years less than 1754
		return DateError(control, pdcc, "Please enter a valid 4-digit year.");

	// actual date checking
    if (Month > 12 || Month < 1)
        return DateError(control, pdcc, "The month must be in the range 1-12.");

	if (IsLeapYear(Year))
		MONTH_LENGTHS[2] = 29;

	if (Day > MONTH_LENGTHS[Month] || Day < 1) 
        return DateError(control, pdcc, "Please enter only valid days for that month.");

	// If future dates are not allowed
	if (future != 1) {
		var currYear = time.getFullYear();
		var currMonth = time.getMonth() + 1;
		var currDay = time.getDate(); 
		if ((parseInt(Year, 10) > currYear) ||
		    (parseInt(Year, 10) == currYear && parseInt(Month, 10) > currMonth) ||
		    (parseInt(Year, 10) == currYear && parseInt(Month, 10) == currMonth && parseInt(Day, 10) > currDay)) {
			return DateError(control, pdcc, "Future dates are not allowed.");
		}
    }
	  	  
	// reset field with modified month, day and year values and return
	if (Day.length < 2)
		Day = "0" + Day;
	if (Month.length < 2)
		Month = "0" + Month;
	if (PartialCode == 1) {
		control.value = Month + "/" + Day + "/" + Year;
		if (AllowPartial)
			pdhc.value = control.value;
	}
	else if (PartialCode == 2) {
		control.value = Month + "/" + Year;
		pdhc.value = Month + "/01/" + Year;
	}
	else if (PartialCode == 3) {
		control.value = Year;
		pdhc.value = "01/01/" + Year;
	}
	if (AllowPartial)
		pdcc.value = PartialCode;
	return true;
}


// This function converts a 2 digit year into a 4 digit year
function ConvertYear(year) {
	var NumYear = parseInt(year, 10);
	if (NumYear > 99) 
		return NumYear;

	if (NumYear >= 21)
		NumYear = 1900 + NumYear; 
	else NumYear = 2000 + NumYear;

	return NumYear;
}


// This function returns true if the given year is a leap year
function IsLeapYear(intYear) {
	if ((intYear % 4) != 0)
		return false;
	if ((intYear % 400) == 0)
		return true;
	if (intYear % 100 == 0)
		return false;
	return true;
}

// This function displays an error message and clears the date controls
function DateError(control, partialDateCodeControl, msg) {
	control.value = "";
	if (partialDateCodeControl != null)
		partialDateCodeControl.value = "";
	alert(msg);
	SetFocus(control);
	return false;
}

