var ac_timeOut = 10000; // Autocomplete Timeout in ms (-1: autocomplete never time out)
var ac_startOut = 1000; // autocomplete start en millisecond (-1; instantanné)
var ac_lim = 5; // Number of elements autocomplete can show (-1: no limit)
var ac_width_minimum = 100; // taille minimum
var ac_width_full = 100; // taille appliquée quand taille minimum dépassée
var ac_url = '/js/autocomplete.php?';
var ac_final_url = ac_url;
var ac_caracteres_minimum = 3; // nombre minimum de caractères requis
var ac_nouvelle_valeur_definie = false; // une valeur a t elle été définie ?

var ac_keywords = []; // valeurs trouvées après recherche AJAX
var ac_display = false; // affiche ou non le tableau
var ac_pos = 0; // position courante
var ac_curr = null; // input courant
var ac_rangeu = 0; // ???
var ac_ranged = 0; // ???
var ac_toid; // id timeout
var ac_soid; // id startout
var mouse_on_list = 0; // souris sur la liste ou pas
var ac_handler_on_penter = null; // function a trigger quand une selection est faite ( penter() )
var ac_current_request = 0; // id de la requete en cours
var ac_last_recherche = null; // dernière texte recherche, la valeur entree

var ac_plugs =
{
  focus:{},
  enter:{}
};

var _KEY_UP = 38;
var _KEY_DOWN = 40;
var _KEY_ENTER = 13;
var _KEY_RIGHT = 39;
var _KEY_ESC = 27;

function ac_checkkey(evt)
{
  var a = evt.keyCode;
  if ( a == _KEY_UP )
  {
    ac_goup();
  }
  else if ( a == _KEY_DOWN )
  {
    ac_godown();
  }
  else if ( a == _KEY_ENTER )
  {
    ac_penter(evt);
  }
}

function ac_setval(val, hid)
{
  if ( typeof ac_curr == 'undefined' )
  {
    return false;
  }
  ac_curr.value = val;
  var nom = ac_curr.name.substr(3, 200);
  ac_curr.form.elements[nom].value = hid;
  return true;
}

function ac_penter(evt)
{
  if ( !ac_display )
  {
    return false;
  }
  ac_display = false;
  var K = ac_keywords[ac_pos - 1];
  try
  {
    // on trim en ajoutant des espaces pour éviter les erreurs si le type est numérique
    var val = ' ' + K.txt + ' ';
    var hid = ' ' + K.id + ' ';
    if ( typeof K.txtvisible != 'undefined' ) { val = ' ' + K.txtvisible + ' '; }
    val = val.trim();
    hid = hid.trim();
    ac_setval(val, hid);
    ac_nouvelle_valeur_definie = true;
  }
  catch(ex)
  {
    alert("Erreur lors de l'attribution de la valeur, ac_pos est : (" + (typeof ac_pos) + ") = " + ac_pos + CR + ex);
  }
  if ( ac_handler_on_penter !== null && typeof ac_handler_on_penter == 'function' )
  {
    try { ac_handler_on_penter(evt, val, hid); }
    catch(ex) { alert(ex); }
  }
  if ( typeof ac_plugs.enter[ac_curr.name] == 'function' )
  {
//    top.$$app.info('plug_enter, ac_curr = ' + ac_curr + '/' + ac_curr.name + '/' + K +'/' + ac_pos );
    ac_plugs.enter[ac_curr.name].call(ac_curr, K);
  }
  ac_removedisp(true);

  return true;
}

function ac_movedown()
{
  ac_rangeu++;
  ac_ranged++;
  ac_remake();
}

function ac_moveup()
{
  ac_rangeu--;
  ac_ranged--;
  ac_remake();
}

