//==================================================================================
//==================================================================================
//
// Navigation-Tool
// OO-PROGRAMMIERUNG
// AUTOR: DF
// © rdts AG
// ERSTELLT: 01.07.2005
//
// Menus für IE- und GECKO-Browser
//
//==================================================================================
//==================================================================================

var undefined;

// ################################################################################
// #############################################################|  Navigation   |##
// ################################################################################

// ============================================================
// Klasse Navigation
// ============================================================
//
// Konstruktor:
// ------------
//   + Navigation()
//
// Eigenschaften:
// --------------
//   + _id : id (readonly)
//   + _navigationStructure : Object (readonly)
//   + _registerStructureItem : NavigationItem (readonly)
//   + _direction : str (readonly) (horizontal, vertical)
//   + _dependVertical : str (readonly) (top, middle, bottom)
//   + _dependHorizontal : str (readonly) (right, left)
//   + _highlightActiveRoot : str (readonly) (no, yes)
//   + _highlightActiveClassPostfix : str (readonly)
//   + _rootLeft : number (readonly)
//   + _rootTop : number (readonly)
//   + _differenceVertical : number (readonly)
//   + _differenceHorizontal : number (readonly)
//   + _chacheRoot = '';
//   + _chacheRootHTMLString = undefined;
//   + _containerIDPrefix : str (readonly)
//   + _menuInUse : boolean (readonly)
//   + _itemIDPrefix : str (readonly)
//   + _activeMenu: Object (readonly)
//   + _timeout : str (readonly)
//   + _delay : number (readonly)
//   + _getNavigationStructureHTMLRoot

//
// Methoden:
// ---------
//   + _setID(str) : void
//   + _setNavigationStructure(obj) : void
//   + _setRegisterStructureItem(obj:NavigationItem) : void
//   + setDirection(str) : void
//   + setDependVertical(str) : void
//   + setDependHorizontal(str) : void
//   + setDifferenceVertical(n) : void
//   + setDifferenceHorizontal(n) : void
//

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

function Navigation(id) {
  if (arguments.length>1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  // Attribute
  this._id = undefined;
  this._setID(id);
  this._navigationAllowedStatus = undefined;
  this._direction = 'horizontal';
  this._dependVertical = 'top';
  this._dependHorizontal = 'right';
  this._highlightActiveRoot = 'no';
  this._highlightActiveClassPostfix = undefined;
  this._rootLeft = 0;
  this._rootTop = 0;
  this._differenceVertical = 0;
  this._differenceHorizontal = 0;
  this._navigationStructure = {};
  this._registerStructureItem = {};
  this._chacheRoot = '';
  this._chacheRootHTMLString = undefined;
  this._activeMenu = {};
  this._menuInUse = false;
  this._containerIDPrefix = this.id() + '_Nav';
  this._itemIDPrefix = this.id() + '_Item';
  this._timeout = undefined;
  this._delay = undefined;
  this._getNavigationStructureHTMLRoot = true;
  
  this.setDelay(1000);
}

// toString()
Navigation.prototype.toString = function() {
  return "\n[Navigation - id: " + this + "]\n";
}

// ------------------------------------------------------------
// Zugriffsmethoden
// ------------------------------------------------------------

// -------
// _id
// -------
Navigation.prototype.id = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._id = str;
  }
  return this._id;
}

// -------
// navigationStructure
// -------
Navigation.prototype.navigationStructure = function(obj) {
  if (arguments.length) {
    if (typeof obj != "object") {
      focus();
      throw new Error("Argument ist nicht vom Typ Object!");
    }
    this._navigationStructure = obj;
  }
  return this._navigationStructure;
}

// -------
// navigationStructure
// -------
Navigation.prototype.registerStructureItem = function(obj) {
  if (arguments.length) {
    if (typeof obj != "object") {
      focus();
      throw new Error("Argument ist nicht vom Typ Object!");
    }
    this._registerStructureItem = obj;
  }
  return this._registerStructureItem;
}

// -------
// _direction
// -------
Navigation.prototype._direction = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._direction = str;
  return this._direction;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// -------
// _setID
// -------
Navigation.prototype._setID = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.id(str);
}

// -------
// _setRegisterStructureItem
// -------
Navigation.prototype._setRegisterStructureItem = function(obj) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof obj != "object") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.registerStructureItem(obj);
}

// -------
// _setRootPosition
// -------
Navigation.prototype._setRootPosition = function() {
  var id = this._containerIDPrefix + 'root';
  if (document.getElementById(id)){
    var elem = document.getElementById(id);
    if (elem.offsetParent){
      elem = elem.offsetParent;
    }
    this._rootLeft = elem.offsetLeft;
    this._rootTop = elem.offsetTop;
  }
}

