/* Nexus6 Validation Library - for use exclusively with N6::JS */
var _doValidation    = 1;

/* ----------------------------------------------------------------------------------
   Function: N6DoValidation
   Description: Function which is used to turn off and on validation of a form
   Usage: onClick=N6DoValidation(0);
   Returns: Nothing
   ---------------------------------------------------------------------------------- */
function N6DoValidation(dovalidate)
{
    _doValidation = dovalidate;
}

// Start Messages for validation
var _messages        = new Array();

// Message tags for error messages generated by the script
_messages["header"]         = "The following error(s) occured:";
_messages["start"]          = "->";

_messages["required"]       = "Field [field name] is required";
_messages["requirednum"]    = "Field [field name] is required and must contain a number";
_messages["requiredemail"]  = "Field [field name] is required and must contain a valid e-mail address";
_messages["requireddate"]   = "Field [field name] is required and must contain a valid date in the form DD-MON-YYYY";

_messages["num"]            = "Field [field name] must contain a number";
_messages["email"]          = "Field [field name] must contain a valid e-mail address";
_messages["date"]           = "Field [field name] must contain a valid date in the form DD-MON-YYYY";
_messages["time"]           = "Field [field name] must contain a valid time in the form HH:MM AM/PM";
_messages["int"]            = "Field [field name] must contain a whole number";

/* Add Kitty - 15/02/07 - start
   to add a validation type - country
   ----------------------------------------------------------  */

_messages["country"]        = "Field [field name] is required";

/* ----------------------------------------------------------
   Kitty - 15/02/07 . end */


_messages["textmin"]      = "Field [field name] must consist of at least [min size] characters";
_messages["textmax"]      = "Field [field name] must not contain more than [max size] characters";
_messages["textminmax"]   = "Field [field name] must consist of at least [min size] and no more than [max size] characters";

_messages["nummin"]         = "Field [field name] must contain a number greater than [min size]";
_messages["nummax"]         = "Field [field name] must contain a number less than [max size]";
_messages["numminmax"]      = "Field [field name] must contain a number greater than [min size] and less than [max size]";

_messages["textreqmin"]   = "Field [field name] is required and must consist of at least [min size] characters";
_messages["textreqmax"]   = "Field [field name] is required and must not contain more than [max size] characters";
_messages["textreqminmax"]= "Field [field name] is required and must consist of at least [min size] and no more than [max size] characters";

_messages["numreqmin"]      = "Field [field name] is required and must contain a number greater than [min size]";
_messages["numreqmax"]      = "Field [field name] is required and must contain a number less than [max size]";
_messages["numreqminmax"]   = "Field [field name] is required and must contain a number greater than [min size] and less than [max size]";

/* ----------------------------------------------------------------------------------
   Function: N6FormValidate
   Description: Base validation function called during the onSubmit of a form
   Usage: onSubmit=return(N6Validate(frm, validateArray)
   Returns: True if form validated OK, False if not
   ---------------------------------------------------------------------------------- */