function ac_goup()
{
  if ( !ac_display )
  {
    return false;
  }
  if ( ac_pos == 1 )
  {
    return false;
  }
  var old = $('tat_tr'+ac_pos);
  if ( old ) { old.className = (ac_pos % 2) ? 'odd' : ''; }
  ac_pos--;
  if ( ac_pos < ac_rangeu )
  {
    ac_moveup();
  }
  var nouv = $('tat_tr'+ac_pos);
  if ( nouv )
  {
    nouv.className = 'ac_active';
  }
  ac_removedisp_startTimeout();
  return true;
}

function ac_godown()
{
  if ( !ac_display )
  {
    return false;
  }
  if ( ac_pos == ac_keywords.length )
  {
    return false;
  }
  var old = $('tat_tr'+ac_pos);
  if ( old )
  {
    old.className = (ac_pos % 2) ? 'odd' : '';
  }
  ac_pos++;
  if ( ac_pos > ac_ranged )
  {
    ac_movedown();
  }
  var nouv = $('tat_tr'+ac_pos);
  if ( nouv )
  {
    nouv.className = 'ac_active';
  }
  ac_removedisp_startTimeout();
  return true;
}

function ac_remplir_start()
{
  ac_nouvelle_valeur_definie = false;
  ac_current_request = ac_current_request + 1;
  var local_request = ac_current_request;
  ac_loading_en_cours();
  if ( ac_curr.value === '' )
  {
    return ac_removedisp();
  }
  AJAX_get(ac_final_url, ac_remplir_start_onok, ac_remplir_start_onerror, ac_handler_requete_en_cours, null, local_request);
  return true;
}

/**
 * reponse AJAX ok
 * @private
 */
function ac_remplir_start_onok(req, local_request)
{
  if ( local_request != ac_current_request )
  {
    return false;
  }
  try
  {
    eval("ac_keywords = " + req.responseText);
  }
  catch (ex)
  {
    alert(req.responseText + ' ' + CR + ' ' + ex);
    // @todo : traduire
    ac_keywords = [{id:'', txt:'erreur de format de la réponse'}];
  }
  ac_removedisp_startTimeout();
  ac_generate();
  return true;
};

/**
 * reponse AJAX error
 * @private
 */
function ac_remplir_start_onerror(req, local_request)
{
  if ( local_request != ac_current_request )
  {
    return false;
  }
  ac_keywords = [{id:'', txt:'erreur de connection, réponse : ' + req.statusText + ' ' + ac_final_url}];
  ac_removedisp_startTimeout();
  ac_generate();
  return true;
};

function ac_remplir(elt, evt, objet, url, handler_penter)
{
  ac_curr = elt;
  if ( ac_soid )
  {
    clearTimeout(ac_soid);
  }
  if ( ac_toid )
  {
    clearTimeout(ac_toid);
  }
  if ( evt.keyCode == _KEY_UP || evt.keyCode == _KEY_DOWN || evt.keyCode == _KEY_ENTER )
  {
    return false;
  }
  if ( evt.keyCode == _KEY_ESC )
  {
    return ac_removedisp();
  }
  if ( elt.value.length < ac_caracteres_minimum && evt.keyCode != _KEY_RIGHT )
  {
    return false;
  }
  if ( elt.value === '' )
  {
    return ac_removedisp();
  }
  ac_handler_on_penter = handler_penter;
  if ( typeof url == 'undefined' || url === null )
  {
    url = ac_url;
  }
  ac_last_recherche = ac_curr.value;
  ac_final_url = url + 'obj=' + escape(objet) + '&v=' + escape(ac_curr.value);
  if ( ac_startOut > 0 && evt.keyCode != _KEY_RIGHT )
  {
    ac_soid = setTimeout(ac_remplir_start, ac_startOut);
  }
  else
  {
    ac_remplir_start();
  }
  return true;
}

function curTop()
{
  var ac_toreturn = 0;
  var obj = ac_curr;
  while ( obj )
  {
    ac_toreturn += obj.offsetTop;
    obj = obj.offsetParent;
  }
  ac_toreturn = ac_toreturn - DOM.getScrollTopSum(ac_curr);
  return ac_toreturn;
}