// -------
// _getNavigationStructureHTML
// -------
Navigation.prototype._getNavigationStructureHTML = function(structure, html, id, loopPosition) {
  var containerClassName = '';
  var first = undefined;
  if (loopPosition == 1){
    first = true;
  }
  var containerStyle = 'display: none;';
  if (this._getNavigationStructureHTMLRoot){
    containerStyle = 'display: block;';    
  }
  if (NavigationItem.hasInstance(id) && NavigationItem.getInstance(id).style()){
    containerStyle += NavigationItem.getInstance(id).style();
  }
  if (NavigationItem.hasInstance(id) && NavigationItem.getInstance(id).className()){
    containerClassName = 'class="'+ NavigationItem.getInstance(id).className() +'"';
  }
  this._getNavigationStructureHTMLRoot = false;
  if (this._direction == 'vertical'){
    if (loopPosition > 1 &&  loopPosition <= 2){
      html += '<div id="'+ id +'"  '+ containerClassName +' style="'+ containerStyle +' position: absolute;">';
    } else  if (loopPosition > 2){
      html += '<div id="'+ id +'"  '+ containerClassName +' style="'+ containerStyle +' position: static;">';
    } else {
      html += '<div id="'+ id +'" '+ containerClassName +' style="'+ containerStyle +' position: absolute;">';
    }
    for (var i in structure){
      var id = this._containerIDPrefix + i;
      var cssStyle = '';
      var cssClassName = '';
      var href = 'href="javascript:void(0);"';
      var target = '';
      var onclick = '';
      var label = this.registerStructureItem()[id].label();
      var title = '';
      //title += 'title="Menupunkt: '+ label +'"';
      if (this.registerStructureItem()[id].style()){
        cssStyle = 'style="' + this.registerStructureItem()[id].style() + '" ';
      }
      if (this.registerStructureItem()[id].className()){
        cssClassName = 'class="' + this.registerStructureItem()[id].className() + '" ';
      }
      if (this.registerStructureItem()[id].href()){
        href = 'href="' + this.registerStructureItem()[id].href() + '" ';
      }
      if (this.registerStructureItem()[id].target()){
        target = 'target="' + this.registerStructureItem()[id].target() + '" ';
      }
      if (this.registerStructureItem()[id].onclick()){
        onclick = 'onclick="' + this.registerStructureItem()[id].onclick();
      } else {
        //onclick = 'onclick="Navigation.getInstance(\''+ this.id() +'\').displaySubmenu(\''+ this.registerStructureItem()[id].id() +'\');"';
      }
      if (this.registerStructureItem()[id].title()){
        title = 'title="' + this.registerStructureItem()[id].title() + '" ';
      }
      if (first){
        html += '<div id="'+ this._itemIDPrefix + this.registerStructureItem()[id].id() +'" style="position: static; float: left;">\n';
      } else {
        html += '<div id="'+ this._itemIDPrefix + this.registerStructureItem()[id].id() +'" style="position: static;">\n';
      }
      if (this._dependVertical == 'top'){
        if (typeof structure[i] == 'object'){
          html += this._getNavigationStructureHTML(structure[i], '', id, loopPosition+1);
        } 
      }
      if (this.registerStructureItem()[id].type() == 0){
        if (this.registerStructureItem()[id].subClassName()){
          cssClassName = 'class="' + this.registerStructureItem()[id].subClassName() + '" ';
        }
        if (this.registerStructureItem()[id].subStyle()){
          cssStyle = 'style="' + this.registerStructureItem()[id].subStyle() + ' display: block;" ';
        }
        if (first){
          html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ href +' '+ cssStyle +' '+ cssClassName +' '+ target +' '+ onclick +' onmouseout="Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" onmouseover="Navigation.getInstance(\''+ this.id() +'\').displaySubmenu(\''+ this.registerStructureItem()[id].id() +'\');" '+ title +'>' + label +'</a>\n';
        } else {
          html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ cssStyle +' '+ cssClassName +' '+ target +' '+ onclick +' onmouseout="Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" '+ title +'>' + label +'</a>\n';
        }
      } else {
        html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ href +' '+ cssStyle +' '+ cssClassName +' '+ target +' '+ onclick +' onmouseout="Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" onmouseover="Navigation.getInstance(\''+ this.id() +'\').displaySubmenu(\''+ this.registerStructureItem()[id].id() +'\');" '+ title +'>' + label +'</a>\n';
      }
      if (this._dependVertical != 'top'){
        if (typeof structure[i] == 'object'){
          html += this._getNavigationStructureHTML(structure[i], '', id, loopPosition+1);
        } 
      } 
      html += '</div>\n'; 
    }
    html += '</div>';
  } else {
    html += '<div id="'+ id +'"  '+ containerClassName +' style="'+ containerStyle +' position: absolute;">\n';
    for (var i in structure){
      var id = this._containerIDPrefix + i;
      var cssStyle = '';
      var cssClassName = '';
      var href = 'href="javascript:void(0);"';
      var target = '';
      var onclick = this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').displaySubmenu(\''+ this.registerStructureItem()[id].id() +'\'); ';
      var label = this.registerStructureItem()[id].label();
      var title = '';
      //title += 'title="Menupunkt: '+ label +'"';
      if (this.registerStructureItem()[id].style()){
        cssStyle = 'style="' + this.registerStructureItem()[id].style() + '" ';
      }
      if (this.registerStructureItem()[id].className()){
        cssClassName = 'class="' + this.registerStructureItem()[id].className() + '" ';
      }
      if (this.registerStructureItem()[id].href()){
        href = 'href="' + this.registerStructureItem()[id].href() + '" ';
      }
      if (this.registerStructureItem()[id].target()){
        target = 'target="' + this.registerStructureItem()[id].target() + '" ';
      }
      if (this.registerStructureItem()[id].onclick()){
        onclick += this.registerStructureItem()[id].onclick() + ' ';
      }
      if (this.registerStructureItem()[id].title()){
        title = 'title="' + this.registerStructureItem()[id].title() + '" ';
      }
      if (first){
        html += '<div id="'+ this._itemIDPrefix + this.registerStructureItem()[id].id() +'" style="position: static; float: left;">\n';
      } else {
        html += '<div id="'+ this._itemIDPrefix + this.registerStructureItem()[id].id() +'" style="position: static;">\n';
      }
      //html += '<div id="'+ this._itemIDPrefix + this.registerStructureItem()[id].id() +'" style="position: static; border:">\n';
      if (this.registerStructureItem()[id].type() == 0){
        if (this.registerStructureItem()[id].subClassName()){
          cssClassName = 'class="' + this.registerStructureItem()[id].subClassName() + '" ';
        }
        if (this.registerStructureItem()[id].subStyle()){
          cssStyle = 'style="display: block; ' + this.registerStructureItem()[id].subStyle() + '" ';
        }
        //html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ href +' '+ cssStyle +' '+ cssClassName +' '+ target +' '+ onclick +' onmouseout="'+ this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" onmouseover="'+ this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').displaySubmenu(\''+ this.registerStructureItem()[id].id() +'\');" '+ title +'>' + label +'</a>\n';
        html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ href +' '+ cssStyle +' '+ cssClassName +' '+ target +' onclick="'+ onclick +'" onmouseout="'+ this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" '+ title +'>' + label +'</a>\n';
      } else {
        //html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ href +' '+ cssStyle +' '+ cssClassName +' '+ target +' '+ onclick +' onmouseout="'+ this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" onmouseover="'+ this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').displaySubmenu(\''+ this.registerStructureItem()[id].id() +'\');" '+ title +'>' + label +'</a>\n';
        html += '<a id="button_'+ this.registerStructureItem()[id].id() +'" '+ href +' '+ cssStyle +' '+ cssClassName +' '+ target +'  onclick="'+ onclick +'" onmouseout="'+ this._chacheRoot +'Navigation.getInstance(\''+ this.id() +'\').collapseMenu();" '+ title +'>' + label +'</a>\n';
      }
      html += '</div>\n';
    } 
    if (first){
      html += '<div class="float-aufheben"><br /></div>\n';
    }
    html += '</div>\n';
    loopPosition++;
    for (var i in structure){
      var id = this._containerIDPrefix + '' + i;
      if (typeof structure[i] == 'object'){
        html += this._getNavigationStructureHTML(structure[i], '', id, loopPosition);
      } 
    }
  }
  return html;
}

// -------
// _setHighlightedItems
// -------
Navigation.prototype._setHighlightedItems = function(id) {
  var items = [];
  var activeItem = NavigationItem.getInstance(id);
  items.push(activeItem);
  for (var i=0; i<items.length; i++){
    var elem = document.getElementById('button_' + items[i].id());
    if (elem){
      var className = items[i].subClassName() + this._highlightActiveClassPostfix;
      elem.className = className;
    }  
  }
}

// -------
// _setOffHighlightedItems
// -------
Navigation.prototype._setOffHighlightedItems = function(id) {
  var items = [];
  var activeItem = NavigationItem.getInstance(id);
  items.push(activeItem);
  for (var i=0; i<items.length; i++){
    var elem = document.getElementById('button_' + items[i].id());
    if (elem){
      var className = items[i].subClassName();
      elem.className = className;
    }  
  }
}


// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------
// setDirection
// -------
Navigation.prototype.setDirection = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._direction = str;
}

// -------
// setChacheRoot
// -------
Navigation.prototype.setChacheRoot = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._chacheRoot = str;
}

