//--------------------------------------
//  Nom Document : gf_search.js
//  Auteur       : G.Ferraz
//  Objet        : Recherche et mise en surbrillance
//  Mise a Jour  : xx.xx.2007
//  ------------------------------------
var _DOC_Ref = null;
var _DOC_innerHTML ="";
var _Tab_Span = new Array();
var _Num_Encours = null;
var _DOC_Valeur_Style = new Array();
var szM_Style = new Array( 'marginTop', 'marginLeft',  'marginBottom',  'marginRight',  'paddingTop',  'paddingLeft',  'paddingBottom',  'paddingRight');
var szP_Style = new Array( 'margin-top','margin-left', 'margin-bottom', 'margin-right', 'padding-top', 'padding-left', 'padding-bottom', 'padding-right');
//-- Preload bouton close
var _IMG_Close = new Image();
_IMG_Close.src =  'gf_close.gif';
//---------------------------------------------
// Ajout d'un evenement
//---------------------------------------------
function Add_Event( obj_, event_, func_, mode_){
  if( obj_.addEventListener)
    obj_.addEventListener( event_, func_, mode_? mode_:false);
  else
    obj_.attachEvent( 'on'+event_, func_);
}
Add_Event( window, 'resize', Ajuste_Fenetre);

//---------------------------------
function Obj_SetFocus( obj_, flag_){
  var Obj = null;
  if( typeof(obj_)=='object')
    Obj = obj_;
  else
    Obj = document.getElementById( obj_);
  if( Obj && flag_)
    Obj.focus();
  else
    setTimeout( "Obj_SetFocus('" +obj_ +"', 1)", 100);
}
//-------------------------------------------------
// Recup des dimensions de la fenetre d'affichage
//-------------------------------------------------
function Win_GetDimension(){
  var Left;
  var Top;
  var Width;
  var Height;
  var DocRef;

  if( window.innerWidth){
    with( window){
      Left   = pageXOffset;
      Top    = pageYOffset;
      Width  = innerWidth;
      Height = innerHeight;
    }
  }
  else{ // Cas Explorer a part
    if( document.documentElement && document.documentElement.clientWidth)
      DocRef = document.documentElement;
    else
      DocRef = document.body;

    with( DocRef){
      Left   = scrollLeft;
      Top    = scrollTop;
      Width  = clientWidth;
      Height = clientHeight;
    }
  }
  return({ width : Width, height : Height, top: Top, right: Left +Width, bottom: Top + Height, left: Left });
}
//-----------------------
// Redimensionne le DIV
//-----------------------
function Ajuste_Fenetre(){
  var O_Div   = document.getElementById('GF_BODY_SEARCH');
  var O_Table = document.getElementById('GF_ENTETE_SEARCH');
  if( O_Div){
    var Dim = Win_GetDimension();
    var Top = O_Table.offsetHeight;
    O_Div.style.top    = Top +"px";
    O_Div.style.width  = Dim.width +"px";
    O_Div.style.height = ( Dim.height -Top) +"px";
  }
}
//---------------------------------------------------
// Recup. position d'un objet par rapport a un parent
// si parent =null  => par rapport au document
//---------------------------------------------------
function Obj_GetPosition( obj_, parent_){
  var PosX = 0;
  var PosY = 0;
  var Obj = null;
  if( typeof(obj_)=='object')
    Obj = obj_;
  else
    Obj = document.getElementById( obj_);
  //-- Si l'objet existe
  if( Obj){
    //-- Recup. Position Objet
    PosX = Obj.offsetLeft;
    PosY = Obj.offsetTop;
    //-- Si propriete existe
    if( Obj.offsetParent){
      //-- Tant que pas le bon parent
      while( (Obj = Obj.offsetParent)!=parent_){
        //-- Ajout position Parent
        PosX += Obj.offsetLeft;
        PosY += Obj.offsetTop;
      }
    }
  }
  //-- Retour des positions
  return( { left :PosX, top :PosY});
}
//-----------------------------------
function Disabled_Bouton( id_, etat_){
  var O_Button  = document.getElementById( id_);
  if( O_Button){
    O_Button.disabled = (etat_ ?  true: false);
  }
}
//----------------------------------
function Change_Etat_Bouton( count_){
  Disabled_Bouton( 'GF_CLEAR_SEARCH', count_ < 1);
  Disabled_Bouton( 'GF_NEXT_SEARCH',  count_ < 2);
  Disabled_Bouton( 'GF_PREV_SEARCH',  count_ < 2);
  //-- Remet focus sur saisie
  if( count_ <1 )
    Obj_SetFocus('GF_TEXT_SEARCH');
}
//--------------------------------
// Replace le SPAN dans la fenetre
//--------------------------------
function Scroll_Fenetre(){
  //-- Les objets manipules
  var O_Win  = document.getElementById('GF_BODY_SEARCH');
  var O_Span = _Tab_Span[ _Num_Encours];
  //-- Recup dimensions et position du SPAN
  var Larg = O_Span.offsetWidth  *2; // *2 pour bien le mettre dans le fenetre
  var Haut = O_Span.offsetHeight *2;
  var Span = Obj_GetPosition( O_Span, O_Win);
  if( !Larg) // element cache
    return( false);
  //-- Recup dimensions et position du DIV
  var Rect = new Object();
  Rect.left   = O_Win.scrollLeft;
  Rect.top    = O_Win.scrollTop;
  Rect.right  = Rect.left +O_Win.clientWidth;
  Rect.bottom = Rect.top  +O_Win.clientHeight;
  //-- Teste les positions
  if( Span.top < Rect.top)
    Rect.top = Span.top -(Haut/2);
  if( Span.top +Haut > Rect.bottom)
    Rect.top += ( Span.top +Haut -Rect.bottom);
  if( Span.left < Rect.left)
    Rect.left = Span.left -(Larg/2);
  if( Span.left +Larg > Rect.right)
    Rect.left += ( Span.left +Larg -Rect.right);
  //-- Reajuste le scroll
  O_Win.scrollTop  = Rect.top;
  O_Win.scrollLeft = Rect.left;
  return( true);
}
//-----------------------
function Show_Find( inc_){
  //-- Tout peu avoir ete dynamiquement supprime
  if( _Tab_Span.length){
    var O_Span;
    var szMsg ="";
    var Max_Find = _Tab_Span.length -1;
    //-- efface message
    Color_Affiche_Resultat( szMsg);
    //-- first en premier
    if( _Num_Encours == null)
      _Num_Encours =0;
    else{
      //-- Supprime surlignage en cours
      O_Span = _Tab_Span[ _Num_Encours];
      //-- Peut etre supprime dynamiquement
      if( O_Span && O_Span.parentNode)
        O_Span.className = O_Span.className.replace(" gf_searchfocus", "");
      //-- Incremente compteur
      _Num_Encours += inc_;
      //-- Test aux bornes et tourne
      if( _Num_Encours < 0){
        _Num_Encours = Max_Find;
        szMsg = "Haut de page atteint, poursuite depuis le bas...";
      }
      if( _Num_Encours > Max_Find){
        _Num_Encours = 0;
        szMsg = "Bas de page atteint, poursuite depuis le haut...";
      }
    }
    //-- Surligne le SPAN avec focus
    O_Span = _Tab_Span[ _Num_Encours];
    if( O_Span){
      //-- ATTENTION peut etre supprime dynamiquement
      if( O_Span.parentNode){
        O_Span.className += " gf_searchfocus";
        //-- Deplace la fenetre eventuellement
        if( !szMsg)
          szMsg = "Ocurrence : " + (_Num_Encours +1) +'/' +(Max_Find+1);
        if( !Scroll_Fenetre())
          szMsg = "<font color='#ff0000'>" +szMsg +" masqu&eacute;e<\/font>";
        //-- affiche resultat
        Color_Affiche_Resultat( szMsg);
      }
      else{
        Color_Affiche_Resultat("<font color='#ff0000'>Occurence supprm&eacute;e<\/font>");
        //-- Relance une recherche
        Color_Result( _DOC_Ref);
        Show_Find( 0);
      }
    }
  }
}
//----------------------------------------------------
// Supprime le haschage des textes en sous noeud #text
//----------------------------------------------------
function Concat_Noeud_Texte( noeud_){
  var Nbr_Child = noeud_.childNodes.length;
  for( var i = 0; i < noeud_.childNodes.length -1; i++){
    //-- Noeud de reference
    var O_Noeud = noeud_.childNodes[i];
    //-- c"est un noeud text
    if( O_Noeud.nodeType == 3){
      //-- Init string de stockage
      var szTmp  = "";
      //-- Get Noeud suivant
      var O_Next = noeud_.childNodes[++i];
      //-- Parcours les noeuds suivant
      while( (i < noeud_.childNodes.length)&& (O_Next.nodeType == 3)){
        //-- Recup ajoute contenu
        szTmp += O_Next.data;
        //-- Detruit le noeud
        noeud_.removeChild( O_Next);
        //-- Noeud suivant ATTENTION i et non i+1 car un noeud a ete detruit
        O_Next = noeud_.childNodes[i];
      }
      //-- Ajout des Datas
      O_Noeud.data += szTmp;
    }
  }
}
//------------------------------------------------------
// Le plus rapide serait de reinjecter le contenu du doc
// inconvenients :
// -c'est pas tres fun
// -si modif dynamique pendant la recherche on perd tout
//------------------------------------------------------
function Color_Undo( where_){
  var S_Obj;
  var P_Obj = new Array();
  where_ = where_? where_ : document.body;
  //-- Recup tableau des SPANs
  S_Obj = where_.getElementsByTagName('span');
  //--Parcours la liste
  for( var i=0; i < S_Obj.length; i++){
    //-- si SPAN Marque
    if( S_Obj[i].getAttribute('GFmarque')){
      //-- Garde Info parent pour nettoyage
      P_Obj[P_Obj.length] = S_Obj[i].parentNode;
      //-- Get le texte du SPAN
      var szText = S_Obj[i].firstChild.data;
      //-- transfert dans noeud adjacent
      if( S_Obj[i].previousSibling){
        S_Obj[i].previousSibling.data = S_Obj[i].previousSibling.data +szText;
      }
      else if( S_Obj[i].nextSibling){
        if( S_Obj[i].nextSibling.data){
          //-- Insertion data en debut du suivant
          S_Obj[i].nextSibling.data =  szText +S_Obj[i].nextSibling.data;
        }
        else{
          //-- creation d'un noeud texte
          var O_Text = document.createTextNode( szText);
          //-- et insertion avant suivant
          S_Obj[i].parentNode.insertBefore( O_Text, S_Obj[i].nextSibling);
        }
      }
      else{
        //-- sinon ajout du texte
        S_Obj[i].parentNode.firstChild.data += szText;
      }
      //-- Suppression du noeud creer
      S_Obj[i].parentNode.removeChild( S_Obj[i]);
      //-- IMPORTANT ------------------//
      // ne pas oublier de reajuster i //
      //------------ ------------------//
      i--;
    }
  }
  //-- OBLIGATOIRE pour une nouvelle recherche
  for( var i=0; i < P_Obj.length; i++){
    if( P_Obj[i] != P_Obj[i+1])
      Concat_Noeud_Texte( P_Obj[i]);
  }
  //-- Clear du resultat
  Color_Affiche_Resultat( "");
  //-- Reaffecte etat boutons
  Change_Etat_Bouton( 0);
  //-- ReInit les variables
  _Num_Encours = null;
  _Tab_Span.length = 0;
}
//---------------------------------------------
// fct recursive de recherche sur noeud #text
//---------------------------------------------
function Color_FindTexte( noeud_, txt_, class_){
  var Pos;      // Position occurence
  var O_Span;   // Objet SPAN a creer
  var O_Deb;    // Element qui contient l'occurence
  var O_Fin;    // Element qui contient la suite
  var O_Clone;  // Element pour clone de O_Deb

  //-- Pas de casse !
  txt_ = txt_.toLowerCase();
  if( noeud_.nodeType == 1 && noeud_.childNodes ){

    //-- on epargne le javascript sinon bonjour les degats
    if(( noeud_.tagName.toLowerCase()!="script" )&&
       ( noeud_.tagName.toLowerCase()!="textarea" )){

      if( !noeud_.getAttribute('GFmarque')){ // pas de recherche dans span cree
        //-- recherche dans les noeuds enfants
        for( var i=0; i < noeud_.childNodes.length; i++){
          i+= Color_FindTexte( noeud_.childNodes[i], txt_, class_);
        }
      }
    }
  }
  //-- Traitement sur noeud Texte
  else if( noeud_.nodeType == 3){
    //-- Cherche occurence pas de casse !
    Pos = noeud_.data.toLowerCase().indexOf(txt_);
    //-- Super Trouve !!
    if( Pos > -1){
      //-- Creation d'un SPAN
      O_Span = noeud_.ownerDocument.createElement( "span");
      //-- Affectation de la class
      O_Span.className = class_;
      //-- Mets un Marqueur
      O_Span.setAttribute('GFmarque','1');
      //-- Coupe le noeud en deux a partir du debut de l'occurence
      O_Deb = noeud_.splitText( Pos);
      //-- Recoupe le noeud en deux a partir de la fin de l'occurence
      O_Fin = O_Deb.splitText( txt_.length);
      //-- Cree un double du noeud de l'occurence
      O_Clone = O_Deb.cloneNode(true);
      //-- Ajoute le clone au SPAN
      O_Span.appendChild( O_Clone);
      //-- Remplace l'ancien noeud O_Deb par le new O_Span
      O_Deb.parentNode.replaceChild( O_Span, O_Deb);
      //-- retour 1 pour incrementation
      return(1);
    }
  }
  return(0);
}
//----------------------------
function Color_Result( where_){
  //-- Mise a zero tableau
  _Tab_Span.length = 0;
  //-- Recup les Objets
  var Obj = where_.getElementsByTagName('span');
  for( var i=0; i < Obj.length; i++){
    if( Obj[i].getAttribute('GFmarque')){
      _Tab_Span.push( Obj[i]);
    }
  }
  //-- Affichage resultat
  var Count = _Tab_Span.length;
  var Html = Count + ((Count >1) ? ' occurences trouv&#233;es' :' occurence trouv&#233;e');
  Color_Affiche_Resultat( Html);
  //-- Reaffecte etat boutons
  Change_Etat_Bouton( Count);
  //-- Si un seul resultat on le cadre
  if( Count == 1)
    Show_Find( 0);
}
//------------------------------------
function Color_Affiche_Resultat( txt_){
  var Obj = document.getElementById('GF_TEXT_RESULT');
  if( Obj){
    if( Obj.value != undefined)
      Obj.value = txt_;
    if( Obj.innerHTML != undefined)
      Obj.innerHTML = txt_;
  }
}
//---------------------------------------------
// fct de depart de la recherche
//---------------------------------------------
function Color_Recherche( where_, txt_, class_){
  if (txt_ == "Rechercher dans le site")  return;
  if (txt_.length < 4)  return;
  //-- Recherche dans tout le document par defaut
  var Where  = where_? where_ : document;
  //-- pour cette appli seulement
  Where  = Where.body;
  _DOC_Ref = Where;

  var Txt    = txt_  ? txt_: '';
  var Class  = class_? class_ : 'gf_searchselect'; // class par defaut
  var szFind = new Array();
  //-- Reset la selection
  Color_Undo( Where);
  //-- on ne traite pas de chaine vide
  if( Txt){
    szFind = Txt.split(' ');
    //-- pour toutes les chaines
    for( var i=0; i< szFind.length; i++){
      if( szFind[i]){
        //-- retrouve et Colorise
        Color_FindTexte( Where, szFind[i], class_);
      }
    }
    //-- Affiche le Resulat
    Color_Result( Where);
  }
  else
  {
    //-- Affichage ERREUR
    //Color_Affiche_Resultat( "<b style='color:#ff0000'>Saisir une recherche<\/b>");
  }
}
//-----------------------------------------
// fct Appel de l'ouverture de la recherche
//-----------------------------------------
function Ouvre_Search(){
  var Obj = document.getElementById('GF_ENTETE_SEARCH');
  if( Obj) return; // Deja ouvert on quitte
  //-- Get le Contenu du document
  _DOC_innerHTML = document.body.innerHTML;
  //-- Get la position du scroll
  var Scroll = Win_GetDimension();
  //-- Overflow sur hidden
  document.body.style.overflow = "hidden";
  //-- Recup l'objet qui contient les styles
  var Doc_Ref = null;
	if( window.getComputedStyle)
    Doc_Ref = document.defaultView.getComputedStyle( document.body, null);
	else if( document.body.currentStyle)
    Doc_Ref = document.body.currentStyle;
  //-- Sauvegarde les styles du document
  if( Doc_Ref)
    for( var i=0; i< szM_Style.length; i++){
      _DOC_Valeur_Style[i] = Doc_Ref[szM_Style[i]];
    }
  //-- Set margin et padding du BODY a 0
  document.body.style.margin  = "0px";
  document.body.style.padding = "0px";
  //-- Write ENTETE --
  var Html ="";
  Html +='<table id="GF_ENTETE_SEARCH" cellpadding="0" cellspacing="2" summary="Entete">';
  Html +='<tr><td _valign="top"><img src="'+ _IMG_Close.src +'" style="display:inline; cursor:pointer;" alt="Ferme la recherche" title="Ferme la recherche" height="21" width="21" hspace="5" border="0" onclick="Fct_Btn_Close();"><\/td>';
  Html +='<td valign="top">';
  Html +='<form class="gf_form_search" action="javascript:Fct_Btn_Search();">';
  Html +=' <input class="gf_button_search" id="GF_CLEAR_SEARCH" type="button" onclick="Fct_Btn_Clear()" value="Clear" style="width:50px;" disabled title="Supprime la recherche actuelle">';
  Html +=' <input class="gf_text_search"   id="GF_TEXT_SEARCH" type="text"  size="20" style="font-size:12px;" value="Recherche">';
  Html +=' <input class="gf_button_search" type="submit" value="Rechercher" title="Lance la recherche">';
  Html +=' <input class="gf_button_search" id="GF_PREV_SEARCH" type="button" onclick="Show_Find(-1);" disabled value="Pr&#233;c&#233;dent" title="Ocurrence pr&#233;c&#233;dente">';
  Html +=' <input class="gf_button_search" id="GF_NEXT_SEARCH" type="button" onclick="Show_Find( 1);" disabled value="Suivant" title="Ocurrence suivante" accesskey="s">';
  Html +='<\/form>';
  Html +='<\/td><td width="100%">';
  Html +='<div id="GF_TEXT_RESULT"></div>';
  Html +='<\/td><\/tr>';
  Html +='<\/table>';
  //-- Write BODY --
  Html += '<div id="GF_BODY_SEARCH" style="margin:0px;padding:0px;position:absolute;left:0px;overflow:auto;">';
  //-- On utilise un DIV pour appliquer le margin et le padding
  Html += '<div id="GF_BODY_SEARCH_CONTENT" style="position:relative;';
  //-- Attribut les margins du document
  for( var i=0; i< szM_Style.length; i++)
    Html += szP_Style[i] +':' + _DOC_Valeur_Style[i] +';';
  Html += '">'+ document.body.innerHTML +'<\/div><\/div>';
  //-- Reecriture du document
  document.body.innerHTML = Html;
  //-- Ajuste la fenetre --//
  Ajuste_Fenetre();
  //-- Scroll la fenetre
  var O_Div = document.getElementById('GF_BODY_SEARCH');
  O_Div.scrollTop = Scroll.top;
  O_Div.scrollLeft = Scroll.left;
  //-- met le focus sur la saisie --//
  //Obj_SetFocus('GF_TEXT_SEARCH');
}
//-----------------------
function Fct_Btn_Search(){
  Color_Recherche( null, document.getElementById('GF_TEXT_SEARCH').value, 'gf_searchselect');
}
//----------------------
function Fct_Btn_Clear(){
  Color_Undo( null);
}
//----------------------
function Fct_Btn_Close(){
  //-- On efface tout
  Color_Undo( null);
  //-- Recup document en cours
  var Html = document.getElementById('GF_BODY_SEARCH_CONTENT').innerHTML;
  //-- Get Scroll Page
  var S_Top  = document.getElementById('GF_BODY_SEARCH').scrollTop;
  var S_Left = document.getElementById('GF_BODY_SEARCH').scrollLeft;
 //-- Restaure le contenu
  document.body.innerHTML = Html;
  //-- Restaure le style du document
  document.body.style.overflow = "auto";
  for( var i=0; i< szM_Style.length; i++){
    document.body.style[szM_Style[i]] = _DOC_Valeur_Style[i];
  }
  //-- restaure le scroll en cours
  window.scrollBy( S_Left, S_Top);
}
//-- EOF

