/**
 *  classe pour le test et traitement des formulaires
 */

dojo.declare('MBRForm', null, {
  /**
  *  scroll vers le haut après validation du formulaire
  *  type : boolean
  *  ATTENTION : pour l'utilisation du scroll
  *  il faut penser à charger dojox.fx dans la page courante
  *  dojo.require('dojox.fx.scroll');
  */
  bScrollToTop : true,
  /**
  *  utilisation de la soumission classique ( pas d'ajax )
  *  type : boolean
  */
  bClassicSubmit : false,
  /**
   * label message d'erreur
   */
  errorLabelMessage : 'Merci de remplir correctement les champs suivants :',
  /**
   *  object de messages d'erreurs personnalisés
   *  type : object
   *  structure : { fieldName : valeur du message à afficher }
   */
  errorMessages : {},
  /**
   *  tableau des champs à ne pas traiter au niveau des erreurs
   */
  aExceptionFields : new Array(),
  /**
   *  tableau des types de champs à ne pas traiter au niveau des erreurs
   */ 
  aExceptionType : new Array(),
  /**
   *
   */
  xhrHandleAs: 'text',         
  /**
   *  l'element FORM
   */
  oFrm : null,
  /**
   *  sauvegarde des valeurs par défault
   */
  aStoredValues: new Array(),
  /**
   *  sauvegarde des event sur les éléments
   */
  aStoredEvents: new Array(),
  /**
   *  { fieldName : longueur mini  }
   */
  minLengthValue : {} ,    

  options:
  {
    aExceptionFields : new Array(),
    aExceptionType : new Array(
  		'image',
		'submit',
		'hidden',
		'button'
    ),
    aErrorEmptyFields : new Array(),
    aQueryStringKey : new Array(),
    aQueryStringValue : new Array(),
    aDefaultValues : new Array(),
    bErrorMessagePersonalized : false
  },
  /**
   *  Constructeur
   *  oFrm              : le formulaire
   *  type object ou string
   *
   *  elementFormSubmit : element permettant la soumission du formulaire ( input type submit ou lien )
   *  type object ou string
   */
  constructor: function( oFrm, elementFormSubmit )
  {			
    this.oFrm = (dojo.isString(oFrm)) ? dojo.byId(oFrm) : oFrm;
    if(this.oFrm==null){
      alert('Attention:\nL\'ID du formulaire fourni n\'existe pas');
      return false;
    }
    this.elementFormSubmit = (dojo.isString(elementFormSubmit)) ? dojo.byId(elementFormSubmit) : elementFormSubmit;

    var oThis = this;
    //  activation des éléments du formulaire
    this.MBREnableElements();

    if( this.elementFormSubmit!=undefined ){
        dojo.connect( this.elementFormSubmit, 'onclick', function(event){
    			if( oThis.MBRFormSubmit() == false ) {
    				dojo.stopEvent(event);
    			}
    		});
      }
    else {
      dojo.connect( this.oFrm, 'onsubmit', function(event){
				if( oThis.MBRFormSubmit() == false ) {
					dojo.stopEvent(event);
				}
			});
    }
    this.addTokens();
	},
  /**
   * Activation des éléments du formulaire si ceux ci n'ont pas la class CSS disabled
   */
  MBREnableElements: function()
  {
    dojo.filter(dojo.query('*', this.oFrm), function(element){
      if( dojo.attr(element, 'disabled')!=null && dojo.hasClass(element,'disabled')===false ){
        dojo.attr(element, 'disabled', false);
      }
    });
  },
  /**
   * Désactivation des éléments du formulaire
   */
  MBRDisableElements: function()
  {
    dojo.filter(dojo.query('*', this.oFrm), function(element){
      dojo.attr(element, 'disabled', 'disabled');      
    });
  },
  /**
   *  Traiement des champs non renseignés et obligatoires
   */
  MBRAppendEmptyField: function( fieldElement, bRemove )
  {
    if( bRemove == undefined )
			bRemove = false;
	    if( fieldElement.type=='checkbox' || fieldElement.type=='radio') {

	      if( this.errorMessages[fieldElement.name]!=undefined ) {
	        var fieldLabel = this.errorMessages[fieldElement.name];
	        this.options.bErrorMessagePersonalized=true;
	      }
	      else if(this.errorMessages[fieldElement.id]!=undefined) {
	        var fieldLabel = this.errorMessages[fieldElement.id];
	        this.options.bErrorMessagePersonalized=true;
	      }
	      else {
	        if( dojo.query('*', fieldElement.parentNode)[0].innerHTML!=undefined && dojo.query('*', fieldElement.parentNode)[0].innerHTML!='') {
	          var fieldLabel =dojo.query('*', fieldElement.parentNode)[0].innerHTML;
	        }
	        else {
	          var fieldLabel = fieldElement.name;
	        }
	      }
		}
		else {
        if( this.errorMessages[fieldElement.name]!=undefined ) {
	        var fieldLabel = this.errorMessages[fieldElement.name];
	        this.options.bErrorMessagePersonalized=true;
	      }
	      else if(this.errorMessages[fieldElement.id]!=undefined) {
	        var fieldLabel = this.errorMessages[fieldElement.id];
	        this.options.bErrorMessagePersonalized=true;
	      }
	      else if( dojo.query( 'label',fieldElement.parentNode )!=undefined
          && dojo.query( 'label',fieldElement.parentNode ).length > 0 
          && dojo.query( 'label',fieldElement.parentNode )[0].innerHTML!=undefined 
          && dojo.query( 'label',fieldElement.parentNode )[0].innerHTML!='') {
	        var fieldLabel = dojo.query( 'label',fieldElement.parentNode )[0].innerHTML;
	      }
	      else {
	        var fieldLabel = fieldElement.name;
	      }
    }

    if( bRemove==true && dojo.indexOf(this.options.aErrorEmptyFields,fieldLabel)!=-1 ) {
			this.options.aErrorEmptyFields.pop();
		}
		else if( bRemove==false && dojo.indexOf(this.options.aErrorEmptyFields,fieldLabel)==-1 ) {
			if( dojo.indexOf(this.options.aQueryStringKey,fieldElement.name)==-1 )
				this.options.aErrorEmptyFields.push( fieldLabel );
		}
	},
	/**
	 *  Récupération des données des champs
	 */
	MBRAppendQueryString: function( fieldElement )
	{
		this.options.aQueryStringKey.push( fieldElement.name );
		this.options.aQueryStringValue.push( encodeURIComponent(fieldElement.value) );
	},
	/**
	 *  Traitement des champs
	 */
	MBRManageField: function( fieldElement )
	{    
	  if(fieldElement.type=='checkbox' || fieldElement.type=='radio') {
			if( fieldElement.checked == false )
				this.MBRAppendEmptyField( fieldElement );
			else{
				this.MBRAppendEmptyField( fieldElement, true );
				this.MBRAppendQueryString( fieldElement );
			}
		}
		else if( ( fieldElement.type=='file' && fieldElement.value.length==0 )
				|| (fieldElement.tagName == 'select'
				&& fieldElement.selectedIndex>-1
				&& fieldElement.options[fieldElement.selectedIndex].value == null)
				|| (fieldElement.value!=undefined && fieldElement.value.length==0)
        || (this.minLengthValue[fieldElement.name]!=undefined &&
					fieldElement.value.length<this.minLengthValue[fieldElement.name])
				|| fieldElement.value==this.options.aDefaultValues[fieldElement.name]
        || (this.aStoredValues[this.oFrm.id]!=undefined && 
					fieldElement.value==this.aStoredValues[this.oFrm.id][fieldElement.name]) )
			this.MBRAppendEmptyField( fieldElement );
		else
		{
      if( fieldElement.name.indexOf('email')!=-1 && fieldElement.value.isEmail()==false )
				this.MBRAppendEmptyField( fieldElement );
			else if( fieldElement.name.indexOf('url')!=-1 && fieldElement.value.isURL()==false )
				this.MBRAppendEmptyField( fieldElement );
			else
				this.MBRAppendQueryString( fieldElement );
		}
	},
	/**
	 *  gestion des valeurs par défaut des champs des formulaires
	 */
	MBRFormDefaultValues: function()
	{
		var oThis = this;
		try {
      var aElm = dojo.query('textarea','input','select', this.oFrm);
			dojo.forEach(aElm, function(element){
				if(dojo.indexOf(['input', 'select', 'textarea'], element.tagName.toLowerCase())>-1){
					if( element.name && element.value != '' ){
						oThis.options.aDefaultValues[ element.name ] = element.value;
					}
				}
			});
		}
		catch(e)
		{
			alert( 'Erreur Javascript:\nmessage: '+e['message']
                             +'\nfileName: '+e['fileName']+'\nlineNumber: '+e['lineNumber']
                             +'\n\nstack: '+e['stack']+'\nname: '+e['name'] );
		}
	},
	/**
	 *  fonction principale du traitement de la soumission du formulaire
	 */
	MBRFormSubmit: function()
	{
    /**
     *  pour l'utilisation du scroll
     *  il faut penser à charger dojox.fx dans la page courante
     *  dojo.require('dojox.fx.scroll');
     */
    if(this.bScrollToTop && dojox.fx!=undefined) {
		  var anim = dojox.fx.smoothScroll({
                                  node: dojo.query('body')[0],
                                  win:window,
                                  duration:300
      }).play()
    }

		this.options.aErrorEmptyFields = new Array();
		this.options.aQueryStringKey = new Array();
		this.options.aQueryStringValue = new Array();

		if( this.aCheckDate != undefined ){
			dojo.forEach(this.aCheckDate, function(el){
				el.MBRDateCheck();
			});
		}

		if( this.aExceptionFields != undefined ){
			this.options.aExceptionFields = this.options.aExceptionFields.concat(this.aExceptionFields);
		}
		if( this.aExceptionType != undefined ){
			this.options.aExceptionType = this.options.aExceptionType.concat(this.aExceptionType);
		}

		var options = this.options;
		var oThis = this;
		try{
			dojo.filter(dojo.query('*', this.oFrm), function(element){
				if(dojo.indexOf(['input', 'select', 'textarea'], element.tagName.toLowerCase())>-1){
					if( dojo.indexOf( oThis.options.aExceptionFields, element.name )==-1
						&&  dojo.indexOf(oThis.options.aExceptionType, element.type )==-1
						&& dojo.attr(element,'disabled')==false) {
						oThis.MBRManageField( element );
					}
					else if( element.type=='hidden' || dojo.indexOf(oThis.options.aExceptionType,element.type)==-1 ){
          				
    
                   if(dojo.indexOf(oThis.aExceptionFields,element.name)>-1 &&
                        oThis.aStoredValues[oThis.oFrm.id]!=undefined 
                        && element.value==oThis.aStoredValues[oThis.oFrm.id][element.name]){
                           dojo.attr(element,'value','');
                      
                   }
            
						oThis.MBRAppendQueryString( element );
					}
				}
			});
			if( this.options.aErrorEmptyFields.length > 0 ){
        if(this.options.bErrorMessagePersonalized==false)
        	alert( this.errorLabelMessage+'\n'+this.options.aErrorEmptyFields.join('\n') );
        else
          alert( this.options.aErrorEmptyFields.join('\n') );
			}
			else
			{
				var myQueryString = '';
				if( this.bClassicSubmit == false ){
					for(i=0; i< this.options.aQueryStringKey.length; i++ ){
						myQueryString += this.options.aQueryStringKey[i]+'='+this.options.aQueryStringValue[i]+'&';
					}
					this.MBRDoXHRSubmit(myQueryString);
				}
				else
					return this.MBRDoSubmit();
			}

		}
		catch(e){
			alert( 'Erreur Javascript:\nmessage: '+e['message']
			                 +'\nfileName: '+e['fileName']+'\nlineNumber: '+e['lineNumber']
			                 +'\n\nstack: '+e['stack']+'\nname: '+e['name'] );
		}

		return false;
	},
	/**
	 *  soumission classique du formulaire
	 */
	MBRDoSubmit: function()
	{
		return true;
	},
	/**
	 *  soumission du formulaire via XHR ( ajax )
	 */
	MBRDoXHRSubmit: function(myQueryString)
	{
		if(this.oFrm.method==undefined)
		  var method = 'GET';
		else
		  var method = this.oFrm.method.toUpperCase();
		  
		var oThis = this;
		dojo.xhr(this.oFrm.method,{
			url:this.oFrm.action,
			form: this.oFrm,
			handleAs: this.xhrHandleAs,
			handle: function(data,args){
				oThis.data = data;
				oThis.args = args;
				if(typeof data == "error"){
	  				  oThis.MBRonErrorSubmit();
	  			}else{
	  				  oThis.MBRonCompleteSubmit();
	  			}
			}
		}, (method=='POST') );
	},
	/**
	 *  Fonction de traitement après la validation du formulaire XHR
	 *  à surcharger
	 */
  MBRonCompleteSubmit: function() {
  },
	/**
	 *  Fonction de traitement des erreurs de la validation du formulaire XHR
	 *  à surcharger éventuellement
	 */
  MBRonErrorSubmit: function() {
    alert('Une erreur est survenue, merci de renouveler ult�rieurement....');
  },
  
  /**
   *  sauvegarde des valeurs par défault 
   *  et ajout évènements   
   */  
  saveDefaultValues: function() {
    var oThis=this;
    oThis.aStoredValues[oThis.oFrm.id]=new Array();
    oThis.aStoredEvents[oThis.oFrm.id]=new Array();
    
    dojo.filter(dojo.query('input,textarea', this.oFrm), function(element){
    
      if(element.value!='' && dojo.attr(element,'name')!=null && dojo.attr(element,'type')!='submit'){
      
        if(oThis.aStoredValues[oThis.oFrm.id][ dojo.attr(element,'name') ]==undefined)
          oThis.aStoredValues[oThis.oFrm.id][ dojo.attr(element,'name') ]=element.value;
        oThis.aStoredEvents[oThis.oFrm.id]['focus'+dojo.attr(element,'name')]=dojo.connect(element,'onfocus', function(event){
        
          if(element.value==oThis.aStoredValues[oThis.oFrm.id][ dojo.attr(element,'name') ])
            element.value='';
        });
        oThis.aStoredEvents[oThis.oFrm.id]['blur'+dojo.attr(element,'name')]=dojo.connect(element,'onblur', function(event){
          if( element.value.trim()=='' )
            element.value=oThis.aStoredValues[oThis.oFrm.id][ dojo.attr(element,'name') ];
        });
      }
    });
  },
  
  /**
   *
   */
  addTokens:function(){
    var inputToken=document.createElement('input');
    dojo.attr( inputToken, {type:'hidden', name:'tokenForm', id:'idTokenForm', value:''} );
    this.oFrm.appendChild(inputToken);
    /**
     *
     */         
    dojo.require( 'dojox.encoding.digests.MD5' );        
    var myHash = dojox.encoding.digests.MD5( dojo.attr(this.oFrm,'action'), dojox.encoding.digests.outputTypes.Hex );    
    var inputToken=document.createElement('input');
    dojo.attr( inputToken, {type:'hidden', name:'cTokenForm', id:'idcTokenForm', value:myHash} );
    this.oFrm.appendChild(inputToken);    
  },   
  /**
   * add textarea limit character
   */
  addTextareaLimit:function(limit, label){
	  if(label==undefined)
		  var label=' caract&egrave;res restants';
	  dojo.filter(dojo.query('*', this.oFrm), function(element){
		  if(dojo.indexOf(['textarea'], element.tagName.toLowerCase())>-1){
			  var p = document.createElement('p');
			  dojo.addClass(p, 'legende');
			  dojo.attr(p,'id','txtAreaLength');
			  dojo.style(p,{textAlign:'right'});
			  p.innerHTML=limit+label;
			  element.parentNode.parentNode.insertBefore(p,element.parentNode.nextSibling);
			  dojo.connect(element, 'onkeyup', function(evt){				  
				  if(element.value.length>limit){
					  element.value=element.value.substr(0,limit);
				  }
				  var resteCaracteres=(limit-element.value.length);

				  if(resteCaracteres>1){
					  dojo.byId('txtAreaLength').innerHTML=resteCaracteres+' caract&egrave;res restants';
				  } else {
					  dojo.byId('txtAreaLength').innerHTML=resteCaracteres+' caract&egrave;re restant';
				  }
			  });
			  
		  }
	  });
  }
});