function N6FormValidate(frm, validateArray)
{
    // Allow javascript functions to turn off validation
    if(!_doValidation)
    {
        return true;
    }

    var returnVal = true;
    var errorMessage = "";
    var focused = false;

    /* Loop through the validate array, validating each element */
    for(var i=0; i<validateArray.length; i++)
    {
        var validateResult = 1;
        /* Add the "actual" object to the validate item */
        validateArray[i].actualObject = _GetFieldObject(frm, validateArray[i].fldName);
        switch(validateArray[i].fldType)
        {
            case "TEXT":
                validateResult = _ValidateText(validateArray[i]);
                break;
            case "EMAIL":
                validateResult = _ValidateEmail(validateArray[i]);
                break;
            case "NUMBER":
                validateResult = _ValidateNumber(validateArray[i]);
                break;
            case "DATE":
                validateResult = _ValidateDate(validateArray[i]);
                break;
            case "TIME":
                validateResult = _ValidateTime(validateArray[i]);
                break;
            case "INT":
                validateResult = _ValidateInt(validateArray[i]);
                break;
/* Add Kitty - 15/02/07 - start
   to add a validation type - country
   ----------------------------------------------------------  */
            case "COUNTRY":
                validateResult = _ValidateCountry(validateArray[i]);
                break;
/* ----------------------------------------------------------
   Kitty - 15/02/07 . end */
            default:
                alert("Unknown Javascript validation type: "+validateArray[i].fldtype);
                break;
        }
        if(validateResult != 1)
        {
            errorMessage += validateResult;
            returnVal = false;
            if (!focused)
            {
                if (validateArray[i].actualObject.style.display == 'none') {
                    if (typeof(tinyMCE) != 'undefined') if (tinyMCE.get(validateArray[i].fldName) && !tinyMCE.get(validateArray[i].fldName).isHidden()) 
                        tinyMCE.execCommand('mceFocus', false, validateArray[i].fldName);
                }
                else validateArray[i].actualObject.focus();
                focused = true;
            }
        }
    }
    /* Show error message if we are returning false */
    if(returnVal == false)
    {
        alert(_messages["header"].concat("\n" + errorMessage));
    }
    return returnVal;
}

/*
   ----------------------------------------------------------------------------------
   Function _ValidateText(obj)
   Description: Function which validates a "validate object" as a text field
   Usage: _ValidateText(validateArray[i])
   Returns: 1 if ok, string containing error if not OK
   ----------------------------------------------------------------------------------
*/
function _ValidateText(obj)
{
    var returnVal = 1;
    var fld = obj.actualObject;
        
    /* If exists tinymce instance, check its content */
    if (typeof(tinyMCE) != 'undefined') if (tinyMCE.get(obj.fldName) && !tinyMCE.get(obj.fldName).isHidden()) fld.value = tinyMCE.get(obj.fldName).getContent(); 

    /* If ignore, then return straight away */
    if((obj.ignoreMin != null) && obj.ignoreMin >= fld.value.length)
    {
        return 1;
    }

    /* If the max and min are defined, then error should mention both */
    if(obj.min && obj.max && (fld.value.length < obj.min || fld.value.length > obj.max))
    {
	    if(obj.ignoreMin == null) {
		    returnVal = _messages["start"] + _ParseMessage(_messages["textreqminmax"], [obj.displayName, obj.min, obj.max])+"\n";
		}
		else
		{
            returnVal = _messages["start"] + _ParseMessage(_messages["textminmax"], [obj.displayName, obj.min, obj.max])+"\n";
        }
    }
    else if (obj.min && !obj.max && (fld.value.length < obj.min))
    {
	    if(obj.ignoreMin == null)
	    {
            returnVal = _messages["start"] + _ParseMessage(_messages["textreqmin"], [obj.displayName, obj.min])+"\n";
	    }
	    else
	    {
            returnVal = _messages["start"] + _ParseMessage(_messages["textmin"], [obj.displayName, obj.min])+"\n";
        }
    }
    else if (obj.max && !obj.min && (fld.value.length > obj.max))
    {
	    if(obj.ignoreMin == null)
	    {
            returnVal = _messages["start"] + _ParseMessage(_messages["textreqmax"], [obj.displayName, obj.max])+"\n";
	    }
	    else
	    {
            returnVal = _messages["start"] + _ParseMessage(_messages["textmax"], [obj.displayName, obj.max])+"\n";
        }
    }
    else if (!obj.min && !obj.max && fld.value.length <= 0)
    {
        returnVal = _messages["start"] + _ParseMessage(_messages["required"], [obj.displayName])+"\n";
    }
    return returnVal;
}

function _ValidateNumber(obj)
{
    var returnVal = 1;
    var fld = obj.actualObject;

    if(isNaN(fld.value))
    {
        returnVal = _messages["start"] + _ParseMessage(_messages["num"], [obj.displayName])+"\n";
    }

    return returnVal;
}

