// If true, empty fields are OK. Can be overridden for each field.
var defaultEmptyOK = true;
var required = false;
var optional = true;
var dateFO = 0;
var dateMDY = 1;
var dateANSI = 2;
var todayOrLater = 1;
var anyDate = 0;

// whitespace characters
var whitespace = " \t\n\r";

// Decimal point character differs by language and culture.
var decimalPointDelimiter = "."

// Returns true if string s is empty.
function isEmpty(s)
{
	return ((s == null) || (s.length == 0));
}

// Returns true if string s is empty or whitespace characters only.
function isWhitespace (s)
{   var i;

    // Is s empty?
    if (isEmpty(s)) return true;
    // Search through string's characters one by one
    // until we find a non-whitespace character.
    // When we do, return false; if we don't, return true.
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);

        if (whitespace.indexOf(c) == -1) return false;
    }
    // All characters are whitespace.
    return true;
}

// Returns true if character c is a digit (0 .. 9).
function isDigit (c)
{
	return ((c >= "0") && (c <= "9"));
}

// isInteger (STRING s [, BOOLEAN emptyOK])
// Returns true if string s is an unsigned integer. 
function isInteger (s)
{
	var i;

    if (isEmpty (s)) 
       if (isInteger.arguments.length == 1) return defaultEmptyOK;
       else return (isInteger.arguments[1] == true);
    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if (!isDigit(c)) return false;
    }
    // All characters are numbers.
    return true;
}

// isFloat (STRING s [, BOOLEAN emptyOK])
// Returns true if string s is an unsigned floating point (real) number. 
// Also returns true for unsigned integers.
// Does not accept exponential notation.
// DS 3 June 2000 Allow commas
function isFloat (s)