function curLeft()
{
  var ac_toreturn = 0;
  var obj = ac_curr;
  while ( obj )
  {
    ac_toreturn += obj.offsetLeft;
    obj = obj.offsetParent;
  }
  ac_toreturn = ac_toreturn - DOM.getScrollLeftSum(ac_curr);
  return ac_toreturn;
}

function ac_table_focus(evt)
{
//  top.$$app.info('focus');
  mouse_on_list = 1;
  return true;
}

function ac_maskWithIframe()
{
  if ( $('tat_iframe') )
  {
    document.body.removeChild($('tat_iframe'));
  }
  var iframe = document.createElement('iframe');
  var table = $('tat_table');
  iframe.id = 'tat_iframe';
  iframe.className = 'ac_iframe';
  iframe.style.width = table.offsetWidth;
  iframe.style.height = table.offsetHeight;
  iframe.style.top = table.style.top;
  iframe.style.left = table.style.left;
  document.body.appendChild(iframe);
  return table;
}

function ac_loading_en_cours()
{
  if ( $('tat_table') )
  {
    document.body.removeChild($('tat_table'));
  }
  var a = document.createElement('table');
  a.className='ac_table';
  a.width = ( ac_curr.offsetWidth < ac_width_minimum ) ? Math.max(ac_width_full, ac_width_minimum) : ac_curr.offsetWidth;
  var hauteur = curTop() + ac_curr.offsetHeight;
  a.style.top = hauteur + "px";
  a.style.left = curLeft() + "px";
  a.id = 'tat_table';
  var r = a.insertRow(-1);
  var c = r.insertCell(-1);
  // @todo : traduction
  c.innerHTML = 'Chargement #' + ac_current_request + ' en cours...';
  document.body.appendChild(a);
  /*@cc_on ac_maskWithIframe(); @*/
}

function ac_base_table()
{
  if ( $('tat_table') )
  {
    document.body.removeChild($('tat_table'));
  }
  var a = document.createElement('table');
  a.className='ac_table';
  a.width = ( ac_curr.offsetWidth < ac_width_minimum ) ? Math.max(ac_width_full, ac_width_minimum) : ac_curr.offsetWidth;
  var hauteur = curTop() + ac_curr.offsetHeight;
  a.style.top = hauteur + "px";
  a.style.left = curLeft() + "px";
  a.id = 'tat_table';
  a.onmouseover = ac_table_focus;
  a.onmouseout = ac_table_unfocus;
  return a;
}

function ac_table_unfocus(evt)
{
//  top.$$app.info('unfocus');
  mouse_on_list = 0;
  ac_removedisp_startTimeout();
  return true;
}

function ac_click_down(evt)
{
  evt = (evt) ? evt : ((window.event) ? window.event : "");
  if ( evt )
  {
    var elem = EVT.getTarget(evt);
    // humm, "this" n'est pas égal à "elem" ici ?
    if ( elem )
    {
      ac_pos = elem.id.substr(6,50);
      ac_movedown();
      ac_removedisp_startTimeout();
    }
  }
  return true;
}

function ac_click_up(evt)
{
  evt = ( evt ) ? evt : ((window.event) ? window.event : "");
  if ( evt )
  {
    var elem = EVT.getTarget(evt);
    // humm, "this" n'est pas égal à "elem" ici ?
    if ( elem )
    {
      ac_pos = elem.id.substr(6,50);
      ac_moveup();
      ac_removedisp_startTimeout();
    }
  }
  return true;
}

function ac_click_table(evt)
{
//  evt = ( evt ) ? evt : ((window.event) ? window.event : "");
  evt = evt || window.event;
  if ( evt )
  {
/*
    var elem = EVT.getTarget(evt);
    if ( elem )
    {
      ac_pos = elem.id.substr(6,50);
      mouse_on_list = 0;
      ac_penter(evt);
    }
*/
    ac_pos = this.id.substr(6,50);
    mouse_on_list = 0;
    ac_penter(evt);
  }
  return true;
}

