function toElement(idOrElement)
{
    if (typeof idOrElement == "string")
    {
        return document.getElementById(idOrElement);
    }
    else
    {
        if (!idOrElement.id)
          idOrElement.id = idOrElement.uniqueId
        if (!idOrElement.id)
          idOrElement.id = "autoid_" + autoIdCount++;
          
        return idOrElement;
    }
}

function outevent(ev)
{
var el;
if (document.all)
  el = event.srcElement;
else
   el = ev.target;

do
{
   if (el.hoverRegistered)
   {
     invokeOut(el);
     return;
   }
   el = el.parentNode;
}
while (el && el != document.body)
}

function invokeOut(el)
{
  if (el.outClass)
    el.className = el.outClass;
  else
    el.className = el.className.replace('_over', '');
}



function overevent(ev)
{
  var el;
  if (document.all)
    el = event.srcElement;
  else
    el = ev.target;
    
  do
  {
    if (el.hoverRegistered)
    {
      invokeOver(el);
      return;
    }
    el = el.parentNode;
  }
  while (el && el != document.body);
}

function invokeOver(el)
{
  if (el.overClass)
    el.className = el.overClass;
  else
    if (el.className.indexOf('_over') == -1)
       el.className += '_over'; 
}
function unRegisterHover(element)
{
  element.hoverRegistered = false;
  element.outClass = null;
  element.overClass = null;
  
  if (element.removeEventListener)
  {
    element.removeEventListener('mouseover', overevent, true);
    element.removeEventListener('mouseout', outevent, true);
  }
  else if (element.detachEvent)
  {
    element.detachEvent('onmouseover', overevent);
    element.detachEvent('onmouseout', outevent);
  }
}


function registerHover(element, className, overClassName)
{
  if (!element.hoverRegistered)
  {
    if (className)
      element.className = className;
      
    element.hoverRegistered = true;
    
    element.outClass = element.className;
    element.overClass = overClassName;
    
    if (element.addEventListener)
    {
      element.addEventListener('mouseover', overevent, true);
      element.addEventListener('mouseout', outevent, true);
    }
    else if (element.attachEvent)
    {
      element.attachEvent('onmouseover', overevent);
      element.attachEvent('onmouseout', outevent);
    }
  }
}


function initializeTab(selectorTable, tabContainer, selectedTab, delegateModify, delegateActivate, delegateDeactivate)
{

  if (! tabContainer.tagName )
    tabContainer = document.getElementById(tabContainer);
  
  if (! selectorTable.tagName )
    selectorTable = document.getElementById(selectorTable);
    
  if (!tabContainer || !selectorTable)
    return;
    
  selectorTable.style.display = 'block';
    
  var row = selectorTable.insertRow(0);
  
  var _tabs = new Array();
  var pos = 0;
  for( var i = 0; i < tabContainer.childNodes.length; i++ )
  {
    var el = tabContainer.childNodes[i];
    if (! tabContainer.childNodes[i].tagName)
      continue;
    
    _tabs[pos++] = tabContainer.childNodes[i];
  }
  
  if (selectedTab > _tabs.length)
    selectedTab = _tabs.length-1;
    
  for( i = 0; i < _tabs.length; i++ )
  {
    var tab = _tabs[i];

    var name = tab.className.split(';')[0];
    
    var selector = row.insertCell(i);
    selector.appendChild( document.createTextNode(name) );
    selector.tab = tab;
    tab.selector = selector;
    selector.index = i;
    selector.count = _tabs.length;
    
    selector.delegateDeactivate = delegateDeactivate;
    selector.delegateActivate = delegateActivate;
    
    cAttachEvent(selector, 'onclick', changeTab);
    
    if ( i == selectedTab || tab.getAttribute("active") == "true")
    {
      if (tabContainer.currentTab)
        tabContainer.currentTab.style.display = 'none';
      tabContainer.currentTab = tab;
    }
    else
      tab.style.display = 'none';
  }
  
  for( i = 0; i < row.cells.length; i++ )
  {
    if (delegateModify)
      delegateModify( row.cells[i], row.cells[i].tab );
  }
    
  if (delegateActivate && tabContainer.currentTab)
    delegateActivate(tabContainer.currentTab.selector, tabContainer.currentTab);
}

