
//
// dtTools.js
//
// Sammlung von Funktionen/Objekten die fuer Xaver HJR-Anwendungen
// benutzt werden.
//
// (c) doctronic GmbH & Co. KG
//


//
// HJRFrameControl-Objekt
// um alle Variablen in einem Namensraum zu halten und einfach
// als Parameter uebergeben zu koennen
//
var dt_oHJR = new Array();

function dtHJRFrameControl(oFrameName,oInitFunction)
{
  // Member initialisieren
  this.oFrameName = oFrameName;
  this.oInitFunction = oInitFunction;
  this.bDOMAvailable = false;
}


//
// legt das HJRFrameControl-Objekt an und initisalisiert es
//
function dtInitHJRFrameControl(oFrameName,oInitFunction)
{
  dt_oHJR[dt_oHJR.length] = new dtHJRFrameControl(oFrameName,oInitFunction);
}


//
// ueberprueft ob das DOM des im HJRFrameControl-Objekt hinterlegten
// Frames schon fertig geladen ist und speichert diese Erkenntnis
// im Objekt
//
function dtCheckDOMAvailable(nNum,oCheckID)
{
  if (!dt_oHJR[nNum])
  {
    return false;
  }

  var oFrame = FF(dt_oHJR[nNum].oFrameName);
  if (!oFrame || !oFrame.document)
  {
    return false;
  }

  dt_oHJR[nNum].bDOMAvailable = (oFrame.document.getElementsByTagName('body').length == 1);

  if (dt_oHJR[nNum].bDOMAvailable && oCheckID)
  {
    dt_oHJR[nNum].bDOMAvailable = (oFrame.document.getElementById(oCheckID) ? true : false);
  }

  return dt_oHJR[nNum].bDOMAvailable;
}


//
// verschiebt die Ausfuehrung der Init-Funktion (mittels
// Timeout) bis das DOM des Navi-Frames geladen ist
//
function dtInitWhenDOMAvailable(nNum,oCheckID)
{
  if (dt_oHJR[nNum] && dt_oHJR[nNum].oInitFunction)
  {
    if (!dtCheckDOMAvailable(nNum,oCheckID))
    {
      this.nCnt = (!this.nCnt) ? 1 : this.nCnt + 1;
      if (this.nCnt < 50)
      {
        var oCmd = "dtInitWhenDOMAvailable("+nNum+")";
        if (oCheckID)
        {
          oCmd = "dtInitWhenDOMAvailable("+nNum+",'" + oCheckID + "')";
        }
        window.setTimeout(oCmd,100);
      }
      return;
    }

    this.nCnt = null;
    window.setTimeout("dtDelayedInitFunction("+nNum+")",100);
    // dt_oHJR[nNum].oInitFunction();
  }
}

//
// fuehrt die InitFunction Nummer 'nNum' aus
//
function dtDelayedInitFunction(nNum)
{
  if (dt_oHJR[nNum] && dt_oHJR[nNum].oInitFunction)
  {
    dt_oHJR[nNum].oInitFunction();
  }
}

//
// Liefert das Objekt des Navi-Frames mit Nummer 'nNum'.
// Für 'nNum == -1' wird das aktuelle Fenster geliefert.
//
function dtGetFrame(nNum)
{
  if (nNum == -1)
  {
    return window;
  }

  if (dt_oHJR[nNum].bDOMAvailable)
  {
    return FF(dt_oHJR[nNum].oFrameName);
  }

  return null;
}


//
// zeigt (bShow = true) oder versteckt (bShow = false) ein
// Objekt im Navi-Frame mit ID oID
//
function dtShowObject(nNum,bShow,oID)
{
  var oNavi = dtGetFrame(nNum);
  if (oNavi)
  {
    var oObj = oNavi.document.getElementById(oID);
    if (oObj)
    {
      if (bShow)
      {
        if (oObj.style.display != "block") oObj.style.display = "block";
      }
      else
      {
        if (oObj.style.display != "none") oObj.style.display = "none";
      }
    }
  }
}


//
// setzt das HREF-Attribut am Objekt mit ID oID
//
function dtSetObjectHREF(nNum,oID,oHREF)
{
  var oNavi = dtGetFrame(nNum);
  if (oNavi)
  {
    if (!oHREF)
    {
      oHREF = '#';
    }

    var oObj = oNavi.document.getElementById(oID);
    if (oObj)
    {
      oObj.href = oHREF;
    }
  }
}


//
// zeigt (bShow = true) oder versteckt (bShow = false) ein
// Objekt im Navi-Frame mit ID oID. Beim Anzeigen wird auch
// das HREF-Attribut gesetzt.
//
function dtShowObjectHREF(nNum,bShow,oID,oHREF)
{
  var oNavi = dtGetFrame(nNum);
  if (oNavi)
  {
    var oObj = oNavi.document.getElementById(oID);
    if (oObj)
    {
      if (bShow)
      {
        if (oObj.style.display != "block") oObj.style.display = "block";

        if (!oHREF)
        {
          oHREF = '#';
        }
        oObj.href = oHREF;
      }
      else
      {
        if (oObj.style.display != "none") oObj.style.display = "none";
      }
    }
  }
}