function ac_flecheup(table, rangeu)
{
  if ( ac_keywords.length > ac_lim )
  {
    r = table.insertRow(-1);
    c = r.insertCell(-1);
    c.colSpan = 2;
    c.innerHTML = ' ';
    if (rangeu > 1)
    {
      c.className='ac_arrow_up_on';
      c.onclick = ac_click_up;
    }
    else
    {
      c.className='ac_arrow_up_off';
    }
  }
}

function ac_flechedown(table, j)
{
  if ( ac_keywords.length > ac_lim )
  {
    r = table.insertRow(-1);
    c = r.insertCell(-1);
    c.colSpan = 2;
    c.innerHTML = '<img src="/images/pictos/16x16/file-close.png" onclick="ac_removedisp(true);EVT.stop(event); return false;" align="right" alt="fermer" Title="Fermer" width="16" height="16" border="0"> ';
    if ( j-1 < ac_keywords.length )
    {
      c.className='ac_arrow_down_on';
      c.onclick = ac_click_down;
    }
    else
    {
      c.className='ac_arrow_down_off';
    }
  }
}
function ac_remake()
{
  var a = ac_base_table();
  var first = true;
  var j = 1;
  ac_flecheup(a, ac_rangeu);
  for ( var i=0; i<ac_keywords.length; i++ )
  {
    var K = ac_keywords[i];
    if ( j >= ac_rangeu && j <= ac_ranged )
    {
      r = a.insertRow(-1);
      if ( j % 2 )
      {
        DOM.addCSS(r, 'odd');
      }
      r.id = 'tat_tr'+(j);
      c = r.insertCell(0);
      c.onclick = ac_click_table;
      c.innerHTML = K.txt;
      c.id = 'tat_td'+(j);
      if ( K.title ) { c.title = K.title; }
      if ( typeof K.hid == 'undefined' )
      {
        c.colSpan = 2;
      }
      else
      {
        d = r.insertCell(-1);
        d.id = 'tac_td' + (j);
        d.className = 'complement';
        if ( K.title ) { d.title = K.title; }
        if ( typeof K.hidAlign != 'undefined' )
        {
//          d.vAlign = K.hidAlign;
          d.style.verticalAlign = K.hidAlign;
        }
        d.innerHTML = K.hid;
        d.onclick = ac_click_table;
      }
    }
    j++;
    if ( j > ac_ranged )
    {
      break;
    }
  }
  ac_flechedown(a, j);
  document.body.appendChild(a);
  /*@cc_on ac_maskWithIframe(); @*/
}

function ac_generate()
{
  var a = ac_base_table();
  var first = true;
  var j = 1;
  ac_flecheup(a, 0);
  var counter = 0;
  for ( var i=0; i<ac_keywords.length; i++ )
  {
    var K = ac_keywords[i];
    counter++;
    r = a.insertRow(-1);
    if ( first )
    {
      r.className = 'ac_active';
      first = false;
      ac_pos = counter;
    }
    else if ( j % 2 )
    {
      DOM.addCSS(r, 'odd');
    }
    r.id = 'tat_tr'+(j);
    c = r.insertCell(-1);
    c.onclick = ac_click_table;
    c.innerHTML = K.txt;
    c.id = 'tat_td'+(j);
    if ( K.title ) { c.title = K.title; }
    if ( typeof K.hid == 'undefined' )
    {
      c.colSpan = 2;
    }
    else
    {
      d = r.insertCell(-1);
      d.className = 'complement';
      d.id = 'tac_td' + (j);
      if ( K.title ) { d.title = K.title; }
      if ( typeof K.hidAlign != 'undefined' )
      {
//        d.vAlign = K.hidAlign;
        d.style.verticalAlign = K.hidAlign;
      }
      d.innerHTML = K.hid;
      d.onclick = ac_click_table;
    }
    j++;
    if ( j - 1 == ac_lim && j < ac_keywords.length )
    {
      break;
    }
  }
  ac_flechedown(a, j);
  ac_rangeu = 1;
  ac_ranged = j-1;
  ac_display = true;
  if (ac_pos <= 0) { ac_pos = 1; }
  document.body.appendChild(a);
  /*@cc_on ac_maskWithIframe(); @*/
}

