/******************************************************
 * Author: Song Bing
 * Date: 2006.11.2
 * Purpose: Supply client form validating.
 ******************************************************/
function Validator(){		
		if( typeof( Validator.__initialized__ ) == 'undefined' ){
				// Validate controls added to this collection, if all passed, return true, otherwise false
				Validator.prototype.validate = function(){
						// Execute validation
						if( typeof( this.controls ) != 'undefined' )
								for( var i = 0 ; i < this.controls.length ; i++ )
										if( !this.controls[i].validate() )
												return false ;
												
						return true ;
				}
				// Add control
				Validator.prototype.add = function( control ){
						if( typeof( control ) == 'undefined'  )
								throw new Error( 'Argument "control" not supplied.' ) ;
						if( typeof( control ) != 'object' )
								throw new TypeError( 'Argument "control" is not a control.' ) ;
						if( typeof( control.validate ) == 'undefined' || typeof( control.validate ) != 'function' )
								throw new Error( 'Argument "control" has not a "validate" property or its "validate" property is not a function.' ) ;
								
						if( typeof( this.controls ) == 'undefined' )
								this.controls = new Array() ;
								
						this.controls.push( control ) ;
				}
				
				Validator.__initialized__ = true ;
		}
}
/**************************************************************
 *	Constructor:
 *		a. Parameters:
 *			1. textBox: required, one of controls mentioned above.
 *			2. errorMessage: optional, a customized error message 
 *				if the content of textBox is empty, if not supplied, 
 *				it will use standard message.
 *			3. name: optional, the alias of textBox for use for error message, 
 *				if not supplied, use the textBox's name; if supply errorMessage, 
 *				then not use it.
 *		b. Exeptions:
 *				if not supply textBox or it isn't a text box or text area, throw exeptions
 * validate method:
 *		a. Function:
 *			validate whether the textBox is filled in. If no, pop up alert window 
 *			and set focus to it.
 *		b. Parameters: no
 *		c. Return value: if validation pass, return true; otherwise false
 *		d. Exceptions: no
 **************************************************************/
function RequiredTextBox( textBox, errorMessage, name ){
		if( !textBox ) throw new Error( 'Argument "textBox" not supplied.' ) ;
		if( ( typeof( textBox.type ) == 'undefined' ) || 
					 ( ( textBox.type != 'text' ) && ( textBox.type != 'textarea' ) ) )
				throw new TypeError( 'Argument "textBox" is not a text box.' ) ;
		
		if( !name ) name = textBox.name ;
		if( !errorMessage ) errorMessage = 'Please fill in ' + name + '!' ;
		
		this.textBox = textBox ;
		this.errorMessage = errorMessage ;
		this.name = name ;
		
		if( typeof( RequiredTextBox.__initialized__ ) == 'undefined' ){
				// Validate method
				RequiredTextBox.prototype.validate = function(){
						if( this.textBox.value != '' ) return true ;
						
						alert( this.errorMessage ) ;
						this.textBox.focus() ;
						return false ;
				}
				
				RequiredTextBox.__initialized__ = true ;
		}
}

function RequiredDropdownList( dropdownList, emptyValue, errorMessage, name ){
		if( !dropdownList ) throw new Error( 'Argument "dropdownList" not supplied.' ) ;
		if( ( typeof( dropdownList.type ) == 'undefined' ) || ( dropdownList.type != 'select-one' ) )
				throw new TypeError( 'Argument "dropdownList" is not a dropdown list.' ) ;
				
		if( ( emptyValue == null ) || ( emptyValue == undefined ) )
				emptyValue = '0' ;
		if( !name ) name = dropdownList.name ;
		if( !errorMessage ) errorMessage = 'Please select ' + name + '!' ;
		
		this.dropdownList = dropdownList ;
		this.emptyValue = emptyValue ;
		this.errorMessage = errorMessage ;
		this.name = name ;
		
		// Mothods
		if( typeof( RequiredDropdownList.__initialized__ ) == 'undefined' ){
				RequiredDropdownList.prototype.validate = function(){
						if( this.dropdownList.value != emptyValue ) return true ;
						
						alert( this.errorMessage ) ;
						this.dropdownList.focus() ;
						return false ;
				}
				
				RequiredDropdownList.__initialized__ = true ;
		}
}