// -------
// setChacheRootHTMLString
// -------
Navigation.prototype.setChacheRootHTMLString = function(obj) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof obj != "object") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._chacheRootHTMLString = obj;
}

// -------
// getNavigationAllowedStatus
// -------
Navigation.prototype.getNavigationAllowedStatus = function() {
  if (document.getElementById){
    this._navigationAllowedStatus = true;
  }
  return this._navigationAllowedStatus;
}

// -------
// setDelay
// -------
Navigation.prototype.setDelay = function(n) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (!NavigationTools.checkNumber(n)) {
    focus();
    throw new Error("Argument ist nicht vom Typ Number!");
  }
  if (document.all){
    if (n < 1200){
      n = n + (n/5);
    }
  }
  this._delay = n;
}

// -------
// setHighlightActiveRoot
// -------
Navigation.prototype.setHighlightActiveRoot = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._highlightActiveRoot = str;
}

// -------
// setHighlightActiveRoot
// -------
Navigation.prototype.setHighlightActiveClassPostfix = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._highlightActiveClassPostfix = str;
}

// -------
// setDependHorizontal
// -------
Navigation.prototype.setDependHorizontal = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._dependHorizontal = str;
}

// -------
// setDependVertical
// -------
Navigation.prototype.setDependVertical = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this._dependVertical = str;
}

// -------
// setDifferenceVertical
// -------
Navigation.prototype.setDifferenceVertical = function(n) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (!NavigationTools.checkNumber(n)) {
    focus();
    throw new Error("Argument ist nicht vom Typ Number!");
  }
  this._differenceVertical = n;
}

// -------
// setDifferenceHorizontal
// -------
Navigation.prototype.setDifferenceHorizontal = function(n) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (!NavigationTools.checkNumber(n)) {
    focus();
    throw new Error("Argument ist nicht vom Typ Number!");
  }
  this._differenceHorizontal = n;
}

// -------
// setNavigationStructure
// -------
Navigation.prototype.setNavigationStructure = function(obj) {
  if(!this.getNavigationAllowedStatus()){
    return;
  }
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof obj != "object") {
    focus();
    throw new Error("Argument ist nicht vom Typ HMTL-Object!");
  }
  var structure = {};
  structure = Navigation._getNavigationStructureByNode(obj, structure, '', 0, this._containerIDPrefix);
  this.navigationStructure(structure);
  this._setRegisterStructureItem(NavigationItem._registerInstance);
  //alert(Navigation._getNavigationStructuretoString(this.navigationStructure(), '', 0));
}

// -------
// drawNavigationStructure
// -------
Navigation.prototype.drawNavigationStructure = function(html) {
  if(!this.getNavigationAllowedStatus()){
    return;
  }
  if(!document.getElementById(this.id())){
    return;
  }
  var html = '';
  html += this._getNavigationStructureHTML(Navigation._getFirstItem(this.navigationStructure()), '', this._containerIDPrefix + 'root', 1);
  //alert(html);
  /*
  var win = window.open('','test');
  var doc = win.document;
  doc.open();
  doc.write(html);
  doc.close();
  */
  document.getElementById(this.id()).innerHTML = html;
  this._setRootPosition();
}

// -------
// hideVisitedNavigation
// -------
Navigation.prototype.hideVisitedNavigation = function(id) {
  var item = NavigationItem.getInstance(id);
  for (var i in this._activeMenu){
    var rootPos = i.split(this._containerIDPrefix)[1];
    if (item.rootObj()[rootPos] == undefined){
      if (this._activeMenu[i]['elem']){
        this._activeMenu[i]['elem'].style.display = 'none';
        this._setOffHighlightedItems(this._activeMenu[i]['item'].id());
      }
      delete this._activeMenu[i];
    }
  }
}

// -------
// showActiveNavigation
// -------
Navigation.prototype.showActiveNavigation = function(id) {
  var elem = document.getElementById(id);
  if (elem){
    this.setElementPosition(id);
    if (elem.style.display == 'block'){
      elem.display = 'none';
    } else {
      elem.style.display = 'block';
    } 
    if (this._highlightActiveRoot == 'yes'){
      if (this._highlightActiveClassPostfix){
        this._setHighlightedItems(id);
      }
    }
  }
}

// -------
// setElementPosition
// -------
Navigation.prototype.setElementPosition = function(id) {
  var item = NavigationItem.getInstance(id);
  var rootPos = id.split(this._containerIDPrefix)[1];
  var activeItem = NavigationItem.createInstance(this._itemIDPrefix +''+ id, '');
  // vertical
  if (this._direction == 'vertical'){
    if (document.getElementById(id)){
      if (this._dependHorizontal=='left'){
        document.getElementById(id).style.marginRight =  this._differenceHorizontal + 'px';
      } else {
        document.getElementById(id).style.marginLeft =  this._differenceHorizontal + 'px';
      }
      document.getElementById(id).style.marginTop = this._differenceVertical + 'px';
    }
  // horizontal
  } else {  
    var _top;
    var _left;
    if (item.rootObj()[rootPos]){
      var idxR = parseFloat(item.rootObj()[rootPos] -1);
      if (item.rootArr()[idxR]){
        var rootItem = NavigationItem.getInstance(this._containerIDPrefix +''+ item.rootArr()[idxR]);
        if (this._dependHorizontal == 'left'){
          if (rootItem.properties().getLeft() != undefined){
            _left = parseFloat(rootItem.properties().getLeft() - item.properties().getWidth());
          } else {
            if (document.getElementById(this._itemIDPrefix +''+ id)){
            _left = parseFloat(activeItem.properties().getLeft() - item.properties().getWidth());
            }
          }
        } else {
          if (rootItem.properties().getRight() != undefined){
            _left = rootItem.properties().getRight();
          } else {
            if (document.getElementById(this._itemIDPrefix +''+ id)){
            _left = activeItem.properties().getRight();
            }
          }
        }
        if (this._dependVertical=='middle'){
          if (document.getElementById(this._itemIDPrefix +''+ id)){
            _top = parseFloat(activeItem.properties().getTop() + parseFloat(activeItem.properties().getHeight() / 2));
          }
        } else if (this._dependVertical=='bottom'){
          if (document.getElementById(this._itemIDPrefix +''+ id)){
            _top = activeItem.properties().getBottom();
          } 
        } else {
          if (document.getElementById(this._itemIDPrefix +''+ id)){
            _top = activeItem.properties().getTop();
          } 
        }
      }
    }
    if (document.getElementById(id)){
      if (_top != undefined){
        if (idxR > 0){
          if (navigator.userAgent.match(/MSIE/)){
            document.getElementById(id).style.top = parseFloat(parseFloat(_top - 61) - this._rootTop) + 'px';
          } else {
            //document.getElementById(id).style.top = parseFloat(parseFloat(_top + this._differenceVertical) - this._rootTop) + 'px';
            document.getElementById(id).style.top = parseFloat(parseFloat(_top - 85) - this._rootTop) + 'px';
          }
        } else {
          if (navigator.userAgent.match(/MSIE/)){
            document.getElementById(id).style.top = parseFloat(parseFloat(_top - 61) - this._rootTop) + 'px';
          } else {
            document.getElementById(id).style.top = parseFloat(parseFloat(_top - 85) - this._rootTop) + 'px';
          }
        }  
      }
      if (navigator.userAgent.match(/Opera/)){
        document.getElementById(id).style.position = 'absolute';
      }
      if (_left != undefined){   
        if (idxR > 0){  
          document.getElementById(id).style.left = parseFloat(parseFloat(_left + this._differenceHorizontal) - this._rootLeft) + 'px';
        } else {  
          document.getElementById(id).style.left = parseFloat(parseFloat(_left - activeItem.properties().getWidth()) - this._rootLeft) + 'px';
        }
      }
      if (navigator.userAgent.match(/Opera/)){
        document.getElementById(id).style.position = 'absolute';
      }
    }
  }
}