function ac_onFocus(elt)
{
  ac_curr = elt;
  ac_curr.ancienne_valeur = ac_curr.value;
//  alert(ac_curr + '/' + ac_curr.form + '/' + ac_curr.form.elements +' / ' + ac_getHiddenId() + '/' + ac_curr.form.elements[ac_getHiddenId()]);
  var eltHide = ac_curr.form.elements[ac_getHiddenId()];
  eltHide.ancienne_valeur = eltHide.value;
  if ( typeof elt.select == 'function' )
  {
    elt.select();
  }
  
  if ( typeof ac_plugs.focus[ac_curr.name] == 'function' )
  {
    ac_plugs.focus[ac_curr.name].call(ac_curr);
  }
}

function ac_getHiddenId()
{
  if ( typeof ac_curr == 'undefined' )
  {
    return false;
  }
  return ac_curr.name.substr(3, 200);
}

function ac_removedisp(forced)
{
  var tbl = $('tat_table');
  if ( typeof ac_curr == 'undefined' )
  {
    return false;
  }
  forced = forced ? forced : false;
//  if (typeof vider == 'undefined') var vider = false;
  if ( forced || mouse_on_list === 0 || ac_curr.value === '' )
  {
    try
    {
      if ( ac_curr.value === '' )
      {
        ac_setval('', '');
      }
      else
      {
        if ( !ac_nouvelle_valeur_definie )
        {
          ac_setval(ac_curr.ancienne_valeur, ac_curr.form.elements[ac_getHiddenId()].ancienne_valeur);
        }
      }
    } catch(x) {}
    ac_display = false;
    if ( tbl )
    {
      document.body.removeChild(tbl);
    }
    /*@cc_on
    var iframe = $('tat_iframe');
    if ( iframe )
    {
      document.body.removeChild(iframe);
    }
    @*/
    if ( ac_toid )
    {
      clearTimeout(ac_toid);
    }
//    if (ac_soid) { clearTimeout(ac_soid); }
  }
  return true;
}

function ac_focusnext(form, i)
{
  i = (1 + parseInt(i, 10)) % form.elements.length;
  if ( form.elements[i].type == 'hidden' )
  {
    return ac_focusnext(form, i);
  }
  form.elements[i].focus();
  return false;
}

function ac_handleEnter(field, event)
{
	var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
	if ( keyCode == 13 )
  {
		for (var i=0, imax=field.form.elements.length; i<imax; i++ )
    {
			if ( field == field.form.elements[i] )
      {
        break;
      }
    }
    return ac_focusnext(field.form, i);
	}
	// @todo : ca devrait pas etre return false ici ?
	return true;
}

/* handler généric AJAX pour afficher qu'une transaction est en cours */
function ac_handler_requete_en_cours(req)
{
  DOM.addCSS(ac_curr, 'ac_transaction_en_cours');
  if ( req.readyState==4 )
  {
    DOM.removeCSS(ac_curr, 'ac_transaction_en_cours');
  }
}

/**
 * Initialise le timer de ac_removedisp
 * @private
 */
function ac_removedisp_startTimeout()
{
  if ( ac_toid )
  {
//    window.clearTimeout(ac_toid);
    clearTimeout(ac_toid);
  }
  if ( ac_timeOut > 0 )
  {
//    ac_toid = window.setTimeout(ac_removedisp, ac_timeOut);
    ac_toid = setTimeout(ac_removedisp, ac_timeOut);
  }
}
/**
 * Désactive l'autocomplete ajouté par les navigateurs
 */
function ac_desactiveBrowsers(e)
{
  var E = $(e);
  try { E.setAttribute('autocomplete', "off"); } catch(x) {}
  try { E.autocomplete = 'off'; } catch(x) {}
}