function _ValidateInt(obj)
{
    var returnVal = 1;
    var fld = obj.actualObject;

    var val = fld.value;
    if(val.length < obj.min || isNaN(val) || val.indexOf('.') > 0)
    {
        returnVal = _messages["start"] + _ParseMessage(_messages["int"], [obj.displayName])+"\n";
    }

    return returnVal;
}

/* Add Kitty - 15/02/07 - start
   to add a validation type - country
   ----------------------------------------------------------  */

function _ValidateCountry(obj)
{
    var returnVal = 1;
    var fld = obj.actualObject;

    var val = fld.value;
    if(fld.value == "?")
    {
        returnVal = _messages["start"] + _ParseMessage(_messages["country"], [obj.displayName])+"\n";
    }


    return returnVal;
}

/* ----------------------------------------------------------
   Kitty - 15/02/07 . end */

function _ValidateTime(obj)
{
    var fld = obj.actualObject;
    var returnVal = 1;

    /* If ignore, then return straight away */
    if((obj.ignoreMin != null) && obj.ignoreMin >= fld.value.length)
    {
        return 1;
    }

    var regexp = /\:/;
    var timeArray = fld.value.split(regexp);

    /* If array size < 2 or > 2 return false */
    if(timeArray.length != 2)
    {
        return(_messages["start"] + _ParseMessage(_messages["time"], [obj.displayName])+"\n");
    }

    var hours = timeArray[0];
    var regexp = /\s/;
    var minsArray = timeArray[1].split(regexp);
    var mins = minsArray[0];
    var AmPm = minsArray[1];

    //alert("HOURS: '"+hours+"' MINS: '"+mins+"' AMPM: '"+AmPm+"'");

    //Check that hours/mins/ampm not null and valid
    if(hours == null || mins == null || AmPm == null)
    {
        //alert('Failed null test');
        return(_messages["start"] + _ParseMessage(_messages["time"], [obj.displayName])+"\n");
    }
    else if(hours == "" || hours.length > 2 || mins == "" || mins.length != 2 || AmPm == "" || AmPm.length > 2)
    {
        //alert('Failed string test');
        return(_messages["start"] + _ParseMessage(_messages["time"], [obj.displayName])+"\n");
    }
    else if(isNaN(hours) || isNaN(mins) || (AmPm != "AM" && AmPm != "PM"))
    {
        //alert('Failed Number/AMPM test');
        return(_messages["start"] + _ParseMessage(_messages["time"], [obj.displayName])+"\n");
    }

    if(hours.indexOf('0') == 0) {
        hours = hours.substr(1);
    }

    // Check boundary conditions
    if(parseInt(hours) < 1 || parseInt(hours) > 12 || parseInt(mins) < 0 || parseInt(mins) > 59)
    {
        //alert('Failed boundary conditions');
        returnVal(_messages["start"] + _ParseMessage(_messages["time"], [obj.displayName])+"\n");
    }
    return 1;
}

function _ValidateEmail(obj)
{
    var returnVal = 1;
    var fld = obj.actualObject;
    var emailStr = fld.value;

    /* If ignore, then return straight away */
    if((obj.ignoreMin != null) && obj.ignoreMin >= fld.value.length)
    {
        return 1;
    }

    var emailPat=/^(.+)@(.+)$/
    var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
    var validChars="\[^\\s" + specialChars + "\]"
    var quotedUser="(\"[^\"]*\")"
    var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
    var atom=validChars + '+'
    var word="(" + atom + "|" + quotedUser + ")"
    var userPat=new RegExp("^" + word + "(\\." + word + ")*$")
    var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")

    var matchArray=emailStr.match(emailPat)
    if (matchArray==null) {
       return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    }
    var user=matchArray[1]
    var domain=matchArray[2]

    if (user.match(userPat)==null) {
       return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    }
    var IPArray=domain.match(ipDomainPat)
    if (IPArray!=null) {
    	  for (var i=1;i<=4;i++) {
    	    if (IPArray[i]>255) {
    		    return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    	    }
        }
       return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    }

    var domainArray=domain.match(domainPat)
    if (domainArray==null) {
       return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    }

    var atomPat=new RegExp(atom,"g")
    var domArr=domain.match(atomPat)
    var len=domArr.length
    if (domArr[domArr.length-1].length<2 ||
        domArr[domArr.length-1].length>3) {
       return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    }

    if (len<2) {
       return _messages["start"] + _ParseMessage(_messages["email"], [obj.displayName])+"\n";
    }

    return returnVal;
}