// -------
// displaySubmenu
// -------
Navigation.prototype.displaySubmenu = function(id) {
  this._menuInUse = true;
  var item = NavigationItem.getInstance(id);
  var elem = undefined;
  if (document.getElementById(id)){
    elem = document.getElementById(id);
  }
  this.hideVisitedNavigation(id);
  this.showActiveNavigation(id);
  if (this._direction == 'vertical'){
    if (this._activeMenu[id] || item.type() == 1){
      this._menuInUse = false;
      this.hideAll();
      return;
    }
  }
  this._activeMenu[id] = {};
  if (document.getElementById(id)){
    this._activeMenu[id]['elem'] = document.getElementById(id);
  }
  this._activeMenu[id]['item'] = item;
}

// -------
// collapseMenu
// -------
Navigation.prototype.collapseMenu = function() {
  this._menuInUse = false;
  if (this._timeout){
    window.clearTimeout(this._timeout);
  }
  var funcStr = 'Navigation.getInstance(\''+ this.id() +'\').hideAll()';
  this._timeout = window.setTimeout(funcStr, this._delay);
}

// -------
// hideAll
// -------
Navigation.prototype.hideAll = function() {
  if (this._timeout){
    window.clearTimeout(this._timeout);
  }
  if (!this._menuInUse){
    for (var i in this._activeMenu){
      if (this._activeMenu[i]['elem']){
        this._activeMenu[i]['elem'].style.display = 'none';
        this._setOffHighlightedItems(this._activeMenu[i]['item'].id());
      }
      delete this._activeMenu[i];
    }
  }
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

Navigation._defaultID = [];

Navigation._registerInstance = {};

Navigation._getNavigationStructureHTMLRoot = true;

Navigation._attributesToIE = {};
Navigation._attributesToIE['src'] = 'src';
Navigation._attributesToIE['style'] = 'style';
Navigation._attributesToIE['align'] = 'align';
Navigation._attributesToIE['title'] = 'title';
Navigation._attributesToIE['alt'] = 'alt';
Navigation._attributesToIE['valign'] = 'valign';
Navigation._attributesToIE['vspace'] = 'vspace';
Navigation._attributesToIE['hspace'] = 'hspace';
Navigation._attributesToIE['class'] = 'className';
Navigation._attributesToIE['border'] = 'border';
Navigation._attributesToIE['cellspacing'] = 'cellspacing';
Navigation._attributesToIE['cellpadding'] = 'cellpadding';
Navigation._attributesToIE['data'] = 'data';
Navigation._attributesToIE['marginwidth'] = 'marginwidth';
Navigation._attributesToIE['marginheight'] = 'marginheight';
Navigation._attributesToIE['margintop'] = 'margintop';
Navigation._attributesToIE['marginleft'] = 'marginleft';
Navigation._attributesToIE['frameborder'] = 'frameborder';
Navigation._attributesToIE['dataformatas'] = 'dataformatas';
Navigation._attributesToIE['type'] = 'type';
Navigation._attributesToIE['width'] = 'width';
Navigation._attributesToIE['height'] = 'height';
Navigation._attributesToIE['onmouseover'] = 'onMouseover';
Navigation._attributesToIE['onmouseout'] = 'onMouseout';
Navigation._attributesToIE['onclick'] = 'onClick';
Navigation._attributesToIE['onfocus'] = 'onFocus';
Navigation._attributesToIE['onblur'] = 'onBlur';
Navigation._attributesToIE['onload'] = 'onLoad';
Navigation._attributesToIE['onchange'] = 'onChange';
Navigation._attributesToIE['onsubmit'] = 'onSubmit';
Navigation._attributesToIE['name'] = 'name';
Navigation._attributesToIE['value'] = 'value';
Navigation._attributesToIE['id'] = 'id';
Navigation._attributesToIE['href'] = 'href';
Navigation._attributesToIE['target'] = 'target';


Navigation._attributesIE = {};
Navigation._attributesIE['src'] = 'src';
Navigation._attributesIE['style'] = 'style';
Navigation._attributesIE['align'] = 'align';
Navigation._attributesIE['title'] = 'title';
Navigation._attributesIE['alt'] = 'alt';
Navigation._attributesIE['valign'] = 'valign';
Navigation._attributesIE['vspace'] = 'vspace';
Navigation._attributesIE['hspace'] = 'hspace';
Navigation._attributesIE['className'] = 'class';
Navigation._attributesIE['border'] = 'border';
Navigation._attributesIE['cellspacing'] = 'cellspacing';
Navigation._attributesIE['cellpadding'] = 'cellpadding';
Navigation._attributesIE['data'] = 'data';
Navigation._attributesIE['marginwidth'] = 'marginwidth';
Navigation._attributesIE['marginheight'] = 'marginheight';
Navigation._attributesIE['margintop'] = 'margintop';
Navigation._attributesIE['marginleft'] = 'marginleft';
Navigation._attributesIE['frameborder'] = 'frameborder';
Navigation._attributesIE['dataformatas'] = 'dataformatas';
Navigation._attributesIE['type'] = 'type';
Navigation._attributesIE['width'] = 'width';
Navigation._attributesIE['height'] = 'height';
Navigation._attributesIE['onMouseover'] = 'onmouseover';
Navigation._attributesIE['onMouseout'] = 'onmouseout';
Navigation._attributesIE['onClick'] = 'onclick';
Navigation._attributesIE['onFocus'] = 'onfocus';
Navigation._attributesIE['onBlur'] = 'onblur';
Navigation._attributesIE['onLoad'] = 'onload';
Navigation._attributesIE['onChange'] = 'onchange';
Navigation._attributesIE['onSubmit'] = 'onsubmit';
Navigation._attributesIE['name'] = 'name';
Navigation._attributesIE['value'] = 'value';
Navigation._attributesIE['id'] = 'id';
Navigation._attributesIE['href'] = 'href';
Navigation._attributesIE['target'] = 'target';

// Aus Performance-Gründen werden nicht zu erwartende Attributes abgeschaltet  
Navigation._styleAttributesIE = {};
Navigation._styleAttributesIE['width'] = 'width';
Navigation._styleAttributesIE['height'] = 'height';
Navigation._styleAttributesIE['top'] = 'top';
Navigation._styleAttributesIE['left'] = 'left';
//Navigation._styleAttributesIE['right'] = 'right';
//Navigation._styleAttributesIE['bottom'] = 'bottom';
Navigation._styleAttributesIE['display'] = 'display';
Navigation._styleAttributesIE['position'] = 'position';
//Navigation._styleAttributesIE['clear'] = 'clear';
//Navigation._styleAttributesIE['styleFloat'] = 'float';
//Navigation._styleAttributesIE['lineHeight'] = 'line-height';
//Navigation._styleAttributesIE['verticalAlign'] = 'vertical-align';
Navigation._styleAttributesIE['textAlign'] = 'text-align';
Navigation._styleAttributesIE['textDecoration'] = 'text-decoration';
//Navigation._styleAttributesIE['textTransform'] = 'text-transform';
//Navigation._styleAttributesIE['whiteSpace'] = 'white-space';
Navigation._styleAttributesIE['padding'] = 'padding';
Navigation._styleAttributesIE['paddingTop'] = 'padding-top';
Navigation._styleAttributesIE['paddingRight'] = 'padding-right';
Navigation._styleAttributesIE['paddingBottom'] = 'padding-bottom';
Navigation._styleAttributesIE['paddingLeft'] = 'padding-left';
Navigation._styleAttributesIE['margin'] = 'margin';
Navigation._styleAttributesIE['marginTop'] = 'margin-top';
Navigation._styleAttributesIE['marginRight'] = 'margin-right';
Navigation._styleAttributesIE['marginBottom'] = 'margin-bottom';
Navigation._styleAttributesIE['marginLeft'] = 'margin-left';
Navigation._styleAttributesIE['border'] = 'border';
Navigation._styleAttributesIE['borderLeft'] = 'border-left';
Navigation._styleAttributesIE['borderRight'] = 'border-right';
Navigation._styleAttributesIE['borderTop'] = 'border-top';
Navigation._styleAttributesIE['borderBottom'] = 'border-bottom';
Navigation._styleAttributesIE['borderColor'] = 'border-color';
Navigation._styleAttributesIE['borderStyle'] = 'border-style';
Navigation._styleAttributesIE['borderWidth'] = 'border-width';
Navigation._styleAttributesIE['borderCollapse'] = 'border-collapse';
Navigation._styleAttributesIE['fontSize'] = 'font-size';
Navigation._styleAttributesIE['fontWeight'] = 'font-weight';
Navigation._styleAttributesIE['fontStyle'] = 'font-style';
Navigation._styleAttributesIE['fontFace'] = 'font-face';
Navigation._styleAttributesIE['color'] = 'color';
Navigation._styleAttributesIE['backgroundColor'] = 'background-color';
Navigation._styleAttributesIE['backgroundImage'] = 'background-image';
Navigation._styleAttributesIE['backgroundPosition'] = 'background-position';
Navigation._styleAttributesIE['backgroundRepeat'] = 'background-repeat';
//Navigation._styleAttributesIE['listStyle'] = 'list-style';
//Navigation._styleAttributesIE['listStyleType'] = 'list-style-type';
//Navigation._styleAttributesIE['listStyleImage'] = 'list-style-image';
//Navigation._styleAttributesIE['listStylePosition'] = 'list-style-position';
//Navigation._styleAttributesIE['tableLayout'] = 'table-layout';
//Navigation._styleAttributesIE['visibility'] = 'visibility';
Navigation._styleAttributesIE['zIndex'] = 'z-index'; 

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------
// -------
// _getNavigationStructureByNode
// -------
Navigation._getNavigationStructureByNode = function(node, structure, path, countx, containerPrefix) {
  if (arguments.length!=5) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (!node){
    return structure;
  }
  var arr = structure;
  for (var i=0; i<node.childNodes.length; i++){
    var child = node.childNodes[i];
    if (child.nodeType == 1){
      if (child.nodeName.toLowerCase() == 'a'){
        if (path.length){
          path += '-';
        }
        arr[path +''+ countx] = 1;
        var item = NavigationItem.createInstance(containerPrefix + path +''+ countx);
        item.setType('1');
        item.setRoot(path +''+ countx);
        if (Navigation.hasAttributes(child, 'class')){
          item.setClassName(Navigation.getAttributesFromElement(child, 'class'));
        }
        if (Navigation.hasAttributes(child, 'style')){
          item.setStyle(Navigation.getAttributesFromElement(child, 'style'));
        }
        if (Navigation.hasAttributes(child, 'href')){
          item.setHref(Navigation.getAttributesFromElement(child, 'href'));
        }
        if (Navigation.hasAttributes(child, 'target')){
          item.setTarget(Navigation.getAttributesFromElement(child, 'target'));
        }
        if (Navigation.hasAttributes(child, 'onclick')){
          item.setOnClick(Navigation.getAttributesFromElement(child, 'onclick'));
        }
        if (Navigation.hasAttributes(child, 'title')){
          item.setTitle(Navigation.getAttributesFromElement(child, 'title'));
        }
        var label = Navigation.getTextNodeValue(child);
        item.setLabel(label);
      }
      if (child.nodeName.toLowerCase() == 'li'){
        countx++;
      }
      if (child.nodeName.toLowerCase() == 'ul'){
        path += countx;
        countx = 0;
        structure[path] = {};
        arr = structure[path];
        var item = NavigationItem.createInstance(containerPrefix + path);
        item.setType('0');
        item.setRoot(path);
        if (Navigation.hasAttributes(child, 'class')){
          item.setClassName(Navigation.getAttributesFromElement(child, 'class'));
        }
        if (Navigation.hasAttributes(child, 'style')){
          item.setStyle(Navigation.getAttributesFromElement(child, 'style'));
        }
        var subChild = undefined;
        if(child.previousSibling){
          if (child.previousSibling && child.previousSibling.nodeName.toLowerCase() == 'a'){
            subChild = child.previousSibling;
          } else if (child.previousSibling.previousSibling && child.previousSibling.previousSibling.nodeName.toLowerCase() == 'a'){
            subChild = child.previousSibling.previousSibling;
          }
        }
        if (subChild){
          if (Navigation.hasAttributes(subChild, 'class')){
            item.setSubClassName(Navigation.getAttributesFromElement(subChild, 'class'));
          }
          if (Navigation.hasAttributes(subChild, 'style')){
            item.setSubStyle(Navigation.getAttributesFromElement(subChild, 'style'));
          }
          if (Navigation.hasAttributes(subChild, 'href')){
            item.setHref(Navigation.getAttributesFromElement(subChild, 'href'));
          }
          if (Navigation.hasAttributes(subChild, 'target')){
            item.setTarget(Navigation.getAttributesFromElement(subChild, 'target'));
          }
          if (Navigation.hasAttributes(subChild, 'onclick')){
            item.setOnClick(Navigation.getAttributesFromElement(subChild, 'onclick'));
          }
          if (Navigation.hasAttributes(subChild, 'title')){
            item.setTitle(Navigation.getAttributesFromElement(subChild, 'title'));
          }
          var label = Navigation.getTextNodeValue(subChild);
          item.setLabel(label);
        }
      }
      Navigation._getNavigationStructureByNode(child, arr, path, countx, containerPrefix);
    }
  }
  return structure;
}

// -------
// _getNavigationStructuretoString
// -------
Navigation._getNavigationStructuretoString = function(nodeList, str, x) {
  if (arguments.length!=3) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  for (var i in nodeList){
    var count = x;
    while (count > 0){
      str += '. .';
      count--;
    }
    str += i + ' = ' + nodeList[i] + '\n';
    if (typeof nodeList[i] == 'object'){
      str += Navigation._getNavigationStructuretoString(nodeList[i], '', x+1);
    }
  }
  return str;
}


// -------
// _getFirstItem
// -------
Navigation._getFirstItem = function(obj) {
  if (arguments.length!=1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  var count = 0;
  for (var i in obj){
    if (count == 0){
      return obj[i];
    }
  }
  return obj;
}

// ------------------------------------------------------------
// Öffentliche Klassenmehtoden
// ------------------------------------------------------------


// -------
// getTextNodeValue
// -------
Navigation.getTextNodeValue = function(node) {
  if (arguments.length!=1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  var str = '';
  for (var i=0; i<node.childNodes.length; i++){
    var child = node.childNodes[i];
    if (child.nodeType == 3){
      str += child.nodeValue;
    }
  }  
  return str;
}

// ----------------------------------
// Navigation.hasAttributes
// ----------------------------------
//
// Beschreibung:
// Methode teile die jeweilige Attribute-ZugriffsMethode zu
//
Navigation.hasAttributes = function(elem, attrName) {
  var str = '';
  if (document.all){
    if (Navigation._attributesToIE[attrName]){
      attrName = Navigation._attributesToIE[attrName];
    }
    if (attrName == 'className'){
      // OPERA kennt nur class
      if (elem.getAttribute('class')){
        attrName = 'class';
      }
    }
  }
  if (elem.getAttribute(attrName)){
    return true;
  }
  return false;
}

// ----------------------------------
// Navigation.GetAttributesFromElement
// ----------------------------------
//
// Beschreibung:
// Methode teile die jeweilige Attribute-ZugriffsMethode zu
//
Navigation.getAttributesFromElement = function(elem, attrName) {
  var str = '';
  if (document.all){
    str = Navigation._getAttributesFromElementIE(elem, attrName);
  } else {
    str = Navigation._getAttributesFromElementDOM(elem, attrName);
  }
  return str;
}

// ----------------------------------
// Navigation._getAttributesFromElementIE
// ----------------------------------
//
// Beschreibung:
// Da IE Array elem.attributes alle ITEMS=NULL wird hier die getAttribute(name) Methode verwendet
// Alle Attribute- und Style-Attribute-Name müssen vorher definiert werden, das getAttribute() mit diesem String-namen aufgerufen wird.
// Vorteil: Es werden nur Attribute und Style-Attriubte verwendet die auch definiert wurden.
//
Navigation._getAttributesFromElementIE = function(elem, attrName) { 
  var str = '';
  if (Navigation._attributesToIE[attrName]){
    var attr = Navigation._attributesToIE[attrName];
    if (attr == 'className'){
      // OPERA kennt nur class nicht className
      if (elem.getAttribute('class')){
        attr = 'class';
      }
    }
    var attrValue = elem.getAttribute(attr);
    if (attrValue){
      if (typeof attrValue == 'object'){
        for (var a in Navigation._styleAttributesIE){
          if (attrValue[a] && attrValue[a].length){
            str += Navigation._styleAttributesIE[a]+': '+attrValue[a]+'; ';
          }
        }
      } else {
        str += attrValue;
      }
    }
  }
  return str;
}

// ----------------------------------
// Navigation._getAttributesFromElementIELoop
// ----------------------------------
//
// Beschreibung:
// Da IE Array elem.attributes alle ITEMS=NULL wird hier die getAttribute(name) Methode verwendet
// Alle Attribute- und Style-Attribute-Name müssen vorher definiert werden, das getAttribute() mit diesem String-namen aufgerufen wird.
// Vorteil: Es werden nur Attribute und Style-Attriubte verwendet die auch definiert wurden.
//
Navigation._getAttributesFromElementIELoop = function(elem, attrName) { 
  var str = '';
  for (var i in Navigation._attributesIE){
    var attr = i;
    if (attr == 'className'){
      // OPERA kennt nur class nicht className
      if (elem.getAttribute('class')){
        attr = 'class';
      }
    }
    if (elem.getAttribute(attr)){
      var name = Navigation._attributesIE[i];
      if (name == attrName){
        var attrValue = elem.getAttribute(attr);
        if (attrValue){
          if (typeof attrValue == 'object'){
            for (var a in Navigation._styleAttributesIE){
              if (attrValue[a] && attrValue[a].length){
                str += Navigation._styleAttributesIE[a]+': '+attrValue[a]+'; ';
              }
            }
          } else {
            str += attrValue;
          }
        }
      } 
    }  
  }
  return str;
}

// ----------------------------------
// Navigation._getAttributesFromElementDOM
// ----------------------------------
//
// Attribute werden über Standard-DOM elem.arttributes Array ermittelt
// Funktioniert nicht bei IE!!!
//
Navigation._getAttributesFromElementDOM = function(elem, attrName) {
  var attributes = elem.attributes;
  var str = '';
  if (attributes.length){
    if (elem.getAttribute(attrName)){
      str += elem.getAttribute(attrName);
    }
  }
  return str;
}


// ----------------------------------
// Navigation._getAttributesFromElementDOMLoop
// ----------------------------------
//
// Attribute werden über Standard-DOM elem.arttributes Array ermittelt
// Funktioniert nicht bei IE!!!
//
Navigation._getAttributesFromElementDOMLoop = function(elem, attrName) {
  var attributes = elem.attributes;
  var str = '';
  var output = '';
  if (attributes.length){
    for (var i=0; i<attributes.length; i++){
      var attr = attributes.item(i);
      // output += attr.name + '=' + attr.value + ' | ';
      if (attr && attr.value && attr.value.length){
        var name = attr.name;
        if (attrName == name){
          var attrValue = attr.value;
          str += attrValue;
        }  
      }
    }
  }
  return str;
}

// -------
// getInstance
// -------
Navigation.getInstance = function(id) {
  if (arguments.length!=1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (! (Navigation._registerInstance[id])){
    focus();
    throw new Error("Es ist keine Navigation.Instance mit id=" + id + " registriert!");
  } 
  return Navigation._registerInstance[id];
}

// -------
// createInstance
// -------
Navigation.createInstance = function(id) {
  if (!arguments.length) {
    id = 'navigation' + Navigation._defaultID.length;
    Navigation._defaultID.push(1);
  }
  if (! (Navigation._registerInstance[id])){
    Navigation._registerInstance[id] = new Navigation(id);
  } 
  return Navigation.getInstance(id);
}


// ################################################################################
// #########################################################|  NavigationItem   |##
// ################################################################################

// ============================================================
// Klasse NavigationItem
// ============================================================
//
// Objekthierarchie:
// -----------------
//   Object
//     |-- Navigation
//           |-- NavigationItem
//
// Konstruktor:
// ------------
//   + NavigationItem()
//
// Eigenschaften:
// --------------
//   + _id : id (readonly)
//   + _rootArr : Array (readonly)
//   + _rootObj : Object (readonly)
//   + _properties : Object (readonly)
//   + _type : str (readonly) | 0=container, 1=link
//   + _style : str (readonly) css-style-angaben
//   + _className : str (readonly) cssName
//   + _subStyle : str (readonly) css-style-angaben
//   + _subClassName : str (readonly) cssName
//   + _href : str (readonly) url
//   + _label : str (readonly) name
//   + _target : str (readonly) target
//   + _onclick : str (readonly) eventHandler
//   + _title : str (readonly) 
//   + _action : link (readonly)
//   + _style : css (readonly)
//   + _target : str (readonly)
//
// Methoden:
// ---------
//   + _setID(str) : void
//   + setType(str) : void
//

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

function NavigationItem(id) {
  if (arguments.length>1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  // Attribute
  this._id = undefined;
  this._rootArr = [];
  this._rootObj = {};
  this._type = undefined;
  this._href = undefined;
  this._label = undefined;
  this._style = undefined;
  this._target = undefined;
  this._onclick = undefined;
  this._className = undefined;
  this._title = undefined;
  this._subStyle = undefined;
  this._subClassName = undefined;
  this._setID(id);
  this._properties = NavigationItemProperties.createNavigationItemProperties(this.id(), this._getParentElement());
}

// toString()
NavigationItem.prototype.toString = function() {
  return "\n[Navigation - id: " + this.id + "]\n";
}

// ------------------------------------------------------------
// Zugriffsmethoden
// ------------------------------------------------------------

// -------
// id
// -------
NavigationItem.prototype.id = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._id = str;
  }
  return this._id;
}

// -------
// type
// -------
NavigationItem.prototype.type = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._type = str;
  }
  return this._type;
}

// -------
// label
// -------
NavigationItem.prototype.label = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._label = str;
  }
  return this._label;
}

