/**
* @ADD_TO_DOCUMENTATION
* @FILE
* @name			Nvi Core
* @file			nvi.core.source.js
* @date 		10:29 AM Thursday, July 08, 2010
* @version		1.0
* @requires		pln.js
*/
if( typeof pln == 'undefined' ){
	alert( "nvi\nThis file required the PLN Javascript Library ( pln.js ) and it need to be loaded before this file." );
}else{
	if( !pln.isset( nvi ) ){

	
		/* ********************************************************************************
		* @ADD_TO_DOCUMENTATION
		* @CLASS
		* @name 		Nvi
		* @date			10:37 AM Thursday, July 08, 2010
		* @version 		1.00
		* @description	This object is not a class that can be instanciated. It is a core 
		*				library object that is running behind the different panel. It is used 
		*				to centralize code.
		*
		* @extends		None
		*/	
		var nvi = new function(){

			var _defaultWaitingPanelId = "nvi_modules_default_waiting_panel" ;
			var _defaultWaitingPanelPrefixId = "default_waiting__" ;

			/**
			* @ADD_TO_DOCUMENTATION
			* @METHOD
			* @name					toString
			* @version 				1.16
			* @description			This method is automatically called when this object is to 
			*						be represented as a text value.
			*
			* @usage				alert( [ nvi ] ) ;
			* @return				String. A string representing the object.
			* @dispatch				Nothing
			* @throw				Nothing
			*/	
			this.toString = function(){
				return "Nvi Core" ;
			} ;

			/**
			* @ADD_TO_DOCUMENTATION
			* @METHOD
			* @name							CreateModal
			* @version 						1.54
			* @description					This method is a shortcut, a way to reduce the size of the 
			*								inline javascript printed to the html document.
			*
			* @usage						void nvi.CreateModal( id , width , height , contentCollection , dragCollection , openCollection , closeCollection , scrollPane , disable , init ) ;
			*
			* @argument id					String. The unique identifier that represent the instance panel.
			* @argument width				Number. The desired width of the modal.
			* @argument height				Number. The desired height of the modal.
			* @argument contentCollection	Array. An array of html element id that will serve as content of the modal.
			* @argument dragCollection		Array. An array of element that will serve as drag handle in order to drag the modal
			* @argument openCollection		Array. An array of element that will serve as open control for the modal
			* @argument closeCollection		Array. An array of element that will serve as close control for the modal
			* @argument scrollPane			String. The id of the element that will serve as the scrollpane of the modal.
			* @argument disable				Boolean. true to disable the closing of the modal by clicking on the overlay
			* @argument init				Boolean. True if you want to run the initialize method, should always be set 
			*								to true, except in special cases.
			*
			* @return						Nothing
			* @dispatch						Nothing
			* @throw						Nothing
			*/
			this.CreateModal = function( id , width , height , contentCollection , dragCollection , openCollection , closeCollection , maximizeCollection , minimizeCollection , scrollPane , disable , init ){
				var modal = nvi.panelManager.createInstance( id , class_nvi_modal_panel , true ) ;
				void modal.setDimension( width , height ) ;
				void modal.pushContent( id ) ;
				for( var i = 0 ; i < contentCollection.length ; i++ ) void modal.pushContent( contentCollection[ i ] ) ;
				for( var i = 0 ; i < dragCollection.length ; i++ ) void modal.registerIdAsDragHandle( dragCollection[ i ] ) ;
				for( var i = 0 ; i < openCollection.length ; i++ ) void modal.registerIdAsOpenButton( openCollection[ i ] ) ;
				for( var i = 0 ; i < closeCollection.length ; i++ ) void modal.registerIdAsCloseButton( closeCollection[ i ] ) ;
				for( var i = 0 ; i < maximizeCollection.length ; i++ ) void modal.registerIdAsMaximizeButton( maximizeCollection[ i ] ) ;
				for( var i = 0 ; i < minimizeCollection.length ; i++ ) void modal.registerIdAsMinimizeButton( minimizeCollection[ i ] ) ;
				if( pln.isString( scrollPane ) ) void modal.registerIdAsScrollPane( scrollPane ) ;
				if( disable ) void modal.disableOverlayInteraction() ;
				if( init ) void modal.initialize() ;
			} ;
						
			/**
			* @ADD_TO_DOCUMENTATION
			* @METHOD
			* @name							CreateIframe
			* @version 						1.54
			* @description					This method is a shortcut, a way to reduce the size of the 
			*								inline javascript printed to the html document.
			*
			* @usage						void nvi.CreateIframe( id , url ) ;
			*
			* @argument id					String. The unique identifier that represent the instance panel.
			* @argument url					String. The url that will be displayed when the iframe modal is initialzied
			*
			* @return						Nothing
			* @dispatch						Nothing
			* @throw						Nothing
			*/			
			this.CreateIframe = function( id , url ){
				var iframe = nvi.panelManager.createInstance( id , class_nvi_iframe_panel ) ;
				void iframe.setUrl( url ) ;
			} ;
			
			/**
			* @ADD_TO_DOCUMENTATION
			* @METHOD
			* @name							CreateToggle
			* @version 						1.52
			* @description					This method is a shortcut, a way to reduce the size of the 
			*								inline javascript printed to the html document.
			*
			* @usage						void nvi.CreateToggle( id , viewCollection , triggerEvent , animateFunction , groupId , isDefault , enableCookie , enableCloseAllView , init ) ;
			*
			* @argument id					String. The unique identifier that represent the instance panel.
			* @argument viewCollection		Array. A collection of views that will be controlled by the toggle control
			* @argument triggerEvent		String. 
			* @argument animateFunction		Function. A function that served to animate the opening and closing of the views, 
			*								by default, there is no animation.
			* @argument groupId				String. A unique identifier that represent a group.
			* @argument isDefault			Boolean. Set to true if you want the toggle to be opened upon instanciation
			* @argument enableCookie		Boolean. Set to true if you want the state of the toggle to be saved in a cookie.
			* @argument enableCloseAllView	String. The id of the group that will change the rule of closing elements
			* @argument init				Boolean. Set to true if we initialize this module.
			*
			* @return						Nothing
			* @dispatch						Nothing
			* @throw						Nothing
			*/
			this.CreateToggle = function( id , viewCollection , triggerEvent , animateFunction , groupId , isDefault , enableCookie , enableCloseAllView , init ){
				var toggle = nvi.panelManager.createInstance( id , class_toggle_control , true  ) ;
				for( var i = 0 ; i < viewCollection.length ; i++ ){
					var viewObject = pln.decode( viewCollection[ i ] ) ;
					void toggle.assignView( viewObject.viewId , viewObject.enableAjaxUpdate , viewObject.updateAjaxUrl , viewObject.updateFrequency ) ;
				}
				if( pln.isString( triggerEvent ) ) void toggle.setTriggerEvent( triggerEvent ) ;
				if( pln.isFunction( animateFunction ) ) toggle.animate = animateFunction ;
				if( pln.isString( groupId ) ) void toggle.registerToGroup( groupId ) ;
				if( isDefault ) void toggle.setAsDefault() ;
				if( enableCookie ) void toggle.enableCookieState( true ) ;
				if( pln.isString( enableCloseAllView ) ){
					void class_toggle_control.enableCloseAllView( enableCloseAllView ) ;
				}
				if( init ) void toggle.initialize() ;
			} ;
			

			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION
			* @CLASS
			* @name 			Nvi Log Manager
			* @date				10:42 AM Thursday, July 08, 2010
			* @version 			1.20
			* @extends			None
			* @description		This class is used to deal with logging usefull information
			*					and control the Nvi console
			* @note 		
			* @see			
			*/			
			var NLM = new function(){

				var _messageCollection = [] ;
				var _console ;
				var _list ;
				var _consoleEnabled = false ;
				var _window			= window;
				var _mainConsole 	= true;
				
				try{
					var _mainConsole 	= window.location.href == top.location.href ;
					var _window			= top;
				}catch( error ){
					
				}

				/*
				* We generate the console only if the key is detected in the url. If the 
				* console is generated. If there is no console, no message is logged into 
				* the messages collection in order to save ressources.
				*/				
				if( /ENABLE-NVI-CONSOLE/gi.test( _window.location.href ) ){
					_consoleEnabled = true ;
					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 ;
				
				/**
				* @ADD_TO_DOCUMENTATION
				* @METHOD
				* @name					toString
				* @version 				1.16
				* @description			This method is automatically called when this object is to 
				*						be represented as a text value.
				*
				* @usage				alert( [ nvi.logManager ] ) ;
				* @return				String. A string representing the object.
				* @dispatch				Nothing
				* @throw				Nothing
				*/	
				this.toString = function(){
					return "Nvi Log Manager" ;
				} ;				
				
				/**
				* @METHOD
				* @name					generateConsole
				* @version 				1.16
				* @description			Generate the nvi console when it is detected in the url.
				*
				* @usage				void generateConsole() ;
				*
				* @note					This method must be called within the scope of the class.
				*
				* @return				Nothing
				* @dispatch				Nothing
				* @throw				Nothing
				*/
				function generateConsole(){
					_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 , 'zIndex' , '999999' );
					void set( _console , 'position' , 'absolute' );
					void set( _console , 'width' , '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 , 'right' , '2px' );
					void set( _console , 'top' , '2px' );
					void set( _console , 'border' , '2px solid #000000' );					
					void set( head , 'padding' , '5px' );
					void set( _list , 'padding' , '5px' );
					void set( _list , 'overflow' , 'auto' );
					void set( _list , 'height' , '600px' );
					void pln.events.addListener( btn , 'click' , null , toggle , btn ) ;
				};

				/**
				* @METHOD
				* @name						toggle
				* @version 					1.16
				* @description				Toggle the display of the debug console.
				*
				* @argument eventObject		Object. The event object generated by the browser
				* @argument control			Html element. The element that serve as the button 
				*							in order to toggle the console view.
				*
				* @usage					void toggle() ;
				*
				* @note						This method must be called within the scope of the class.
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				function toggle( eventObject , control ){
					var display = pln.node.getProperty( _list , 'display' ) ;
					var displaying = display == 'none' ;
					void set( _list , 'display' , displaying ? 'block' : 'none' ) ;
					void set( control , 'innerHTML' , displaying ? '[ minimize ]' : '[ maximize ]' ) ;
				};

				/**
				* @METHOD
				* @name						addMessageToConsole
				* @version 					1.16
				* @description				This method will generate a html element to support the 
				*							message, add style to it and add it to the console message
				*							list container.
				*
				* @argument message			String. The event object generated by the browser
				*
				* @usage					void addMessageToConsole( message ) ;
				*
				* @note						This method must be called within the scope of the class.
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					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 );
				} ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						log
				* @version 					1.16
				* @description				This method will add a message to the console, and sty
				*
				* @argument message			String. The message that you want to appear in the console.
				* @argument type			String. The type of the message, error, warning, etc. It will 
				*							affect the style of the display.
				* @argument className		String. The name of the class in which the log have been initiated.
				* @argument methodName		String. The name of the method in which the log have been initiated.
				*
				* @usage					void nvi.logManager.log( message ) ;
				*
				* @note						
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.log = function( message , type , className , methodName ){
					if( _consoleEnabled ){
						try{
							var outputMessage = '' ;
							if( pln.isString( type ) ){
								var typeColor = "#000000";
								if( type == 'Event' ) typeColor = "#228B22" ;
								if( type == 'Error' ) typeColor = "#CC0000" ;
								if( type == 'Core' ) typeColor = "#000000" ;
								if( type == 'Instanciation' ) typeColor = "#0099CC" ;
								if( type == 'Warning' ) typeColor = "#FF6905" ;
								if( type == 'Report' ) typeColor = "#8B008B" ;
								outputMessage += "<span style='padding:2px 5px;margin-right:5px;background:" + typeColor + ";'>[ " + type + " ]</span> " ;
							}
							if( pln.isString( className) ) outputMessage += className + " " ;
							if( pln.isString( methodName ) ) outputMessage += '.' + methodName + "()<br />" ;
							if( outputMessage.indexOf( '<br />' ) != -1 ) outputMessage += '&nbsp;&nbsp;&nbsp;->&nbsp;' ;
							outputMessage += message ;
							void _messageCollection.push( ":: " + outputMessage ) ;
							var newMessage = _messageCollection[ _messageCollection.length-1 ] ;
							/*
							* if this code is executed in an iframe or a frame, we try to log information into the 
							* console that is on the top frame(the main console) since we dont want to have multiple 
							* consoles at the same time.
							*/
							_mainConsole ? void addMessageToConsole( newMessage ) : void _window.nvi.logManager.log( newMessage ) ;
						}
						catch( error ){
							return null ;
						}
					}
					return null ;
				} ;

				/**
				* @METHOD
				* @name						initializeConsole
				* @version 					1.16
				* @description				This is is the callback listener of the '__documentReady' event, it will call the 
				* 							generateConsole method and push message into the console, message that have been 
				* 							logged before the event was fired.
				*
				* @usage					void initializeConsole() ;
				*
				* @note						This method must be called within the scope of the class.					
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				function initializeConsole(){
					if( _console ) return ;
					try{
						if( _mainConsole ){
							void generateConsole() ;
							while( _messageCollection.length > 0 ) void addMessageToConsole( _messageCollection.shift() ) ;
							void set( _console , 'display' , 'block' );
						}else{
							while( _messageCollection.length > 0 ) void _window.nvi.logManager.log( _messageCollection.shift() ) ;
						}
					}catch( error ){}
				};
				//
				this.log( 'Nvi Log Manager initiated' , 'Core' );
			};


			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION
			* @CLASS
			* @name 			Nvi Shared Ressources Manager
			* @date				1:45 PM Thursday, July 08, 2010
			* @version 			1.22
			* @extends			None
			* @description		This class manage the shared ressources
			* @note 		
			* @see			
			*/
			var NSRM = new function(){
				var _ressources = {} ;

				/**
				* @ADD_TO_DOCUMENTATION
				* @METHOD
				* @name					toString
				* @version 				1.16
				* @description			This method is automatically called when this object is to 
				*						be represented as a text value.
				*
				* @usage				alert( [ nvi.logManager ] ) ;
				* @return				String. A string representing the object.
				* @dispatch				Nothing
				* @throw				Nothing
				*/	
				this.toString = function(){
					return "Nvi Shared Ressources Manager" ;
				} ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						registerToGroup
				* @version 					1.16
				* @description				This method will register one or more panels instance id to a shared ressources group 
				*							so when one member of the group submit to the server, using ajax, it will 
				*							also send all other members shared data to the server.
				* ~newline
				*							A class instance can be registered to a multitude of group.
				*
				* @usage					void nvi.sharedRessourcesManager.registerToGroup( groupId , elementId1 [ , elementId2 , ... ] ) ;
				*
				* @argument groupId			String. The group unique id. If a group with the user defined id do not exist, 
				*							the group will be created.
				* @argument elementId		String. The panel class instance unique identifier. It must be a valid panel class instance id.
				*
				* @note						
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.registerToGroup = function( groupId /*, elementId1 , elementId2 , ... */ ){
					var items = pln.argsToArray( arguments , 1 ) ;
					var group = _ressources[ groupId ] || ( _ressources[ groupId ] = {} ) ;
					var i=0;
					while( items.length > 0 ){
						group[ i ] = items.shift() ;
						i++;
					}
				} ;
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						unregisterFromGroup
				* @version 					1.16
				* @description				This method will remove pre-registered panel(s) instance id 
				*							from the pre-defined shared ressources group id.
				*
				* @usage					void nvi.sharedRessourcesManager.unregisterFromGroup( groupId , elementId1 [ , elementId2 , ... ] ) ;
				*
				* @argument groupId			String. The group unique id.
				* @argument elementId		String. The panel class instance unique identifier. It must be a valid panel class instance id.
				*
				* @note						
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				this.unregisterFromGroup = function( groupId /*, elementId1 , elementId2 , ... */ ){
					try{
						var items = pln.argsToArray( arguments , 1 ) ;
						while( items.length > 0 ){
							delete _ressources[ groupId ][ items.shift() ] ;
						}
					}catch( error ){}
				} ;				

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name							getRessources
				* @version 						1.20
				* @description					This method will get every shared data of members of a selected group.
				*	
				* @usage						var data = nvi.sharedRessourcesManager.getRessources( groupId , exceptionObject ) ;
				*
				* @argument groupId				String. The group unique id.
				* @argument exceptionObject		Object. A class instance, usually the instance that trigger the call to the 
				*								getRessources method since we dont want duplicated data(the instance that trigger 
				*								the call gets is data included as the first item). The execeptionObject
				*								will not get its data shared.
				*
				* @note						
				*
				* @return						Array. An array of object containing data.
				* @dispatch						Nothing
				* @throw						Nothing
				*/				
				this.getRessources = function( groupId , exceptionObject ){
					try{
						var collection = [] ;
						var group = _ressources[ groupId ] ;
						for( var i in group ){
							var instance = NPM.getInstance( group[ i ] ) ;
							var ressources = ( instance ) ? instance.getSharedRessources() : null ;
							if( ressources ){
								if( ( exceptionObject && exceptionObject.id != ressources.id ) || !exceptionObject ) void collection.push( ressources ) ;
							}
						}
						return collection.length > 0 ? collection : null ;						
					}catch( error ){ return null; }
				};

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name							getGroupByRessourceId
				* @version 						1.20
				* @description					Acquire and return the group id using an class intance previously 
				*								registered to a group id. Usefull when you dont know if an element 
				*								is part of one or more group for shared ressources.
				*	
				* @usage						var data = nvi.sharedRessourcesManager.getGroupByRessourceId( ressourceId ) ;
				*
				* @argument ressourceId			String. The id of a class instance that was previously registered to a group.
				*								If the user define ressource was never registered to a group or
				*
				* @note						
				*
				* @return						Array. An array of object containing the id of the groups that the user 
				*								selected element is registered to.
				* @dispatch						Nothing
				* @throw						Nothing
				*/				
				this.getGroupByRessourceId = function( ressourceId ){
					try{
						var collection = [] ;
						for( var i in _ressources ){
							var group = _ressources[ i ] ;
							for( var j in group ){
								if( group[ j ] == ressourceId ){
									collection.push( i );
									break ;
								}
							}
						}
						return collection ;
					}catch( error ){ return null ;}
				};
				void NLM.log( 'Nvi Shared Ressources Manager' , 'Core' );
			};


			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION
			* @CLASS
			* @name 			Nvi Event Manager
			* @date				10:39 AM Friday, July 09, 2010
			* @version 			1.00
			* @extends			None
			* @description		This class the events
			* @note 		
			* @see			
			*/			
			var NEM = new function(){
				
				var _eventCollection = {} ;
				var _host = this ;
				
				/*
				* Event constant definition
				*/
				var _events = {
					__updating : 'updating' ,
					__ready : 'ready' ,
					__success : 'success' ,
					__failed : 'failed' ,
					__opened : 'opened' ,
					__closed : 'closed' ,
					__changed : 'changed' ,
					__moved : 'moved' ,
					__resized : 'resized' ,
					__stopped : 'stopped' ,
					__rating : 'rating' ,
					__dateSelected : 'date_selected' ,
					__validationFailed : 'validation_fail' ,
					__validationSucceeded : 'validation_succeeded',
					__triggered : 'triggered' ,
					__beforeChanged : 'before_changed' ,
					__pageInitialized : 'page_initialized'
				};
				this.events = _events ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name							dispatchEvent
				* @version 						1.20
				* @description					This will disptach a user defined event to registered event handler
				*	
				* @usage						var data = nvi.eventManager.dispatchEvent( identifier , eventName , eventObject ) ;
				*
				* @argument identifier			String or Html element. The html element or its id that was used to add/register the event listener.
				* @argument eventName			String. The event name or event constant
				* @argument eventObject			Object. You can pass an event object to this method or create one using navigator method. The creation
				*								of real event object is complex and not crossbrowser so the nvi framework does not provide it natively.
				* ~newline									
				*								If no event object is defined, an empty object will be created.
				*
				* @note						
				*
				* @return						Nothing
				* @dispatch						Nothing
				* @throw						Nothing
				*/
				this.dispatchEvent = function( identifier , eventName , eventObject ){
					if( eventName == _events.__ready ) void displayWaitingPanel( identifier , false ) ;
					if( eventName == _events.__updating ) void displayWaitingPanel( identifier , true ) ;
					void pln.events.dispatchEvent( identifier , eventName , eventObject ) ;					
					void NLM.log( 'Dispatching ' + eventName + ' event for the ' + identifier + ' element' , 'Event' , 'Nvi Event Manager' , 'dispatchEvent' ) ;
				};

				/**
				* @METHOD
				* @name							displayWaitingPanel
				* @version 						1.20
				* @description					This will display or hide the waiting panel, default or custom, releated with the user 
				*								selected panel instance. It will also ajust the width and height of waiting panel to fit
				*								the dimension of the related panel.
				*	
				* @usage						void displayWaitingPanel( id , display ) ;
				*
				* @argument id					String. The unique id of the panel instance.
				* @argument display				Boolean. If set to true, it will display the panel, else it will hide it.
`				*
				* @note							This method must be called within the scope of the class.	
				*
				* @return						Nothing
				* @dispatch						Nothing
				* @throw						Nothing
				*/
				function displayWaitingPanel( id , display ){
					try{
						var instance = NPM.getInstance( id ) ;
						var customWaitingPanel = instance.getCustomWaitingPanel() ;
						if( !pln.isNull( customWaitingPanel ) ){
							void pln.node.setProperty( customWaitingPanel , 'display' , display ? 'block' : 'none' ) ;
						}else{
							var element = instance.getElement() ;
							var defaultPanelId = _defaultWaitingPanelPrefixId + id ;
							/*
							* We create a pointer to the getProperty method since we will be 
							* using it alot in the next few lines.
							*/
							var _get = pln.node.getProperty ;
							/*
							* We get the width and height(borders size and padding also) of the selected panel and aplpy to its default 
							* waiting panel in order to reflect the actual panel size.
							*/
							var width = _get( element , 'offsetWidth' ) ;
							var height = _get( element , 'offsetHeight' ) ;
							var borderTop = _get( defaultPanelId , 'border-top-width') || 0 ;
							var borderRight = _get( defaultPanelId , 'border-right-width') || 0 ;
							var borderBottom = _get( defaultPanelId , 'border-bottom-width') || 0 ;
							var borderleft = _get( defaultPanelId , 'border-left-width') || 0 ;
							var paddingLeft = _get( defaultPanelId , 'padding-left') || 0 ;
							var paddingRight = _get( defaultPanelId , 'padding-right') || 0 ;
							var paddingBottom = _get( defaultPanelId , 'padding-bottom') || 0 ;
							var paddingTop = _get( defaultPanelId , 'padding-top') || 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' );							
						}
						/*
						* This should not be 'block' because the element that the panel 
						* represent could be in inline mode. This need to be corrected later.
						*/
						void pln.node.setProperty( defaultPanelId , 'display' , display ? 'block' : 'none' ) ;
						void NLM.log( ( display ? 'Displaying' : 'Hidding' ) + ' the default waiting panel for the ' + id + ' panel' , 'Event' , 'Nvi Event Manager' , 'displayWaitingPanel' );
					}catch( error ){}
				};

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name							addListener
				* @version 						1.20
				* @description					This method is used to add an event listener on a specific element 
				*								and for a pre-defined event.
				*	
				* @usage						void nvi.eventManager.addListener( identifier , eventName , scopeObject , eventHandler ) ;
				*
				* @argument identifier			String or Html element. The html element or its id that was used to add/register the event listener.
				* @argument eventName			String. The event name or event constant
				* @argument scopeObject			Object. The instance of a class. If the event handler is a method of a class and use the 'this' 
				*								keyword in the method declaration, we have to re-assign the scope. Else the 'this' keyword will
				*								represent the window object. By assigning the scopeObject, the event handler will be executed 
				*								in that particular context.
				* @argument eventHandler		Function. The function that will be executed when the event will be triggered. 
				*									
				* @note						
				*
				* @return						Nothing
				* @dispatch						Nothing
				* @throw						Nothing
				*/
				this.addListener = function( identifier , eventName , scopeObject , eventHandler ){
					var identifier = pln.events.sanitizeIdentifier( identifier ) ;
					void pln.events.addListener.apply( null , pln.argsToArray( arguments ) ) ;
					if( identifier != "all" ) void pln.events.addListener.apply( null , [ identifier , eventName , null , ALLTrigger , eventName ] ) ;
				} ;
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name							removeListener
				* @version 						1.20
				* @description					This method is used to remove a pre-registered event listener on a specific element.
				*	
				* @usage						void nvi.eventManager.removeListener( identifier , eventName , scopeObject , eventHandler ) ;
				*
				* @argument identifier			String or Html element. The html element or its id that was used to add/register the event listener.
				* @argument eventName			String. The event name or event constant
				* @argument scopeObject			Object. The instance of a class. If the event handler is a method of a class and use the 'this' 
				*								keyword in the method declaration, we have to re-assign the scope. Else the 'this' keyword will
				*								represent the window object. By assigning the scopeObject, the event handler will be executed 
				*								in that particular context.
				* @argument eventHandler		Function. The function that will be executed when the event will be triggered. 
				*									
				* @note						
				*
				* @return						Nothing
				* @dispatch						Nothing
				* @throw						Nothing
				*/
				this.removeListener = function( identifier , eventName , scopeObject , eventHandler ){
					var identifier = pln.events.sanitizeIdentifier( identifier ) ;
					void pln.events.removeListener( identifier , eventName , scopeObject , eventHandler ) ;
					if( identifier != "all" ) void pln.events.removeListener( identifier , eventName , null , ALLTrigger ) ;
				} ;
				
				/**
				* @METHOD
				* @name							ALLTrigger
				* @version 						1.20
				* @description					This is a shortcut method to disptach an defined event with the 'all' identifier.
				*	
				* @usage						void ALLTrigger( eventObject , eventName ) ;
				*
				* @argument eventObject			Object. You can pass an event object to this method or create one using navigator method. The creation
				*								of real event object is complex and not crossbrowser so the nvi framework does not provide it natively.
				* @argument eventName			String. The event name or event constant
				*									
				* @note							This method must be called within the scope of the class.
				*
				* @return						Nothing
				* @dispatch						Nothing
				* @throw						Nothing
				*/				
				function ALLTrigger( eventObject , eventName ){
					void pln.events.dispatchEvent( 'all' , eventName , eventObject ) ;
				} ;

				void NLM.log( 'Nvi Event Manager initiated' , 'Core' );
			};

			
			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION			
			* @CLASS
			* @name 			Nvi Ajax Connection Manager
			* @date				2:34 PM Friday, July 09, 2010
			* @version 			1.00
			* @extends			None
			* @description		This class the events
			* @note 			This class is a cub private class of this package. It can only be 
			*					executed in the scope of the package.
			* @see			
			*/			
			var NACM = new function(){
				var _connectionCollection = {} ;
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						getConnection
				* @version 					1.20
				* @description				This method will create a new ajax connection and manage it. 
				*							The url use is the current window url minus the hash part.
				*	
				* @usage					void NACM.getConnection( id ) ;
				*
				* @argument id				String. A unique identifier of an panel instance.
				*									
				* @note 					This method is public but in a private class of the package, it can 
				*							only be executed in the scope of the package.
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.getConnection = function( id ){
					try{
						/*
						* Since this is the basic ajax method and only work with panels, 
						* all getway url is the current window url plus a parameter that tell
						* the server to render only the view of the selected panel.
						*/
						if( !NPM.instanceExist( id ) ){
							void NLM.log( 'There is no panel instance with the selected id: ' + id , 'Error' , 'Nvi Ajax Connection Manager' , 'getConnection' );
						}else{
							var href = window.location.href ;
							var hash = window.location.hash ;

							/*
							* When there is no data after the hash, the window.location.hash is 
							* empty and the hash will remain on the url, disabling all following 
							* paramters. We need to validate this, else it will cause error.
							*/
							var url = href.replace( pln.isEmpty( hash ) ? '#' : hash , '' ) ;
							var instance = NPM.getInstance( id ) ;
							if( pln.isObject( instance ) ){
								try{
								 var overwritingUrl = instance.getCustomUpdateViewUrl() ;
								 if( pln.isString( overwritingUrl ) ) url = overwritingUrl ;
								}catch( error ){}
							}

							var connectionUrl = url + ( url.indexOf( '?' ) !=-1 ? '&' : '?' ) + "render_only=" + id ;
							/*
							* Note that we always use the POST method, because we are alway sending 
							* data to the server, even if we also pass data embeded in the url.
							*/
							var connectionObject = _connectionCollection[ id ] || ( _connectionCollection[ id ] = { inUsage : false , connection : null } );
							if( !connectionObject.inUsage ) connectionObject.connection = new pln.server.connection( connectionUrl , 'POST' ) ;
							return connectionObject ;
						}
					}catch( error ){}
				};
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						clearConnection
				* @version 					1.20
				* @description				This is use to abort the ajax connection. The abort method is not available on all browser
				*							so if the browser 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.
				*	
				* @usage					void NACM.clearConnection( id ) ;
				*
				* @argument id				String. A unique identifier of an panel instance.
				*									
				* @note 					This method is public but in a private class of the package, it can 
				*							only be executed in the scope of the package.
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.clearConnection = function( id ){
					if( !NPM.instanceExist( id ) ){
						void NLM.log( 'There is no panel instance with the selected id: ' + id , 'Error' , 'Nvi Ajax Connection Manager' , 'clearConnection' );
					}else{
						/*
						* If the connection object exist, cancel the connection and 
						* delete the cached connection
						*/
						var connectionObject = _connectionCollection[ id ] ;
						if( pln.isObject( connectionObject ) ){
							void connectionObject.connection.abort();
							delete _connectionCollection[ id ] ;
						}
					}
				};
				//
				void NLM.log( 'Nvi Ajax Connection Manager initiated' , 'Core' );				
			};

			
			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION			
			* @CLASS
			* @name 			Nvi Memory Id Manager
			* @date				2:15 PM Monday, July 12, 2010
			* @version 			1.00
			* @extends			None
			* @description		This class is usefull to manage element that have been removed 
			*					from the document and will be re-injected in the future at some point.
			* @note 			
			* @see			
			*/			
			var NMIM = new function(){
				var _collection = {} ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						find
				* @version 					1.22
				* @description				This method is used to find and acquire an element in the memory 
				*							collection. Element that are in usedare added to this collection
				*	
				* @usage					var item nvi.memoryIdManager.find( id ) ;
				*
				* @argument id				String. A unique identifier of an panel instance.
				*									
				* @return					Object. An object with some panel related data
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				this.find = function( id ){
					try{
						return pln.isset( _collection[ id ] ) ;
					}catch( error ){ return false ; }
				} ;
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						findByParentId
				* @version 					1.22
				* @description				This method is used to find and acquire an element in the memory 
				*							collection by doing a comparaison with the parent element id.
				*	
				* @usage					var item nvi.memoryIdManager.findByParentId( parentId ) ;
				*
				* @argument parentId		String. A unique identifier of an panel instance.
				*									
				* @return					Array. An array of element that share the same parent element.
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.findByParentId = function( parentId ){
					var collection = [] ;
					try{
						for( var i in _collection ){
							var item = _collection[ i ] ;
							if( item.parentId == parentId ) void collection.push( item.id ) ;
						}
					}catch( error ){}
					return collection ;
				} ;				
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						add
				* @version 					1.22
				* @description				This method is used to find and acquire an element in the memory 
				*							collection by doing a comparaison with the parent element id.
				*	
				* @usage					var item = { id : 'id_of_panel' , parentId : 'id_of_parent_panel' } ;
				* ~newline
				*							void nvi.memoryIdManager.add( item ) ;
				*
				* @argument item			Object. The object that contain related data that you wish to 
				*							add to the memory collection.
				*									
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.add = function( item ){
					if( !pln.isObject( item ) ) return ;
					_collection[ item.id ] = item ;
				} ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						remove
				* @version 					1.22
				* @description				This method is used to remove an element from the memory 
				*							collection.
				*	
				* @usage					var item = { id : 'id_of_panel' , parentId : 'id_of_parent_panel' } ;
				* ~newline
				*							void nvi.memoryIdManager.remove( item ) ;
				*
				* @argument item			Object. The object that contain related data that you wish to 
				*							remove from the memory collection.
				*									
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				this.remove = function( item ){
					if( !pln.isObject( item ) ) return ;
					delete _collection[ item.id ] ;
				} ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						clear
				* @version 					1.22
				* @description				This method is used remove all elements already registered in the 
				*							memory collection.
				*	 
				* @usage					void nvi.memoryIdManager.clear() ;
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				this.clear = function(){
					_collection = {} ;
				} ;
				void NLM.log( 'Nvi Memory Id Manager' , 'Core' );
			} ;


			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION			
			* @CLASS
			* @name 			Nvi Panel Manager
			* @date				10:42 AM Tuesday, July 13, 2010
			* @version 			1.00
			* @extends			None
			* @description		This class is the panel factory and it is used to manage all 
			*					all the framework panels.
			* @note 			
			* @see			
			*/			
			var NPM = new function(){
				var _instanceCollection = {} ;
				var _strictMode = false ;
				var _count = 0 ;
				var _host = this ;
				
				/**
				* @METHOD
				* @name						copyDefaultWaitingPanel
				* @version 					1.16
				* @description				Clone the default waiting panel that was rendered in the document and
				*							append it just after the node of the element that the panel represent.
				*	 
				* @usage					void copyDefaultWaitingPanel( id ) ;
				*
				* @argument id				String. The unique identifier that represnet the instance panel.
				*				
				* @note						This method must be called within the scope of the class.	
				*
				* @return					Html Element, the cloned default waiting panel or null
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				function copyDefaultWaitingPanel( id , injectInsideTarget ){
					/*
					* We can, in certain case, inject the default waiting panel 
					* inside a selected target.
					*/
					var injectInsideTarget = pln.isBoolean( injectInsideTarget ) ? injectInsideTarget : false ;

					// Validate if there is already a clone for the selected panel instance.
					var newId = _defaultWaitingPanelPrefixId + id ;
					if( pln.isHtmlElement( pln.node.getById( newId ) ) ){
						void NLM.log( 'There is already a default waiting panel for the '+ id +' panel' , 'Report' , 'Nvi Panel Manager' , 'copyDefaultWaitingPanel' );
					}else{
						// Get the default waiting panel in the document
						var target = pln.node.getById( _defaultWaitingPanelId ) ;
						if( !pln.isHtmlElement( target ) ){
							void NLM.log( 'There is no default waiting panel rendered in the current html page' , 'Warning' , 'Nvi Panel Manager' , 'copyDefaultWaitingPanel' );
						}else{
							var clone = pln.node.clone( target ) ;
							var panel = pln.node.getById( id ) ;
							void pln.node.setProperty( clone , 'id' , newId ) ;
							if( injectInsideTarget ){
								return pln.node.add( clone , panel ) ;
							}else{
								return pln.node.add( clone , pln.node.getParent( 1 , panel ) , panel , false ) ;
							}
						}
					}
					return null ;
				} ;
				/*
				* We create a public pointer for the 'copyDefaultWaitingPanel' function
				*/
				this.copyDefaultWaitingPanel = copyDefaultWaitingPanel ;
				
				/**
				* @METHOD
				* @name						cleanupId
				* @version 					1.16
				* @description				Remove all white spaces that can be before or after the id. Most 
				*							of the time, its an error of the user due to wrong copy-paste, etc.
				*							We make sure that this is not the case by cleaning it up.
				*	 
				* @usage					var id = cleanupId( id ) ;
				*
				* @argument id				String. The unique identifier that represnet the instance panel.
				*				
				* @note						This method must be called within the scope of the class.	
				*
				* @return					Strinf, a cleaned id
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				function cleanupId( id ){
					try{
						return id.replace( /\s+/gi , '' ) ;
					}catch( error ){ return null ; }
				};

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						getInstance
				* @version 					1.11
				* @description				Validate if an instance exist and if so returns it. If this
				*							method is called from an iframe/frame it will also check all 
				*							parent window element in order to see if the instance exist.
				*							This is usefull when you try to call method of a panel when 
				*							not in the same window scope.
				*	 
				* @usage					var instance =  nvi.panelManager.getInstance( id ) ;
				*
				* @argument id				String. The unique identifier that represent the instance panel.
				*				
				* @return					Object, the panel class instance
				* @dispatch					Nothing
				* @throw					Nothing
				*/								
				this.getInstance = function( id ){
					try{
						id=cleanupId( id ) ;
						var instance = this.instanceExist( id )? _instanceCollection[ id ] : null ;
						if( pln.isNull( instance ) ){
							return window.location.href != parent.location.href ? parent.nvi.panelManager.getInstance( id ) : null ;
						}
						else{ return instance ; }
					}catch( error ){ return null ; }
				};
				
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						instanceExist
				* @version 					1.11
				* @description				Validate if there is a registered instance of a panel 
				*							using the panel id.
				*	 
				* @usage					var instanceExist = nvi.panelManager.instanceExist( id ) ;
				* ~newline
				*							alert( instanceExist ) ; //true
				*
				* @argument id				String. The unique identifier that represent the instance panel.
				*				
				* @return					Boolean, true is exist else, false.
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				this.instanceExist = function( id ){
					try{
						return pln.isObject( _instanceCollection[ cleanupId( id ) ] ) ;
					}catch( error ){ return null ; }
				};
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						deleteInstance
				* @version 					1.11
				* @description				This method is use to remove the instance from the instance collection
				*							and to execute the deleteInstance method of the panel in order to remove all
				*							html elements and javascript object relative to the selected panel.
				*	 
				* @usage					void nvi.panelManager.deleteInstance( id ) ;
				*
				* @argument id				String. The unique identifier that represent the instance panel.
				*				
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.deleteInstance=function( id ){
					id=cleanupId( id ) ;
					var instance = this.getInstance( id ) ;
					try{
						void instance.deleteInstance() ;
						delete _instanceCollection[ id ] ;
					}catch( error ){}
				};

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						createInstance
				* @version 					1.11
				* @description				This method generate panel class instances, it is the main factory method.
				*	 
				* @usage					void nvi.panelManager.createInstance( id , constructor , isVirtual ) ;
				*
				* @argument id				String. The unique identifier that represent the instance panel.
				* @argument constructor		Function.
				* @argument isVirtual		Boolean. 
				*				
				* @return					Object. The class instance
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.createInstance = function( id , Constructor , isVirtual ){
					var id = cleanupId( id ) ;
					var isVirtual = pln.isBoolean( isVirtual ) ? isVirtual : false ;
					var constructorName = pln.getFunctionName( Constructor ) ;

					/*
					* We validate if an instance with the same ID already exist. The 'id' must 
					* be unique and if an instance already exist, return it, do not create a new one.
					*/
					if( this.instanceExist( id ) ){
						void NLM.log( 'There is already a panel instance with the selected id: ' + id + ' of type ' + constructorName + '. 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{
							/*
							* In some cases, like the Modal or the Tooltip class, when we redeclare
							* the instance, we need to clear its memory( html elements, data or process )
							* that are encapsulated in the class instance. 
							*
							* In the case of a modal, if we do not remove its content, we will end-up 
							* with duplicated content.
							*/
							if( instance.isContentRemovalEnabled() ){
								if( constructorName == 'class_nvi_tooltip_panel' || constructorName == 'class_nvi_modal_panel' ){
									void instance.removeAllContent( true ) ;
								}
							}
						}catch( error ){}
						if( !isVirtual ) void copyDefaultWaitingPanel( instance.getId() ) ;
						return instance ;
					}else{
						
						if( _strictMode && !pln.isHtmlElement( pln.node.getById( id ) ) && !NMIM.find( id ) ){
							if( Constructor == class_nvi_tooltip_panel || Constructor == class_nvi_modal_panel ){
								/*
								* There is an exception to this rule, the content of a modal or a tooltip because
								* the content is only available when the modal/tooltip is open.
								*/
								void NMIM.add( { id : id , parentId : null } ) ;
							}else{
								/*
								* A panel requires an html view. If we cannot find it in the document
								* or in the memory id collection, we return nothing, the interpreter will 
								* return undefined. That way, the javascript will cause an error on the page
								* and de programmer will undestand that there is a problem.
								*/
								void NLM.log( 'The html element linked to tho this class instance cannot be found in the current html document. ( id = '+ id +').' , 'Error' , 'Nvi Panel Manager' , 'createInstance' );
								return ;
							}
						}

						// We compile the class.
						var instance = pln.compiler.createClass( Constructor , id ) ;
						_count++ ;
						void NLM.log( 'Instanciation of ' + id + ' ( ' + instance + ' )' , 'Instanciation' );
						if( !pln.isObject( instance ) ){
							void NLM.log( 'Unable to instanciate the '+ id +' panel of type '+ constructorName , 'Error' , 'Nvi Panel Manager' , 'createInstance' );
							return ;
						}else{
							/*
							* We only create a default waiting panel if the panel is not virtual.
							* Some class panel are not linked with an html view and in this particular case,
							* we do not need a waiting panel.
							*/
							if( !isVirtual ){
								var waiting = copyDefaultWaitingPanel( id ) ;
								if( !pln.isHtmlElement( waiting ) ){
									void NLM.log( 'Unable to copy the default waiting panel for the '+ id +' panel' , 'Warning' , 'Nvi Panel Manager' , 'createInstance' );
								}
							}
							return ( _instanceCollection[ id ] = instance ) ;						
						}
					}
				} ;

				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						updateView
				* @version 					1.11
				* @description				This method will execute an ajax call in order to update the view of the 
				*							selected panel. This method handle the response from the server before 
				*							refreshing the view. It will execute any javascript found in the server 
				*							response with the exception of external javascript file declaration which
				*							will be handle by the browser once the html is updated.(It does not look 
				*							or try to load any external javascript or css files.)
				* ~newline
				*							This method also clean the response from the server, it will remove 
				*							javascript and html comments.
				* ~newline
				*							Note that it also removes the outer container of a panel view. When a panel 
				*							is updated, we only need to changes its content and not the container. The 
				*							first html starting node and the last ending node is considered as the panel 
				*							view container.
				* ~newline
				*							Also, during the ajax connection with the server shared ressources will also 
				*							be sent to the server and all data from any member of a shared ressources group.
				*	 
				* @usage					void nvi.panelManager.updateView( id , data ) ;
				*
				* @argument id				String. The unique identifier that represent the instance panel.
				* @argument data			Object. The panel class instance shared ressources object
				*				
				* @return					Nothing
				* @dispatch					Dispatch the __updating and __ready event
				* @throw					Nothing
				*/
				this.updateView = function( id , data ){
					try{
						var instance = this.getInstance( id ) ;
						if( !pln.isObject( instance ) ){
							void NLM.log( 'The instance is not a valid instance of a panel' , 'Error' , 'Nvi Panel Manager' , 'updateView' );
							return;
						}
					}catch( error ){ return; }
					
					// We get a new connection binded to the id of the panel class instance.
					var connectionObject = NACM.getConnection( id ) ;
					
					// If there is already a pending call, we simply do nothing.
					if( connectionObject.inUsage ) return ; 
					
					connectionObject.inUsage = true ;		
					connectionObject.connection.onLoad = function( success , serverData , message ){
						// We free the connection so it can be use again.
						connectionObject.inUsage = false ;

						var response = null ;
						try{
							response = _host.parseServerResponse( success , serverData , message , true ) ;
						}catch( error ){
							void NLM.log( error.message + ", ( " + id + " )" , 'Error' , 'Nvi Panel Manager' , 'updateView' );
						}
						
						try{
							// We try to paste the html response in the panel view.
							void pln.node.setProperty( id , 'innerHTML' , response.source );
						}catch( error ){
							/*
							* The innerHTML way of adding html will generates error in IE6 & IE7 if 
							* the html contain a from element. The browser will throw an Unknown runtime
							* error EVEN if it succeed at adding the form node.
							*/
							return ;
						}
						
						/*
						* We reset the view of the container of the panel instance and dispatch
						* the reay event for the panel class instance which will remove the
						* default or custom waiting panel.
						*/ 
						void pln.node.setProperty( id , 'display' , '' ) ;
						void NEM.dispatchEvent( id , NEM.events.__ready ) ;

						/*
						* We then call the onUpdateView of the instance class panel.
						*/
						var instance = _host.getInstance( id ) ;
						void pln.dispatch( instance, instance.onUpdatedView , success , response.dataObject , message ) ;

						// And finally, we execute all javascript found in the server source.
						void pln.evalScriptCollection( response.scripts ) ;
						void NISM.runtimeActivation() ;
					} ;

					/*
					* We hide the panel view and dispatch the updating event 
					* which will display the default or custom waiting panel during
					* the transaction.
					*/
					void NEM.dispatchEvent( id , NEM.events.__updating ) ;
					void pln.node.setProperty( id , 'display' , 'none' ) ;
					
					/*
					* We also check if this instance is part of a shared ressources group
					* and if yes, we will get the data of member and add it to the current server 
					* transaction.
					*/
					var data = pln.isset( data ) ? data : null ;					
					var groups = NSRM.getGroupByRessourceId( id ) ;
					var sharedData = [] ;
					while( groups.length > 0 ){
						var ressources = NSRM.getRessources( groups.shift() , data ) ;
						if( !pln.isNull(ressources) ) sharedData = sharedData.concat( ressources ) ;
					}
					
					// We execute the server call
					void connectionObject.connection.sendAndLoad( pln.encode( { data : data , sharedData : ( sharedData.length == 0 ? null : sharedData ) } ) );
				};
				
				this.parseServerResponse = function( success , serverData , message , removeFirstNode ){
					var removeFirstNode = pln.isBoolean( removeFirstNode ) ? removeFirstNode : true ;
					if( !success ){
						throw new Error( "Ajax connection failed, error message = " + message ) ;
					}
					if( !pln.isset( serverData ) ){
						throw new Error( "The server returned no data or null" ) ;
					}else{
						var dataObject = null ;
						try{
							dataObject = pln.decode( serverData ) ;
						}catch( error ){
							throw new Error( "The data returned from the server is not a valid JSON encoded string." ) ;
						}			
						var html = dataObject.dataHtml ;
							
						if( pln.isString( html ) ){
							/*
							* Single an multiline javascript comment removal
							*/
							html = html.replace( /\/\*(\s|.)*?\*\//gi , '' ).replace( /(^|\s+)\/\/.*/gi , '' ) ;

							/*
							* Html comment removal
							*/
							html = html.replace( /<!--(\s|.)*?-->/gi , '' ) ;
							
							/*
							* Stylesheet link element removal ( Since it should not be 
							* loaded that way, stylesheets must be loaded in the head )
							*/
							html = html.replace( /<link(\s|\w)*[^>]*>/gi , '' ) ;
							
							var extractedObject = pln.extractScriptFromSource( html , true ) ;
							var source = extractedObject.source ;
							var scripts = extractedObject.scripts ;
							
							if( removeFirstNode ){
								/*
								* Since we are refreshing a view, we must remove the view 
								* node and keep only the content of that node.
								*/
								var startRegexp = /^\s*<(\w*)\b[^<]*>/ ;
								void source.match( startRegexp ) ;
								var name = RegExp.$1 ;
								try{
									var endRegexp = new RegExp( "<\\s?\/\\s?" + name + ">\\s*$" , "i" ) ;
									if( !pln.isNull( source.match( endRegexp ) ) ){
										source = source.replace( startRegexp , '' ) ;
										source = source.replace( endRegexp , '' ) ;
									}
								}catch( error ){}
							}
							return { 
								source : source ,
								scripts : scripts ,
								dataObject : dataObject
							} ;
						}			
					}
				} ;
				
				
				/**
				* @ADD_TO_DOCUMENTATION				
				* @METHOD
				* @name						cancelUpdateView
				* @version 					1.13
				* @description				This method is used to cancel the updateview process of a 
				* 							selected panel class instance.
				*	 
				* @usage					void nvi.panelManager.cancelUpdateView( id ) ;
				*
				* @argument id				String. The unique identifier that represent the instance panel.
				*				
				* @return					Nothing
				* @dispatch					Dispatch the __ready event.
				* @throw					Nothing
				*/
				this.cancelUpdateView = function( instance ){
					try{
						var id = instance.getId() ;
					}catch( error ){
						void NLM.log( 'The instance is not a valid instance of a panel' , 'Error' , 'Nvi Panel Manager' , 'cancelUpdateView' );
						return;					
					}
					void NACM.clearConnection( id ) ;
					void pln.node.setProperty( id , 'display' , '' );
					void NEM.dispatchEvent( id , NEM.events.__ready );
				} ;
				
				// javascript:alert(nvi.panelManager.getNumberOfInstances());
				this.getNumberOfInstances = function(){
					return _count ;
				} ;

				//
				void NLM.log( 'Nvi Panel Manager initiated' , 'Core' ) ;
			} ;
			
			
			/* ********************************************************************************
			* @ADD_TO_DOCUMENTATION			
			* @CLASS
			* @name 			Nvi Image State Manager
			* @date				11:33 AM Tuesday, July 13, 2010
			* @version 			1.00
			* @extends			None
			* @description		With this class, every img html elements in the html document 
			*					will get the is over state (same image name but with the '_on' 
			*					suffix before the image extension) preloaded and will get the 
			*					mouseover and mouseout events assign to the element for 
			*					image swapping.
			* @note 			
			* @see			
			*/
			var NISM = new function(){
				var _collection = {} ;

				/**
				* @METHOD
				* @name					initialize
				* @version 				1.13
				* @description			This method is executed when the document DOM become ready to be used.
				*						It will collect img html element and validate if they have the 'rollover'
				*						and/or 'active' className so they can be registered in the image collection
				*						and perform the neccessary events registration for the image swapping.
				*	 
				* @usage				void initialize() ;
				*
				* @note					This method must be called within the scope of the class.
				*
				* @return				Nothing
				* @dispatch				Nothing
				* @throw				Nothing
				*/				
				function initialize(){
					//void pln.events.removeListener( document , '__documentReady' , null , initialize ) ;
					void populateCollection() ;
					void manageEventsRegistration( true ) ;
				} ;
				
				/**
				* @METHOD
				* @name					populateCollection
				* @version 				1.13
				* @description			Scan the document.images, where all images in the html document are stored,
				*						and if an image is detected to be a client for image state swapping, we create 
				*						a collection object and add it to the collection.
				* ~newline
				*						This method will not include a previously registered element in the collection.
				*	 
				* @usage				void populateCollection( id ) ;
				*
				* @note					This method must be called within the scope of the class.
				*
				* @return				Nothing
				* @dispatch				Nothing
				* @throw				Nothing
				*/				
				function populateCollection(){
					var collection = [] ;
					var inputCollection = pln.node.getByName( 'input' ) ;
					if( pln.isNull( inputCollection ) ) inputCollection = [] ;
					for( var i = 0 ; i < inputCollection.length ; i++ ){
						var input = inputCollection[ i ] ;
						if( input.type.toLowerCase() == 'image' ) void collection.push( input ) ;
					}
					for( var i = 0 ; i < document.images.length ; i++ ) void collection.push( document.images[ i ] ) ;
					for( var i = 0 ; i < collection.length ; i++ ){
						var item = collection[ i ] ;
						var name = item.className ;
						if( !pln.isString( name ) || pln.isNull( name.match( /\brollover\b/i ) ) ) continue ;
						var src = item.src ;
						var id = !pln.isEmpty( item.id ) ? item.id : 'NISM_' + pln.getUniqueId() ;
						if( !pln.isObject( _collection[ id ] ) || _collection[ id ].id != id ){
							var buttonCollection = pln.node.getByName( 'button' ) ;
							if( pln.isNull( buttonCollection ) ) buttonCollection = [] ;
							var button = null ;
							for( var j = 0 ; j < buttonCollection.length ; j++ ){
								var buttonItem = buttonCollection[ j ] ;
								if( pln.node.isChildOf( item , buttonItem ) ){
									button = buttonItem ;
									break ;
								}
							}
							var extension = src.match( /\.\w{3,4}$/i ) ;
							var path = src.replace( /\.\w{3,4}$/i , '' ) ;
							path = path.replace( '_on' , '' ) ;
							item.id = id ;
							_collection[ id ] = { item : item , normal : src , over : path + '_on' + extension , className : name , id : id , active : false , button : button } ;
							var tempImg = new Image() ;
							tempImg.src = _collection[ id ].over ;
						}
					}				
				} ;
				
				/**
				* @METHOD
				* @name					manageEventsRegistration
				* @version 				1.13
				* @description			Add or remove event listener for each img html element registered in 
				*						the collection.
				*	 
				* @usage				void manageEventsRegistration( enable , id , remove ) ;
				*
				* @argument enable		Boolean. true to add event listener, false to remove them.
				* @argument id			String. Optional. The unique identifier of an html element. If found 
				*						in the collection, this specific element will be removed.
				* @argument remove		Boolean. Definivly remove an img element from the collection.
				*
				* @note					This method must be called within the scope of the class.
				*
				* @return				Nothing
				* @dispatch				Nothing
				* @throw				Nothing
				*/
				function manageEventsRegistration( enable , id , remove ){
					var id = pln.isString( id ) && !pln.isEmpty( id ) ? id : null ;
					var remove = pln.isBoolean( remove ) ? remove : false ;
					for( var i in _collection ){
						var imgObject = _collection[ i ] ;
						if( !imgObject.item || !imgObject.normal || !imgObject.over || !pln.isBoolean( imgObject.active ) ) continue ;
						if( id != null && id == imgObject.id ){
							void changeState( null , imgObject , 'normal' ) ;
							if( remove ) delete _collection[ id ] ;
							break ;
						}
						if( !pln.isNull( imgObject.className.match( /\bactivate\b/i ) ) ){
							void changeState( null , imgObject , 'over' ) ;
							continue ;
						}
						if( !enable == imgObject.active ){
							_collection[ i ].active = enable ;
							void pln.events[ enable ? 'addListener' : 'removeListener' ]( !pln.isNull( imgObject.button ) ? imgObject.button : imgObject.item , 'mouseover' , null , changeState , imgObject , 'over' ) ;
							void pln.events[ enable ? 'addListener' : 'removeListener' ]( !pln.isNull( imgObject.button ) ? imgObject.button : imgObject.item , 'mouseout' , null , changeState , imgObject , 'normal' ) ;
						}
					}
				} ;
				
				/**
				* @METHOD
				* @name						changeState
				* @version 					1.13
				* @description				Change the src of the img html element
				*	 
				* @usage					void changeState( eventObject , imgObject , state ) ;
				*
				* @argument eventObject		Object. The event object generated by the browser.
				* @argument imgObject		Object. The image object from the image collection
				* @argument state			String. The new state of the image, 'over' or 'normal'
				*
				* @note						This method must be called within the scope of the class.
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				function changeState( eventObject , imgObject , state ){
					try{
						imgObject.item.src = imgObject[ state ] ;
					}catch( error ){
					}
				} ;
				
				/**
				* @ADD_TO_DOCUMENTATION	
				* @METHOD
				* @name						runtimeActivation
				* @version 					1.13
				* @description				By default, the Image State Manager is activated but in case 
				*							it as been deactivated, you can reactivate it by calling this 
				*							method.
				*	 
				* @usage					void nvi.imageStateManager.runtimeActivation() ;
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/
				this.runtimeActivation = function(){
					void populateCollection() ;
					void manageEventsRegistration( true ) ;
				} ;
				
				/**
				* @ADD_TO_DOCUMENTATION	
				* @METHOD
				* @name						runtimeDeactivation
				* @version 					1.13
				* @description				In order to deactivate the Image State Manager, and remove events 
				*							which mean there will be no more image swapping you simply call 
				*							this method.
				*	 
				* @usage					void nvi.imageStateManager.runtimeDeactivation() ;
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.runtimeDeactivation = function(){
					void populateCollection() ;
					void manageEventsRegistration( false ) ;
				} ;
				
				/**
				* @ADD_TO_DOCUMENTATION	
				* @METHOD
				* @name						removeSpecific
				* @version 					1.13
				* @description				In order to deactivate a specific automatic swapping on 
				*							an image element, simply call this method and pass the id of
				*							the html element as a parameter.
				* ~newline
				*							Note that if the remove is set to true, the img element will 
				*							be remove from the collection.
				*	 
				* @usage					void nvi.imageStateManager.removeSpecific( id , remove ) ;
				*
				* @argument id				String. The id of the html element.
				* @argument remove			Boolean. Remove the element from the collection.
				*
				* @return					Nothing
				* @dispatch					Nothing
				* @throw					Nothing
				*/				
				this.removeSpecific = function( id , remove ){
					void manageEventsRegistration( false , id , remove ) ;
				} ;
				
				//
				void pln.events.addListener( document , '__documentReady' , null , initialize ) ;
			} ;


			/* ********************************************************************************
			* Public pointer to private class
			*/
			this.logManager = NLM ;
			this.eventManager = NEM ;			
			this.panelManager = NPM ;
			this.sharedRessourcesManager = NSRM ;
			this.memoryIdManager = NMIM ;
			this.imageStateManager = NISM ;
			
			//
			this.getDefaultWaitingPanelPrefixId = function(){
				return _defaultWaitingPanelPrefixId ;
			} ;
		}
	}
}