//This function is hardwired to accept dates in the format DD-MM-YYYY.
//This needs to be changed in the near future.
function _ValidateDate(obj)
{
    var returnVal = 1;
    var fld = obj.actualObject;
	var dateArray = CreateDateArray(fld.value);

    /* If ignore, then return straight away */
    if((obj.ignoreMin != null) && obj.ignoreMin >= fld.value.length)
    {
        return 1;
    }

	var fday   = dateArray[0];
	var fmonth = dateArray[1];
	var fyear  = dateArray[2];

	//alert("DAY '"+ fday +"', MONTH '"+ fmonth +"', YEAR '"+ fyear +"'");

	//Check we have day/month/year that have been entered
	if(fday == null || fmonth == null || fyear == null || fday == "" || fday.length > 2 || fmonth == "" || fyear == "" || isNaN(fday) || isNaN(fyear) || fmonth < 1){
		//alert("DAY '"+ fday +"', MONTH '"+ fmonth +"', YEAR '"+ fyear +"'");
		return _messages["start"] + _ParseMessage(_messages["date"], [obj.displayName])+"\n";
	}

	//Remove 0's from start of numbers - can do this as we have checked the length..
	if(fday.indexOf('0') == 0){
		fday = fday.substr(1);
	}

	//Check year/date ranges are valid for dates in general
	if(parseInt(fyear) < 1000 || parseInt(fday) < 1 || parseInt(fday) > 31 || parseInt(fmonth) > 12 || parseInt(fmonth) < 1){
		//alert("DAY IS: '"+fday+"'...it reckons '"+parseInt(fday)+"' MONTH IS: '"+fmonth+"'... it reckons '"+parseInt(fmonth)+"'");
		return _messages["start"] + _ParseMessage(_messages["date"], [obj.displayName])+"\n";
	}
	//Make sure months with 30 days don't enter 31st
	if ((fmonth==4 || fmonth==6 || fmonth==9 || fmonth==11) && fday==31) {
		return _messages["start"] + _ParseMessage(_messages["date"], [obj.displayName])+"\n";
	}
	if(fmonth==2 && LeapYear(fyear) && fday > 29){
		return _messages["start"] + _ParseMessage(_messages["date"], [obj.displayName])+"\n";
	}
	else if(fmonth==2 && !LeapYear(fyear) && fday > 28){
		return _messages["start"] + _ParseMessage(_messages["date"], [obj.displayName])+"\n";
	}
	//alert("DAY '"+ fday +"', MONTH '"+ fmonth +"', YEAR '"+ fyear +"'");
	return 1;
}

<!-- StringMonthToInt function: Converts a text based month entry to its numerical equivalent. -->
<!-- 						Eg: 'JUN' -> 6						  							   -->

function StringMonthToInt(strMonth) {
	var monthArray = new Array(12);
	monthArray = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];

	var numMonth = -1;
	//Determine month as a number value (between 1-12)
	for(var i=0; i<12; i++){
		regexp = new RegExp(strMonth, "gi");
		//alert("IN LOOP on "+ monthArray[i]);
		if(regexp.test(monthArray[i])){
			numMonth = ++i;
			break;
		}
	}
	return (numMonth);
}

function CreateDateArray(dateString) {
	var regexp = /\-/;
	var dateArray = dateString.split(regexp);
	dateArray[1] = StringMonthToInt(dateArray[1]);
	return(dateArray);
}

function LeapYear(intYear) {
	if (intYear % 100 == 0) {
		if (intYear % 400 == 0) {
			return true;
		}
	}
	else {
		if ((intYear % 4) == 0) {
			return true;
		}
	}
	return false;
}