// -------
// href
// -------
NavigationItem.prototype.href = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._href = str;
  }
  return this._href;
}

// -------
// title
// -------
NavigationItem.prototype.title = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._title = str;
  }
  return this._title;
}

// -------
// target
// -------
NavigationItem.prototype.target = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._target = str;
  }
  return this._target;
}

// -------
// onclick
// -------
NavigationItem.prototype.onclick = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._onclick = str;
  }
  return this._onclick;
}

// -------
// style
// -------
NavigationItem.prototype.style = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._style = str;
  }
  return this._style;
}

// -------
// className
// -------
NavigationItem.prototype.className = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._className = str;
  }
  return this._className;
}

// -------
// subStyle
// -------
NavigationItem.prototype.subStyle = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._subStyle = str;
  }
  return this._subStyle;
}

// -------
// subClassName
// -------
NavigationItem.prototype.subClassName = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("Argument ist nicht vom Typ String!");
    }
    this._subClassName = str;
  }
  return this._subClassName;
}

// -------
// rootArr
// -------
NavigationItem.prototype.rootArr = function(arr) {
  if (arguments.length) {
    if (typeof arr != "object") {
      focus();
      throw new Error("Argument ist nicht vom Typ Object!");
    }
    this._rootArr = arr;
  }
  return this._rootArr;
}