//
// zeigt eins (bShow = true => das erste) der beiden Objekte
// mit IDs oIDPrefix_on und oIDPrefix_off an und versteckt das andere.
//
function dtToggleObjects(nNum,bShow,oIDPrefix)
{
  var oNavi = dtGetFrame(nNum);
  if (oNavi)
  {
    var oObj1 = oNavi.document.getElementById(oIDPrefix + '_on');
    var oObj2 = oNavi.document.getElementById(oIDPrefix + '_off');
    if (oObj1 && oObj2)
    {
      if (bShow)
      {
        if (oObj1.style.display != "block") oObj1.style.display = "block";
        if (oObj2.style.display != "none") oObj2.style.display = "none";
      }
      else
      {
        if (oObj1.style.display != "none") oObj1.style.display = "none";
        if (oObj2.style.display != "block") oObj2.style.display = "block";
      }
    }
  }
}


//
// zeigt eins (bShow = true => das erste) der beiden Objekte
// mit IDs oIDPrefix_on und oIDPrefix_off an und versteckt das andere.
// Beim
// jeweils angezeigten wird auch das HREF-Attribut gesetzt (wenn
// vorhanden).
//
function dtToggleObjectsHREF(nNum,bShow,oHREF,oIDPrefix)
{
  var oNavi = dtGetFrame(nNum);
  if (oNavi)
  {
    var oObj1 = oNavi.document.getElementById(oIDPrefix + '_on');
    var oObj2 = oNavi.document.getElementById(oIDPrefix + '_off');
    if (oObj1 && oObj2)
    {
      if (!oHREF)
      {
        oHREF = '#';
      }

      if (bShow)
      {
        if (oObj1.style.display != "block") oObj1.style.display = "block";
        if (oObj2.style.display != "none") oObj2.style.display = "none";

        if (oObj1.href && (oObj1.nodeName == "A"))
        {
          oObj1.href = oHREF;
        }
      }
      else
      {
        if (oObj1.style.display != "none") oObj1.style.display = "none";
        if (oObj2.style.display != "block") oObj2.style.display = "block";
        
        if (oObj2.href && (oObj2.nodeName == "A"))
        {
          oObj2.href = oHREF;
        }
      }
    }
  }
}


//
// nimmt eine bel. Anzahl von Objekt-IDs. Das nNum-te wird
// angezeigt, die anderen versteckt. nNum = 0 versteckt alle.
//
function dtShowOneObject(nFNum,nNum,oID/*,oID2,oID3...*/)
{
  var oNavi = dtGetFrame(nFNum);
  if (oNavi)
  {
    nNum++;

    for (var i = 2; i < dtShowOneObject.arguments.length; i++)
    {
      var oObj = oNavi.document.getElementById(dtShowOneObject.arguments[i]);
      if (oObj)
      {
        if (i == nNum)
        {
          if (oObj.style.display != "block") oObj.style.display = "block";
        }
        else
        {
          if (oObj.style.display != "none") oObj.style.display = "none";
        }
      }
    }
  }
}


//
// nimmt eine bel. Anzahl von Objekt-IDs an. Das nNum-te
// wird angezeigt und sein HREF-Attribut gesetzt (wenn vorhanden),
// die anderen werden versteckt. nNum = 0 versteckt alle.
//
function dtShowOneObjectHREF(nFNum,nNum,oHREF,oID/*,oID2,oID3,...*/)
{
  var oNavi = dtGetFrame(nFNum);
  if (oNavi)
  {
    nNum += 2;

    for (var i = 3; i < dtShowOneObjectHREF.arguments.length; i++)
    {
      var oObj = oNavi.document.getElementById(dtShowOneObjectHREF.arguments[i]);
      if (oObj)
      {
        if (i == nNum)
        {
          if (oObj.style.display != "block") oObj.style.display = "block";
          
          if (oObj.href && (oObj.nodeName == "A"))
          {
            if (!oHREF)
            {
              oHREF = '#';
            }
            oObj.href = oHREF;
          }
        }
        else
        {
          if (oObj.style.display != "none") oObj.style.display = "none";
        }
      }
    }
  }
}


//
// Hilfsfunktionen zur Framesteuerung
//

// Findet den XaverApplicationFrame
function FAppF()
{
  for (var i = 0; i < top.frames.length; i++)
  {
    if (top.frames[i].name.substr(0,21) == 'XaverApplicationFrame')
    {
      return top.frames[i];
    }
  }

  return null;
}

// Findet den XaverCommunicationFrame
function FComF(oRoot)
{
  if (!oRoot)
  {
    oRoot = top;
  }

  for (var i = 0; i < oRoot.frames.length; i++)
  {
    if (oRoot.frames[i].name.substr(0,18) == 'xaverKommunikation')
    {
      return oRoot.frames[i];
    }
  }

  return null;
}