function N6StopSearch(frm, l1array, l2array, l3array, msg)
{
    var returnVal = false;
    
    var l1Count = 0;
    var l2Count = 0;
    var l3Count = 0;
    var l1Done = false;
    var l2Done = false;
    var l3Done = false;
    
    // Check level 1's
    if(l1array.length > 0 && l1array[0] != '')
    {
        l1Done = true;
        for(var i=0; i<=l1array.length; i++)
        {
            l1Count += _CheckItemForValue(frm, l1array[i]);
        }
    }
    
    // Check level 2's
    if(l2array.length > 0 && l2array[0] != '')
    {
        l2Done = true;
        for(var i=0; i<=l2array.length; i++)
        {
            l2Count += _CheckItemForValue(frm, l2array[i]);
        }
    }
    
    // Check level 3's
    if(l3array.length > 0 && l3array[0] != '')
    {
        l3Done = true;
        for(var i=0; i<=l3array.length; i++)
        {
            l3Count += _CheckItemForValue(frm, l3array[i]);
        }
    }
    
   //alert("L1: "+l1Count+"  L2: "+l2Count+"  L3: "+l3Count);
   //alert("L1: "+l1Done+"  L2: "+l2Done+"  L3: "+l3Done);
    
    if((l1Done && l1Count >= 1) ||
       (l2Done && l2Count >= 2) || 
       (l2Done && l1Done && l1Count >= 1) ||
       (l3Done && l3Count >= 3) ||
       (l3Done && l1Done && l1Count >= 1) ||
       (l3Done && l2Done && (l2Count + l3Count) >= 3) ||
       (l3Done && l1Done && l2Done && l1Count >= 1 || l2Count >= 2 || l3Count >=3))
    {
        returnVal = true;
    }
    else 
    {
        alert(msg);
    }
    return returnVal;
}

function _CheckItemForValue(frm, itemName)
{
    var re = /\s/;
    var result = 0;
    for(var i=0; i<=frm.elements.length; i++)
    {
        if(frm.elements[i] != null && frm.elements[i].name == itemName)
        {
            if(frm.elements[i].type == 'text')
            {
                var itemVal = frm.elements[i].value;
                itemVal.replace(re, "");
                if(itemVal.length > 0)
                {
                    result = 1;
                }
            }
            else if(frm.elements[i].type == 'checkbox')
            {
                if(frm.elements[i].checked)
                {
                    result = 1;
                }
            }
            else if(frm.elements[i].type == 'select-one')
            {
                var itemVal = frm.elements[i].options[frm.elements[i].options.selectedIndex].value;
                itemVal.replace(re, "");
                if(itemVal != 'BLANK' && itemVal != 'ANY' && itemVal.length > 0)
                {
                    result = 1;
                }
            }
        }
    }
    return result;
}
/* ---------------------------------------------------------------------------------- */
/* UTILITY FUNCTIONS (NOT DIRECTLY USED)                                              */
/* ---------------------------------------------------------------------------------- */
function _GetFieldObject(frm, fldName)
{
    for(var i=0; i<frm.length; i++)
    {
        if(frm.elements[i].name == fldName)
        {
            return frm.elements[i];
        }
    }
}

function _ParseMessage(msg, valueArray)
{
	//Local variables used in extracting value slots in message tag
	var valueIndex = 0;
	var counter = 0;
	var re = /\[/;
	var startOffset, endOffSet, firstHalf, lastHalf
	var noCharsArray = msg.match(re);

	//Continue to loop while there are still '[' in the string
	while(noCharsArray != null && noCharsArray.length > 0)
	{
		//Get the indexs of the start and end character
		startOffSet = msg.indexOf('[');
		endOffSet = msg.indexOf(']');

		firstHalf = msg.substr(0, startOffSet);
		lastHalf = msg.substr(endOffSet+1);
		msg = firstHalf + valueArray[valueIndex] + lastHalf;
		valueIndex++;
		noCharsArray = msg.match(re);
	}
	return msg;
}
