/* *****************************************************************************
  (C) 2004, Estudio Net Ltda. All rights reserved.

  Copy of any portion of this software is prohibited.
 
  VALIDATE.JS
***************************************************************************** */

var CHECK_IF_PRESENT	= 0x01 ; // Bit 0
var CHECK_LENGTH		= 0x02 ; // Bit 1
var CHECK_DATE			= 0x04 ; // Bit 2
var CHECK_EMAIL			= 0x08 ; // Bit 3
var CHECK_INTEGER		= 0x10 ; // Bit 4
var CHECK_FLOAT			= 0x20 ; // Bit 5
var CHECK_USERNAME		= 0x40 ; // Bit 6
var CHECK_FOR_BOOLEAN	= 0x80 ; // Bit 7

var items				= new Array() ;
var checkFunction		= new Array() ;
var errorItemIndex		= -1
var errorCode			= 0

// Error message structure (when a msg text is NOT passed)
// errorMsgPart1 + item.name + "(" + errorMsgPart2 + " " + errCode + ")"
var errorMsgPart1		= "Error on field"
var errorMsgPart2		= "errcode="

checkFunction[0]				 = doNothing ; // NO OPTION
checkFunction[CHECK_IF_PRESENT]	 = doNothing ;
checkFunction[CHECK_LENGTH]		 = checkLength ;
checkFunction[CHECK_DATE]		 = checkDate ;
checkFunction[CHECK_EMAIL]		 = checkEmail ;
checkFunction[CHECK_INTEGER]	 = checkInteger ;
checkFunction[CHECK_FLOAT]		 = checkFloat ;
checkFunction[64]				 = checkUsername ;
checkFunction[128]				 = bit7 ;

// Object used to manipulate dates.
// I don't use the embedded because NetScape does transformations
function dateStruct ( month, day, year )
{
	this.month	= month ;
	this.day	= day ;
	this.year	= year ;
}

// Constructor
function item ( field, bitmask, minRange, maxRange, fldFocus, usrMsg )
{
	this.field		= field		;
	this.bitmask	= bitmask ;
	this.minRange	= minRange	;
	this.maxRange	= maxRange	;
	this.fldFocus	= fldFocus	;
	this.usrMsg		= usrMsg ;
	this.value		= ""

	// Check for incompatible bitmask
	if ( item.bitmask & CHECK_LENGTH )
	{
		item.bitmask &= ~CHECK_INTEGER ;
		item.bitmask &= ~CHECK_FLOAT ;
		item.bitmask &= ~CHECK_DATE ;
	}
}

function addItem ( field, bitmask, minRange, maxRange, fldFocus, usrMsg )
{
	items[items.length] =
			new item ( field, bitmask, minRange, maxRange, fldFocus, usrMsg ) ;
}

function validateFields ()
{
	var index ;

	for ( index = 0 ; index < items.length ; index++ )
	{
		switch ( items[index].field.type )
		{
			case "select-one":
				items[index].value = 
						items[index].field.options[items[index].field.selectedIndex].value	 ;
				break ;
			default:
				items[index].value = items[index].field.value ;
				break ;
		}

		if ( errCode = checkField( items[index] ) )
		{
			errorItemIndex = index ;
			return errCode ;
		}
	}
	return false ;
}

function validateDisplayErrMsg ()
{
	if ( errorItemIndex == -1 )
		return ;

	with ( items[errorItemIndex] )
	{
		if 	( usrMsg.length )
			alert ( usrMsg ) ;
		else
			alert ( errorMsgPart1 + name + "(" + errorMsgPart2 + " " + errCode + ")" ) ;

		fldFocus.focus() ;
	}
}

function checkField ( item )
{
	if ( item.bitmask & CHECK_IF_PRESENT )
		if ( ! item.value.length )
			return 0 ;

	for ( bit = 1 ; bit < 8 ; bit++ )
	{
		if ( errCode = checkFunction[ (1 << bit) & item.bitmask ] ( item ) )
			return errCode ;
	}
}

function bit3( item ) { alert( "BIT 3" ) ; return false ; }
function bit5( item ) { alert( "BIT 5" ) ; return false ; }
function bit6( item ) { alert( "BIT 6" ) ; return false ; }
function bit7( item ) { alert( "BIT 7" ) ; return false ; }