// Findet den Frame, dessen Name auf 'oName' endet.
function FF(oName,oRoot)
{
  var oFrame = null;

  if (!oRoot)
  {
    oRoot = top;
  }

  for (var i = 0; i < oRoot.frames.length; i++)
  {
    var oFName = oRoot.frames[i].name;
    if ( (oFName.length >= oName.length) && 
         (oFName.substr(oFName.length - oName.length) == oName) )
    {
      return oRoot.frames[i];
    }
  }

  for (var i = 0; i < oRoot.frames.length; i++)
  {
    oFrame = FF(oName,oRoot.frames[i]);
    if (oFrame != null)
    {
      break;
    }
  }

  return oFrame;
}

function on(oIDPrefix)
{
  var oObj1 = document.getElementById(oIDPrefix + '_on');
  var oObj2 = document.getElementById(oIDPrefix + '_off');
  if (oObj1 && oObj2)
  {
    if (oObj1.style.display != 'block') oObj1.style.display = 'block';
    if (oObj2.style.display != 'none') oObj2.style.display = 'none';
  }
  var oObj3 = document.getElementById(oIDPrefix + '_no');
  if (oObj3 && oObj3.style.display != 'none') oObj3.style.display = 'none';
}

// Element mit Prefix 'oIDPrefix' in 'Off'-Status schalten
function off(oIDPrefix,bDisable)
{
  var oObj1 = document.getElementById(oIDPrefix + '_off');
  var oObj2 = document.getElementById(oIDPrefix + '_on');
  var oObj3 = document.getElementById(oIDPrefix + '_no');
  if (bDisable)
  {
    if (oObj1 && oObj2 && oObj3)
    {
      if (oObj1.style.display != 'none') oObj1.style.display = 'none';
      if (oObj2.style.display != 'none') oObj2.style.display = 'none';
      if (oObj3.style.display != 'block') oObj3.style.display = 'block';
    }
  }
  else
  {
    if (oObj1 && oObj2)
    {
      if (oObj3 && oObj3.style.display != 'none') oObj3.style.display = 'none';
      if (oObj1.style.display != 'block') oObj1.style.display = 'block';
      if (oObj2.style.display != 'none') oObj2.style.display = 'none';
    }
  }
}

// den TextBottom-Frame öffnen
function openTextBottom(oLink1,oLink2,oSize)
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('content');
    if (oFrameSet && oFrameSet.rows)
    {
      var oRows = oFrameSet.rows;
      if (oRows.substr(oRows.length - 2) == ',0')
      {
        var oSizeTop = '50%';
        var oSizeBottom = '50%';
        if (oSize)
        {
          oSizeBottom = oSize + '%';
          oSizeTop = (100 - Number(oSize)) + '%';
        }

        oFrameSet.rows = oSizeTop + ',' + oSizeBottom;
      }

      if (oLink1)
      {
        var oFrame = FF('_text',oAppF);
        if (oFrame && (oFrame.location.href != oLink1))
        {
          oFrame.location.href = oLink1;
        }
      }
      if (oLink2)
      {
        var oFrame = FF('_textbottom',oAppF);
        if (oFrame && (oFrame.location.href != oLink2))
        {
          oFrame.location.href = oLink2;
        }
      }
    }
  }
}

// die Groesse den TextBottom-Frames ermitteln
function textBottomSize()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('content');
    if (oFrameSet && oFrameSet.rows)
    {
      var oRows = oFrameSet.rows;
      return oRows.substr(oRows.indexOf(',') + 1).replace(/%/g,'');
    }
  }

  return "0";
}

// den TextBottom-Frame schliessen
function closeTextBottom()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('content');
    if (oFrameSet && oFrameSet.rows)
    {
      if (oFrameSet.rows != '*,0')
      {
        oFrameSet.rows = '*,0';
      }
    }

    var oFrame = FF('_textbottom',oAppF);
    if (oFrame)
    {
      oFrame.document.location.href = 'about:blank';
    }
  }
}

// enthaelt der TextBottom-Frame die Trefferliste?
function textBottomHasHitlist()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('content');
    if (oFrameSet && oFrameSet.rows && (oFrameSet.rows != '*,0'))
    {
      var oBottom = FF('_textbottom',oAppF);
      if (oBottom)
      {
        return (oBottom.document.location.href.indexOf('hitlist.xav') != -1);
      }
    }
  }

  return false;
}

// enthaelt der TextBottom-Frame das fixierte Dokument?
function textBottomHasFixed()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('content');
    if (oFrameSet && oFrameSet.rows && (oFrameSet.rows != '*,0'))
    {
      var oBottom = FF('_textbottom',oAppF);
      if (oBottom)
      {
        return (oBottom.document.location.href.indexOf('text.xav') != -1);
      }
    }
  }

  return false;
}

// den uebergebenen AppNav-Request in die Buttonleiste laden
function showAsButtons(oLink)
{
  var oButtons = FF('_buttons');
  if (oButtons)
  {
    var oRE = /name=([^&]+)(&|$)/;
    oRE.exec(oButtons.document.location.href);
    var oEins = RegExp.$1;
    oRE.exec(oLink);
    var oZwei = RegExp.$1;
    if (oEins != oZwei)
    {
      oButtons.document.location.replace(oLink);
    }
  }
}

