/**
 * Object d'autocomplétion
 * développé par Laurent Chaloupe pour 01net
 * 
 * On peut grace à une instance avoir plusieur champ qui utilise l'autocomplétion
 *
 * @param ajax = nom du fichier à appeler
 * @param id   = nom du champ
 * @param min  = nombre de caractére pour executer l'autocomplétion
 */
function suggest( ajax, id, min ) {
  // initialise les variables
  if( !min ) min = 3;
  
  var parenthis  = this;
  this.ajax      = ajax;
  this.id        = id; // ID du champ que l'on redéfini pour l'autocomplétion
  this.limit_min = min;
  this.old_value = "";
  this.sel       = { current: -1,
                     nbr: 0,
                     list: new Array()
                   };

  $( this.id ).set( "autocomplete", "off" );
  
  this.insert_box();
  
  $( this.id ).addEvent( 'keyup', function( e ) {
    if( e.code == 40 )
      parenthis.descend();
    else if( e.code == 38 )
      parenthis.monte();
    else if( parenthis.verif( e.code ) && e.code != 13 )
      {
      new Event(e).stop(); // desactive les evenements
      parenthis.load_list();
      }
    });
  
  // Si on clique ailleurs alors ferme la fenetre si elle est précédement ouverte
  document.addEvent( 'click', function( event ) {
    if( $( event.target ).get( "id" ) != parenthis.id && $( parenthis.id + "_aff" ).getStyle( 'display' ) == "inline" )
      {
      $( parenthis.id + "_aff" ).setStyle( 'display', 'none' );
      $( parenthis.id + "_ombre" ).setStyle( 'display', 'none' );
      }
    });
  }


/**
 * Crée les box en dom
 */
suggest.prototype.insert_box = function() {
  var div_aff  = new Element( 'div', { "id": this.id + "_aff", "class": "suggest" } );
  var divombre = new Element( 'div', { "id": this.id + "_ombre", "class": "suggest_ombre" } );
  
  $( div_aff ).injectAfter( this.id );
  $( divombre ).injectAfter( this.id );
  };


/**
 * Verifie si le nombre de carac et supérieur à la limite et s'il y a une modif depuis la derniere fois
 * 
 * @return 1 si vrai
 */
suggest.prototype.verif = function( touche ) {
  if( $( this.id ).value.length < this.limit_min )
    {
    if( $( this.id + "_aff" ).getStyle( 'display' ) == 'inline' )
      {
      $( this.id + "_aff" ).setStyle( 'display', 'none' );
      $( this.id + "_ombre" ).setStyle( 'display', 'none' );
      }

    this.old_value = "";
    return 0;
    }
  else
    {
    if( this.old_value != $( this.id ).value )
      {
      if( touche == 27 )
        {
        if( $( this.id + "_aff" ).getStyle( 'display' ) == 'none' )
          return 0;
        
        this.sel.list[ this.sel.current ].removeClass( 'sele' );
        this.sel.current = -1;
        $( this.id ).value = this.old_value;
        
        return 0;
        }
      else
        {
        this.old_value = $( this.id ).value;
        return 1;
        }
      }
    }
  };
  
  
/**
 * Charge la liste de recherche trouvée et la place juste en dessous de l'element
 */
suggest.prototype.load_list = function() {
  var parenthis = this;

  $( this.id ).addClass( 'ajax-loading' );
  
  var ajax = new Request.HTML( { method: 'post', 
    url: this.ajax,
    onComplete: function() {
      $( parenthis.id ).removeClass( 'ajax-loading' );
      
      if( !$( parenthis.id + "_aff" ).get( 'text' ).length )
        {
        $( parenthis.id + "_aff" ).setStyle( 'display', 'none' );
        $( parenthis.id + "_ombre" ).setStyle( 'display', 'none' );
        }
      else
        {
        var xy = $( parenthis.id ).getCoordinates();

        $( parenthis.id + "_aff" ).setStyles( { 'display': 'inline',
                                                'left': xy.left + "px",
                                                'top': xy.top + xy.height + "px" });
        
        $( parenthis.id + "_ombre" ).setStyles( { 'width': $( parenthis.id + "_aff" ).clientWidth + "px",
                                                  'height': ( $( parenthis.id + "_aff" ).clientHeight -3 ) + "px",
                                                  'left': xy.left + "px",
                                                  'top': xy.top + xy.height + "px",
                                                  'display': 'inline' });
        }
      
      parenthis.init_sel( Array());
      }, 
    update: parenthis.id + "_aff"
    });

  ajax.cancel(); // stop l'ancienne requette ajax
  ajax.send( "recherche=" + $( this.id ).value );
  };


/**
 * initialise la liste de selection pour le déplacement clavier
 */
suggest.prototype.init_sel = function ( liste_a ) {
  this.sel.list    = liste_a;
  this.sel.nbr     = liste_a.length;
  this.sel.current = -1;
  };

  
/**
 * permet de monter dans une selection et de remplacer la valeur du champ "this.id" par celle de la selection
 */
suggest.prototype.monte = function () {
  if( $( this.id + "_aff" ).getStyle( 'display' ) == 'none' )
    return;
  
  if( !this.sel.nbr )
    this.init_sel( $( this.id + "_aff" ).getChildren( 'a' ));
  
  if( this.sel.current != -1 )
    {
    this.sel.list[ this.sel.current ].removeClass( 'sele' );
    }
  
  if( this.sel.current <= 0 )
    {
    if( this.sel.current == 0 )
      {
      this.sel.current = -1;
      $( this.id ).value = this.old_value;
      }
    else if( this.sel.current == -1)
      {
      this.sel.current = this.sel.nbr -1;
      this.sel.list[ this.sel.current ].addClass( 'sele' );
      $( this.id ).value = this.et_commercial( this.sel.list[ this.sel.current ].get( 'html' ));
      }
    }
  else
    {
    this.sel.list[ --this.sel.current ].addClass( 'sele' );
    $( this.id ).value = this.et_commercial( this.sel.list[ this.sel.current ].get( 'html' ));
    }
  };
  
  
/**
 * permet de descendre dans une selection et de remplacer la valeur du champ "searchstring" par celle de la selection
 */
suggest.prototype.descend = function () {
  if( $( this.id + "_aff" ).getStyle( 'display' ) == 'none' )
    return;
      
  if( !this.sel.nbr )
    this.init_sel( $( this.id + "_aff" ).getChildren( 'a' ));
  
  if( this.sel.current != -1 )
    {
    this.sel.list[ this.sel.current ].removeClass( 'sele' );
    }
  
  if( this.sel.current +1 == this.sel.nbr )
    {
    this.sel.current = -1;
    $( this.id ).value = this.old_value;
    }
  else
    {
    this.sel.list[ ++this.sel.current ].addClass( 'sele' );
    $( this.id ).value = this.et_commercial( this.sel.list[ this.sel.current ].get( 'html' ));
    }
  };
  

/**
 * Convertie un "&amp;" html en "&"
 * 
 * @param txt = texte à convertir
 * @return texte corrigé
 */
suggest.prototype.et_commercial = function( txt ) {
  return txt.replace( /(&amp;)/g, "&" );
  //return txt.split( "&amp;" ).join( "&" );
  };
  