function cAttachEvent(object, event, delegate)
{
  if (object.addEventListener)
    object.addEventListener(event.replace('on', ''), delegate, true);
  else if (object.attachEvent)
    object.attachEvent(event, delegate);
}

function cDetachEvent(object, event, delegate)
{
  if (object.removeEventListener)
    object.removeEventListener(event.replace('on', ''), delegate, true);
  else if (object.attachEvent)
    object.detachEvent(event, delegate);
}


function highlight(textOrElement, searchTerm, highlightStartTag, highlightEndTag) 
{
    var isString = typeof textOrElement == "string";
    
    var bodyText = isString ? textOrElement : textOrElement.innerHTML;
    
    // the highlightStartTag and highlightEndTag parameters are optional
    if ((!highlightStartTag) || (!highlightEndTag)) {
      highlightStartTag = "&lt;font class='highlight'>";
      highlightEndTag = "&lt;/font>";
    }

    var newText = "";
    var i = -1;
    var lcSearchTerm = searchTerm.toLowerCase();
    var lcBodyText = bodyText.toLowerCase();
    
    while (bodyText.length > 0) {
      i = lcBodyText.indexOf(lcSearchTerm, i+1);
      if (i < 0) {
        newText += bodyText;
        bodyText = "";
      } else {

        if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("&lt;", i)) {

          if (lcBodyText.lastIndexOf("/script>", i) >= lcBodyText.lastIndexOf("&lt;script", i)) {
            newText += bodyText.substring(0, i) + highlightStartTag + bodyText.substr(i, searchTerm.length) + highlightEndTag;
            bodyText = bodyText.substr(i + searchTerm.length);
            lcBodyText = bodyText.toLowerCase();
            i = -1;
          }
        }
      }
    }
    return (isString ? newText : (textOrElement.innerHTML = newText));
}

function changeTab(ev)
{
  var selector = document.all ? event.srcElement : ev.target;
  activateTab(selector);
}

function activateTabAt(selectorTable, id)
{
  if (!selectorTable.tagName)
    selectorTable = document.getElementById(selectorTable);
    
  var row = selectorTable.rows[0];
  for( i = 0; i < row.cells.length; i++ )
  {
     cell = row.cells[i];
     
     if (i == id || cell.innerText == id)
     {
       activateTab(cell);
     }
  }
}

function activateTab(selector)
{
  var tab = selector.tab;
  
  if (selector.delegateActivate)
    selector.delegateActivate(selector, tab);
  
  var curTab = tab.parentNode.currentTab;
  
  if (curTab != tab)
  {
    if (curTab.selector.delegateDeactivate)
      curTab.selector.delegateDeactivate(curTab.selector, curTab);
      
    curTab.style.display = 'none';
  }
  tab.style.display = 'block';
  tab.parentNode.currentTab = tab;
}