// Popup mit einer HTML-Datei öffnen
function showHTMLPopup(oTextRequest,oMyURI,oURL)
{
  var oBase = "/Xaver";
  var nIndex = oTextRequest.indexOf("/text.xav?");
  if (nIndex > -1)
  {
    oBase = oTextRequest.substr(0,nIndex);
  };
  var oWin = window.open(oBase + '/extern/'+oMyURI+'/'+oURL,oMyURI+'_popup','width=800,height=552,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes');
  if (oWin)
  {
    oWin.focus();
  }
}

// Schnellsuchzeile löschen
function clearSimpleQuery()
{
  var oFrame = FF('_qmask');
  if (oFrame)
  {
    var oInput = oFrame.document.simple.te0;
    if (oInput)
    {
      oInput.value = '... Ihr Schnellsuchbegriff ...';
    }
  }
}

// SID aus einem Xaver-Request isolieren
function dtGetSID(oURL)
{
  return (oURL.search(/([?]|&|^)SID=([^&]*)(&|$)/) != -1) ? RegExp.$2 : "";
}

// NOCA aus einem Xaver-Request isolieren
function dtGetNOCA(oURL)
{
  return (oURL.search(/([?]|&|^)noca=([0-9]+)(&|$)/) != -1) ? RegExp.$2 : "";
}

//
// Treffertermnavigation
//

// Nummer des ersten Trefferterms
function dtGetFirstTermNr(oDok)
{
  var oAnchors = oDok.getElementsByTagName("a");
  if (oAnchors)
  {
    for (var i = 0; i < oAnchors.length; ++i)
    {
      if (oAnchors[i].name.substr(0,2) == "ht")
      {
        return Number(oAnchors[i].name.substr(2));
      }
    }
  }

  return -1;
};

// Term 'nCnt' hervorheben
function dtHighTerm(oDok,nCnt)
{
  if (nCnt >= 0)
  {
    var oSpan = oDok.getElementById("hit" + nCnt);
    if (oSpan && (oSpan.className != "nohitterm"))
    {
      oSpan.className = "hittermactive";
    }
  }
};

// Term 'nCnt' nicht mehr hervorheben
function dtLowTerm(oDok,nCnt)
{
  if (nCnt >= 0)
  {
    var oSpan = oDok.getElementById("hit" + nCnt);
    if (oSpan && (oSpan.className != "nohitterm"))
    {
      oSpan.className = "hitterm";
    }
  }
};

// alle HitTerme nicht mehr als solche markieren
function dtHideHitterms(oDok)
{
  var nLast = dtGetLastTermNr(oDok);
  for (var i = dtGetFirstTermNr(oDok); i <= nLast; ++i)
  {
    var oSpan = oDok.getElementById("hit" + i);
    if (oSpan)
    {
      oSpan.className = "nohitterm";
    }
  }
}

// vorherigen Trefferterm finden
function dtGetPrevTermNr(oDok)
{
  if ((top.nCurPos == -1) || !top.nPrevPosList || (top.nPrevPosList.length == 0) )
  {
    return -1;
  }

  return top.nPrevPosList[top.nPrevPosList.length - 1];
};

// gibt es einen vorherigen Trefferterm?
function dtIsPrevTerm(oDok)
{
  return (dtGetPrevTermNr(oDok) != -1);
};

// den letzten Trefferterm finden
function dtGetLastTermNr(oDok)
{
  var oAnchors = oDok.getElementsByTagName("a");
  if (oAnchors)
  {
    for (var i = oAnchors.length - 1; i >= 0; i -= 1)
    {
      if (oAnchors[i].name.substr(0,2) == "ht")
      {
        return Number(oAnchors[i].name.substr(2));
      }
    }
  }

  return -1;
};

// nächsten Trefferterm finden
function dtGetNextTermNr(oDok)
{
  if (top.nCurPos == -1)
  {
    return -1;
  }

  var nNextNr = -1;
  for (var i = 0; i < oDok.links.length; ++i)
  {
    var nPos = oDok.links[i].href.indexOf('#ht');
    if (nPos != -1)
    {
      var nNr = Number(oDok.links[i].href.substr(nPos+3));
      if (nNr > top.nCurPos)
      {
        nNextNr = nNr;
        break;
      }
    }
  }
  if (nNextNr != -1)
  {
    var nLast = dtGetLastTermNr(oDok);
    while (nNextNr <= nLast)
    {
      if (oDok.getElementById("hit" + nNextNr))
      {
        return nNextNr;
      }
      nNextNr++;
    }
  }

  return -1;
};

// gibt es einen weiteren Trefferterm?
function dtIsNextTerm(oDok)
{
  return (dtGetNextTermNr(oDok) != -1);
};

// Leerzeichen vorne und hinten entfernen
function dtStrip(oStr)
{
  return oStr.replace(/^\s+/,"").replace(/\s+$/,"");
}

