/*																																										*/
if( typeof pln == 'undefined' ){

	/**
	 @requires pln.js
	 @description if not found, alert the developers and do nothing;
	*/
	alert( "This file required the PLN Javascript Library ( pln.js ) and it need to be loaded before this file." );

}else{

	if( typeof nvi == 'undefined' ){


		/**
		 @namespace nvi
		*/
		var nvi = new function(){

			var _defaultWaitingPanelId = "nvi_modules_default_waiting_panel" ;
			var _defaultWaitingPanelPrefixId = "default_waiting__" ;

			this.toString = function(){ return "Nvi Core Class" ; }

			/*																																										*/
			/**
			 @name NLM | Nvi Log Manager
			 @private
			 @version 1.20
			*/
			var NLM = new function(){

				var _messageCollection = [] ;
				var _console ;
				var _list ;
				var _consoleEnabled = false ;
				
				if( /ENABLE-NVI-CONSOLE/gi.test( top.location.href ) ){
					_consoleEnabled = true ;
					// We generate the console is the key is detected in the url
					void pln.events.addListener( document , '__documentReady' , null , initializeConsole ) ;
				}
				
				// We create a pointer to pln.node.setProperty in order to maximize file weight
				var set = pln.node.setProperty ;
				
				function generateConsole(){
				
					// We should use the layer class but it's not done yet
					_console = pln.node.add( pln.node.create( 'div' ) , document.body ) ;
					
					var head = pln.node.add( pln.node.create( 'div' ) , _console ) ;
					var btn = pln.node.add( pln.node.create( 'span' ) , head ) ;
					var title = pln.node.add( pln.node.create( 'span' ) , head ) ;
				
					void set( title , 'innerHTML' , '<strong>NVI DEBUG CONSOLE</strong> ~ Version 1.00' ) ;
					void set( btn , 'innerHTML' , '[ minimize ]' ) ;
					void set( btn , 'cursor' , 'pointer' ) ;
					void set( btn , 'marginRight' , '10px' ) ;
					
					_list = pln.node.add( pln.node.create( 'div' ) , _console ) ;
					
					void set( _console , 'display' , 'none' );
					void set( _console , 'position' , 'absolute' );
					void set( _console , 'width' , '600px' );
					void set( _console , 'height' , '800px' );
					void set( _console , 'background' , '#444444' );
					void set( _console , 'color' , '#ffffff' );
					void set( _console , 'fontFamily' , 'Verdana,Arial' );
					void set( _console , 'fontSize' , '10px' );
					void set( _console , 'overflow' , 'auto' );
					void set( _console , 'right' , '10px' );
					void set( _console , 'top' , '10px' );
					void set( _console , 'border' , '2px solid #000000' );					

					void set( head , 'padding' , '10px' );
					void set( _list , 'padding' , '10px' );
					
					void pln.events.addListener( btn , 'click' , null , toggle , btn ) ;
					
				}

				/**
				 @public
				 @description	Toggle the display of the debug console.
				 @returns		Nothing ;
				*/
				function toggle( eventObject , btn ){
					var display = pln.node.getProperty( _list , 'display' ) ;
					void set( _list , 'display' , display == 'none' ? 'block' : 'none' ) ;
					void set( btn , 'innerHTML' , display == 'none' ? '[ minimize ]' : '[ maximize ]' ) ;
					void set( _console , 'height' , display == 'none' ? '800px' : '' );
				}

				/**
				 @private
				 @description	We generate a container for the message and add it to the console
				 @returns		Nothing
				*/				
				function addMessageToConsole( $message ){
					var item = pln.node.add( pln.node.create( 'div' ) , _list ) ;
					void set( item , 'borderBottom' , '1px solid #000000' );
					void set( item , 'padding' , '5px 0px' );
					void set( item , 'innerHTML' , $message );
				}

				/**
				 @public
				 @description	This method is used to log message
				 @returns		Nothing
				*/
				this.log = function( $message , $type , $class , $method ){
					if( _consoleEnabled && pln.isString( $message ) ){
						
						var message = '' ;
						if( pln.isString( $type ) ){
							var type_color = "#000000";
							if( $type == 'Event' ) type_color = "#228B22" ;
							if( $type == 'Error' ) type_color = "#CC0000" ;
							if( $type == 'Core' ) type_color = "#000000" ;
							if( $type == 'Instanciation' ) type_color = "#0099CC" ;
							if( $type == 'Warning' ) type_color = "#FF6905" ;
							if( $type == 'Report' ) type_color = "#8B008B" ;
							message += "<span style='padding:2px 5px;margin-right:5px;background:" +type_color+ ";'>[ " + $type + " ]</span> " ;
						}
						if( pln.isString( $class) ) message += $class + " " ;
						if( pln.isString( $method ) ) message += '.' + $method + "()<br />" ;
						if( message.indexOf( '<br />' ) != -1 ) message += '&nbsp;&nbsp;&nbsp;->&nbsp;' ;
						message += $message ;
						
						void _messageCollection.push( ":: " + message ) ;
						if( pln.isHtmlElement( _console ) ){
							var new_message = _messageCollection[ _messageCollection.length-1 ] ;
							/*
								if we detect that we are in an iframe, we try to log information into the 
								console that is on the top frame, the main console since we dont want to have
								multiple console embeded in small viewport.
							*/
							if( window.location.href != top.location.href && pln.isset( top.nvi ) ){
								void top.nvi.logManager.log( new_message ) ;
							}else{
								void addMessageToConsole( new_message ) ;
							}
						}
					}
					return null ;
				}

				/**
				 @public
				 @description	We initialized this panel and assign keydown event listener
				 @returns		Nothing
				*/
				function initializeConsole(){
					if( !pln.isHtmlElement( _console ) ){
						if( window.location.href != top.location.href && pln.isset( top.nvi ) ){
							if( !pln.isEmpty( _messageCollection ) ){
								for( var i = 0 ; i < _messageCollection.length ; i++ ) void top.nvi.logManager.log( _messageCollection[ i ] ) ;
							}							
						}else{
							generateConsole() ;
							// Populate console with existing messages.
							if( !pln.isEmpty( _messageCollection ) ){
								for( var i = 0 ; i < _messageCollection.length ; i++ ) void addMessageToConsole( _messageCollection[ i ] ) ;
							}
							// Display console
							void set( _console , 'display' , 'block' );							
						}
					}
				}
				//
				this.log( 'Nvi Log Manager initiated' , 'Core' );
			}
			
			/*																																										*/			
			/*																																										*/			
			/**
			 @name NSRM | Nvi Shared Ressources Manager
			 @private
			 @version 1.00
			*/
			var NSRM = new function(){
				
				var _ressources = {} ;
				
				/**
				 @public
				 @description	We register panels id to a group id.
				 @returns		Nothing ;
				*/
				this.registerToGroup = function( groupId ){
					var itemCollection = pln.argsToArray( arguments , 1 ) ;
					var collection = _ressources[ groupId ] ;
					if( !pln.isObject( collection ) ) _ressources[ groupId ] = {} ;
					for( var i = 0 ; i < itemCollection.length ; i++ ){
						_ressources[ groupId ][ i ] = itemCollection[ i ] ;
					}
				}

				/**
				 @public
				 @description	We remove panels ids(previously registered panels id) from a group id.
				 @returns		Nothing ;
				*/				
				this.unregisterFromGroup = function( groupId ){
					var itemCollection = pln.argsToArray( arguments , 1 ) ;
					if( !pln.isObject( collection ) ) return null ;
					for( var i = 0 ; i < itemCollection.length ; i++ ){
						var member = _ressources[ groupId ][ itemCollection[ i ] ] ;
						if( pln.isset( member ) ) delete _ressources[ groupId ][ itemCollection[ i ] ] ;
					}
				}				

				/**
				 @public
				 @description	We call the getSharedRessources method of each panel instance registered 
								to a group and return the gathered data in an array.
				 @returns		Array ;
				*/
				this.getRessources = function( groupId , exceptionObject ){
					var group = _ressources[ groupId ] ;
					if( pln.isset( group ) ){
						var ressources_collection = [] ;					
						for( var i in group ){
							var id = group[ i ] ;
							var instance = NPM.getInstance( id ) ;
							if( pln.isObject( instance ) && pln.isFunction( instance.getSharedRessources ) ){
								var ressources = instance.getSharedRessources() ;
								if( pln.isObject( ressources ) ){
									if( ( pln.isObject( exceptionObject ) && exceptionObject.id != ressources.id )  || !pln.isObject( exceptionObject ) ) void ressources_collection.push( ressources ) ;
								}
							}
						}
					}
					return pln.isEmpty( ressources_collection ) ? null : ressources_collection ;
				}
				
				/**
				 @public
				 @description	Create a collection of group id where the selected ressource is 
								registered, very usefull if you dont know anything about a panel 
								and still want to get the data he is sharing with other panels.
				 @returns		Array ;
				*/				
				this.getGroupByRessourceId = function( ressourceId ){
					if( pln.isString( ressourceId ) ){
						var collection = [] ;
						for( var i in _ressources ){
							var group = _ressources[ i ] ;
							for( var j in group ){
								if( group[ j ] == ressourceId ) collection.push( i ) ;
							}
						}
						return collection ;
					}else{
						return null ;
					}
				}
			}
			
			
			/*																																										*/			
			/**
			 @name NEM | Nvi Event Manager
			 @private
			 @version 1.00
			*/
			var NEM = new function(){
				
				var _eventCollection = {} ;
				
				/**
				 @definition Events constant
				*/
				var _events = {
					__updating : 'updating' ,
					__ready : 'ready' ,
					__success : 'success' ,
					__opened : 'opened' ,
					__closed : 'closed' ,
					__changed : 'change' ,
					__validationFailed : 'validation_fail' ,
					__validationSucceeded : 'validation_succeeded',
					__triggered : 'triggered'
				};
				// Publicize the constant event collection
				this.events = _events ;

				/**
				 @public
				 @description	This the panel event dispatcher
				 @returns		Nothing
				*/
				this.dispatchEvent = function( $id , $eventName , $multilevel ){
					
					// The multilevel variable is just being used by us.
					// If the multilevel is set to true, we allso dispatch to all for the specified event name
					var multilevel = pln.isBoolean( $multilevel )? $multilevel : true ;
				
					if( !pln.isString( $id ) || !pln.isString( $eventName ) ){
						if( !pln.isString( $id ) ) NLM.log( 'The panel id is undefined' , 'Error' , 'Nvi Event Manager' , 'dispatchEvent' );
						if( !pln.isString( $eventName ) ) NLM.log( 'The event name is undefined' , 'Error' , 'Nvi Event Manager' , 'dispatchEvent' );
					}else{
						// Execute spacial cases
						if( $id != 'all' ) void executeSpecialCase( $id , $eventName ) ;
						if( !pln.isObject( _eventCollection[ $id ] ) ){
							//
							NLM.log( 'There is no listener registered to the '+ $eventName +' event of ' + ( $id == 'all' ? 'all panels' : 'the '+ $id +' panel' ) , 'Event' , 'Nvi Event Manager' , 'dispatchEvent' );
							
						}else{
							var callbackCollection = _eventCollection[ $id ][ $eventName ] ;
							if( !pln.isArray( callbackCollection ) || ( pln.isArray( callbackCollection ) && pln.isEmpty( callbackCollection ) ) ){
								//
								NLM.log( 'There is no listener registered to the '+ $eventName +' event of the '+ $id +' panel' , 'Event' , 'Nvi Event Manager' , 'dispatchEvent' );
								
							}else{
								//
								NLM.log( 'Dispatching to listener registered to the '+ $eventName +' event of ' + ( $id == 'all' ? 'all panels' : 'the '+ $id +' panel' ) , 'Event' , 'Nvi Event Manager' , 'dispatchEvent' );
								for( var i = 0 ; i < callbackCollection.length ; i++ ) pln.dispatch( callbackCollection[ i ].scope , callbackCollection[ i ].callback ) ;
							}
							if( multilevel ) void this.dispatchEvent( 'all' , $eventName , false ) ;
						}
					}
				}

				/**
				 @private
				 @description	This method is called via the dispatchEvent method is to work with special cases.
				 @returns		Nothing
				*/
				function executeSpecialCase( $id , $eventName ){
					// Special case for the waiting event, by default we show the assign default waiting panel.
					if( $eventName == _events.__updating ){
						
						var instance = null ;
						var element = null ;
						try{
							instance = NPM.getInstance( $id ) ;
							element = instance.getElement() ;
						}catch( e ){}
						
						if( pln.isObject( instance ) ){
							// If this instance have custom waiting panel registered to it, do not display the default waiting panel
							if( pln.isHtmlElement( instance.getCustomWaitingPanel() ) ) return ;
						}
						
						var defaultPanelId = _defaultWaitingPanelPrefixId + $id ;
						if( pln.isHtmlElement( element ) ){

							// We create a pointer to the getProperty method of the pln.node class since we use 
							// it alot and want to save on the weight of the file
							var _get = pln.node.getProperty ;

							// set width and height of the default waiting panel to reflect the width and height of the actual panel
							var width = _get( element , 'offsetWidth' ) ;
							var height = _get( element , 'offsetHeight' ) ;
							
							// We acquire the border width and the padding on each side of the default waiting panel since these will interfere with the
							// new width and height we will assign to the waiting panel and we need to substract these numbers
							var borderTop = _get( defaultPanelId , 'border-top-width') ;
							var borderRight = _get( defaultPanelId , 'border-right-width') ;
							var borderBottom = _get( defaultPanelId , 'border-bottom-width') ;
							var borderleft = _get( defaultPanelId , 'border-left-width') ;
							
							var paddingLeft = _get( defaultPanelId , 'padding-left') ;
							var paddingRight = _get( defaultPanelId , 'padding-right') ;
							var paddingBottom = _get( defaultPanelId , 'padding-bottom') ;
							var paddingTop = _get( defaultPanelId , 'padding-top') ;
							
							if( isNaN( borderTop ) ) borderTop = 0 ;
							if( isNaN( borderRight ) ) borderRight = 0 ;
							if( isNaN( borderBottom ) ) borderBottom = 0 ;
							if( isNaN( borderleft ) ) borderleft = 0 ;
							
							if( isNaN( paddingLeft ) ) paddingLeft = 0 ;
							if( isNaN( paddingRight ) ) paddingRight = 0 ;
							if( isNaN( paddingBottom ) ) paddingBottom = 0 ;
							if( isNaN( paddingTop ) ) paddingTop = 0 ;

							void pln.node.setProperty( defaultPanelId , 'width' , ( width - borderRight - borderleft - paddingLeft - paddingRight ) + 'px' );
							void pln.node.setProperty( defaultPanelId , 'height' , ( height - borderTop - borderBottom - paddingTop - paddingBottom ) + 'px' );
						
						}
						
						void pln.node.setProperty( defaultPanelId , 'display' , 'block' ) ; // This should not be 'block' because we dont know if the element was of type inline or block
						//
						void NLM.log( 'Displaying the default waiting panel for the ' + $id + ' panel' , 'Event' , 'Nvi Event Manager' , 'executeSpecialCase' );
					}
					// Special case for the ready event, by default we hide the assign default waiting panel.
					if( $eventName == _events.__ready ){
						void pln.node.setProperty( _defaultWaitingPanelPrefixId + $id , 'display' , 'none' );
						//
						void NLM.log( 'Hiding the default waiting panel for the ' + $id + ' panel' , 'Event' , 'Nvi Event Manager' , 'executeSpecialCase' );
					}					
				}

				/**
				 @public
				 @description	This method will register an function to be executed when a certain events occurs on a certain element.
				 @returns		Nothing
				*/		
				this.addListener = function( $triggerId , $eventName , $callBackScope , $callBackFunction ){

					if( !pln.isString( $triggerId ) ){
						//
						void NLM.log( 'The trigger id is not defined or not valid' , 'Error' , 'Nvi Event Manager' , 'addListener' );
						return null ;
					}
					
					// if the all trigger id is detected, set it to lowecase for later validation
					if( $triggerId.toLowerCase() == 'all' ) $triggerId = 'all';
					
					if( !pln.isObject( _eventCollection[ $triggerId ] ) ) _eventCollection[ $triggerId ] = {} ;
					if( !pln.isArray( _eventCollection[ $triggerId ][ $eventName ] ) ) _eventCollection[ $triggerId ][ $eventName ] = [] ;
					if( !pln.isFunction( $callBackFunction ) ){
						//
						void NLM.log( 'The callback method is undefined for the ' + $eventName + ' event of the ' + $triggerId + ' panel' , 'Error' , 'Nvi Event Manager' , 'addListener' );
					}else{
						void _eventCollection[ $triggerId ][ $eventName ].push( { scope : $callBackScope , callback : $callBackFunction } );
					}
				}
				
				//
				void NLM.log( 'Nvi Event Manager initiated' , 'Core' );
			}
			
			
			/*																																										*/
			/**
			 @name NACM | Nvi Ajax Connection Manager
			 @private
			 @version 1.00
			*/
			var NACM = new function(){
				
				var _connectionCollection = {} ;
				
				/**
				 @public
				 @description	This method will register an function to be executed when a certain events occurs on a certain element.
				 @returns		Object ; An object containing a connection and a status variable
				*/					
				this.getConnection = function( $instanceId ){
				
					var connectionObject = null ;
					// Since this is the basic ajax method, all getway url is the current window url.
					
					// We remove all element after the Hash (#)
					var temporaryUrl = window.location.href.replace( window.location.hash , '' ) ;
					var connectionUrl =  temporaryUrl + ( temporaryUrl.indexOf( '?' ) !=-1 ? '&' : '?' ) + "render_only=" + $instanceId ;
					
					if( !NPM.instanceExist( $instanceId ) ){
						//
						void NLM.log( 'There is no panel instance with the selected id: ' + $instanceId , 'Error' , 'Nvi Ajax Connection Manager' , 'getConnection' );
					}else{
						// We always use the post method
						var method = 'POST' ;
						// If the connection object do not already exist, create one
						if( !pln.isObject( _connectionCollection[ $instanceId ] ) ){
							connectionObject = _connectionCollection[ $instanceId ] = {
								inUsage : false ,
								connection : new pln.server.connection( connectionUrl , method )
							}
						}else{
							connectionObject = _connectionCollection[ $instanceId ] ;
							if( !connectionObject.inUsage ){
								connectionObject.connection = new pln.server.connection( connectionUrl , method ) ;
							}
						}
					}
					return connectionObject ;
				}
				
				/**
				 @public
				 @description	This is use to abort the ajax connection. The abort method is available on all browser
								so if the bvrowser do not support it, we simply do not return any data from the server.
								We make it act as if the connection was dead. The clearConnection method is mainly used
								by the cancelUpdateView method of the panelManager.
				 @returns		Nothing ;
				*/				
				this.clearConnection = function( $instanceId ){
					if( !NPM.instanceExist( $instanceId ) ){
						//
						void NLM.log( 'There is no panel instance with the selected id: ' + $instanceId , 'Error' , 'Nvi Ajax Connection Manager' , 'clearConnection' );
					}else{
						// If the connection object exist, cancel the connection and remove cached connection data
						var connectionObject = _connectionCollection[ $instanceId ] ;
						if( pln.isObject( connectionObject ) ){
							void connectionObject.connection.abort();
							delete _connectionCollection[ $instanceId ] ;
						}
					}
				}				
				
				//
				void NLM.log( 'Nvi Ajax Connection Manager initiated' , 'Core' );				
			}						

			/*																																										*/
			/**
			 @name NPM | Nvi Panel Manager
			 @private
			 @version 1.00
			 @
			*/
			var NPM = new function(){
				
				var _instanceCollection = {} ;
				var _host = this ;
				
				/**
				 @private
				 @description	This will clone the default waiting panel of the framework and add it just 
								after the html element that represent the panel
				 @returns		Element (html element); The cloned waiting panel or null if the cloning operation failed.
				*/
				function copyDefaultWaitingPanel( $id , $element ){
				
					// Validate if a copy already exist
					if( pln.isHtmlElement( pln.node.getById( _defaultWaitingPanelPrefixId + $id ) ) ){
						//
						void NLM.log( 'There is already a default waiting panel for the '+ $id +' panel' , 'Report' , 'Nvi Panel Manager' , 'copyDefaultWaitingPanel' );
					}else{
						var panel = pln.node.getById( _defaultWaitingPanelId ) ;
						if( !pln.isHtmlElement( panel ) ){
							//
							void NLM.log( 'There is no default waiting panel rendered in the current html page' , 'Warning' , 'Nvi Panel Manager' , 'copyDefaultWaitingPanel' );
						}else{
							// We clone the default waiting panel
							var clone = pln.node.clone( panel ) ;
							
							// We change its id else it will generate errors since id must be unique							
							void pln.node.setProperty( clone , 'id' , _defaultWaitingPanelPrefixId + $id ) ;
							
							// We then add the clonded html element just after the html element that represent the specified panel
							return pln.node.add( clone , pln.node.getParent( 1 , pln.node.getById( $id ) ) , pln.node.getById( $id ) , false ) ;
						}
					}
					return null ;
				}
				
				/**
				 @public
				 @description	Remove whitespace from id
				 @returns		String ; Return a clean id
				*/
				function cleanupId( $id ){
					if( pln.isString( $id ) ) return $id.replace( /\s+/gi, '' ) ;
					return $id ;
				}
				
				/**
				 @public
				 @description	Return this planel class instance related to the selected id
				 @returns		Object ; Return the class instance
				*/
				this.getInstance = function( $id ){
					$id=cleanupId( $id ) ;
					var instance = this.instanceExist( $id )? _instanceCollection[ $id ] : null ;
					if( pln.isNull( instance ) ){
						// Check if the instance exist at the top window.
						if( window.location.href != top.location.href && pln.isset( top.nvi ) ){
							return top.nvi.panelManager.getInstance( $id ) ;
						}
						else{ return null ; }
					}
					else{ return instance ; }
				}
				
				/**
				 @public
				 @description	Valid if there is an instance liked to the selected id
				 @returns		Boolean ;
				*/				
				this.instanceExist = function( $id ){
					$id=cleanupId( $id ) ;
					return pln.isObject( _instanceCollection[ $id ] ) ;
				}
				
				/**
				 @public				
				 @description	We instanciate class here
				 @returns		Object ; Return the class instance
				*/				
				this.createInstance = function( $id , $constructor , $virtual ){
					$id=cleanupId( $id ) ;
					var virtual = pln.isBoolean( $virtual ) ? $virtual : false ;
					
					// Validation if the instance of the selected class already exist
					if( this.instanceExist( $id ) ){
						//
						void NLM.log( 'There is already a panel instance with the selected id: ' + $id + ' of type ' + pln.getFunctionName( $constructor ) + '. Id must be unique! The first instance with the selected id will be returned' , 'Warning' , 'Nvi Panel Manager' , 'createInstance' );
						
						var instance = this.getInstance( $id ) ;
						try{
							// Since we re-assign content to the panel, and there is already nodes in memory
							// The content will be duplicated... we must remove the actual content.
							// This may cause error if we do not push any content... the panel will be empty...
							void instance.removeAllContent( true ) ;
						}catch( errorObject ){}
						return instance ;

					}else{

						//
						_instanceCollection[ $id ] = pln.compiler.createClass( $constructor , $id ) ;
						
						// Validation if the class was well instanciated
						if( !pln.isObject( _instanceCollection[ $id ] ) ){
							//
							void NLM.log( 'Unable to instanciate the '+ $id +' panel of type '+ pln.getFunctionName( $constructor ) , 'Error' , 'Nvi Panel Manager' , 'createInstance' );							
							return null ;
						}
						
						NLM.log( 'Instanciation of ' + $id + ' ( ' + _instanceCollection[ $id ] + ' )' , 'Instanciation' );

						// If the instance is not only virtual copy the default waiting panel and 
						// add it just after the instance html element representation node.
						var element = pln.node.getById( $id ) ;							
						if( pln.isHtmlElement( element ) && !virtual ){
							var defaultWaitingPanel = copyDefaultWaitingPanel( $id , element ) ;
							if( !pln.isHtmlElement( defaultWaitingPanel ) ){
								void NLM.log( 'Unable to copy the default waiting panel for the '+ $id +' panel' , 'Warning' , 'Nvi Panel Manager' , 'createInstance' );
							}
						}
						// return the instance
						return _instanceCollection[ $id ] ;
					}
				}

				/**
				 @public				
				 @description	This is the basic method to update the view of a panel
				 @returns		Nothing
				*/
				this.updateView = function( $instanceId , $data ){
				
					// Get the class ID
					var instance = this.getInstance( $instanceId ) ;
					var instanceId = $instanceId ;
					
					// Validate if ID is a string ( we never know )
					if( !pln.isString( $instanceId ) ){
						//
						void NLM.log( 'The instance is not a valid instance of a panel' , 'Error' , 'Nvi Panel Manager' , 'updateView' );
						return;
					}

					// Get a new ajax connection
					var connectionObject = NACM.getConnection( instanceId ) ;
					
					// If the connection is already in use cancel the execution of the code
					if( connectionObject.inUsage ) return ;
					
					// Set the usage flasg to true so any call will be canceled until the connection is done
					connectionObject.inUsage = true ;
					
					// Connection event handler
					connectionObject.connection.onLoad = function( success , serverData , message ){
						// Set the usage flasg to true so any call will be canceled until the connection is done
						connectionObject.inUsage = false ;
						
						// If success is true means that the javascript has succeeded to connect to the server and load data
						if( success ){
							// Decode the data received form the server. The data returned from the 
							// server in the updateView method must always return Json string
							var dataObject = pln.decode( serverData );
							if( !pln.isObject( dataObject ) ){
								//
								void NLM.log( 'The returned serverData must be a json string ( Panel id: ' + instanceId + ' )' , 'Error' , 'Nvi Panel Manager' , 'updateView' );
							}else{
								
								if( pln.isString( dataObject.dataHtml ) ){
									// Remove Javascript comments
									dataObject.dataHtml = dataObject.dataHtml.replace( /\/\*(\s|.)*?\*\//gi , '' ).replace( /\/\/.*/gi , '' ) ;
									
									// Remove html comments
									dataObject.dataHtml = dataObject.dataHtml.replace( /<!--(\s|.)*?-->/gi , '' ) ;
																		
									// Remove all link tag
									dataObject.dataHtml = dataObject.dataHtml.replace( /<link(\s|\w)*[^>]*>/gi , '' ) ;
								}

								// We remove any javascript from the received server data, execpt thos coded on element using events
								var scriptObject = pln.extractScriptFromSource( dataObject.dataHtml , true ) ;
								
								// We now have a clean data source
								var sourceWithNoJavascript = scriptObject.source ;
								
								// We also obtain an Array of script, not that script tag are remove and that we 
								// cannot add javascript file to the header of the document that way.
								var scriptCollection = scriptObject.scripts ;

								// We need to remove the container node from the returned data before pasting 
								// the new html into the container.
								var startRegexp = /^\s*<(\w*)\b[^<]*>/ ;
								void sourceWithNoJavascript.match( startRegexp ) ;
								var nodeName = RegExp.$1 ;
								if( !pln.isEmpty( nodeName ) ){
									try{
										var endRegexp = new RegExp( "<\\s?\/\\s?" + nodeName + ">\\s*$" , "i" ) ;
										if( !pln.isNull( sourceWithNoJavascript.match( endRegexp ) ) ){
											sourceWithNoJavascript = sourceWithNoJavascript.replace( startRegexp , '' ) ;
											sourceWithNoJavascript = sourceWithNoJavascript.replace( endRegexp , '' ) ;
										}
									}catch( errorObject ){}
								}
								
								// Set the html receive by the server into the panel element
								try{ void pln.node.setProperty( instanceId , 'innerHTML' , sourceWithNoJavascript ); }
								catch( errorObject ){
									// innerHTML can generate errors!?
									// Yes, if in ie6 & ie7 , if we add a form element using innerHTML, it generates an error( Unknown runtime error )
								}

								// Display the panel
								void pln.node.setProperty( instanceId , 'display' , '' ) ; // This should not be 'block' because we dont know if the element was of type inline or block

								// Dispatch the ready event since the html element have successfully been updated
								void NEM.dispatchEvent( instanceId , NEM.events.__ready ) ;

								// Call this onUpdateView of the selected panel and transfert

								var instance = _host.getInstance( instanceId ) ;
								void pln.dispatch( instance, instance.onUpdatedView , success , dataObject , message ) ;

								// We now execute all javascript found in the server source
								void pln.evalScriptCollection( scriptCollection ) ;
							}
						}else{
							//
							void NLM.log( 'Ajax connection failed, error message = ' + message , 'Error' , 'Nvi Panel Manager' , 'updateView' );
						}						
						
					}

					// Dispatch the waiting event
					void NEM.dispatchEvent( instanceId , NEM.events.__updating ) ;

					// Hide the selected panel
					void pln.node.setProperty( instanceId , 'display' , 'none' );
					
					$data = pln.isset( $data ) ? $data : null ;
					var sharedData = NSRM.getRessources( NSRM.getGroupByRessourceId( instanceId ) , $data ) ;
					sharedData = pln.isset( sharedData ) ? sharedData : null ;

					void connectionObject.connection.sendAndLoad( pln.encode( { data : $data , sharedData : sharedData } ) );
				}
				
				/**
				 @public				
				 @description	This cancel the basic update method
				 @returns		Nothing
				*/				
				this.cancelUpdateView = function( $instance ){
				
					// Get the class ID
					var instanceId = $instance.getId() ;
					
					// Validate if ID is a string ( we never know )
					if( !pln.isString( instanceId ) ){
						//
						void NLM.log( 'The instance is not a valid instance of a panel' , 'Error' , 'Nvi Panel Manager' , 'cancelUpdateView' );
						return;
					}
					
					// Clear the ajax connection
					void NACM.clearConnection( instanceId ) ;
								
					// Display the panel
					void pln.node.setProperty( instanceId , 'display' , '' ); // This should not be 'block' because we dont know if the element was of type inline or block
								
					// Dispatch the ready event in order to remove the waiting panel...
					void NEM.dispatchEvent( instanceId , NEM.events.__ready );

				}				
				
				//
				void NLM.log( 'Nvi Panel Manager initiated' , 'Core' );
			}
			
			
			
			/*																																										*/		
			/**
			 @description public pointer to the private class NLM
			*/
			this.logManager = NLM ;

			/**
			 @description public pointer to the private class NEM
			*/			
			this.eventManager = NEM ;			


			/**
			 @description public pointer to the private class NPM
			*/			
			this.panelManager = NPM ;
			
			/**
			 @description public pointer to the private class NSRM
			*/
			this.sharedRessourcesManager = NSRM ;
			
		
			this.getDefaultWaitingPanelPrefixId = function(){
				return _defaultWaitingPanelPrefixId ;
			}
		
		}
	}
}