function RequiredCheckboxGroup( checkBoxGroup, errorMessage, name ){
		if( !checkBoxGroup ) throw new Error( 'Argument "checkBoxGroup" not supplied.' ) ;
//		if( typeof( checkBoxGroup.type ) == 'undefined' || 
//				   checkBoxGroup.type != 'checkbox' || typeof( checkBoxGroup.length ) == 'undefined' )
//				throw new TypeError( 'Argument "checkBoxGroup" is not check box group.' ) ;
				
		if( !name ) name = checkBoxGroup.name ;
		if( !errorMessage ) errorMessage = 'Please select at least an item of ' + name + '!' ;
		
		this.checkBoxGroup = checkBoxGroup ;
		this.errorMessage = errorMessage ;
		this.name = name ;
		
		if( typeof( RequiredCheckboxGroup.__initialized__ ) == 'undefined' ){
				RequiredCheckboxGroup.prototype.validate = function(){
						for( var i = 0 ; i < this.checkBoxGroup.length ; i++ )
								if( this.checkBoxGroup[i].checked )
										return true ;
						
						alert( this.errorMessage ) ;
						this.checkBoxGroup[0].focus() ;
						return false ;
				}
			
				RequiredCheckboxGroup.__initialized__ = true ;
		}
}
// Email validate
function EmailTextBox( textBox, errorMessage, name, customRgeExp, canEmpty ){
		if( !textBox ) throw new Error( 'Argument "textBox" not supplied.' ) ;
		if( ( typeof( textBox.type ) == 'undefined' ) || ( textBox.type != 'text' ) )
				throw new TypeError( 'Argument "textBox" is not a text box.' ) ;
		if( customRgeExp && !( customRgeExp instanceof RegExp ) )
				throw new TypeError( 'Argument "customRgeExp" is not a regular expression.' ) ;
				
		if( !name ) name = textBox.name ;
		if( !errorMessage ) errorMessage = 'The ' + name + ' format seems not correct!' ;
		if( !customRgeExp )
				customRgeExp = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/i ;
		if( canEmpty == undefined ) canEmpty = true ;
				
		this.textBox = textBox ;
		this.errorMessage = errorMessage ;
		this.name = name ;
		this.customRgeExp = customRgeExp ;
		this.canEmpty = canEmpty ;
		
		if( typeof( EmailTextBox.__initialized__ ) == 'undefined' ){
				EmailTextBox.prototype.validate = function(){
						if( ( this.textBox.value == '' && this.canEmpty ) || this.customRgeExp.test( this.textBox.value ) )
								return true ;
								
						alert( this.errorMessage ) ;
						this.textBox.focus() ;
						return false ;
				}
				EmailTextBox.__initialized__ = true ;
		}
}

function Validation( validation, errorMessage, control ){
		if( typeof( validation ) == 'undefined' )
				throw new Error( 'Argument "validation" not supplied.' ) ;
		if( typeof( validation ) != 'function' )
				throw new TypeError( 'Argument "validation" is not a function.' ) ;				
		if( ( typeof( control ) != 'undefined' ) && ( ( typeof( control.focus ) == 'undefined' ) || ( typeof( control.focus ) != 'function' ) ) )
				throw new TypeError( 'Argument "control" has not a "focus" method.' ) ;
		
		this.validation = validation ;
		this.errorMessage = errorMessage ;
		this.control = control ;
		
		if( typeof( Validation.__initialized__ ) == 'undefined' ){
				Validation.prototype.validate = function(){
						if( this.validation() )
								return true ;
						
						if( this.errorMessage )
								alert( this.errorMessage ) ;
						if( this.control )
								this.control.focus() ;
								
						return false ;
				}
			
				Validation.__initialized__ = true ;
		}
}