<!-- Original:  Richard Gorremans (RichardG@spiritwolfx.com) -->
<!-- Web Site:  http://www.spiritwolfx.com -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->


// Check browser version
var isNav4 = false, isNav5 = false, isIE4 = false;
var vStrSeperator = "/"; 

// If you are using any Java validation on the back side you will want to use the / because 
// Java date validations do not recognize the dash as a valid date separator.
var vDateType = 1; // Global value for type of date format
//                1 = mm/dd/yyyy
//                2 = yyyy/dd/mm  (not supported)
//                3 = dd/mm/yyyy  (not supported)
var vYearType = 4; //Set to 2 or 4 for number of digits in the year for Netscape
var vYearLength = 4; // Set to 4 if you want to force the user to enter 4 digits for the year before validating.
var err = 0; // Set the error code to a default of zero
var keyDownVar;

if(navigator.appName == "Netscape") {
	if (navigator.appVersion < "5") {
		isNav4 = true;
		isNav5 = false;
	}
	else if (navigator.appVersion > "4") {
			isNav4 = false;
			isNav5 = true;
   	}
}
else {
	isIE4 = true;
}

function DFKeyDown(vDateName, e) 
{
	keyDownVar = vDateName.value;
	//alert(keyDownVar);
}

function DateFormat(vDateName, vDateValue, e, dateType) 
{
// vDateName = object name
// vDateValue = value in the field being checked
// e = event
// dateCheck 
// True  = Verify that the vDateValue is a valid date
// False = Format values being entered into vDateValue only
// vDateType
// 1 = mm/dd/yyyy
// 2 = yyyy/mm/dd not supported
// 3 = dd/mm/yyyy not supported

//vDateType = dateType;
vDateType = 1;
var whichCode;
//whichCode = (window.Event) ? window.event.keyCode : e.which;	// : e.keyCode;
if(window.event) {
	whichCode = window.event.keyCode;
} else if(e) {
	whichCode = e.which;
}

var shiftKey = e.shiftKey;
var ctrlKey = e.ctrlKey;

//alert(vDateValue + ", Key " + whichCode + ", char " + String.fromCharCode(whichCode) + ", shift " + shiftKey + ", ctrl " + ctrlKey);

//Enter a tilde sign for the first number and you can check the variable information.
if (vDateValue == "~") {
	alert("AppVersion = " + navigator.appVersion + " \nNav. 4 Version = " + isNav4 + " \nNav. 5 Version = " + isNav5 + " \nIE Version = " + isIE4 + " \nYear Type = " + vYearType + " \nDate Type = " + vDateType + " \nSeparator = " + strSeperator
		+ "\n Event " + whichCode );
	setDateFocus(vDateName.id);
	return true;
}

var vLen = vDateValue.length;
var didx;

if (whichCode == 8 || whichCode == 33 || whichCode == 34 || whichCode == 35 || whichCode == 36 || whichCode == 45 || whichCode == 46	//Ignore the Netscape value for backspace 8, home 36, end 35, page up 33, page down 34, insert 45, del 46.
	|| whichCode == 12 || whichCode == 13 || whichCode == 37 || whichCode == 38 || whichCode == 39 || whichCode == 40		//ignore if Enter, nav keys (37 left, 38 up, 39 right, 40 down)
	|| whichCode == 16 || whichCode == 17 || whichCode == 18 || whichCode ==20 || whichCode == 91 || whichCode == 92 || whichCode == 93	//shift, ctrl, alt, caps, win, edit
	)
	return false;
else
{

// accepts only 0 (48) to 9 (57) and #s from numeric keypad 0 (96) - 9 (105)
if ( !shiftKey && ((whichCode >= 48 && whichCode <= 57) || (whichCode >= 96 && whichCode <= 105)) )
{
	//Create numeric string values for 0123456789/
	//The codes provided include both keyboard and keypad values
	var strCheck = 'undefined,0,48,49,50,51,52,53,54,55,56,57,96,97,98,99,100,101,102,103,104,105';
	if (strCheck.indexOf(whichCode) != -1)
	{
		// input ok - auto insert /
		//alert(vDateValue + ", Event " + whichCode + ", len " + vDateValue.length);
               if (vDateType == 1)
               {
                  if (vLen == 2)  
                  {
                     vDateName.value = vDateValue + vStrSeperator;
                  }
                  if (vLen == 3)  
                  {
                  	 if (vDateValue.indexOf(vStrSeperator) == -1)
                  	 {
                     	vDateName.value = vDateValue.substring(0,2) + vStrSeperator + vDateValue.substring(2);
                     }
                  }
                  if (vLen == 5)  
                  {
                     vDateName.value = vDateValue + vStrSeperator;
                  }
                  if (vLen == 6)  
                  {
                  	 if (vDateValue.substring(5) != vStrSeperator)
                  	 {
                     	vDateName.value = vDateValue.substring(0,5) + vStrSeperator + vDateValue.substring(5);
                     }
                  }
               }
               
               if (vDateType == 2)
               {
                  if (vLen == 4)  
                  {
                     vDateName.value = vDateValue + vStrSeperator;
                  }
                  if (vLen == 7)  
                  {
                     vDateName.value = vDateValue + vStrSeperator;
                  }
               }
               
               if (vDateType == 3)
               {
                  if (vLen == 2)  
                  {
                     vDateName.value = vDateValue + vStrSeperator;
                  }
                  if (vLen == 5)  
                  {
                     vDateName.value = vDateValue + vStrSeperator;
                  }
               }
        //if (vLen == 10)	// mm/dd/yyyy - check on onBlur only
        	//return DateCheck(vDateName, vDateValue);
		return true;
	}
	else  
	{
         // If the value is not in the string return the string minus the last
         // key entered.
         if (isNav4)
         {
            vDateName.value = "";
			setDateFocus(vDateName.id);
         }
         else
         {
			if (whichCode != 16)
	            vDateName.value = vDateName.value.substr(0, (vLen-1));
         }
		return false;
	}
}
else
{
	if (whichCode == 189 || whichCode == 109)	//109FF, 189IE? - entered, treats it like a / only at certain position
	{
		didx = vDateValue.indexOf('-');
		if (didx == -1)
			didx = vDateValue.indexOf('_');
		if (didx == 2 || didx == 5)
			vDateName.value = vDateValue.substr(0, didx) + "/" + vDateValue.substr(didx+1);
		else //throw it out
			vDateName.value = keyDownVar;	//vDateValue.substr(0, didx) + vDateValue.substr(didx+1);
	}
	else if (whichCode == 191)	//accepts / only at certain position
	{
		didx = vDateValue.lastIndexOf('/');
		if ( (vLen == 3 && didx == 2) || (vLen == 6 && didx == 5) )
		{
			//alert(whichCode + ", val " + vDateValue + ", idx " + didx);
			//ok / in 2 places
		}
		else //throw it out
			vDateName.value = keyDownVar;	//vDateValue.substr(0, didx) + vDateValue.substr(didx+1);
	}
	else
	{
		//alert(whichCode + ", val " + vDateValue + ", len " + vLen);
		//vDateName.value = vDateValue.substr(0, (vLen-1));	//throw out the last char entered like backspace
		if (!ctrlKey)
			vDateName.value = keyDownVar;
	}
}

}

}

