;(function(){
  
  
  /**
   * Moves focus to next element or next section
   */
  function $preSelectionElement(element, sectionValidation){
    
    
    /**
     * Search next element correctly.
     * Sometimes we may have 2 option radio. In this case next element mustn't be next option radio
     * with the same name!
     */
    function searchElement(element){
      
      var 
        name = element.name,
        tagName = element.getTag(),
        type = element.getProperty('type');
      
      if ( tagName == 'input' && type == 'radio' ){
        /*
         * Element is an option radio
         */
        
        while( true ){
          
          /*
           * we are searching the next element that isn't the same option radio!
           * (we're assuming that next element has the same name and the same attributes!)
           */
          if ( element ){
            
            var 
              _name = element.name,
              _tagName = element.getTag(), 
              _type = element.getProperty('type'); 
            
            if ( tagName != tagName || type != _type || name != _name ){
              /*
               * Element is not the same, return new element
               */
              return element;
            }
            
          } else {
            /*
             * No next element found ( it may be an error ) 
             */
            return null;
          }
          
          /*
           * Move to next element
           */
          element = element.next;
        }
        
      } else {
        /*
         * this element is not an option radio, return next element
         */
        return element.next;
      }
    }
    
    var el = element;
    
    if (  (el = searchElement( element ) )  ) {
      /*
       * We found an element which follows given element, so move focus on it!
       */
      element.section.selectElement( el );
      
    } else if ( sectionValidation  ){
      /*
       * No next element found, section is valid.
       * So we have to move focus to next section that contains errors
       */
      
      var section = element.section.next;
      while( section && section._validation(false) ) {
        /*
         * Section is valid, goto next section
         */
        section = section.next;
      }
      
      if ( section ){
        /*
         * Section found. Move focus to its first element
         */
        section.selectElement();
      } else {
        /*
         * No section with errors found.
         * We're assuming page is completed!
         */
      }
      
    }
    
  }
  
  
  window.Sliding = {
  
  
  	/**
  	 *	Constants and default properties
  	 */
  	'options':{
  		'form': 'quotationForm',
  		'section':'.quotation_section',
  		'radioButtonSection':'radioButtonSection',
  		'header':'.quotation_section_title',
  		'content':'.quotation_section_content',
  		'footer':'.quotation_section_footer',
  		'handler':'.quotationModifyLink',
  		'elements': $A(  ('input,select,textarea').split(',')  ),
  		'err_div': 'error_',
  		'containerId':'',
  		'nextbutton':'nextButton',
  		'savebutton':'newSaveButton',
  		'disableButton':'disabledButton',
  		'activeButton':'activeButton',
  		'disableSaveButton':'disabledButton',
  		'activeSaveButton':'activeButton',
  		'opened':'opened',
  		'closed':'quotation_section_close',
  		'active' : 'quotation_section_active',
  		'hide': 'hidden',
  		'timer': 500,
  		'effectDuration': 500,
  		'stopEventClass': 'js_ajaxAction',
  		'noFxClass' : 'js_nofx',
  		'noToggleClass' : 'js_noToggle',
  		'methodForward':'evaluation',
  		'methodSave':'',
  		'closeLastSection': true,
  		'onSubmit': undefined,
  		'onSectionOpen': Class.empty,
  		'onSectionClose': Class.empty,
  		'defaultValues':['JJ/MM/AAAA','MM/AAAA'],
  		'elementNotReset':'elementNotReset',
  		'isAjax' : false,
  		'type':'navigationscript',
  		'displayAlwaysHandler' : false,
  		
  		
  		/**
  		 * Enable or disable the autonavigation.
  		 * This flag helps user while filling page.
  		 * (Enable or disable the auto-focus on all elements)
  		 */
  		autonavigation: false,
  		
  		/**
  		 * These properties will be invoked while enabling/disabling the 'nextButton'
  		 * @see enableNextButton
  		 */
  		onDisableButton: null,
  		onEnableButton: null,
  		
  		/**
  		 * Enable the auto sliding between sections.
  		 * autoSliding = true, the autoSliding is enabled : 
  		 * when a section is valid, the section is closed and the next section is opened.
  		 * autoslider = false, the autoSliding is disabled : 
  		 * when a section is valid, the section is not closed and the next section is not opened.
  		 * The modifier link hand manually the behaviour.
  		 */
  		autoSliding:true
  	    
  	},
  	
  	/**
  	 *	Initialization of all sections
  	 *	Retrieve all sections such as children of 'parent' parameter. Configure all pointers
  	 *	and all functions.
  	 *	Make a list of sections and list of elements in section
  	 */
  	'init': function( parent , options  ){
  	
  		parent = $( parent || document.body );
  		
  		Sliding.options = $merge( Sliding.options , options );
  		
  		this.nextButton = parent.getElement( '#' + Sliding.options[ 'nextbutton' ] );
  		this.saveButton = parent.getElement( '#' + Sliding.options[ 'savebutton' ] );
  		this.containerId = Sliding.options['containerId'] || parent.id;
  		
  		this.form = $( Sliding.options[ 'form' ] );
  		
  		/* 	Retrieve all section such as children of 'parent' parameter	*/
  		$ES( Sliding.options[ 'section' ] , parent ).each( function(section , index , array ){
  		
  			if ( index == 0 ) this._first = section;
  		
  			this.buildSection( section , index );
  		
  		}, this );
  	
  		/* Set submit button functions and pointers */
  		this.nextButton.form = this.form;
  		this.nextButton.method = Sliding.options[ 'methodForward' ];
  		this.saveButton && (this.saveButton.form = this.form);
  		this.saveButton && (this.saveButton.method = Sliding.options[ 'methodSave' ]);
  		
  		this.nextButton.removeEvents().addEvent( 'click' , this.forward.bind( this ) );
  		this.saveButton && this.saveButton.removeEvents().addEvent( 'click' , this.save.bind( this ) );
  		
  		this.loaded = true;
  		this.makeValidationThread();
  		
  		return this;
  	
  	},
  
  	'makeValidationThread': function(){
  		if ( ! this.loaded ) return;
  		$clear( this.timer );
  		if ( Sliding.options[ 'timer' ] ){
  			$('_sliding_check') && $('_sliding_check').remove();
  			new Element( 'input',{
  				'type':'hidden',
  				'id':'_sliding_check',
  				'class':'hidden hide'
  			}).injectBefore( this.nextButton );
  			this.timer = this.enableNextButton.periodical( Sliding.options[ 'timer' ] , this );
  		}
  	},
  	
  	'check': function(){
  		if ( $('_sliding_check') && $('_sliding_check').getParent() )
  			return true;
  		return false;
  	},
  	
  	'buildSection': function( section , index ){
  	
  		/* Store functionally object */
  		section.header = section.getElement( Sliding.options[ 'header' ] );								// title of section
  		section.content = section.getElement( Sliding.options[ 'content' ] );							// body of section
  		section.footer = section.getElement( Sliding.options[ 'footer' ] );								// footer of section
  		section.handler = section.getElement( Sliding.options[ 'handler' ] );							// link to open section
  		section.isRadioButtonSection = section.hasClass(Sliding.options['radioButtonSection']);		// is a radio button section
  		
  		section._nextbutton = this.nextButton;
  		section._savebutton = this.saveButton;
  		section._form = this.form;
  	
  		/* check the objects */
  		if ( !section.header || !section.content || !section.footer  ){
  			return null; // exit
  		}
  		
  		/* build the effect engine */
  		if ( ! section.fx ){
  			if ( section.hasClass( Sliding.options[ 'noFxClass' ] ) )
  				// implement an empty effect
  				section.fx = {
  					'slideIn': function(){
  						return {
  							'chain': function(){}
  						};
  					},
  					'slideOut': function(){}
  				};
  			else
  				section.fx = new Fx.Slide( section.content , { 'duration': Sliding.options[ 'effectDuration' ] , 'transition' : Fx.Transitions.Quart.easeOut , 'wait' : false } );
  				/** IE8 bug fix:
  				 * 		IE8 doesn't retrieve offsetHeight correctly.
  				 * 		Then set 'offset' manually in slidOut.chain function ( 'close' method ) and 
  				 * 		NOT overwrite that if 'offset' has been set.
  				 */
  				if ( window.ie8 )
  					section.fx.vertical = function(){
  						this.margin = "margin-top";
  				        this.layout = "height";
  				        if ( !$defined( this.offset ) )
  				        	this.offset = this.element.offsetHeight;
  					};
  		}
  			
  		this.buildAllElement(section);
  		
  //		var _elementsIndex = 0;
  //		$ES( '*' , section ).each( function( element , index , a ) {
  //			
  //			/* check tag of element. Have to match with required tags */
  //			if ( ! Sliding.options[ 'elements' ].contains( element.getTag() )   ) return;
  //			
  //			//if ( _elementsIndex == 0 ) section._first = element;
  //			
  //			this.buildElement( section , element , _elementsIndex++ );
  //			
  //		} , this );
  		
  		
  		// Store old pointers
  		var _prevSection = index > 0 ? this.find( this , index ) : null;
  		var _nextSection = ( _prevSection ) ? _prevSection.next : null;
  		
  		/* Make a list of section: set the 'previous' pointer to section */
  		section.prev = _prevSection;
  		if ( _prevSection )
  			_prevSection.next = section;
  		
  		/* Next pointer of list of sections */
  		section.next = _nextSection;
  		if ( _nextSection )
  			_nextSection.prev = section;
  		
  		/* Store functions */
  		section._validation = this.validateSection.bind( section );
  		section.isErrorMessagePresent = this.isErrorMessagePresent.bind( section );
  		section.isErrorServerPresent = this.isErrorServerPresent.bind(section);
  		section.open = this.open.bind( section );
  		section.openRadioButtonSection = this.openRadioButtonSection.bind( section );
  		section.resetSection = this.resetSection.bind( section );
  		section.selectElement = this.selectElement.bind( section );
  		section.close = this.close.bind( section );
  		section.clearErrors = this.clearErrors.bind( section );
  		section.resize = this.resize.bind( section );
  		section.setCSSClasses = this.setCSSClasses.bind( section );
  		
  		//section.handler && section.handler.addEvent('click', section.open.bind(section,[ ]));
  		
  		section.handler && section.handler.removeEvents().addEvent('mousedown', this.manageModifier.bind( section , [ ] ) );
  		
  		return section;
  	},
  	
  	'buildAllElement':function(section){
  		var _elementsIndex = 0;
  		$ES( '*' , section ).each( function( element , index , a ) {
  			
  			/* check tag of element. Have to match with required tags */
  			if ( ! Sliding.options[ 'elements' ].contains( element.getTag() )   ) return;
  			
  			//if ( _elementsIndex == 0 ) section._first = element;
  			
  			if ( this.find( section , element ) == -1 ) {
  			  // elements doesn't exist, add events
  			  
  			  this.buildElement( section , element , _elementsIndex++ );
  			  
  			} else {
  			  /*
  			   * Element already exists.
  			   * In this case we have to increment the element counter to prevent any errors
  			   */
  			  _elementsIndex++
  			}
  			
  		} , this );
  		
  	},
  	
  	'buildElement': function( section , element , index ) {
  		
  		if ( index == undefined || index == null )
  			index = 1000; // default: last element
  	
  		/* Pointer to parent section */
  		element.section = section;
  		
  		element._validation = this.validateElement.bind( element );
  		element.showError = this.showElementError.bind(element);
  		element.clearError = this.clearError.bind( element );
  		element.clip = this.clip.bind( element );
  		
  		/* Pointer to error string container / calculate the name of div */
  		var _elementID = '';
//  		if (window.ie) {
  			_elementId = element.name.replace( new RegExp( "\\.", "gi" ), '_').replace( new RegExp( "\\[", "gi" ), '_').replace( new RegExp( "\\]", "gi" ) , '');
  			_elementId = _elementId.replace( new RegExp( "\\(", "gi" ), "_");
  			_elementId = _elementId.replace( new RegExp( "\\)", "gi" ), "");
//  		} else {
//  			_elementId = element.name.replace( '.' , '_' , 'g' ).replace( '[' , '_' , 'g' ).replace( ']' , '' , 'g' );
//  			_elementId = _elementId.replace( "(" , "_" , "g" );
//  			_elementId = _elementId.replace( ")" , "" , "g" );
//  		}
  		
  		
  		element._error = $( Sliding.options[ 'err_div' ] + _elementId );
  		
  		
  		/*
  		 * Shortcut: select next element
  		 */
  		element.selectNextElement = function(skip){
  		  $preSelectionElement( this , !!skip );
  		  return this;
  		}
  		
  		/* chek the tag of element, and set the functions */
  		if ( element.getTag() == 'input' && element.getProperty( 'type' ) == 'radio' ){
  			element.addEvent( 'click' , this.onLostfocus.bind( element ) );
  		} else if ( element.getTag() == 'input' ){
  			element.addEvent( 'blur' , this.onLostfocus.bind( element ) );
  		} else if ( element.getTag() == 'select' ) {
  			element.addEvent( 'change' , this.onLostfocus.bind( element ) );
  		} else if ( element.getTag == 'textarea' ) {
  			// not used yet
  		}
  	
  		// Store old pointers
  		var _prevElement = index > 0 ? this.find( section , index ) : null;
  		var _nextElement = ( _prevElement ) ? _prevElement.next : null;
  		
  		/* Make a list of section: set the 'previous' pointer to section */
  		element.prev = _prevElement;
  		if ( _prevElement )
  			_prevElement.next = element;
  		
  		/* Next pointer of list of sections */
  		element.next = _nextElement;
  		if ( _nextElement )
  			_nextElement.prev = element;
  		
  		
  		if ( ! element.prev )
  			section._first = element;
  
  		// store the index of the current element
  		element._index = this.find( section , element );
  		
  		
  		return element;
  	},
  	
  	'clear':function (section){
  		var element = section._first;
  		
  		while( element ){
  			_elem = element;
  			element = element.next;
  			_elem.prev = null;
  			_elem.next = null;
  		}
  		section._first = null;
  	},	
  	
  	/**
  	 *	Find an element into a collection ( section / elements )
  	 *	returns mixed-in values based on 'index' parameter
  	 *	 'index' is a number:
  	 *		returns the element at the 'index' position, or last element if 'index' is out of bound
  	 *	 'index' is an element:
  	 *		returns the index of element, or -1 if element is not present in collection
  	 */
  	'find': function( collection , index ){
  		if ( $type( index ) == 'number' ){
  			if ( index < 0 ) return null;
  			var el = collection._first;
  			while( el && index > 0 ){
  				if ( !el.next ) break;
  				el = el.next;
  				index--;
  			}
  			return el;
  		} else if ( $type( index ) == 'element' ){
  			var el = collection._first; var _index = 0;			
  			while( el ){
  				if(el===index)return _index;
  				el = el.next;
  				_index++;
  			}
  			return -1;
  		}
  	},
  	
  	/**
  	 *	Close all sections if no errors present
  	 *	keep open the 'toOpen' sections
  	 *	'toOpen' : array of section
  	 */
  	'closeAll': function( toOpen ){
  		var section = this._first;
  		while( section ){
  			if ( ! toOpen.contains( section ) )
  				section.close.apply( section , [ false ] );
  			else
  				section.setCSSClasses();
  			section = section.next;
  		}
  		return this;
  	},
  	
  	
  	/**
  	 *	Thread: launch the validation function on all sections
  	 *	Submit button is enabled if no errors present
  	 */
  	'enableNextButton':function(){
  		if ( ! this.check() )
  			if ( this.timer )
  				return $clear( this.timer );
  		
  		this.errors = 0;
  		
  		var section = this._first;
  		while( section ){
  			
  			/* validation on all sections */
  			var _validation = section._validation( false , true );
  			

  			if(section.hasClass(Sliding.options['closed']) && 
  					(Sliding.options['displayAlwaysHandler'] || _validation)){
  				section.handler	&& section.handler.removeClass(Sliding.options['hide']);
  			}
  			
			this.errors = _validation ? this.errors : this.errors + 1;
  			
  			section = section.next;
  		}
  		
  		if ( this.errors == 0 ){
  		  
  		  if ( Sliding.options['onEnableButton'] &&  Sliding.options['onEnableButton'].apply ){
  		    
  		    Sliding.options['onEnableButton']();
  		    
  		  } else {
  		  
    			// enable button
    			this.nextButton.removeClass( Sliding.options[ 'disableButton' ] );	
    			this.nextButton.addClass( Sliding.options[ 'activeButton' ] );
    			// enable saving button
    			if(this.saveButton) {
    				this.saveButton.removeClass( Sliding.options[ 'disableSaveButton' ] );	
    				this.saveButton.addClass( Sliding.options[ 'activeSaveButton' ] );
    			}
  		  }
  		  
  		} else {
  		  
  		  if ( Sliding.options['onDisableButton'] &&  Sliding.options['onDisableButton'].apply ){
          
          Sliding.options['onDisableButton']();
           
  		  } else {
  		  
    			// disable button
    			this.nextButton.removeClass( Sliding.options[ 'activeButton' ] );	
    			this.nextButton.addClass( Sliding.options[ 'disableButton' ] );
    			// enable saving button 
    			if(this.saveButton) {
    				this.saveButton.removeClass( Sliding.options[ 'activeSaveButton' ] );	
    				this.saveButton.addClass( Sliding.options[ 'disableSaveButton' ] );
    			}
  		  }
  		  
  		}
  		
  		this.options.onEnableDisableButton && this.options.onEnableDisableButton.apply && this.options.onEnableDisableButton( this.errors == 0 );
  		
  	},
  	
  	/**
  	 *	Forward function: launch submit on form, default parameter is 'method=forward'
  	 */
  	'forward': function(){
  		if (  this.nextButton.hasClass( Sliding.options[ 'disableButton' ] )  )return false;
  		// destroy thread
  		$clear( this.timer);
  		if(Sliding.options['isAjax']){
  			this.submitFormWithAjax(this.nextButton);	
  		} else {
  			this.submitForm(this.nextButton);	
  		}
  	},
  	
  	/**
     *  Save function: launch submit on form, default parameter is 'method=forward'
     */
    'save': function(){
      if (  this.saveButton.hasClass( Sliding.options[ 'disableButton' ] )  )return false;
      // destroy thread
      $clear( this.timer);
      if(Sliding.options['isAjax']){
        this.submitFormWithAjax(this.saveButton);  
      } else {
        this.submitForm(this.saveButton);  
      }
    },
    
  	'submitForm':function(button){
  		// force check on 'nextButton'
  		if (  button.hasClass( Sliding.options[ 'disableButton' ] )  ) return false;
  		/* Modify action of form */
  		if ( $type( this.options.onSubmit ) == 'function' )
  			return this.options.onSubmit.call( this );
  		this.form.action = button.form.action.replace(/(\#.*)?$/, '?method=' + button.method + '$1');
  		myCursor.show();  
  		this.form.submit();		// submit form
  	},
  	
  	'submitFormWithAjax': function(button){
  		if ( button.hasClass( Sliding.options[ 'disableButton' ])) return false;
  		if ($type( this.options.onSubmit ) == 'function') {
  			return this.options.onSubmit.apply(this,[]);
  		}
  		
  		new Ajax( this.form.action, {
  			'onRequest':function(){myCursor.show();},
  			'onComplete':function(rsp){myCursor.hide();},
  			'evalScripts': true,
  			'update':this.containerId
  		}).request([
  		            'method=' +  Sliding.options['methodForward'],
  		            button.form.toQueryString()
  		           ].join('&')); 
  	
  	},
  	/**
  	 *	E L E M E N T S
  	 */
  	
  	/* Clear error of element: hide error div */
  	'clearError':function(){
  		
  		if ( this._error ){
  			this._error.addClass( Sliding.options[ 'hide' ] );
  			//this.section.resize();
  		}
  		
  		return this;
  	},
  	
  	/* Validate function of element: if 'show' is true show the error element if present */
  	'validateElement': function( show , thread ){
  		if ( ! this.form ) return true;
  		
  		var _validation = false;
  		
  		if ( this.getProperty( 'type' ) == 'radio' ) {
  			
  			// search and check other option radio
  			var _elements = this.form.elements[ this.name ];
  			for ( var i =0; i < _elements.length; i++ )
  				if ( _elements[i].checked ){
  					_validation = true;
  					break;
  				}
  		} else if ( this.getProperty( 'type' ) == 'checkbox' ){
  		  
  		  _validation = this.checked;
  		  
  		} else {
  			if(this.value == '')
  				_validation = false;
  			else if(this.value != '' && this.hasClass('hasDefaultText'))
  				_validation = false;
  			else 
  				_validation = true;
  		}
  		
  		
  		if ( $type( this.validation ) == 'function' )
  			_validation = this.validation( _validation , !!thread );
  		
  		
  		if ( show && this._error ) {
  		  this.showError( _validation );
  		}
  		
  		return _validation;
  		
  	},
  	
  	
  	
  	'showElementError': function(result) {
  	  if ( ! this._error ){
  	    return this;
  	  }
  	  
  	  this._error[ result ? 'addClass' : 'removeClass']( Sliding.options[ 'hide' ] );
      
      this.section.resize();
  	},
  	
  	
  	
  	/**
  	 * onBlur event 
  	 */
  	'onLostfocus': function(){
  	  /*
  	   * Validate element
  	   */
  		var validation = this._validation( true );
  		
  		if ( validation ){
  		  /*
  		   * Validation went right
  		   */
  		  
  		  
  		  /*
  		   * Check if element doesn't allow to close section
  		   */
  		  var skip = false;
  		  skip = this.hasClass( Sliding.options[ 'stopEventClass' ] ) || !this.section.hasClass( Sliding.options[ 'opened' ] );
  		  
  		  var sectionValidation = skip ? false : this.clip();
  		  var type = this.getProperty('type');
  		  
  		  
  		  /*
  		   *  NOTE: autonavigation is enabled skipping text field.
  		   *  When user presses 'TAB' or 'SHIFT-TAB' we have to skip autonavigation
  		   */
  		  if ( Sliding.options['autonavigation'] && (type != 'text' && type != 'password')  ){
  		    /*
  		     * autonavigation is eneble, select next element.
  		     */
  		    this.selectNextElement( sectionValidation );
  		  }
  		}
  		
  		return validation;
  	},
  	
  	
  	/**
  	 * This methods validates element's parent section.
  	 * Close element's parent section and open next section if present
  	 * @return boolean
  	 */
  	'clip': function(){
  		
  		var 
  		  sectionCorrect = this.section._validation( false );			// check all field in this section
  		
  		if ( sectionCorrect ) {
  		  
  			/* no errors are present */
  			if ( this.section.next ){
  				/* next section found, open it if its validation fails */
  				var _section = this.section.next;
  				
  				while( _section && _section._validation() ){
  					_section = _section.next;
  				}
  				
  				if ( _section ) {
  				  
  					if(_section.isRadioButtonSection){
  						_section.openRadioButtonSection( true , true ); 
  					} else {
  			  			if(Sliding.options['autoSliding']) {
  			  				_section.open( true , true );
  			  			} // Else is manually managed by handler link
  					}
  				}
  				
  			}
  			if(Sliding.options['autoSliding']) {
  				/* close this section */
  	  			this.section.close( true );
  			} // Else is manually managed by handler link
  			
  		} else {
  			
  			/* Bug fix: reset the size of content of section in case of 
  			 * error messages present in section and not present for this field
  			 */
  			//if ( elementCorrect )
  		  
  			this.section.resize();
  		}
  		
  		return sectionCorrect;
  	},
  	
  	
  	
  	/**
  	 *	S E C T I O N
  	 */
  	
  	/* clear all error in this section */
  	'clearErrors':function(){
  	
  		var element = this._first;
  		while( element ){
  			element.clearError();		// hide error of element
  			element = element.next;
  		}
  		return this;
  	},
  	
  	
  	/**
  	 *	Validation function: launch validation function on all given elements.
  	 *	if 'elements' is missing, 'elements' is 'all elements in section';
  	 *	if 'show' is true, show or hide the error message of single element
  	 *	'thread' indicates if function was called from 'enableNextButton' thread
  	 */
  	'validateSection':function( show , thread ){
  		this.errors = 0;
  		
  		var element = this._first;
  		while( element ){
  			if (  ! element._validation( show , !!thread )  )
  				this.errors++;		// an error found
  			element = element.next;
  		}
  		
  		var _result = (this.errors == 0);
  		
  		if ( $type(this.onValidation) == 'function' )
  			_result = this.onValidation( _result , !!thread );
  		
  		return _result;
  	},
  	
  	
  	/* Check for error messages shown */
  	'isErrorMessagePresent':function(){
  		var errors = 0;
  		
  		var element = this._first;
  		while( element ){
  			if ( element._error )
  				errors = element._error.hasClass( Sliding.options[ 'hide' ] )  ?  errors : errors + 1;
  			element = element.next;
  		}
  		
  		return (errors > 0);	// return boolean: are there any errors shown?
  	},
  	
  	'isErrorServerPresent':function(){
  		var errors = 0;
  		$ES('.error_message', this).each(function(element) {
  			if(!element.hasClass(Sliding.options['hide'])){
  				if(element.innerHTML.trim().length > 0) {
  					++errors;
  				}
  			}
  		});
  		return (errors > 0);
  	},
  	
  	
  	/* Select a given element in this section */
  	'selectElement': function( element ) {
  		try{
  			element = element || this._first;
  			element.focus();
  		} catch ( e ){
  			// alert( 'errore in focus' );
  		}
  	},
  	
  	/**
  	 *	Opens section. If 'select' is true, executes 'focus' event on first element in this section.
  	 *	Close all other sections, modify css classes and hide the handler link
  	 */
  	'open':function( select , skipClose ){
  		
  		if ( $type(this.onOpen) == 'function' )
  			if ( ! this.onOpen.apply( this , [] ) )
  				return;
  		
  		Sliding.options.onSectionOpen.apply( this , [] );
  		
  		// launch the slide effect, and select an element if 'select' is true
  		
  //		if ( select )
  //			this.fx.slideIn().chain( this.selectElement );	
  //		else
  		
  		
  		this.fx.slideIn().chain( (function() {
  			if (this.hasClass(Sliding.options['opened'])&& this.fx.element) {
  				if (this.fx.element.offsetHeight != this.fx.wrapper.offsetHeight){
  					this.fx.wrapper.setStyle('height',this.fx.element.offsetHeight);
  				}
  				//Bugfix for hidden div (claims)
  				if(this.fx.element.getBoundingClientRect().top != this.fx.wrapper.getBoundingClientRect().top){
  					var amountToSlide = this.fx.wrapper.getBoundingClientRect().top - this.fx.element.getBoundingClientRect().top;
  					this.fx.element.setStyle('margin-top', amountToSlide);
  				}
  				
  			}
  		}).bind( this ) );
  	
  		
  		if ( !skipClose ){
  			var section = Sliding._first;
  			while( section ){
  			
  				if (  section !== this && ! section.hasClass( Sliding.options[ 'closed' ]  )  )		// this is current section, "I will not close myself!"
  					section.close( true );	// close section
  				
  				section = section.next;
  			}
  		}
  		
  		if (this.hasClass(Sliding.options['noToggleClass']))
  			return this;
  		
  		
  		this.setCSSClasses();
  		
  		this.isOpen = true;
  		
  		return this;
  	},
  	
  	'openRadioButtonSection': function( select , skipClose ){
  		this.addClass( Sliding.options[ 'opened' ] );
  		this.removeClass( Sliding.options[ 'closed' ] );
  		
  		this.handler && this.handler.addClass( Sliding.options[ 'hide' ] );
  		
  		this.header.removeClass( Sliding.options[ 'closed' ] );
  		this.header.addClass( Sliding.options[ 'active' ] );
  	},
  	
  	/**
	 *	manage the handler link: 
	 *	for RFC 30136, open the section and display the 
	 *	closer link.
	 */
	'manageModifier':function( select , skipClose ) {
		if(Sliding.options['autoSliding']) {//Backward compatibility
			return this.open.apply( this , [] );
		} else {
			if(this.isOpen){
				var _validation = this._validation( false , true );
				if(_validation){
					return this.close.delay(100, this);
				}
			}else{
				return this.open.apply( this , [] );
			}
		}
	},
  	
  	
  	'setCSSClasses': function(){
  		/* modify css classes */
  		this.addClass( Sliding.options[ 'opened' ] );
  		this.removeClass( Sliding.options[ 'closed' ] );
  		if(Sliding.options['autoSliding']) {
  			this.handler && this.handler.addClass( Sliding.options[ 'hide' ] );
  		} else {
  			if(this.handler) {
  				this.handler.innerHTML = 'fermer';
  			}
  		}
  		this.header.removeClass( Sliding.options[ 'closed' ] );
  		this.header.addClass( Sliding.options[ 'active' ] );
  		this.footer.removeClass( Sliding.options[ 'hide' ] );
  	},
  	
  	
  	/* Resize body of section */
  	'resize': function() {
  		if(this.hasClass(Sliding.options['opened'])){
  			this.fx.slideIn();
  		}
  	},
  	
  	/* Close section and launch validation if 'validate' is true */
  	'close':function( validate ){
  		
  		if ( $type(this.onClose) == 'function' )
  			if ( ! this.onClose.apply( this , [] ) )
  				return;
  		
  		Sliding.options.onSectionClose.apply( this , [] );
  		
  		if ( validate )
  			if ( ! this._validation( true ) )	// launch validation
  				return this;	// vlidation failed, "do not close me"
  		
  		if (  ( this._validation() && !this.next )  &&  !Sliding.options[ 'closeLastSection' ]  )
  			this.addClass(Sliding.options['noToggleClass']); // do not close last section
  		
  		if (this.hasClass(Sliding.options['noToggleClass']))
  			return this;
  		
  		/* Fat - TODO : create a thread to keep open current section */
  		(function _close(){
  			
  			if ( window.ie8 ){
  				/** IE8 bug fix:
  				 * 		set 'offset' manually because IE8 doesn't retrieve that correctly
  				 */
  				var _height = this.content.offsetHeight;
  				this.fx.slideOut().chain( (function(){
  					this.fx.offset = _height;
  				}).bind( this ) );
  			} else
  				this.fx.slideOut();	// slide effect: close
  			
  			/* modify css classes */
  			this.removeClass( Sliding.options[ 'opened' ] );
  			this.addClass( Sliding.options[ 'closed' ] );
  			
  			this.header.removeClass( Sliding.options[ 'active' ] );
  			this.header.addClass( Sliding.options[ 'closed' ] );
  			this.footer.addClass( Sliding.options[ 'hide' ] );
  			
  			if(!Sliding.options['autoSliding']) {
  				this.handler.innerHTML = 'modifier';
  			}
  			
  			return this;
  			
  		}).delay( 1 , this );
  		
  		this.isOpen = false;
  		
  		return this;
  	},
  	'resetSection': function() {
  		$ES( 'input,select' , this ).each( function(element) {
  			if(!element.hasClass(Sliding.options['elementNotReset'])){
  				Sliding.resetElement(element);
  			}
  		} );
  	},
  	'resetElement': function( element ) {
  		if(!Sliding.options['defaultValues'].contains( element.value )){
  			if(!element.disabled){
  				if (element.tagName.toLowerCase() == 'input') {
  					if (element.type.toLowerCase() == 'text')
  						element.value = '';
  					if (element.type.toLowerCase() == 'password')
  						element.value = '';
  					if (element.type.toLowerCase() == 'radio' || element.type.toLowerCase() == 'checkbox')
  						element.checked = false;
  				}
  				if (element.tagName.toLowerCase() == 'select') {
  					element.selectedIndex = 0;
  				}
  			}
  		}
  	},
  	'getAllSectionsWithServerError' : function () {
  		var sectionsWithError = []; 
  		var section = Sliding._first;
  		while(section) {
  			if (section.isErrorServerPresent()) {
  				sectionsWithError.push(section);
  			}
  			section = section.next;
  		}
  		return sectionsWithError;
  	}
  	
  };
  
})();