{   var i;
    var seenDecimalPoint = false;

    if (isEmpty(s)) 
       if (isFloat.arguments.length == 1) return defaultEmptyOK;
       else return (isFloat.arguments[1] == true);

    if (s == decimalPointDelimiter) return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true;
        else if ((c != ',') && !isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}

// isIntegerInRange (STRING s, INTEGER a, INTEGER b [, BOOLEAN emptyOK])
// Returns true if string s is an integer 
// within the range of integer arguments a and b, inclusive.
function isIntegerInRange (s, a, b)
{
	if (isEmpty(s)) 
       if (isIntegerInRange.arguments.length == 3) return defaultEmptyOK;
       else return (isIntegerInRange.arguments[3] == true);

    // Catch non-integer strings to avoid creating a NaN below,
    // which isn't available on JavaScript 1.0 for Windows.
    if (!isInteger(s, false)) return false;

    // Now, explicitly change the type to integer via parseInt
    // so that the comparison code below will work both on 
    // JavaScript 1.2 (which typechecks in equality comparisons)
    // and JavaScript 1.1 and before (which doesn't).
    // Without radix, a number like 08 is assumed to be octal and evaluates to 0.
    var num = parseInt (s, 10);
	//alert ('iIR: str=' + s + '; val=' + num);
    return ((num >= a) && (num <= b));
}

// isYear (STRING s [, BOOLEAN emptyOK])
// Returns true if string s is a valid SQL Server year
function isYear (s)
{
	if (isEmpty(s)) 
       if (isYear.arguments.length == 1) return defaultEmptyOK;
       else return (isYear.arguments[1] == true);
    return isIntegerInRange (s, 1753, 9999);
}

// isMonth (STRING s [, BOOLEAN emptyOK])
// Returns true if string s is a valid month number between 1 and 12.
function isMonth (s)
{
	if (isEmpty(s)) 
       if (isMonth.arguments.length == 1) return defaultEmptyOK;
       else return (isMonth.arguments[1] == true);
    return isIntegerInRange (s, 1, 12);
}

// isDay (STRING s [, BOOLEAN emptyOK])
// Returns true if string s is a valid day number between 1 and 31.
function isDay (s)
{
	if (isEmpty(s)) 
       if (isDay.arguments.length == 1) return defaultEmptyOK;
       else return (isDay.arguments[1] == true);   
    return isIntegerInRange (s, 1, 31);
}

// daysInFebruary (INTEGER year)
// Given integer argument year, returns number of days in February of that year.
function daysInFebruary (year)
{
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}

var daysInMonth = new Array (0,31,29,31,30,31,30,31,31,30,31,30,31);

// isDate (STRING year, STRING month, STRING day)
// Returns true if string arguments year, month, and day form a valid date. 
function isDate (year, month, day)
{
	// Catch invalid years, months and days
    if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(year, 10);
    var intMonth = parseInt(month, 10);
    var intDay = parseInt(day, 10);

    // Catch invalid days in month, except for February
	if (intDay > daysInMonth[intMonth]) return false; 
    if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

    return true;
}

// Notify user that contents of field theField are invalid.
// String s describes expected contents of theField.value.
// Put select theField, put focus in it, and return false.
function warnInvalid (theField, s)
{
	theField.focus ();
    theField.select ();
    alert (s);
	//theField.focus ();	//Retains focus on MSIE v4 after tab
    return false;
}

/* FUNCTIONS TO CHECK VARIOUS FIELDS */

var iString = "This field must not be empty."
var iWhite = "This field shouldn't just be spaces."
var iInteger = "This field must be a number."
var iFloat = "This field must contain a number. It may include a decimal point."

function checkString (theField, emptyOK)
{   // Next line is needed on NN3 to avoid "undefined is not a number" error
    // in equality comparison below.
    if (checkString.arguments.length == 1) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if (isWhitespace(theField.value))
		if (emptyOK == true)
			return warnInvalid (theField, iWhite);
		else
 			return warnInvalid (theField, iString);
   else return true;
}

function checkFloat (theField, emptyOK)
{
	if (checkFloat.arguments.length == 1) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if (!isFloat(theField.value, false)) 
       return warnInvalid (theField, iFloat);
    else return true;
}

function checkInteger (theField, emptyOK)
{
	if (checkInteger.arguments.length == 1) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if (!isInteger (theField.value, false)) 
       return warnInvalid (theField, iInteger);
    else return true;
}

var iAnsiDate = "This field must be a date in the form yyyy-mm-dd."
var iFODate = "This field must be a date in the form dd/mm/yyyy."
var iMdyDate = "This field must be a date in the form mm/dd/yyyy."
var iBadDate = "Unknown date format."
var iYear = "The year must be a number between 1753 and 9999."
var iMonth = "The month must be a number between 1 and 12."
var iDay = "The day must be a number between 1 and 31."
var iDate = "This day, month and year do not form a valid date."
var iNoEarlier = "This date must be no earlier than today."

function checkDate (theField, fmt, startDate, emptyOK)
{
	var sy, sm, sd, ss;
	
	if (theField.value == '') return true;
	
	if (checkDate.arguments.length == 3) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    //We support three styles, depending on fmt
    if (fmt == dateFO)
	{
		if (theField.value.indexOf ("/") == -1)	//No slashes
		{
			if (theField.value.length == 8) //ddmmyyyy
			{
				sd = theField.value.substring (0, 2);
				sm = theField.value.substring (2, 4);
				sy = theField.value.substring (4, 8);
			}
			else
			{
				return warnInvalid (theField, iFODate);
			}
		}
		else
		{
			ss = theField.value.split ("/");
			if (ss.length != 3)
			{
				return warnInvalid (theField, iFODate);
			}
			sd = ss[0];
			sm = ss[1];
			sy = ss[2];
		}
	}
	else if (fmt == dateMDY)
	{
		if (theField.value.indexOf ("/") == -1)	//No slashes
		{
			if (theField.value.length == 8) //mmddyyyy
			{
				sm = theField.value.substring (0, 2);
				sd = theField.value.substring (2, 4);
				sy = theField.value.substring (4, 8);
			}
			else
			{
				return warnInvalid (theField, iMdyDate);
			}
		}
		else
		{
			ss = theField.value.split ("/");
			if (ss.length != 3)
			{
				return warnInvalid (theField, iMdyDate);
			}
			sm = ss[0];
			sd = ss[1];
			sy = ss[2];
		}
	}
   else if (fmt == dateANSI)
    {
		if (theField.value.indexOf ("-") == -1)	//No hyphens
		{
			//alert ("Length " + theField.value.length);
			if (theField.value.length == 8) //yyyymmdd
			{
				sy = theField.value.substring (0, 4);
				sm = theField.value.substring (4, 6);
				sd = theField.value.substring (6, 8);
				//alert ("ymd " + sy + "|" + sm + "|" + sd);
			}
			else
			{
				return warnInvalid (theField, iAnsiDate);
			}
		}
		else
		{
			ss = theField.value.split ("-");
			if (ss.length != 3)
			{
				return warnInvalid (theField, iAnsiDate);
			}
			sy = ss[0];
			sm = ss[1];
			sd = ss[2];
		}
	}
	else
	{
		return warnInvalid (theField, iBadDate);
	}
	
	if (!isYear (sy)) return warnInvalid (theField, iYear);
	if (!isMonth (sm)) return warnInvalid (theField, iMonth);
	if (!isDay (sd)) return warnInvalid (theField, iDay);
	if (!isDate (sy, sm, sd)) return warnInvalid (theField, iDate);
	
	if (startDate == todayOrLater)
	{
		var today, y, m, d;
		var theDate;
		
		today = new Date ();
		y = today.getFullYear ();
		m = today.getMonth ();	
		d = today.getDate ();	
		today = new Date (y, m, d);
		theDate = new Date (parseInt (sy, 10), parseInt (sm, 10) - 1, parseInt (sd, 10));
		if (theDate < today)
		{
			return warnInvalid (theField, iNoEarlier);
		}
	}

	if (sd.length == 1) sd = "0" + sd;
	if (sm.length == 1) sm = "0" + sm;
	if (fmt == dateFO)	//Standardise format
	{
		theField.value = sd + "/" + sm + "/" + sy;
	}
	else if (fmt == dateMDY)
	{
		theField.value = sm + "/" + sd + "/" + sy;
	}
	else
	{
		theField.value = sy + "-" + sm + "-" + sd;
	}
	return true;
}

var iAnsiTime = "This field must be a time in the 24hr format (hh:mm)."
var iHour = "The hour must be a number between 00 and 23."
var iMinute = "The minute must be a number between 00 and 59."

function checkTime (theField, emptyOK)
{
	var sh, sm;
	
	if (checkTime.arguments.length == 1) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if ((theField.value.length != 5) || (theField.value.substring (2, 3) != ':'))
		return warnInvalid (theField, iAnsiTime);

	sh = theField.value.substring (0, 2);
	sm = theField.value.substring (3, 5);

    if (!isIntegerInRange (sh, 0, 23, false)) return warnInvalid (theField, iHour);
    if (!isIntegerInRange (sm, 0, 59, false)) return warnInvalid (theField, iMinute);

	return true;
}

function CheckVenueIsSelected(sender,arg){

	if ((document.getElementById('txtVenuePref1').value.toUpperCase() != 'NO PREFERENCE') || (document.getElementById('txtVenuePref2').value.toUpperCase() != 'NO PREFERENCE') || (document.getElementById('txtVenuePref3').value.toUpperCase() != 'NO PREFERENCE')) 
	{
		arg.IsValid = true;
	}else
	{
		arg.IsValid = false;
	}
}