// -------
// root
// -------
NavigationItem.prototype.rootObj = function(obj) {
  if (arguments.length) {
    if (typeof obj != "object") {
      focus();
      throw new Error("Argument ist nicht vom Typ Object!");
    }
    this._rootObj = obj;
  }
  return this._rootObj;
}

// -------
// properties
// -------
NavigationItem.prototype.properties = function(obj) {
  if (arguments.length) {
    if (typeof obj != "object") {
      focus();
      throw new Error("Argument ist nicht vom Typ Object!");
    }
    this._properties = obj;
  }
  return this._properties;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// -------
// _setID
// -------
NavigationItem.prototype._setID = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.id(str);
}

// -------
// _setID
// -------
NavigationItem.prototype._getParentElement = function() {
  var elem = document.getElementById(this.id());
  var parentElem = '';
  if (elem){
    if (document.all){
      parentElem = elem.parentElement.id;
    } else {
      parentElem = elem.parentNode.id;
    }  
  }  
  return parentElem;
}



// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------
// setType
// -------
NavigationItem.prototype.setType = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.type(str);
}

// -------
// setLabel
// -------
NavigationItem.prototype.setLabel = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.label(str);
}

// -------
// setHref
// -------
NavigationItem.prototype.setHref = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.href(str);
}

// -------
// setTitle
// -------
NavigationItem.prototype.setTitle = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.title(str);
}