// zum Setzen von Xaver-Variablen
function dtSetXaverVar(oURI,oName,oValue)
{
  var oComF = FComF();
  if (oComF)
  {
    var oSID = dtGetSID(oComF.location.search);
    if (oSID == "") oSID = dtGetSID(location.search);


    var oHREF = top.location.pathname.replace(/\/[^\/]+\.xav$/,"/preferences.xav?SID=" + oSID + "&tf=&hlf=&tocf=&qmf=&name=dummy&back=&set=&bk=" + oURI + "&") + oName + "=" + escape(oValue);
    for (var i = 3; i < dtSetXaverVar.arguments.length - 1; i += 2)
    {
      oHREF = oHREF + "&" + dtSetXaverVar.arguments[i] + "=" + encodeURIComponent(dtSetXaverVar.arguments[i + 1]);
    }
    oComF.location.replace(oHREF); 
  }
}

function dtSaveContext()
{
  var oContext = (top.oLastQueryCtxt != null ? top.oLastQueryCtxt : "") + "|";
  oContext += (top.bLastExtQueryOR ? "1" : "0") + "|";
  oContext += (top.bLastExtQueryPhonetic ? "1" : "0") + "|";
  oContext += top.nLastExtQueryCtxt[0] + "|";
  oContext += top.nLastExtQueryCtxt[1] + "|";
  oContext += top.nLastExtQueryCtxt[2] + "|";
  oContext += top.oLastExtQueryQDatum + "|";
  oContext += top.oLastExtQueryQNorm + "|";
  oContext += top.oLastExtQueryQPara + "|";
  oContext += top.oLastExtQueryQNormRN + "|";
  oContext += top.oLastExtQueryQParaRN + "|";
  oContext += top.oLastExtQueryQRN + "|";
  oContext += top.oLastExtQueryFDatL + "|";
  oContext += top.oLastExtQueryFDatH + "|";
  oContext += (top.bUserToggledSidebar ? "1" : "0") + "|";
  oContext += (top.bSidebarOpen ? "1" : "0") + "|"; 
  dtSetXaverVar(top.oCurURI,"col:dtSavedContext",oContext);
}

function dtRestoreContext(oContext)
{
  if (oContext.length > 0)
  {
    var oStr = oContext.split("|",16);

    if (oStr.length >= 16)
    {
      top.oLastQueryCtxt = (oStr[0].length == 0) ? null : oStr[0];
      top.bLastExtQueryOR = (oStr[1] == "1");
      top.bLastExtQueryPhonetic = (oStr[2] == "1");
      top.nLastExtQueryCtxt[0] = parseInt(oStr[3]);
      top.nLastExtQueryCtxt[1] = parseInt(oStr[4]);
      top.nLastExtQueryCtxt[2] = parseInt(oStr[5]);
      top.oLastExtQueryQDatum = oStr[6];
      top.oLastExtQueryQNorm = oStr[7];
      top.oLastExtQueryQPara = oStr[8];
      top.oLastExtQueryQNormRN = oStr[9];
      top.oLastExtQueryQParaRN = oStr[10];
      top.oLastExtQueryQRN = oStr[11];
      top.oLastExtQueryFDatL = oStr[12];
      top.oLastExtQueryFDatH = oStr[13];
      top.bUserToggledSidebar = (oStr[14] == "1");
      top.bSidebarOpen = (oStr[15] == "1");
    }
  }
}

//
// Funktionen fuer die Intelligente Schnellsuche(R)
//

// Prototype fuer die Normentabelle
//var dtISNormTable = new Object();
//dtISNormTable['gg']='gg';

function dtISCheckNorm(oNorm)
{
  // wenn eine Tabelle definiert ist...
  if (dtISNormTable)
  {
    var oNormTst = dtStrip(oNorm).replace(/\s+/," ");

    // ... und sie diese Norm enthaelt...
    if (dtISNormTable[oNormTst])
    {
      // ... liefern wir ein normalisiertes Resultat,...
      return dtISNormTable[oNormTst];
    }
  }

  // ... ansonsten 'null'.
  return null;
}

function dtISCheckQuery(oQuery)
{
  // Default: nichts gefunden
  var oNorm = null;
  var oPara = null;

  // auf Paragraphensuche testen
  if (oQuery.search(/^(§§|Artikel|Art|Art\.)\s*(\d+\w?)(\s+f\.?|\s+ff\.?)\s+(.+)$/i) != -1)
  {
    oPara = RegExp.$2;
    oNorm = dtISCheckNorm(RegExp.$4);
  }
  else if (oQuery.search(/^(§|Art|Art\.|Artikel)\s*(\d+\w?)\s+(.+)$/i) != -1)
  {
    oPara = RegExp.$2;
    oNorm = dtISCheckNorm(RegExp.$3);
  }
  else if (oQuery.search(/^(.+)\s+(§|Art|Art\.|Artikel)\s*(\d+\w?)$/i) != -1)
  {
    oPara = RegExp.$3;
    oNorm = dtISCheckNorm(RegExp.$1);
  }
  else if (oQuery.search(/^(.+)\s+(§§|Artikel|Art|Art\.)\s*(\d+\w?)(\s+f\.?|\s+ff\.?)$/i) != -1)
  {
    oPara = RegExp.$3;
    oNorm = dtISCheckNorm(RegExp.$1);
  }
  else if (oQuery.search(/^(ZTR\s+|WISTRA\s+)?(\d\d\d\d)[,]?\s*(\d+)(\s+f\.?|\s+ff\.?|\s?-\s?\d+)?$/i) != -1)
  {
    oPara = RegExp.$3;
    oNorm = RegExp.$2;
  }

  // wenn beides gefunden, beides zurueckgeben, sonst 'null'
  return (oNorm && oPara) ? new Object({norm:oNorm,para:oPara}) : null;
}