// CHECK FUNCTIONS

function doNothing() { return false ; }

function checkLength ( item )
{
	if ( item.value.length ) // Removes trailing spaces *ONLY*
	{
		for ( var index = item.value.length - 1 ;
			index != -1 && item.value.charAt(index) == " " ; index-- ) ;

		if ( item.field.type == "text" )
			item.value = item.field.value = item.field.value.substring(0, index+1) ;
	}

	if ( item.value.length < item.minRange )
		return 1 ;

	if ( item.maxRange != -1 )
	{
		if ( item.value.length > item.maxRange )
			return 2 ;
	}

	return false ;
}

// The value of the field item.field.value must be passed as a
// date formatted string in the format "mm/dd/yyyy"

function checkDate ( item )
{
	var localErrCode ;
	var dateToCheck = new dateStruct() ;
	var daysOfMonth = Array( 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ) ;

	if ( localErrCode = parseDate ( item.field.value, dateToCheck ) )	
		return localErrCode ;

	if ( dateToCheck.month < 1 || dateToCheck.month > 12 )
		return 3 ;

	if ( ( dateToCheck.year ) % 4  ) // check leap year
		daysOfMonth[1] = 28 ;

	if ( dateToCheck.day < 1 ||
		 dateToCheck.day > daysOfMonth[dateToCheck.month-1] )
		return 4 ;

	return false ;
}

function parseDate ( dateStr, outputDate )
{
	var dateComponent = Array(3) ; // 0=month, 1=day, 2=year
	var xxx = 0, index, lastIndex = 0 ;

	for ( lastIndex = xxx = 0 ; xxx < 3 ; xxx++, lastIndex = index + 1 )
	{
		if ( ( index = dateStr.indexOf("/", lastIndex )) == -1 )
			index = dateStr.length ;

		dateComponent[xxx] = parseInt ( dateStr.substring( lastIndex, index ), 10 )

		if ( isNaN ( dateComponent[xxx] ) )
			return 2 ;
	}

	outputDate.month	= dateComponent[0] ;
	outputDate.day		= dateComponent[1] ;
	outputDate.year		= dateComponent[2] ;

	return false ;
}

function checkInteger ( item )
{
	var check = isNaN( parseInt( item.field.value, 10 ) )

	if ( check )
		return 1 ;

	if ( item.field.value.match( eval ( "/[^0-9]/" ) ) )
		return 2 ;

	item.field.value = parseInt( item.field.value, 10 ) ;

	if ( item.field.value < item.minRange )
		return 3 ;

	if ( item.maxRange != -1 )
	{
		if ( item.field.value > item.maxRange )
			return 4 ;
	}
	return false ;
}

function checkFloat ( item )
{
	var check = isNaN( parseFloat( item.field.value ) )
	
	if ( check )
		item.field.value = "" ;
	else
		item.field.value = parseFloat( item.field.value ) ;

	if ( item.field.value < item.minRange )
		return 3 ;
		
	if ( item.field.value > item.maxRange )
			return 4 ;

	return check ;
}

function checkEmail ( item )
{
	var result = item.field.value.match ( eval("/@/g") ) ;

	if ( result )
	{
		if ( result.length > 1) // More than 1 '@' caracter found
			return 1 ;
	} else {
		return 2 ;
	}
	
	// Check illegal characters and positions
	var expression = "/@$|^@|^\\.|\\.$|\\.{2,}|\\.@|@\\.|[^-A-Za-z0-9\\.@()]/" ;

	result = item.field.value.match( eval ( expression ) ) ;

	if ( result )
		return 3 ;

	// Check characters that MUST exist
	expression = "/\\./" ;

	result = item.field.value.match( eval ( expression ) ) ;

	if ( ! result )
		return 4 ;

	return false ;
}

function checkUsername( item )
{
	var expression = "/[^A-Za-z0-9_\\-\\.]/"
	
	result = item.field.value.match( eval ( expression ) ) ;

	if ( result )
		return 1 ;

	return false ;
}
/* EOF */

