  /**  
  * Seite durchsuchen und Treffer farbig markieren    IE,FF,NS,Opera(8.53 getestet) 
  *
  * @resources    
  *   js/class/sos_exception.js
  *   js/util/sos_util.js
  *
  * @copyright    Software- und Oranisation-Service GmbH, Germany
  * @author       Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @since        1.0-2006/03/03
  *
  * @access       public
  * @package      SITE
  */
  
  var SOS_Search = function(){}
  
  /** @access public */
  
  /** Farbe der gefundenen Zeichenkette */  
  SOS_Search.color          = '#ffffff';  
  /** Hintergrundfarbe der gefundenen Zeichenkette. IE Look : #000080, FF Look : #38d878 */
  SOS_Search.bgColor        = '#38d878'; 
  /** Klein|Groß - Schreibung nicht beachten */
  SOS_Search.ignoreCase     = true;
 
  
  /** @access private */
  
  SOS_Search.searchStr      = '';
  SOS_Search.countSpans     = 0;
  
  
  /**
  * Suche alle Browser
  * alle Vorkommen werden farbig markiert 
  *
  * @param    searchStr     Suchzeichenkette
  * @param    frame         optional - Suchseite (default aktuelle Seite), sonst zB.: parent.frames[0]
  * @throw    SOS_Exception
  * @access   public
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.search = function(searchStr,frame){
    
    try{   
      // falls SOS_Search.ignoreCase auf kein Boolean gesetzt wurde
      SOS_Search.ignoreCase = (SOS_Search.ignoreCase == true) ? true : false;
            
      if(!frame){frame = window;}
      SOS_Search.reset(frame);
      
      SOS_Search.searchStr  = null;
      
      if(!searchStr){return;}
            
      if(searchStr != null && searchStr.length > 0){
        SOS_Search.searchStr  = searchStr;
        
        if(frame.document.body.createTextRange){  //IE
          SOS_Search.highlightIE(searchStr,frame);
        }
        else{                                     // alle anderen
          SOS_Search.highlight(SOS_Util.regQuoted(searchStr),frame);
          SOS_Search.countSpans     = 0;
        }
      }
   
    }
    catch(x){
      alert(x.message);  
    }
  }
   
        
  /**
  * Markierungen entfernen  alle Browser
  * 
  * @param    frame         optional - Suchseite (default aktuelle Seite), sonst zB.: parent.frames[0]       
  * @throw    SOS_Exception
  * @access   public
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.reset = function(frame){
    
    try{
      
      if(SOS_Search.searchStr != null && SOS_Search.searchStr.length > 0){
        
        if(!frame){ frame = window; }
        
        // falls SOS_Search.ignoreCase auf kein Boolean gesetzt wurde
        SOS_Search.ignoreCase = (SOS_Search.ignoreCase == true) ? true : false;
              
        if(frame.document.body.createTextRange){  // IE
          SOS_Search.resetHighlightIE(frame);
        }
        else{                                     // alle anderen
          SOS_Search.resetHighlight(frame);
        }
      }
      
      SOS_Search.searchStr  = null;
    }
    catch(x){
      alert(x.message);  
    }
    
  }
  
  
  /**
  * Suche IE
  * alle Vorkommen werden farbig markiert 
  *
  * @param    searchStr     Suchzeichenkette
  * @param    frame         optional - Suchseite (default aktuelle Seite), sonst zB.: parent.frames[0]
  * @throw    SOS_Exception
  * @access   private
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.highlightIE = function(searchStr,frame){
    /* http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/execcommand.asp */
    
    /*
    bFound = TextRange.findText(sText [, iSearchScope] [, iFlags])
    
    Parameters    
      sText         Required. String that specifies the text to find. 
      iSearchScope  Optional. Integer that specifies the number of characters to search from the starting point of the range. A positive integer indicates a forward search; a negative integer indicates a backward search.  
      iFlags        Optional. Integer that specifies one or more of the following flags to indicate the type of search: 0 Default. Match partial words. 
        
        1           Match backwards. 
        2           Match whole words only. 
        4           Match case. 
        131072      Match bytes. 
        536870912   Match diacritical marks. 
        1073741824  Match Kashida character. 
        2147483648  Match AlefHamza character.
    
    Return Value
      Boolean that returns one of the following values: 
    
      true  The search text was found. 
      false The search text was not found. 
    */
    
    try{
      if(!searchStr)  { return;         }
      if(!frame)      { frame = window; }      
      
      var textRange,i = frame.document.selection.createRange().text;
      textRange       = frame.document.body.createTextRange();
      
      if(SOS_Search.ignoreCase == true){
        for(i=0; textRange.findText(searchStr); i++){
          textRange.execCommand('BackColor',false,SOS_Search.bgColor);
          textRange.execCommand('ForeColor',false,SOS_Search.color);
          /*
          Die collapse-Methode bewegt den Textcursor (Stelle an dem der getippte Text eingefügt wird) 
          an den Anfang (true / Standard) oder das Ende (false). 
          */
          textRange.collapse(false);
        }
      }
      else{     
        // 4 bedeutet - Klein|Groß Schreibung beachten
        for(i=0; textRange.findText(searchStr,1000000000,4); i++){
          textRange.execCommand('BackColor',false,SOS_Search.bgColor);
          textRange.execCommand('ForeColor',false,SOS_Search.color);
          textRange.collapse(false);
        }
      }
    }
    catch(x){
      alert(x.message);  
    }
          
  }
  
  
  /**
  * Markierungen von SOS_Search.highlightIE() entfernen
  * 
  * @param    frame         optional - Suchseite (default aktuelle Seite), sonst zB.: parent.frames[0]
  * @throw    SOS_Exception       
  * @access   private
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.resetHighlightIE = function(frame){
    
    try{
      if(!frame)      { frame = window; }
      
      var textRange,i = frame.document.selection.createRange().text;
      textRange       = frame.document.body.createTextRange();
      
      if(SOS_Search.ignoreCase == true){
        for(i=0; textRange.findText(SOS_Search.searchStr); i++){
          textRange.execCommand('BackColor',false,'');
          textRange.execCommand('ForeColor',false,'');
          
          // entfernt ALLE Fonts :(
          //textRange.execCommand('removeformat');
          
          textRange.collapse(false);
        }
      }
      else{
        for(i=0; textRange.findText(SOS_Search.searchStr,1000000000,4); i++){
          textRange.execCommand('BackColor',false,'');
          textRange.execCommand('ForeColor',false,'');
          textRange.collapse(false);
        }
      }
   
    }
    catch(x){
      alert(x.message);  
    }
  }  
  
  /**
  * Suche : alle Browser (auch IE, nur bei IE machen wir anders)
  * alle Vorkommen werden farbig markiert 
  *
  * @param    searchStr     Suchzeichenkette
  * @param    frame         Suchseite (default aktuelle Seite), sonst zB.: parent.frames[0]
  * @param    node          Startknoten zum Suchen (default BODY)       
  * @throw    SOS_Exception
  * @access   private
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.highlight = function(searchStr,frame,node){
    
    try{
      if(!searchStr)  { return;                       }
      if(!frame)      { frame = window;               }
      if(!node)       { node  = frame.document.body;  }      
      
      switch (node.nodeType) {
        case 1    : // Elementknoten
                    for(var i=0;i<node.childNodes.length;i++){
                      SOS_Search.highlight(searchStr,frame,node.childNodes[i]);
                    }
                    break;
                      
         case 3   : // Textknoten                     
                    switch(node.parentNode.tagName.toLowerCase()){
                      //case 'form'     :
                      case 'select'   :
                      case 'option'   :
                      case 'textarea' :
                      case 'input'    :
                      case 'radio'    :
                      case 'script'   :
                      case 'table'    :
                      case 'tbody'    :
                      case 'thead'    :
                      case 'tfoot'    :
                      case 'tr'       :
                                        break;  
                      default         :                 
                                        
                                        if(SOS_Util.trim(node.data) != ''){
                                          var searchPattern = (SOS_Search.ignoreCase == true) ? eval('/('+searchStr+')/i') : eval('/('+searchStr+')/'); 
                                          
                                          if(node.data.search(searchPattern) != -1){
                                            
                                            var span        = document.createElement('span');
                                            var pattern     = (SOS_Search.ignoreCase == true) ? eval('/('+searchStr+')/ig') : eval('/('+searchStr+')/g');
                                            
                                            span.id         = 'sos_search_parent_span_'+SOS_Search.countSpans;
                                            span.innerHTML  = node.data.replace(pattern,'<span id="sos_search_child_span_'+SOS_Search.countSpans+'"  style="background-color:'+SOS_Search.bgColor+';color:'+SOS_Search.color+'">\$1</span>');
                                            
                                            node.parentNode.replaceChild(span,node);
                                            SOS_Search.countSpans++;
                                          }
                                        }
                      
                    }
                    
                    break;
      }

      
    }
    catch(x){
      alert(x.message);  
    }
  }
  
  
  /**
  * Markierungen von SOS_Search.highlight() entfernen
  *
  * @param    frame           optional - Suchseite (default aktuelle Seite), sonst zB.: parent.frames[0]       
  * @throw    SOS_Exception
  * @access   private
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.resetHighlight = function(frame){
    try{
      
      if(!frame){ frame = window;}
      
      SOS_Search.countSpans = 0;
      
      /*******************************
      * zuerst innere SPANS entfernen
      ********************************/
      var spanIdPrefix  = 'sos_search_child_span_';
      var spans         = frame.document.getElementsByTagName('span');
      var nodes         = new Array();
      var count         = 0;
      
      for(var i=0;i< spans.length;i++){
        var span = spans[i];
        if(span.id != null && span.id.indexOf(spanIdPrefix) != -1){
          var val       = span.firstChild.nodeValue;
          nodes[count]  = {
            spanNode  : span,
            textNode  : frame.document.createTextNode(val)  
          }
          count++;
        }
      }
      
      for(var i=0;i<nodes.length;i++){
        var parentNode = nodes[i].spanNode.parentNode;
        parentNode.replaceChild(nodes[i].textNode,nodes[i].spanNode);
      }
      
      /*******************************
      * dann die äusseren
      ********************************/
      spanIdPrefix  = 'sos_search_parent_span_';
      spans         = frame.document.getElementsByTagName('span');
      nodes         = new Array();
      count         = 0;
      
      for(var i=0;i<spans.length;i++){
        var span = spans[i];            
        if(span.id != null && span.id.indexOf(spanIdPrefix) != -1){
          var val = '';
          for(j=0;j<span.childNodes.length;j++){
            val += span.childNodes[j].data; 
          }
          nodes[count]  = {
            spanNode  : span,
            textNode  : frame.document.createTextNode(val)  
          }
          count++;
        }
      }
      
      for(var i=0;i<nodes.length;i++){
        var parentNode = nodes[i].spanNode.parentNode;
        parentNode.replaceChild(nodes[i].textNode,nodes[i].spanNode);
      }
      
      
    }
    catch(x){
      alert(x.message); 
    }

  
  }
  
  
  
  /**
  * Treffer nacheinander anzeigen
  *
  * !!!!! nicht fertig wegen FF & NS :(
  * on man überhaupt braucht ???
  *
  * @param    searchStr     Suchzeichenkette
  * @param    frame         optional - Suchseite (default aktuelle Seite)  sonst zB.: parent.frames[0]       
  * @throw    SOS_Exception
  * @access   private
  * @author   Robert Ehrlich <robert.ehrlich@sos-berlin.com>
  * @version  1.0-2006/03/03
  */
  SOS_Search.stepSearch = function(searchStr,frame){
   
    try{   
      if(!searchStr)  { return;         }
      if(!frame)      { frame = window; }
      if(frame.focus) { frame.focus();  }
      
      var found = false;
         
      if(window.find){
        if( document.layers ){ // NS
          // find (suchwort, casesensitive , von hinten nach vorne)
          found = frame.find( searchStr, false, false );
        } 
        else {//FF
          //found = frame.find( searchStr, false, false, true, false, true, false );
          //found = frame.find( searchStr, false, false, true, true, true, false );
          frame.find( searchStr, false,true)
          
        }
      } 
      else if(frame.document.body && frame.document.body.createTextRange ){ //IE
        var textRange = '';
        
        if(frame.document.selection && frame.document.selection.type != 'none'){
          textRange = frame.document.selection.createRange();
          textRange.collapse(false);
        } 
        else {
          var textRange = frame.document.body.createTextRange();
        }
        
        found = textRange.findText(searchStr);
        if(found) {
          textRange.select(); 
        }
        else{
          //textRange = frame.document.selection.createRange();
          //textRange.collapse(true);
        }
      }
    }
    catch(x){                                     
      alert(x.message);   
    }
  }                                             