function DateCheck(vDateName, vDateValue) {
	//return true;	//for testing only
/************************************************
DESCRIPTION: Validates that a string contains only
    valid dates with 2 digit month, 2 digit day,
    4 digit year. Date separator can be ., -, or /.
    Uses combination of regular expressions and
    string parsing to validate date.
    Ex. mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy

PARAMETERS:
   strValue - String to be tested for validity

RETURNS:
   True if valid, otherwise false.

REMARKS:
   Avoids some of the limitations of the Date.parse()
   method such as the date separator character.
*************************************************/
  var objRegExp = /^\d{2}(\-|\/|\.)\d{2}\1\d{4}$/
  // the reg exp below allows for 1 or 2 digits for month or day
  //var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
  var tov;

  if (vDateValue.length == 0)
	return true;	// no check for empty input

  //alert(vDateValue);
  //check to see if in correct format
  if(!objRegExp.test(vDateValue))
  {
	alert("Invalid date format entered! Expect mm/dd/yyyy.");
	//setDateFocus(vDateName.id);
    tov = setTimeout("setDateFocus('" + vDateName.id + "');", 1);
    return false; //doesn't match pattern, bad date
  }
  else
  {
	var arrayDate = vDateValue.split(vStrSeperator); //split date into month, day, year
	//alert(arrayDate[0] + " " + arrayDate[1] + " " + arrayDate[2]);

    //create a lookup for months not equal to Feb.
    var arrayLookup = { '01' : 31,'03' : 31, '04' : 30,'05' : 31,'06' : 30,'07' : 31,
                        '08' : 31,'09' : 30, '10' : 31,'11' : 30,'12' : 31};

    var intDay = parseInt(parseFloat(arrayDate[1]));	// if not use parse float, 08 or 09 day will cause error for octal

	//check if month value and day value agree
	//alert(arrayLookup[arrayDate[0]] + ", day " + intDay);
	if (arrayLookup[arrayDate[0]] != null) {
		if (intDay <= arrayLookup[arrayDate[0]] && intDay != 0)
			return true; //found in lookup table, good date
		else
		{
  			alert("Invalid day entered!");
			//setDateFocus(vDateName.id);
    		tov = setTimeout("setDateFocus('" + vDateName.id + "');", 1);
  			return false; //any other values, bad date
		}
	}

	//check for February (bugfix 20050322)
	var intMonth = parseInt(arrayDate[0]);
	var intYear = parseInt(arrayDate[2]);
    if (intMonth == 2)
    { 
       if( ((LeapYear(intYear) && intDay <= 29) || (!LeapYear(intYear) && intDay <=28)) && intDay !=0)
          return true; //Feb. had valid number of days
		else
		{
  			alert("Invalid day entered for February!");
			//setDateFocus(vDateName.id);
    		tov = setTimeout("setDateFocus('" + vDateName.id + "');", 1);
  			return false; //any other values, bad date
		}
	}
  }

  alert("Invalid month entered!");
  //setDateFocus(vDateName.id);
  tov = setTimeout("setDateFocus('" + vDateName.id + "');", 1);
  return false; //any other values, bad date
}


function LeapYear(intYear) {
	if (intYear % 100 == 0) {
		if (intYear % 400 == 0) { return true; }
	}
	else {
		if ((intYear % 4) == 0) { return true; }
	}
	return false;
}

//set focus work around for FF and cursor at end of textbox for IE
function setDateFocus(id) {
	var control = document.getElementById(id);
	pp = control.value;
	setDFCaretPosition(id, pp.length);
}

// IE cursor jumps to begin of text so must use this fct.
function setDFCaretPosition(elemId, caretPos) {
    var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}