// glossary
  function glossary_modifyTab(selector, tab)
  {
    selector.className = "out";
    
    var tbc = tab.className.split(";");
    
    if (tbc.length > 2)
    {
      selector.glossaryState = document.getElementById('glossaryState' + tbc[1]);
      selector.stateText = tbc[2];
    }

    registerHover(selector, "out", "over");
    selector.innerText = selector.innerText;
  }

  function glossary_tabActivated(selector, tab)
  {
    unRegisterHover(selector);

    if (selector.glossaryState)
    {
      selector.glossaryState.innerHTML = selector.stateText;
      if (!selector.glossaryState.style.displaybackup)
        selector.glossaryState.style.displaybackup = selector.glossaryState.style.display;
      selector.glossaryState.style.display = (!selector.stateText || selector.stateText == "") ? 'none' : selector.glossaryState.style.displaybackup;
    }

    selector.className = "active";

    if (typeof updateLayout != 'undefined')
      updateLayout();
  }

  function glossary_tabDeactivated(selector, tab)
  {
    registerHover(selector, "out", "over");
    selector.className = "out";
  }
  
  function glossary(charsTabTable, searchResults, searchResultsInfo)
  {
    this.glosses = new Array();
    this.chars = toElement(charsTabTable);
    this.searchResults = toElement(searchResults);
    this.searchResultsInfo = toElement(searchResultsInfo);
    this.noTermText = "Bitte geben Sie einen Suchbegriff in das obige Textfeld ein!"
    this.resultsText = "Suchergebnisse für \"[text]\""
    this.noResultsText = "Keine Suchergebnisse für \"[text]\""
    
    this.add = function glossary_add(id, name, meaning) {
      var o = new Object();
      o.id = id;
      o.name = name.toLowerCase();
      o.meaning = meaning.toLowerCase();
      
      this.glosses.push(o);  
    }
    
    this.show = function show(glossId) {
      var gloss = document.getElementById("gloss_" + glossId);
      if (gloss)
      {
        activateTab(gloss.parentNode.selector);
        scrollIntoView(gloss, 60);
        blink(gloss.id, "highlighted", 2);
      }  
    }
    this.history = new Array();
    
    this.search = function glossary_search(text) {
      if (text != this.lastSearchText)
      {
        var found = this.history[text];
        if (!found)
          found = new Array();
          
        var foundbyid = new Array();  
        
        this.lastSearchText = text;
        
        var foundCount = 0;
        
        var texts = text.split(' ');
        
        if (text != "" && found.length == 0)
        {
          var foundTimes = 0;
          var foundsInMeaning = new Array();
          
          
          for( var gi = 0; gi < this.glosses.length; gi++ )
          {
            gloss = this.glosses[gi];
            
            var foundTimes = 0;
            var mustFoundTimes = 0;
            var foundInName = false;
            
            for( var ti = 0; ti < texts.length; ti++ )
            {
              var t = texts[ti];
              
              if (! t || t == "")
                continue;
     
              mustFoundTimes++;
              
              if (!foundbyid[gloss.id] && gloss.name.indexOf(t.toLowerCase()) != -1)
              {
                foundTimes ++;;
                foundInName = true;
              }
              else if (!foundbyid[gloss.id] && gloss.meaning.indexOf(t.toLowerCase()) != -1)
              {
                foundTimes ++;
              }
            }
            
            if (foundTimes == mustFoundTimes && foundInName)
            {
              found.push(gloss);
              foundbyid[gloss.id] = gloss;
            }
            else if (foundTimes == mustFoundTimes)
            {
              foundsInMeaning.push(gloss);
            }
          }
          for( var i = 0; i < foundsInMeaning.length; i++ )
          {
            gloss = foundsInMeaning[i];
            if (!foundbyid[gloss.id])
            {
              found.push(gloss);
            }
          }
          
          foundsInMeaning = new Array();
          foundbyid = new Array();
        }
        
        this.searchResults.innerHTML = "";
        this.searchResultsInfo.innerHTML = "";
        
        if (text == "")
           this.searchResultsInfo.appendChild(document.createTextNode(this.noTermText));
        else if (found.length >0)  
           this.searchResultsInfo.appendChild(document.createTextNode(this.resultsText.replace("[text]", text)));
        else
           this.searchResultsInfo.appendChild(document.createTextNode(this.noResultsText.replace("[text]", text)));
        
        activateTabAt(this.chars, "Suche");  
        
        for( var i = 0; i < found.length; i++ )
        {
           gloss = found[i];
           var glossElement = document.getElementById("gloss_" + gloss.id)
           if (glossElement)
           {
             var newGloss = glossElement.cloneNode(true);
             this.searchResults.appendChild(newGloss);
           }  
        }
        
        this.history[text] = found;
        
        mayHighlight(this.searchResults, text);
      }  
    }
  }
  
  var highlighting;
  function mayHighlight(id, text, internal)
  {
      var el = toElement(id);
      
      if (!internal)
      {
        if (highlighting)
          window.clearTimeout(highlighting);
        
        var cmd = "mayHighlight('" + el.id + "', '" + text + "', true)";

        highlighting = window.setTimeout(cmd, 5);
      }
      else
      {
        var bodyText = el.innerHTML;
        
        var searchArray = text.split(' ');
        for (var i = 0; i < searchArray.length; i++) {
          if (searchArray[i] && searchArray[i].length > 0)
          {
            bodyText = highlight(bodyText, searchArray[i]);
          }
        }
        
        el.innerHTML = bodyText;
      }      
  }