// -------
// setTarget
// -------
NavigationItem.prototype.setTarget = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.target(str);
}

// -------
// setOnClick
// -------
NavigationItem.prototype.setOnClick = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.onclick(str);
}

// -------
// setStyle
// -------
NavigationItem.prototype.setStyle = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.style(str);
}

// -------
// setClassName
// -------
NavigationItem.prototype.setClassName = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.className(str);
}

// -------
// setSubStyle
// -------
NavigationItem.prototype.setSubStyle = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.subStyle(str);
}

// -------
// setSubClassName
// -------
NavigationItem.prototype.setSubClassName = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  this.subClassName(str);
}

// -------
// setRoot
// -------
NavigationItem.prototype.setRoot = function(str) {
  if (arguments.length!=1) {
    focus();
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Argument ist nicht vom Typ String!");
  }
  var arr = str.split(/-/);
  var _str = '';
  var rootListArr = [];
  var rootListObj = {};
  for (var i=0; i<arr.length; i++){
    if (i>0){
      _str += '-';
    }
    _str += arr[i];
    rootListObj[_str] = i;
    rootListArr[i] = _str;
  }
  this.rootArr(rootListArr);
  this.rootObj(rootListObj);
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

NavigationItem._defaultID = [];

NavigationItem._registerInstance = {};

NavigationItem._isRoot = false;

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmehtoden
// ------------------------------------------------------------

// -------
// getInstance
// -------
NavigationItem.getInstance = function(id) {
  if (arguments.length!=1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (! (NavigationItem._registerInstance[id])){
    focus();
    throw new Error("Es ist keine NavigationItem.Instance mit id=" + id + " registriert!");
  } 
  return NavigationItem._registerInstance[id];
}

// -------
// hasInstance
// -------
NavigationItem.hasInstance = function(id) {
  if (arguments.length!=1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (! (NavigationItem._registerInstance[id])){
    return false;
  } 
  return true;
}

// -------
// createInstance
// -------
NavigationItem.createInstance = function(id) {
  if (!arguments.length) {
    id = 'navigation' + NavigationItem._defaultID.length;
    NavigationItem._defaultID.push(1);
  }
  if (! (NavigationItem._registerInstance[id])){
    NavigationItem._registerInstance[id] = new NavigationItem(id);
  } 
  return NavigationItem.getInstance(id);
}


// ################################################################################
// ###############################################|  NavigationItemProperties   |##
// ################################################################################

// ============================================================
// Klasse NavigationItemProperties
// ============================================================
//
// Objekthierarchie:
// -----------------
//   Object
//     |-- Navigation
//           |-- NavigationItem
//                     |-- NavigationItemProperties
//
// Konstruktor:
// ------------
//   + NavigationItemProperties()
//
// Eigenschaften:
// --------------
//   + _id : id (readonly)
//   + _id : id (readonly)
//   + _idParentElement : str (readonly)
//
// Methoden:
// ---------
//   + getTop() : void
//   + getLeft() : void
//   + getBottom() : void
//   + getRight() : void
//   + getWidth() : void
//   + getHeight() : void
//

// ------------------------------------------------------------
// Konstruktor
// ---------------------------


function NavigationItemProperties(id, idParentElement) {  
  // Attribute
  this._id = undefined;
  this._idParentElement = 'body';
  // Initialisierungen
  this.id(id);
  this.idParentElement(idParentElement);
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// id(string)
// -----------
//
// Beschreibung:
// -------------
//

NavigationItemProperties.prototype.id = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._id = str;
  }
  return this._id;
}

// -----------
// idParentElement(string)
// -----------
//
// Beschreibung:
// -------------
//

NavigationItemProperties.prototype.idParentElement = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }  
    this._idParentElement = str.toLowerCase();
  }
  return this._idParentElement;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// getTop()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt relative Top-Position zu einem bestimmten Eltern-Element.
