/*																																										*/
if( typeof pln == 'undefined' || typeof nvi == 'undefined' ){

	/**
	 @requires pln.js
	 @requires nvi.core.js
	 @requires class.nvi.basic.panel.js	 
	 @description if not found, alert the developers and do nothing;
	*/
	if( typeof pln == 'undefined' ) alert( "This file required the PLN Javascript Library ( pln.js ) and it need to be loaded before this file." );
	if( typeof nvi == 'undefined' ) alert( "This file required the NVI CORE ( nvi.core.js ) and it need to be loaded before this file." );
	if( typeof class_nvi_basic_panel == 'undefined' ) alert( "This file required the Class Nvi Basic Panel and it need to be loaded before this file." );

}else{


	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/**
	 @name 			Form Panel Class
	 @version		1.00
	*/
	function class_nvi_form_panel(){
		
		var _formContainerPrefix = 'nvi_modules_form_container_' ;
		var _sendingData = false ;
		var _ajaxSubmission = false ;
		var _enableFormSubmission = true ;
		var _submitBackup ;
		var _host = this ;		
		
		this.__constructor = function( $id ){
			__super.__constructor( $id ) ;
		}			
		
		this.toString = function(){ return "Nvi Form Panel Class" ; }	

		this.initialize = function(){
			
			var form = this.getElement() ;
			if( pln.isHtmlElement( form ) ){
				/*
					We hijack the form onsubmit method since this is executed 
					before any other event handler registered via event 
					registration method. (attachEvent|addEventListener). We 
					also hijack the submit method an make it point to the 
					onsubmit since a call to the submit method of a form, by 
					code, will not trigger the onsubmit event.
				*/
				
				_submitBackup = form.submit ;
				form.submit = function(){
					if( form.onsubmit() ){
						return _submitBackup.apply( form , [] ) ;
					}
				}				
				
				form.onsubmit = function(){
					if( _enableFormSubmission ){
						var formDataObject = getFormData() ;
						if( formDataObject.canSubmit ){
							_sendingData = true ;
							return _host.updateView( _host.getSharedRessources( formDataObject.data ) ) ;
						}else{
							return false ;
						}
					}else{
						nvi.eventManager.dispatchEvent( _host.getId() , nvi.eventManager.events.__triggered ) ;	
						return false ;
					}
				}
			}
			__super.initialize() ;
		}
		
		this.terminate = function(){
			__super.terminate() ;
		}		

		/**
		 @private
		 @description	We parse the form and collect name/value pair for each elements.
		 @return		Encoded JSON string representing the form (UTF-8)
		*/		
		function getFormData( validateInput ){
			var validateInput = pln.isBoolean( validateInput ) ? validateInput : true ; 
			var canSubmit = true ;
			var form = _host.getElement() ;
			// We validate if the form is an html element

			if( pln.isHtmlElement( form ) ){

				//var isTest = _host.getId() == 'optionForm' ;

				// We validate if the html element is really a form
				if( form.nodeName.toLowerCase() != 'form' ) return null ;
				
				// We create the data object which will hold the name/value pairs
				var inputCollection = {} ;
				
				// We parse the form
				for( var i = 0 ; i < form.elements.length ; i++ ){

					var item = form.elements[ i ] ;
					
					var name = item.name ;
					var id = item.id ;
					var key = !pln.isEmpty( id )? id : !pln.isEmpty( name ) ? name : null ;
					if( pln.isString( key ) ){

						// With the input id, we acquire the input class instance from the panel manager
						var instance = nvi.panelManager.getInstance( key ) ;

						if( pln.isObject( instance ) ){

							// ok, there is an instance, we can deal with the validation and other method/properties provided by the Input Class
							var value = instance.getValue() ;
							var type = instance.getType() ;
							
							var validated = !validateInput ? true : instance.validate() ;

							// If the validation return true, we can add it to the data 
							// object that we will be sending to the server
							
							
							if( !validated ){
								canSubmit = false ;
							}else{
								
								var result ;
								if( type == 'checkbox' || type == 'radio' ){
									result = { value : value , checked : instance.isChecked() } ;
								}else{
									result = value ;
								}

								if( !pln.isset( inputCollection[ name ] ) ){
									inputCollection[ name ] = result ;
								}else{
									if( pln.isArray( inputCollection[ name ] ) ){
										inputCollection[ name ].push( result ) ;
									}else{
										var current = inputCollection[ name ] ;
										inputCollection[ name ] = [] ;
										inputCollection[ name ].push( current ) ;
										inputCollection[ name ].push( result ) ;
									}
								}								
							}
							
						}else{
						
							// There is no Input Class instance for that particular input
							// so we dump the value into the object. we cannot apply validation...
							var result ;
							if( item.type.toLowerCase() == 'checkbox' || item.type.toLowerCase() == 'radio' ){
								result = { value : item.value , checked : item.checked } ; 
							}else{
								result = item.value ;
							}

							if( !pln.isset( inputCollection[ name ] ) ){
								inputCollection[ name ] = result ;
							}else{
								if( pln.isArray( inputCollection[ name ] ) ){
									inputCollection[ name ].push( result ) ;
								}else{
									var current = inputCollection[ name ] ;
									inputCollection[ name ] = [] ;
									inputCollection[ name ].push( current ) ;
									inputCollection[ name ].push( result ) ;
								}
							}
						}
					}
				}
				
				// We return the data from the form and if it can be submitted or not because of validation errors
				return { data : inputCollection , canSubmit : canSubmit } ;
			}
			return { data : null , canSubmit : false } ;
		}		
		
		/**
		 @public
		 @description	When the view of the panel is updated, we then trigger the SUCCESS event if any panel are listening
		 @return		Nothing
		*/			
		this.onUpdatedView = function( success , serverData , message ){
			if( !_sendingData ){
				// we did not send data to the server that mean that we only have updated the view.
				// and because we did update the view, we need to initialize the form again to assign fonctionnalities.
				_sendingData = false ; // we reset the var since the operation is completed
				this.initialize() ;
			}else{
				// data was sent to the server and we can analyse the response and trigger the proper event and/or do other operations.
				if( serverData.status != 'invalid_validation' ) nvi.eventManager.dispatchEvent( this.getId() , nvi.eventManager.events.__success ) ;
			}
		}		
		
		/**
		 @public
		 @description	We overwrite the basic updateView method and transform it to POST our data object to the server.
		 @return		False ; In this case, this method is the event handler of the form submission, and return false
						will cancel the form submission and page change and will enable to us to ajax it's content instead.
		*/		
		this.updateView = function( data ){
			if( _ajaxSubmission ){
				nvi.panelManager.updateView( this.getId() , data ) ;
				return false ;
			}else{
				return true ;
			}
		}
		
		/**
		 @public
		 @description	We enable submitting data via httpRequest object
		 @return		Nothing.
		*/			
		this.enableAjaxSubmission = function( enable ){
			if( pln.isBoolean( enable ) ) _ajaxSubmission = enable ;
		}
		
		this.enableFormSubmission = function( enable ){
			if( pln.isBoolean( enable ) ) _enableFormSubmission = enable ;
		}
		
		/**
		 @public
		 @description	Get the desired data and returned it( when called) to 
						the Nvi Shared Ressources Manager
		 @returns		Object ;
		*/		
		this.getSharedRessources = function( data ){
			return {
				type : 'form' ,
				id : this.getId() ,
				parameters : pln.isset( data ) ? data : getFormData().data
			} ;
		}
		
		this.submit = function(){
			this.getElement().submit() ;
		}
		
	}

	/**
	  @definition	We are extending this class with the basic panel class
	*/
	class_nvi_form_panel.extend = class_nvi_basic_panel ;

	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
}