function dtISCheckIntelliQuery(oForm,nQueryNum)
{
  top.oIsSpecialOrIntelliSearch = false;
  if (nQueryNum == 0)
  {
    // erster Aufruf fuer dieses Suchformular: initialisieren
    oForm.qXavParaText.value = "";
  }

  var oQuery = dtStrip(oForm.elements["te" + nQueryNum].value).toLowerCase();
  var oResult = dtISCheckQuery(oQuery);

  if (oResult)
  {
    // Intelligente Schnellsuche(R) durchfuehren
    top.oIsSpecialOrIntelliSearch = true;
    oForm.qXavParaText.value += " é" + oResult.norm + "X" + oResult.para;

    // Kontextrolle der Originalsuchzeile auf illegalen Wert setzen
    var oCRObj = oForm.elements["cr" + nQueryNum];
    if (oCRObj.options)
    {
      // ... fuer eine Kombobox (erweiterte Suche)
      top.nLastExtQueryCtxt[nQueryNum] = oCRObj.selectedIndex;
      oCRObj.value = "CtxtXavNone"; //new Option("-","CtxtXavNone",false,true);
    }
    else
    {
      if (oForm.name != 'simple' && oCRObj.value) {
        oCRObj.value = "CtxtXavNone";
      }
      else
      {
        // ... fuer ein Input-Element (Schnellsuche)
        top.oLastQueryCtxt = oCRObj.value;
        oCRObj.value = "CtxtXavNone";
      };
    }
  }
}

//
// Funktionen zur DOM Bearbeitung
//
function dtGetNodeText(oNode)
{
  var oTxt = "";

  if (oNode)
  {
    if (oNode.nodeType == 3)
    {
      oTxt = oNode.nodeValue;
    }
    else if (oNode.nodeType == 1)
    {
      var oCurChild = oNode.firstChild;
      while (oCurChild)
      {
        oTxt += dtGetNodeText(oCurChild);
        oCurChild = oCurChild.nextSibling;
      }
    }
  }

  return oTxt;
}

function dtSetAttribute(oNode,oAttrName,oAttrValue)
{
  if (oNode)
  {
    var oAttrNode = document.createAttribute(oAttrName);
    oAttrNode.nodeValue = oAttrValue;
    oNode.setAttributeNode(oAttrNode);
  }
}

//
// Funktionen für die Sidebar
//

// den Sidebar-Frame öffnen
function openSidebar()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('sidebarfs');
    if (oFrameSet && oFrameSet.cols)
    {
      var oCols = oFrameSet.cols;
      if (oCols.substr(oCols.length - 2) == ',0')
      {
        oFrameSet.cols = '*,150';
      }
    }

    var oFrame = FF('_sidebar',oAppF);
    if (oFrame)
    {
      // absoluter Pfad, damit's beide Browser richtig machen...
      oFrame.document.location.href = top.oCurBasepath + 'extern/' + top.oCurURI + '/sidebar.html';
    }
  }
}

// den Sidebar-Frame schliessen
function closeSidebar()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('sidebarfs');
    if (oFrameSet && oFrameSet.cols)
    {
      if (oFrameSet.cols != '*,0')
      {
        oFrameSet.cols = '*,0';
      }
    }

    var oFrame = FF('_sidebar',oAppF);
    if (oFrame)
    {
      oFrame.document.location.href = 'about:blank';
    }
  }
}

// Test auf geoeffnete Sidebar
function isSidebarOpen()
{
  var oAppF = FAppF();
  if (oAppF)
  {
    var oFrameSet = oAppF.document.getElementById('sidebarfs');
    if (oFrameSet && oFrameSet.cols)
    {
      if (oFrameSet.cols != '*,0')
      {
        return true;
      }
    }
  }

  return false;
}


