/******************************************************************************************
MooAjax is a mootools 1.2.x class for use a Ajax Request and returns <html>
Is a unobtrusive JavaScript and can run it without Javascript, for it use <noscript> tag

Example:  <a href="controller/action" class="mooajax.target[:event]" rel="controller/action" lang="es">my_link</a>
Example:  <select class="mooajax.target:change" name="mi_select">...</select>
Example:  <input type="submit" class="mooajax.target" name="mi_button" lang="idioma" />

Runnable on: Internet Explorer 6, 7 y 8 , Firefox 2 y 3, Opera 9.5, Safari 3 & Chrome 1.0
Valid for: XHTML 1.1, XHTML 1.0 Strict/Transitional and HTML 4/5

@Author: Ricard Catalan Díaz
@Version: 0.6.3  En esta revision se ha añadido el tag LANG para recargar el objeto
@License: GNU
*****************************************************************************************/
var MooAjax = new Class({
     options:{
          divEvent: 'event',  //Capa opcional donde contendrá el divLoading y que esta definida en HTML y CSS y solo cambia su estado display
          divLoading: 'estado',  // Capa contenedora donde mostrar div loading, error, succes, etc.
          fx: 'opacity', //Efecto a mostrar cuando se cargue el contenido. False para desabilitar
          duration: 1000,  //Tiempo de duración del efecto (en ms)
          transition: 'Fx.Transitions.Circ.easeOut',
          request: {
               //ruta de la imágen que muestra la carga del contenido
               loadingImg: '<img src="../media/img/loader.gif" alt="" />',
               loadingImg2: '<img src="../media/img/loader2.gif" alt="" />',
               encoding:'utf-8'
          },
          submit: '',
          failure: '<b>Ha ocurrido un error</b> y no se ha podido cargar el contenido. Disculpe las molestias.',
          checkestado: 0
     },
     //Constructor de la clase MooAjax, captura todos los elementos con la clase que contenga la palabra "mooajax.xx[:yy]"
     initialize: function(){
          $$('[class*=mooajax]').each(function(el){
               //if(el.getProperty('type')=='submit') el.setProperty('type', 'button');
               //comprovamos si hay dos puntos dentro del nombre de la clase y si es el caso capturamos el tipo de evento
               if(el.get('class').match(':') ) this.event = el.get('class').slice(el.get('class').lastIndexOf(':')+1);
               else this.event = 'click';
               // la propiedad lang nos indicará si a ese elemento ya se le ha asignado el evento
               // de esta manera, no se añadirán múltiples eventos
               if( el.getProperty('lang') != 'es' ) {
                 el.setProperty( 'lang','es' );
                 el.addEvent(this.event, function(e){
                      new Event(e).stop();
                      this.tagType(el);
                 }.bind(this));
               }

          }.bind(this));
     },
     tagType: function(el){
          //Depende del <tag> realizaremos un proceso de capturas de datos u otras
          switch(el.get('tag')){
               // IE 6 con envio método POST no funciona correctamente al devolverle con GET, por defecto se especifica GET, excepto type SUBMIT
               case 'a':      el.set('href','#'); //Eliminamos el link, para que no cargue la página
                              this.method ='get';
                              if( el.getParent('form') ) this.data = el.getParent('form').toQueryString();
                              this.path = el.getProperty('rel');
                              break;
               case 'input': if(el.get('type') == 'submit' || el.get('type') == 'button' || el.get('type') == 'radio'){
                                  this.method = el.getParent('form').get('method');
                                  $(this.options.divEvent).setStyle('display','block'); //Cambiamos opcion de la css para mostrar el contenido
                              }else{
                                  this.method ='get';
                              }
                              this.path = el.getParent('form').get('action');
                              this.data = el.getParent('form').toQueryString();
                              break;
               case 'select': this.method ='get';
                              this.path = el.getParent('form').get('action');
                              this.data = el.getParent('form').toQueryString();
                              break;
	}
         //Para los campos input del tipo TEXT para no realizar constantes consultas se realiazarán consultas con un mínimo de 4 carácteres
         if(el.get('tag')=='input' && el.get('type')=='text' || el.get('type')=='password' ){
              if( el.getProperty('value').length >= 4) this.htmlRequest(el);
         }else{
              this.htmlRequest(el);
         }
     },
     htmlRequest: function(el){
          //Capturamos el target para cada clase del tipo mooajax
         if(el.get('class').match(':') ) this.target = el.get('class').slice( el.get('class').lastIndexOf('.')+1,el.get('class').lastIndexOf(':') );
         else this.target = el.get('class').slice( el.get('class').lastIndexOf('.')+1 );
         //Creamos instancia del objeto Request.HTML
         this.request = new Request.HTML({
              method: this.method,
              data: this.data,
              url: this.path,
              evalScripts: true,
              encoding: this.options.request.encoding,
              headers: {
                   'Pragma':'no-cache',
                   'cache-control': 'no-store,  must-revalidate'
              },
              onRequest: function(){
                    if(this.path=='/e-notificacion/solicitar/e-notificacion'){ 
                          setTimeout(this.failed.bind(this), 10000); //Comprobamos disponibilidad eNotificación en 10 segundos
                    }
                    /* dentro de onComplete se elimina la capa "loader", sin embargo si clicamos varias veces en poco tiempo suelen quedar capas de carga.
                     * para evitarlo realizamos si existe la capa "loader"  un borrado de la misma */
                   if($('loader')) $('loader').destroy();
                   $(this.options.divLoading).empty(); //Vaciamos contenido
                   if(el.get('title')) var loadingText = el.get('title'); //Si añadimos un tag <title> aparecerá al lado de la imágen de carga
                   else  loadingText ='';
                   //Durante la cosulta mostramos la imágen de carga
                   if(el.getNext() && el.getNext().get('id') ){
                        $(this.options.divEvent).setStyle('display','none'); //Cambiamos opcion de la css para mostrar el contenido
                        this.loading = new Element( 'div', { 'id': 'loader', 'html': this.options.request.loadingImg2+" "+loadingText  });
                        this.loading.injectInside(el.getNext().get('id'));
                   }else{ //Cargamos en la capa divEvento que contiene el divLoading
                        this.loading = new Element( 'div', { 'id': 'loader', 'html': this.options.request.loadingImg+" "+loadingText  });
                        if($(this.options.divEvent)){
                             $(this.options.divEvent).setStyle('display', 'block');
                             $(this.options.divEvent).removeProperty('class'); //Eliminamos el atributo class
                             $(this.options.divEvent).addClass('loading');
                             this.divEvent = this.options.divEvent;
                             this.loading.injectInside(this.options.divLoading);
                        }else{
                              this.loading.injectInside(this.options.divLoading);
                        }
                   }
              }.bind(this),
              onComplete: function(a,b,c){
                   //Comprovamos en C si hay que realizar cambios en la barra de estados
                   this.options.checkestado = 1;
                   if(c){
                        if( c.match(/^\[\w+\]/) ){
                              this.estado = c.slice( c.lastIndexOf('[')+1,c.lastIndexOf(']') );
                              if(this.estado=='error')  $(this.options.divEvent).addClass('error');
                              else if(this.estado=='ok')  $(this.options.divEvent).addClass('ok');
                              else if(this.estado=='alert')  $(this.options.divEvent).addClass('alert');
                              $(this.target).setProperty('html', c.slice( c.lastIndexOf(']')+1));
                         }else{
                              $(this.target).setProperty('html', c);
                         }
                   }else{
                        $(this.options.divEvent).addClass('error'); //Cambiamos estilo
                        $(this.target).setProperty('html', this.options.failure); //En caso de error mostramos el mensaje
                   }
                   if(this.options.fx){
                        if(this.divEvent) this.effect(this.divEvent); //Si tenemos la opción de efecto activada lo ejecutamos
                        else this.effect(this.target);
                   }
                   this.loading.destroy(); //eliminamos el div creado para mostrar el Loading al finalizar la carga
                   if( $(this.options.divLoading).get('html')=='' ) $(this.options.divEvent).setStyle('display', 'none'); //Si divLoading esta vacio, ocultamos la capa Evento
                   // En casos de cargar un mooajax y tener que cargar de nuevo usaremos en la 1a carga el atributo LANG, para indicar que necesitamos crear de nuevo el objeto
                   var mooj = new MooAjax;
              }.bind(this)
          }).send();
     },
     effect: function(target){
          switch(this.options.fx){
               //Creamos efecto Morph con transición de opacidad de 0 a 1
               case 'opacity': var opacityFx = new Fx.Morph($(target), {duration: this.options.duration});
                                    $(target).setOpacity(0);
                                    opacityFx.start({'opacity':1});
                                    break;
               //Creamos efecto Tween
               case 'tween': var tweenFx =  new Fx.Tween(target, {duration: this.options.duration});
                                   tweenFx.start('background-color', '#fff', '#ddd');
                                   break;
               //Creamos efecto Slide
               case 'slide': if(this.options.transition) var slideFx = new Fx.Slide(target,{duration: this.options.duration, transition: this.options.transition });
                                 else slideFx = new Fx.Slide(target,{duration: this.options.duration});
                                 slideFx.hide().slideIn(); //Desplegamos DIV con el resto de campos
                                 break;
          }
     },
     failed: function(){ //Si no se modificó el estado en 10 segundos mostramos error
           if(!this.options.checkestado) $(this.target).setProperty('html', '<div style="display: block;" class="alert" id="event"><div class="left"></div><div id="estado" style="width: 400px"><img title="aviso" alt="aviso" src="/media/img/icons/alert.png"/><b>Servicio no disponible temporalmente.</b></div><div id="delete"><a href="/e-notificacion/no-disponible#"><img title="borrar estado" alt="borrar estado" src="/media/img/icons/delete-bar.png"/></a></div><div class="right"></div><div class="both"></div></div><br /><p>Ha ocurrido un fallo de conexión con nuestro proveedor del servicio de <b>e-Notificación</b>.<br/>Para evitar una compra errónea espere unos minutos antes de volver a intentarlo.<br/>Si persiste el error, por favor póngase en contacto con nosotros en el 902 11 89 40, o bien en nuestro <a href="http://www.gestoriaonline.com/contacte-con-nosotros">formulario de contacto</a>.</p>');
     }
});