//
// Beispiel:
// ---------
// getTop();
//

NavigationItemProperties.prototype.getTop = function() {  
  if (this._existsElement(this.id())){
    var parentDiv = document.getElementById(this.id());
    var topPosition = 0;
    if (this._existsElement(this.idParentElement())){
      while (parentDiv && parentDiv.id != this.idParentElement()){
        if (parentDiv.nodeType == 1){
          topPosition += parseFloat(parentDiv.offsetTop);
        }
        parentDiv = parentDiv.offsetParent;
      }
    }
    else{
      while (parentDiv){
        if (parentDiv.nodeType == 1){
          topPosition += parseFloat(parentDiv.offsetTop);
        }
        parentDiv = parentDiv.offsetParent;
      }
    }
    return parseFloat(topPosition);
  }
  return undefined;
}

// -------------------------------------------
// getLeft()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt relative Left-Position zu einem bestimmten Eltern-Element.
//
// Beispiel:
// ---------
// getLeft();
//

NavigationItemProperties.prototype.getLeft = function() {  
  if (this._existsElement(this.id())){
    var parentDiv = document.getElementById(this.id());
    var leftPosition = 0;
    if (this._existsElement(this.idParentElement())){
      while (parentDiv && parentDiv.id != this.idParentElement()){
        if (parentDiv.nodeType == 1){
          leftPosition += parseFloat(parentDiv.offsetLeft);
        }
        parentDiv = parentDiv.offsetParent;
      }
    }
    else{
      while (parentDiv){
        if (parentDiv.nodeType == 1){
          leftPosition += parseFloat(parentDiv.offsetLeft);
        }
        parentDiv = parentDiv.offsetParent;
      }
    }
    return parseFloat(leftPosition);
  }
  return undefined;
}

// -------------------------------------------
// getBottom()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt relative Bottom-Position zu einem bestimmten Eltern-Element.
//
// Beispiel:
// ---------
// getBottom();
//

NavigationItemProperties.prototype.getBottom = function() {
  if (this._existsElement(this.id())){
    var bottomPosition = parseFloat(this.getTop() +  this.getHeight());
    return parseFloat(bottomPosition);
  }
  return undefined;
}

// -------------------------------------------
// getRight()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt relative Right-Position zu einem bestimmten Eltern-Element.
//
// Beispiel:
// ---------
// getRight();
//

NavigationItemProperties.prototype.getRight = function() {  
  if (this._existsElement(this.id())){
    var rightPosition = parseFloat(this.getLeft() + this.getWidth());
    return parseFloat(rightPosition);
  }
  return undefined;
}

// -------------------------------------------
// getWidth()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt width des Elements.
//
// Beispiel:
// ---------
// getWidth();
//

NavigationItemProperties.prototype.getWidth = function() {
  if (this._existsElement(this.id())){
    var width = parseFloat(document.getElementById(this.id()).offsetWidth);
    return parseFloat(width);
  }
  return undefined;
}

// -------------------------------------------
// getHeight()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt height des Elements.
//
// Beispiel:
// ---------
// getHeight();
//

NavigationItemProperties.prototype.getHeight = function() {
  if (this._existsElement(this.id())){
    var height = parseFloat(document.getElementById(this.id()).offsetHeight);
    return parseFloat(height);
  }
  return undefined;
}

// -------------------------------------------
// _existsElement()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode ermittelt relative Right-Position zu einem bestimmten Eltern-Element.
//
// Beispiel:
// ---------
// _existsElement();
//

NavigationItemProperties.prototype._existsElement = function(id) {
  if (document.getElementById(id) != undefined){
    return true;
  }
  return false;
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// NavigationItemProperties.createNavigationItemProperties()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// NavigationItemProperties.createNavigationItemProperties(id, idParentElement);
//

NavigationItemProperties.createNavigationItemProperties = function(id, idParentElement) { 
  return new NavigationItemProperties(id, idParentElement);
}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

NavigationItemProperties.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  return Object.prototype.toString.apply(this);
}


// ################################################################################
// #########################################################|  NavigationTools   |##
// ################################################################################

// ============================================================
// Klasse NavigationTools
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ---------------------------

function NavigationTools() {
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// NavigationTools.checkNumber()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode prüft Argument auf type Number
//
// Beispiel:
// ---------
// NavigationTools.checkNumber(n);

NavigationTools.checkNumber = function(n){
  if (!arguments.length){
    return false;
  }
  if (n == undefined){
    return false;
  }
  n = n.toString();
  if (n == '0'){
    return n;
  }
  if (!n.length){
    return false;
  }
  n = n.replace(/,/g,'.');
  if (isNaN(n)){
    return false;
  }
  if (!isFinite(n)) {
    return false;
  }
  n = parseFloat(n);
  return n;
}

// -------------------------------------------
// NavigationTools.checkWertInArrayVorhanden(str, arr)
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode prüft ob ein Wert in einem Array vorhanden ist.
// Argument = wert und jeweiliges Array
//
// Beispiel:
// ---------
// NavigationTools.checkWertinArrayVorhanden(str, arr);

NavigationTools.checkWertInArrayVorhanden = function(){
  var str = arguments[0];
  var arr = new Array();
  arr = arguments[1];
  for (var i in arr){
    if (arr[i] == str){
      return true;
    } 
  }
  return false;
}

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

NavigationTools.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  return Object.prototype.toString.apply(this);
}