// Aus dem Chaos des Users versuchen wir ein Datum zu entziffern ...
// Parameter:
// - oDatum: Eigabe des Users
// Rückgabewert:
//   Datum als Objekt { day, month, year }, nicht eingebene Werte sind
//   'null' oder Rückgabe 'null' im Fehlerfall
function dtParseDatum(oDatum)
{
  var oResult = null;

  // Kein Datum eingetragen .... tschüss ...
  oDatum = dtStrip(oDatum);
  if (oDatum == "") return null;

  // Unnötige Zeichen entfernen
  oDatum = oDatum.replace(/\s+/g," "); // aufeinander folgende Leerzeichen reduzieren
  oDatum = oDatum.replace(/-/g,"."); // Bindestrich wird zu Punkt
  oDatum = oDatum.replace(/\//g,"."); // Schrägstrich wird zu Punkt
  oDatum = oDatum.replace(/\s/g,"."); // Leerzeichen wird zu Punkt

  // Monatsangaben im "Klartext" konvertieren
  oDatum = oDatum.toLowerCase();
  if (oDatum.search(/jan.*?\./) >= 0) oDatum = oDatum.replace(/jan.*?\./,".1.");
  if (oDatum.search(/feb.*?\./) >= 0) oDatum = oDatum.replace(/feb.*?\./,".2.");
  if (oDatum.search(/mär.*?\./) >= 0) oDatum = oDatum.replace(/mär.*?\./,".3.");
  if (oDatum.search(/apr.*?\./) >= 0) oDatum = oDatum.replace(/apr.*?\./,".4.");
  if (oDatum.search(/mai/) >= 0) oDatum = oDatum.replace(/mai/,".5.");
  if (oDatum.search(/jun.*?\./) >= 0) oDatum = oDatum.replace(/jun.*?\./,".6.");
  if (oDatum.search(/jul.*?\./) >= 0) oDatum = oDatum.replace(/jul.*?\./,".7.");
  if (oDatum.search(/aug.*?\./) >= 0) oDatum = oDatum.replace(/aug.*?\./,".8.");
  if (oDatum.search(/sep.*?\./) >= 0) oDatum = oDatum.replace(/sep.*?\./,".9.");
  if (oDatum.search(/okt.*?\./) >= 0) oDatum = oDatum.replace(/okt.*?\./,".10.");
  if (oDatum.search(/nov.*?\./) >= 0) oDatum = oDatum.replace(/nov.*?\./,".11.");
  if (oDatum.search(/dez.*?\./) >= 0) oDatum = oDatum.replace(/dez.*?\./,".12.");

  // Aufeinander folgende Punkte zu jeweils einem reduzieren
  oDatum = oDatum.replace(/\.+/g,".");
  if (oDatum == "" || oDatum == ".") return null;

  // Jetzt sollten nur noch Ziffern und Punkte enthalten sein. Wenn nicht, ist hier Ende.
  for (nI = 0; nI < oDatum.replace(/\./g, "").length; nI++)
  {
    if (isNaN(oDatum.replace(/\./g, "").substr(nI,1))) return null;
  };
 
  // Jetzt trennen wir die Datumsangabe in die Bestandteile Tag, Monat und Jahr auf ...
  oParts = oDatum.split(".");

  // korrekte Umwandlung der einzelnen Bestandteile in Integer sicherstellen
  for (var nI = 0; nI < oParts.length; nI++)
  {
    // führende Nullen weg ...
    oParts[nI] = oParts[nI].replace(/^0+/,"");
    oParts[nI] = (oParts[nI] == "") ? 0 : oParts[nI];
  }

  // Welche Bestandteile hat die Usereingabe?
  if (oParts.length > 3)
  {
    // Es ist mehr als Tag, Monat, Jahr angegeben? Damit können wir nichts anfangen ...
    return null;
  }
  else if (oParts.length == 3)
  {
    // Die Eingabe hat drei Bestandteile, das werden wohl Tag, Monat und Jahr sein ...
    oResult = new Object({ day:parseInt(oParts[0]), month:parseInt(oParts[1]), year:parseInt(oParts[2]) });
  }
  else if (oParts.length == 2)
  {
    // Nur zwei Werte angegeben, das werden wohl Monat und Jahr sein ...
    oResult = new Object({ day:null, month:parseInt(oParts[0]), year:parseInt(oParts[1]) });
  }
  else if (oParts.length == 1)
  {
    // Nur eine Angabe? Das muss dann wohl das Jahr sein
    oResult = new Object({ day:null, month:null, year:parseInt(oParts[0]) });
  }
  
  // Der User hat eine kurze Jahresangabe eingegeben, wir interpretieren ...
  if (oResult.year < 1000)
  {
    if (oResult.year > 70 && oResult.year < 100) oResult.year+=1900;
    else if (oResult.year < 1900)                oResult.year+=2000;
  }

  // Absolut unsinnige Angaben für Monate und Tage werden gefiltert
  if (oResult.day != null)
  {
    if (oResult.day <= 0)      oResult.day = 1;
    else if (oResult.day > 31) oResult.day = 31;
  }
  if (oResult.month != null)
  {
    if (oResult.month <= 0)      oResult.month = 1;
    else if (oResult.month > 12) oResult.month = 12;
  }

  // Normiertes Datum als Rückgabe
  return oResult;
}

//
// Tools zum Bearbeiten von Formularen
//
function dtSetValueIfAvail(oID,oValue)
{
  var oObj = document.getElementById(oID);
  if (oObj)
  {
    oObj.value = oValue;
  }
}

function dtSetValueIfEmpty(oID,oValue)
{
  var oObj = document.getElementById(oID);
  if (oObj)
  {
    oObj.value = dtStrip(oObj.value);
    if (oObj.value.length == 0)
    {
      oObj.value = oValue;
    }
  }
}

function dtResetValueOnFocus(oObj,oValue,bFocus)
{
  if (bFocus)
  {
    if (oObj.value == oValue) oObj.value = "";
  }
  else
  {
    if (dtStrip(oObj.value).length == 0) oObj.value = oValue;
  }
}

function dtClearIfUntouched(oID,oUntouchedValue)
{
  var oObj = document.getElementById(oID);
  if (oObj)
  {
    if (oObj.value == oUntouchedValue)
    {
      oObj.value = "";
    }
  }
}

//
// Optionsfeld mit Wert und Text zusammenbauen
//
function newOptionField(sValue, sText)
{
  var newOption   = document.createElement("option");
  newOption.text  = sText;
  newOption.value = sValue;
  return newOption;
};

//
// Gesetzesliste fuer die Gesetze ausfuellen
//
function fillGesetzeGesetze(oobj)
{
  var oOptionfield = document.getElementById("qNorm");
  if (oOptionfield)
  { 
    for (var Eigenschaft in oobj)
    {
      try
      {
        oOptionfield.add(newOptionField(oobj[Eigenschaft], Eigenschaft), null); // standards compliant; doesn't work in IE
      }
      catch(ex)
      {
        oOptionfield.add(newOptionField(oobj[Eigenschaft], Eigenschaft)); // IE only
      };
    };
  };
};

//
// Gesetzesliste fuer die Kommentierungen ausfuellen
//
function fillGesetzeKommentierung(oobj)
{
  var oOptionfield = document.getElementById("qNormRN");

  if (oOptionfield)
  { 
    for (var Eigenschaft in oobj)
    {
      try
      {
        oOptionfield.add(newOptionField(oobj[Eigenschaft], Eigenschaft), null); // standards compliant; doesn't work in IE
      }
      catch(ex)
      {
        oOptionfield.add(newOptionField(oobj[Eigenschaft], Eigenschaft)); // IE only
      };
    };
  };
};

//
// ein-/ausblendbare Box mit Überschrift
//
function EPS_toggleBox(oBoxHeader)
{
  if (oBoxHeader)
  {
    // die zu diesem Header gehoerende Box finden
    var oBox = oBoxHeader.nextSibling;
    while (oBox && ((oBox.nodeType != 1) || (oBox.className.substring(0,15) != 'EPSchaltbar_box')))
    {
      oBox = oBox.nextSibling;
    }

    if (oBox)
    {
      // Gefunden! Aktuelle Sichtbarkeit umsetzen
      if (oBox.className != "EPSchaltbar_box_on")
      {
        oBox.className = "EPSchaltbar_box_on";
        oBoxHeader.style.backgroundImage='url(img/button_pfeil_rechts.gif)';
        oBoxHeader.style.backgroundPosition='1px 1px';
      }
      else
      {
        oBox.className = "EPSchaltbar_box";
        oBoxHeader.style.backgroundImage='url(img/button_pfeil_runter.gif)';
        oBoxHeader.style.backgroundPosition='1px 5px';
      }
    }
  }
}


function EPS_ImgMouseOver(oBoxHeader)
{
  // die zu diesem Header gehoerende Box finden
  var oBox = oBoxHeader.nextSibling;
  while (oBox && ((oBox.nodeType != 1) || (oBox.className.substring(0,15) != 'EPSchaltbar_box')))
  {
    oBox = oBox.nextSibling;
  };
  
  if (oBox)
  {
    // Gefunden! Pfeilchen anzeigen
    if (oBox.className != "EPSchaltbar_box_on")
    {
      oBoxHeader.style.backgroundImage='url(img/button_pfeil_runter.gif)';
      oBoxHeader.style.backgroundPosition='1px 5px';
    }
    else
    {
      oBoxHeader.style.backgroundImage='url(img/button_pfeil_rechts.gif)';
      oBoxHeader.style.backgroundPosition='1px 1px';
    };
  }; 
}

function EPS_ImgMouseOut(oBoxHeader)
{
  // die zu diesem Header gehoerende Box finden
  var oBox = oBoxHeader.nextSibling;
  while (oBox && ((oBox.nodeType != 1) || (oBox.className.substring(0,15) != 'EPSchaltbar_box')))
  {
    oBox = oBox.nextSibling;
  };
  
  if (oBox)
  {
    // Gefunden! Pfeilchen anzeigen
    if (oBox.className != "EPSchaltbar_box_on")
    {
      oBoxHeader.style.backgroundImage='url(img/button_pfeil_rechts.gif)';
      oBoxHeader.style.backgroundPosition='1px 1px';
    }
    else
    {
      oBoxHeader.style.backgroundImage='url(img/button_pfeil_runter.gif)';
      oBoxHeader.style.backgroundPosition='1px 5px';
    };
  }; 
};