//
// Copyright(c) 2005, myview systems GmbH
//
// $Header: /workdir/myview/javadev_root/procat-base/web/myTree/myTree.js,v 1.1.10.1 2008/05/21 16:10:38 sneuhaus Exp $
//
// $Log: myTree.js,v $
// Revision 1.1.10.1  2008/05/21 16:10:38  sneuhaus
// zwischenstand
//
// Revision 1.1.8.2  2008/04/03 12:47:38  andree.wormuth
// next step
//
// Revision 1.1.2.5.2.1  2008/03/31 15:48:20  oliver.hager
// Improved layout.
//
// Revision 1.1.2.5  2008/02/01 16:54:16  oliver.hager
// Added hack for hyphen hyphenation.
//
// Revision 1.1.2.4  2008/01/10 15:02:27  andree.wormuth
// Text of links is html now.
//
// Revision 1.1.2.3  2007/12/14 14:37:44  andree.wormuth
// iframe only created if necessary (led to additional request in firefox)
//
// Revision 1.1.2.2  2007/12/14 13:24:07  andree.wormuth
// iframe only created if necessary (led to additional request in firefox)
//
// Revision 1.1.2.1  2007/11/12 16:37:30  andree.wormuth
// Added title to tree links
//
// Revision 1.1  2007/10/08 15:59:05  andree.wormuth
// Initial version
//
// Revision 1.1.6.1  2007/05/10 09:49:34  andree.wormuth
// the javascript tree
//
// Revision 1.1.4.5  2007/04/18 11:03:27  heise
// CR : ANG_07_00020-1 / Relaunch 2007
//
// Revision 1.1.4.4  2007/03/08 09:45:07  heise
// UI
//
// Revision 1.1.4.3  2007/03/07 15:39:44  heise
// UI
//
// Revision 1.1.4.2  2007/03/06 16:44:01  heise
// UI
//
// Revision 1.1.4.1  2007/03/05 15:21:46  heise
// CR : ANG_06_00046-01 / Javascript Baum
//
// Revision 1.1.2.1  2006/11/09 13:20:39  andree.wormuth
// Removed obsolete pages, replaced applet with jsTree
//
// Revision 1.1.2.4  2006/03/28 12:54:26  heise
// Javascriptbaum : Anpassungen f�r XMLHttpRequest Opera, IE und KHTML
//
// Revision 1.1.2.3  2006/03/27 14:39:05  heise
// Javascript-Baum : Anpassung f�r unterschiedliche Browser
//
// Revision 1.1.2.2  2006/03/27 13:10:19  heise
// Javascript-Baum : Anpassung f�r Opera
//
// Revision 1.1.2.1  2006/03/24 14:09:32  heise
// Javascript-Baum
//
//

var myTrees = new Array();

function myTree(id, div) {

  //
  // variable
  //
  
  myTrees[id] = this;

  this.id = id;
  this.div = div;

  var documentObject = null;

  var baseUrl = '';
  var baseUrlSelect = '';

  var myPanels = new Array();

  var myNodesImages = new Array();

  var myNavigationImages = new Array();
  var myNavigationImagesSelectedLevel = new Array();
  var myNavigationImagesSelectedPath = new Array();
  var myNavigationImagesSelectedPathAndLevel = new Array();  

  var spaceImage = '';
  var lineImage = '';
  var lineImageSelectedLevel = '';  
  var rootImage = '';
  
  var showFolder = true;
  var showLine = true;
  var showNavigation = true;
  var showIndent = true;
  var showTable = true;  

  var showPuristic = false;

  var changeSelectedPathClass = false;
  
  var changeNavigationImageSelectedPath = false;
  var changeNavigationImageSelectedLevel = false;
  var ignoreNavigationLevelConnection = false;

  var openOnClick = true;
  var closeOnClick = true;
  var selectOnNavigate = true;  

  var ownClassForTree = false;
  var ownClassForPanel = false;
  
  var appendElementIdToText = false;

  var loggingDiv = null;

  var requestMode = 'IFrame';
  if (window.ActiveXObject && !window.XMLHttpRequest) {
    requestMode = 'ActiveX';
  } else {
    if (window.XMLHttpRequest) {
      requestMode = 'XML';
    }
  }
  
  //
  // document object
  //
  
  createDocumentObject();
  
  //
  // private
  //

  function createDocumentObject() {
    documentObject = document.createElement('object');
    documentObject.id = id;
    documentObject.style.display = 'none';
    document.body.appendChild(documentObject);
  
    documentObject.addPanel = addPanel;
    documentObject.delPanel = delPanel;
    documentObject.showPanel = showPanel;
    documentObject.setPanelPath = setPanelPath;
    documentObject.invalidatePanel = invalidatePanel;
    documentObject.openPath = openPanelPath;
    documentObject.hasEntry = hasEntry;
    documentObject.selectEntry = selectEntry;
    documentObject.setEntryText = setEntryText;
    documentObject.delEntryLink = delEntryLink;
    documentObject.delEntry = delEntry;
    documentObject.invalidateEntry = invalidateEntry;
    documentObject.addEntry = addEntry;
  }

  function deleteDocumentObject() {
    document.body.removeChild(documentObject);
    delete documentObject;
    documentObject = null;
  }

  function setRequestMode(mode) {
    requestMode = mode;
  }

  function getRequestMode() {
    return requestMode;
  }

  function setBaseUrl(url) {
    baseUrl = url + 'myTree=active&';
  }

  function getBaseUrl() {
    if (getRequestMode() != 'IFrame') {
      return baseUrl + 'myTreeXML=true&';
    }
    return baseUrl;
  }

  function setBaseUrlSelect(url) {
    baseUrlSelect = url;
  }

  function getBaseUrlSelect() {
    return baseUrlSelect;
  }
  
  function addPanel(name, path) {
    if (myPanels[name] != null) {
      return;
    }
    myPanels[name] = new myPanel(name, myTrees[id]);
    
    if (path != '') {
      myPanels[name].setPath(path);
    }
  }

  function delPanel(name) {
    var myPanel = myPanels[name];
    if (myPanel != null) {
      myPanel.destroy();
      delete myPanels[name];
    }
  }

  function showPanel(name) {
    for (var panelName in myPanels) {
      if (myPanels[panelName] != null) {
        if (myPanels[panelName] instanceof myPanel && myPanels[panelName].name != name ) {
          myPanels[panelName].hide();
        }
      }
    }  
    for (var panelName in myPanels) {
      if (myPanels[panelName] != null) {
        if (myPanels[panelName].name == name) {
          myPanels[panelName].show();
        }
      }
    }  
  }

  function setPanelPath(name, path) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    
    var isVisible = panel.isVisible();
    var panelPath = panel.getPath();
    if (panelPath != '' && panelPath != path) {
      panel.destroy();

      delete myPanels[name];
      myPanels[name] = new myPanel(name, myTrees[id])
      if (isVisible) {
        myPanels[name].show();
      }
    }
    
    return myPanels[name].setPath(path);
  }

  function invalidatePanel(name) {
    var panel = getPanel(name);
    if (panel == null) {
      return;
    }
    
    var isVisible = panel.isVisible();
    var panelPath = panel.getPath();

    panel.destroy();

    delete myPanels[name];
    myPanels[name] = new myPanel(name, myTrees[id])
    if (panelPath != '') {
      myPanels[name].setPath(panelPath);
      if (isVisible) {
        myPanels[name].show();
      }
      return true;
    }

    return false;
  }

  function openPanelPath(name, path) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.openPath(path); 
  }

  function getPanel(name) {
    return myPanels[name];
  }

  function getPanels() {
    return myPanels;
  }

  function hasEntry(name, id) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.hasEntry('', id);
  }

  function selectEntry(name, id) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.selectEntry('', id);
  }

  function setEntryText(name, id, text) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.setEntryText('', id, text);
  }

  function delEntryLink(name, parentid, id) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.delEntry(parentid, id);
  }

  function delEntry(name, id) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.delEntry('', id);
  }

  function invalidateEntry(name, id) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.invalidateEntry(id);
  }

  function addEntry(name, parentid, id, text, img, selimg, exppath, selpath, seltarget) {
    var panel = getPanel(name);
    if (panel == null) {
      return false;
    }
    return panel.addEntry(parentid, id, text, img, selimg, exppath, selpath, seltarget);
  }

  function addNodeImage(image) {
    myNodesImages[myNodesImages.length] = image;
  }

  function setNodeImage(image, index) {
    while (myNodesImages.length < index)
      myNodesImages[myNodesImages.length] = '';
    myNodesImages[index] = image;
  }

  function setNodeImages(imageList) {
    while (myNodesImages.length > 0)
      myNodesImages.pop();
    var imageArray = imageList.split(',');
    for( i=0; i < imageArray.length; i++) {
      myNodesImages[myNodesImages.length] = imageArray[i];
    }
  }

  function getNodeImages() {
    return myNodesImages;
  }

  function setNavigationImage(image, index) {
    while (myNavigationImages.length < index)
      myNavigationImages[myNavigationImages.length] = '';
    myNavigationImages[index] = image;
  }

  function setNavigationImageSelectedLevel(image, index) {
    while (myNavigationImagesSelectedLevel.length < index)
      myNavigationImagesSelectedLevel[myNavigationImagesSelectedLevel.length] = '';
    myNavigationImagesSelectedLevel[index] = image;
  }

  function setNavigationImageSelectedPath(image, index) {
    while (myNavigationImagesSelectedPath.length < index)
      myNavigationImagesSelectedPath[myNavigationImagesSelectedPath.length] = '';
    myNavigationImagesSelectedPath[index] = image;
  }

  function setNavigationImageSelectedPathAndLevel(image, index) {
    while (myNavigationImagesSelectedPathAndLevel.length < index)
      myNavigationImagesSelectedPathAndLevel[myNavigationImagesSelectedPathAndLevel.length] = '';
    myNavigationImagesSelectedPathAndLevel[index] = image;
  }

  function getNavigationImages() {
    return myNavigationImages;
  }

  function getNavigationImagesSelectedLevel() {
    return myNavigationImagesSelectedLevel;
  }

  function getNavigationImagesSelectedPath() {
    return myNavigationImagesSelectedPath;
  }

  function getNavigationImagesSelectedPathAndLevel() {
    return myNavigationImagesSelectedPathAndLevel;
  }

  function setSpaceImage(image) {
    spaceImage = image;
  }

  function getSpaceImage() {
    return spaceImage;
  }

  function setLineImage(image) {
    lineImage = image;
  }

  function getLineImage() {
    return lineImage;
  }

  function setLineImageSelectedLevel(image) {
    lineImageSelectedLevel = image;
  }

  function getLineImageSelectedLevel() {
    return lineImageSelectedLevel;
  }

  function setRootImage(image) {
    rootImage = image;
  }

  function getRootImage() {
    return rootImage;
  }

  function setShowFolder(flag) {
    showFolder = flag;
  }

  function getShowFolder() {
    return showFolder;
  }

  function setShowLine(flag) {
    showLine = flag;
  }

  function getShowLine() {
    return showLine;
  }

  function setShowNavigation(flag) {
    showNavigation = flag;
  }

  function getShowNavigation() {
    return showNavigation;
  }

  function setShowIndent(flag) {
    showIndent = flag;
  }

  function getShowIndent() {
    return showIndent;
  }

  function setShowTable(flag) {
    showTable = flag;
  }

  function getShowTable() {
    return showTable;
  }

  function setShowPuristic(flag) {
    showPuristic = flag;
  }

  function getShowPuristic() {
    return showPuristic;
  }

  function setChangeSelectedPathClass(flag) {
    changeSelectedPathClass = flag;
  }

  function getChangeSelectedPathClass() {
    return changeSelectedPathClass;
  }

  function setChangeNavigationImageSelectedPath(flag) {
    changeNavigationImageSelectedPath = flag;
  }

  function getChangeNavigationImageSelectedPath() {
    return changeNavigationImageSelectedPath;
  }

  function setChangeNavigationImageSelectedLevel(flag) {
    changeNavigationImageSelectedLevel = flag;
  }

  function getChangeNavigationImageSelectedLevel() {
    return changeNavigationImageSelectedLevel;
  }

  function setIgnoreNavigationLevelConnection(flag) {
    ignoreNavigationLevelConnection = flag;
  }

  function getIgnoreNavigationLevelConnection() {
    return ignoreNavigationLevelConnection;
  }

  function setAppendElementId(flag) {
    appendElementIdToText = flag;
  }

  function getAppendElementId() {
    return appendElementIdToText;
  }

  function setOpenOnClick(flag) {
    openOnClick = flag;
  }

  function getOpenOnClick() {
    return openOnClick;
  }

  function setCloseOnClick(flag) {
    closeOnClick = flag;
  }

  function getCloseOnClick() {
    return closeOnClick;
  }

  function setSelectOnNavigate(flag) {
    selectOnNavigate = flag;
  }

  function getSelectOnNavigate() {
    return selectOnNavigate;
  }

  function setOwnClassForTree(flag) {
    ownClassForTree = flag;
  }

  function getOwnClassForTree() {
    return ownClassForTree;
  }

  function setOwnClassForPanel(flag) {
    ownClassForPanel = flag;
  }

  function getOwnClassForPanel() {
    return ownClassForPanel;
  }

  function setLoggingDiv(div) {
    loggingDiv = div;
  }

  function logData(logText) {
    if (loggingDiv != null) {
      var logTxt = document.createTextNode(getTimeString() + ' ' + logText);
      loggingDiv.appendChild(logTxt);
      var logBr = document.createElement("br");
      loggingDiv.appendChild(logBr);
    }
  }

  function getTimeString() {
      var logDate = new Date();
      var logHou = logDate.getHours();
      var logMin = logDate.getMinutes();
      var logSec = logDate.getSeconds();
      var logMil = logDate.getMilliseconds();

      if (logHou == 0) logHou = '00'; else if (logHou < 10) logHou = '0' + logHou;
      if (logMin == 0) logMin = '00'; else if (logMin < 10) logMin = '0' + logMin;
      if (logSec == 0) logSec = '00'; else if (logSec < 10) logSec = '0' + logSec;
      if (logMil == 0) logMil = '000'; else if (logMil < 10) logMil = '00' + logMil; else if (logMil < 100) logMil = '0' + logMil;
      
      return logTime = logHou + ':' + logMin + ':' + logSec + ':' + logMil;
  }

  function destroy() {
    for (var panelName in myPanels) {
      if (myPanels[panelName] != null) {
        myPanels[panelName].destroy();
        myPanels[panelName] = null;
      }
    }

    myPanels = null;
    myNodesImages = null;
    myNavigationImages = null;
    myNavigationImagesSelectedLevel = null;
    myNavigationImagesSelectedPath = null;
    myNavigationImagesSelectedPathAndLevel = null;
    deleteDocumentObject();
    myTrees[id] = null;
    div = null;
  }
  
  //
  // public
  //

  this.setRequestMode = function(mode) {
    setRequestMode(mode);
  }

  this.getRequestMode = function() {
    return getRequestMode();
  }

  this.setBaseUrl = function(url) {
    setBaseUrl(url);
  }

  this.getBaseUrl = function() {
    return getBaseUrl();
  }

  this.setBaseUrlSelect = function(url) {
    setBaseUrlSelect(url);
  }

  this.getBaseUrlSelect = function() {
    return getBaseUrlSelect();
  }
  
  this.addPanel = function(name, path) {
    return addPanel(name, path);
  }

  this.delPanel = function(name) {
    return delPanel(name);
  }

  this.showPanel = function(name) {
    return showPanel(name);
  }

  this.setPanelPath = function(name, path) {
    return setPanelPath(name, path);
  }

  this.invalidatePanel = function(name) {
    return invalidatePanel(name);
  }

  this.openPath = function(name, path) {
    return openPanelPath(name, path);
  }

  this.getPanel = function(name) {
    return getPanel(name);
  }

  this.getPanels = function() {
    return getPanels();
  }

  this.hasEntry = function(name, id) {
    return hasEntry(name, id);
  }

  this.selectEntry = function(name, id) {
    return selectEntry(name, id);
  }

  this.setEntryText = function(name, id, text) {
    return setEntryText(name, id, text);
  }

  this.delEntryLink = function(name, parentid, id) {
    return delEntryLink(name, parentid, id);
  }

  this.delEntry = function(name, id) {
    return delEntry(name, id);
  }

  this.invalidateEntry = function(name, id) {
    return invalidateEntry(name, id);
  }

  this.addEntry = function(name, parentid, id, text, img, selimg, exppath, selpath, seltarget) {
    addEntry(name, parentid, id, text, img, selimg, exppath, selpath, seltarget);
  }

  this.addNodeImage= function(image) {
    addNodeImage(image);
  }

  this.setNodeImage = function(image,index) {
    setNodeImage(image,index);
  }
  
  this.setNodeImages = function(imageList) {
    setNodeImages(imageList);
  }

  this.getNodeImages = function() {
    return getNodeImages();
  }

  this.setNavigationImage = function(image,index) {
    setNavigationImage(image,index);
  }

  this.getNavigationImages = function() {
    return getNavigationImages();
  }

  this.setNavigationImageSelectedLevel = function(image,index) {
    setNavigationImageSelectedLevel(image,index);
  }

  this.getNavigationImagesSelectedLevel = function() {
    return getNavigationImagesSelectedLevel();
  }

  this.setNavigationImageSelectedPath = function(image,index) {
    setNavigationImageSelectedPath(image,index);
  }

  this.getNavigationImagesSelectedPath = function() {
    return getNavigationImagesSelectedPath();
  }

  this.setNavigationImageSelectedPathAndLevel = function(image,index) {
    setNavigationImageSelectedPathAndLevel(image,index);
  }

  this.getNavigationImagesSelectedPathAndLevel = function() {
    return getNavigationImagesSelectedPathAndLevel();
  }
  
  this.setSpaceImage = function(image) {
    setSpaceImage(image);
  }

  this.getSpaceImage = function() {
    return getSpaceImage();
  }

  this.setLineImage = function(image) {
    setLineImage(image);
  }

  this.getLineImage = function() {
    return getLineImage();
  }

  this.setLineImageSelectedLevel = function(image) {
    setLineImageSelectedLevel(image);
  }

  this.getLineImageSelectedLevel = function() {
    return getLineImageSelectedLevel();
  }

  this.setRootImage = function(image) {
    setRootImage(image);
  }

  this.getRootImage = function() {
    return getRootImage();
  }

  this.setShowFolder = function(flag) {
    setShowFolder(flag);
  }

  this.getShowFolder = function() {
    return getShowFolder();
  }

  this.setShowLine = function(flag) {
    setShowLine(flag);
  }

  this.getShowLine = function() {
    return getShowLine();
  }

  this.setShowNavigation = function(flag) {
    setShowNavigation(flag);
  }

  this.getShowNavigation = function() {
    return getShowNavigation();
  }

  this.setShowIndent = function(flag) {
    setShowIndent(flag);
  }

  this.getShowIndent = function() {
    return getShowIndent();
  }

  this.setShowTable = function(flag) {
    setShowTable(flag);
  }

  this.getShowTable = function() {
    return getShowTable();
  }

  this.setShowPuristic = function(flag) {
    setShowPuristic(flag);
  }

  this.getShowPuristic = function() {
    return getShowPuristic();
  }

  this.setChangeSelectedPathClass = function(flag) {
    setChangeSelectedPathClass(flag);
  }

  this.getChangeSelectedPathClass = function() {
    return getChangeSelectedPathClass();
  }

  this.setChangeNavigationImageSelectedPath = function(flag) {
    setChangeNavigationImageSelectedPath(flag);
  }

  this.getChangeNavigationImageSelectedPath = function() {
    return getChangeNavigationImageSelectedPath();
  }

  this.setChangeNavigationImageSelectedLevel = function(flag) {
    setChangeNavigationImageSelectedLevel(flag);
  }

  this.getChangeNavigationImageSelectedLevel = function() {
    return getChangeNavigationImageSelectedLevel();
  }

  this.setIgnoreNavigationLevelConnection = function(flag) {
    setIgnoreNavigationLevelConnection(flag);
  }

  this.getIgnoreNavigationLevelConnection = function() {
    return getIgnoreNavigationLevelConnection();
  }

  this.setAppendElementId = function(flag) {
    setAppendElementId(flag);
  }

  this.getAppendElementId = function() {
    return getAppendElementId();
  }

  this.setOpenOnClick = function(flag) {
    setOpenOnClick(flag);
  }

  this.getOpenOnClick = function() {
    return getOpenOnClick();
  }

  this.setCloseOnClick = function(flag) {
    setCloseOnClick(flag);
  }

  this.getCloseOnClick = function() {
    return getCloseOnClick();
  }

  this.setSelectOnNavigate = function(flag) {
    setSelectOnNavigate(flag);
  }

  this.getSelectOnNavigate = function() {
    return getSelectOnNavigate();
  }

  this.setOwnClassForTree = function(flag) {
    setOwnClassForTree(flag);
  }

  this.getOwnClassForTree = function() {
    return getOwnClassForTree();
  }

  this.setOwnClassForPanel = function(flag) {
    setOwnClassForPanel(flag);
  }

  this.getOwnClassForPanel = function() {
    return getOwnClassForPanel();
  }
  
  this.setLoggingDiv = function(div) {
    setLoggingDiv(div);
  }
 
  this.logData = function(logText) {
    logData(logText);
  }

  this.destroy = function() {
    destroy();
  }
  
}

function myPanel(name, tree) {

  //
  // variable
  //

  this.name = name;
  this.tree = tree;

  var panelDiv = document.createElement('div');
  panelDiv.id = tree.id + '_' + name + '_div';
  panelDiv.className = 'myTreePanel';
  determineClassName(panelDiv);
  panelDiv.style.display = 'none';
  tree.div.appendChild(panelDiv);   

  var requestFrame = null;
  if (tree.getRequestMode() == 'IFrame') {
  	requestFrame = document.createElement('iframe');
  	requestFrame.id = tree.id + '_' + name + '_frame';
  	requestFrame.name = requestFrame.id;
  	requestFrame.className = 'myTreeRequestFrame';
  	determineClassName(requestFrame);
  	requestFrame.src = '';
  	requestFrame.setAttribute('inUse','false');
  	requestFrame.style.display = 'none';
  	panelDiv.appendChild(requestFrame);
  }

  var frameDocument = getFrameDocument();
  if (frameDocument) {
    frameDocument.write("<html><head><title>Request<\/title><\/head><body></body><html>");
  }

  var visible = false;
  
  var panelPath = "";
  
  var requestIdle = 0;
  var requestMaxIdle = 100;
  
  var maxElementsForAnalyse = 200;

  var baseTime = 150;
  var idleTime = 100;
  var finiTime = 100;

  var rootTreeElement = new myTreeElem('root', 0, '', '', 'root', '', '', '', '', '', '');
  rootTreeElement.setChildrenElement(panelDiv);
        
  var myTreeElements = new Array();
  myTreeElements[rootTreeElement.elementId] = rootTreeElement;
  
  var selectedTreeElement = null;
  var selectedTreeElements = new Array();
  var selectedTreeElementsForNavigationImage = new Array();
  var selectedTreeElementsForLevelImage = new Array();  

  //
  // private
  //

  function show() {
    panelDiv.style.display = '';
    visible = true;
  }

  function hide() {
    panelDiv.style.display = 'none';
    visible = false;
  }

  function isVisible() {
    return visible;
  }
  
  /**
  * Escapes special characters like %,:,( and others to ensure that they can be passed correctly via request.
  */
  function escapeSpecialChars( string ) {
	string = string.replace(/\%/g,"%25");
	string = string.replace(/\"/g,"%22");
	string = string.replace(/\(/g,"%28");
	string = string.replace(/\)/g,"%29");
    string = string.replace(/\:/g,"%3A");
    string = string.replace(/\{/g,"%7B");
    string = string.replace(/\}/g,"%7D");
    string = string.replace(/\[/g,"%5B");
    string = string.replace(/\]/g,"%5D");
    return string;
  }

  function setPath(path) {
	var escapedPath = escapeSpecialChars( path );
    panelPath = escapedPath;
    runRequest(escapedPath, '');
    return true;
  }

  function getPath() {
    return panelPath;
  }

  function openPath(path) {
    if (path == '') {
      return false;
    }

    if (tree.getRequestMode() != 'IFrame') {
      expandPath(path, 0);
    } else {
      window.setTimeout(function () { expandPath(path, 0); }, idleTime);
    }

    return true;
  }

  function expandPath(path, level) {
    tree.logData(tree.id + '.' + name + '.expandPath : ' + path + ' / ' + level + '\n');

    var pathArray = path.split(',');
    for(i=level; i < pathArray.length; i++) {
      var parentId = '';
      if (i == 0) {
        parentId = 'root';
      } else {
        parentId = escapeSpecialChars( pathArray[i-1] );
      }

      var childId = escapeSpecialChars( pathArray[i] );

      var elementId = panelDiv.id + '_' + parentId + '_' + childId;
      var treeElement = myTreeElements[elementId];
      if (treeElement == null) {
        if (tree.getRequestMode() != 'IFrame') {
          // alert('Path could not be resolved completely : ' + path);
          return;
        } else {
          window.setTimeout(function () { expandPath(path, i); }, idleTime);
          return;
        }
      }

      if (treeElement.getChildrenElement() != null) {
        if (i < pathArray.length-1 ||
            (!treeElement.getExpanded() && treeElement != selectedTreeElement)) {
          expandElement(treeElement);
        }
      }
      
      if (i == pathArray.length-1) {
        var treeDiv = tree.div;
        var elementDiv = treeElement.getElement();
        if ((elementDiv.offsetTop - treeDiv.offsetTop) < treeDiv.scrollTop ||
          elementDiv.offsetTop > treeDiv.scrollTop + treeDiv.clientHeight) {
          treeDiv.scrollTop = elementDiv.offsetTop - treeDiv.offsetTop;
        }
        defineSelectedTreeElements(treeElement);
      }
    }
  }

  function runRequest(request, parentElementId) {
  
    tree.logData(tree.id + '.' + name + '.runRequest : ' + request + ' / ' + parentElementId + '\n');

    if (parentElementId == '' ) {
      parentElementId = 'root';
    }

    if (tree.getRequestMode() != 'IFrame') {
      var requestObject = null;
      if (tree.getRequestMode() == 'ActiveX') {
        var msXMLs = new Array('Msxml2.XMLHTTP.5.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP','Microsoft.XMLHTTP');
        for (var i = 0; i < msXMLs.length; i++) {
          try {
            requestObject = new ActiveXObject(msXMLs[i]);
            break;
          } catch (e) {
          }
        }
      } else {
        requestObject = new XMLHttpRequest();
      }
      requestObject.open('GET', tree.getBaseUrl() + request, false);
      if (requestObject.overrideMimeType) {
          requestObject.overrideMimeType('text/xml');
      }
      requestObject.send(null);
      if(requestObject.status == 200) {
        var xmlDoc = requestObject.responseXML;
        if (xmlDoc) {
          var xmlTable = xmlDoc.getElementsByTagName('table').item(0);
          if (xmlTable) {
            analyseData(parentElementId,  null, xmlTable);
          } else {
            alert('XML-Table not valid');
          }
        } else {
          alert('XML-Document not valid');
        }
      } else {
        alert(requestObject.status + ' Request error : ' + request);
      }
      return;      
    } else {
      if (requestFrame && requestFrame.getAttribute('inUse') == 'false') {
        requestFrame.setAttribute('inUse','true');
        requestFrame.src = tree.getBaseUrl() + request;
        requestIdle = 0;
        window.setTimeout(function () { analyseData(parentElementId, null, null); }, baseTime);
      } else {
        window.setTimeout(function () { runRequest(request, parentElementId); }, idleTime);
      }
    }
  }

  function analyseData(parentElementId, lastRowElement, tableElement) {

    tree.logData(tree.id + '.' + name + '.analyseData : ' + parentElementId + '\n');
  
    var endOfRequest = false;
    var elementsOfAnalyse = 0;

    var rowToAnalyse = null
    if (lastRowElement != null) {
      rowToAnalyse = lastRowElement.nextSibbling;
    } else if (tableElement != null) {
      var tableChild = tableElement.firstChild;
      while (tableChild != null && rowToAnalyse == null) {
        if (tableChild.tagName.toLowerCase() == 'tr') {
          rowToAnalyse = tableChild;
        }
        tableChild = tableChild.nextSibling;
      }
    } else {
      var frameDocument = getFrameDocument();
      if (frameDocument != null) {
        var frameBody = frameDocument.body;
        if (frameBody != null) {
          var frameBodyChild = frameBody.firstChild;
          while (frameBodyChild != null && rowToAnalyse == null) {
            if (frameBodyChild.tagName.toLowerCase() == 'table') {
              var frameBodyTableChild = frameBodyChild.firstChild;
              while (frameBodyTableChild != null && rowToAnalyse == null) {
                if (frameBodyTableChild.tagName.toLowerCase() == 'tbody') {
                  var frameBodyTableBodyChild = frameBodyTableChild.firstChild;
                  while (frameBodyTableBodyChild != null && rowToAnalyse == null) {
                    if (frameBodyTableBodyChild.tagName.toLowerCase() == 'tr') {
                      rowToAnalyse = frameBodyTableBodyChild;
                    }
                    frameBodyTableBodyChild = frameBodyTableBodyChild.nextSibling;
                  }
                }
                frameBodyTableChild = frameBodyTableChild.nextSibling;
              }
            }
            frameBodyChild = frameBodyChild.nextSibling;
          }
        }
      }
    }
    
    var lastRowAnalized = null;
    while (rowToAnalyse != null) 
    {
      if (rowToAnalyse.tagName.toLowerCase() == 'tr') {
        if (rowToAnalyse.getAttribute('id') != 'start' &&
            rowToAnalyse.getAttribute('id') != 'end') {
          var rowChild = rowToAnalyse.firstChild;
          var cellArray = new Array();
          while (rowChild != null) {
            if (rowChild.tagName.toLowerCase() == 'td') {
               var cellText = '';
               if (rowChild.childNodes.length == 1) {
                cellText = rowChild.childNodes[0].data;
               }
               cellArray[cellArray.length] = cellText;
            }
            rowChild = rowChild.nextSibling;
          }

          if (cellArray[cellArray.length-1] == 'end') {
            // update tree (panel)
            var parentElement = myTreeElements[parentElementId];
            parentId = parentElement.id;
            level = parentElement.level + 1;

            var elementId = panelDiv.id + '_' + parentId + '_' + cellArray[1];
            if (myTreeElements[elementId] == null) {

              var logText = tree.id + '.' + name + '.analyseData.receiveData : ';
              for (var iLogger = 0; iLogger < cellArray.length; iLogger++) {
                if (iLogger > 0)
                  logText = logText + ' | ';
                logText = logText + cellArray[iLogger];
              }
              logText = logText + '\n';
              tree.logData(logText);

              var treeElement = new myTreeElem(elementId,
                                               level,
                                               parentElementId,
                                               cellArray[0],
                                               cellArray[1],
                                               cellArray[2],
                                               cellArray[3],
                                               cellArray[4],
                                               cellArray[5],
                                               cellArray[6],
                                               cellArray[7]);
              myTreeElements[elementId] = treeElement;

              // update panel
              insertElement(treeElement);

              elementsOfAnalyse++;
            }
            lastRowAnalized = rowToAnalyse;
          } else {
            break;
          }
        } else if (rowToAnalyse.getAttribute('id') == 'end') {
          endOfRequest = true;
        }               
      }
      if (tree.getRequestMode() == 'IFrame') {
        if (maxElementsForAnalyse > 0 && elementsOfAnalyse == maxElementsForAnalyse) {
          window.setTimeout(function () { analyseData(parentElementId, lastRowAnalized, null); }, idleTime);
          return;
        }
      }
      rowToAnalyse = rowToAnalyse.nextSibling;
    }

    requestIdle++;
    if (requestIdle < requestMaxIdle && endOfRequest == false) {
      if (tree.getRequestMode() == 'IFrame') {
        window.setTimeout(function () { analyseData(parentElementId, lastRowAnalized, null); }, idleTime);
      } else {
        alert('Requested data not completed!');
      }
    } else {
      if (myTreeElements[parentElementId] != null) {
        myTreeElements[parentElementId].setChildrenLoaded(true);
      }
      if (requestFrame) {
      	requestFrame.src='';
      }
      window.setTimeout(function () { finishRequest(parentElementId); }, finiTime);
    }
  }

  function finishRequest(parentElementId) {

    tree.logData(tree.id + '.' + name + '.finishRequest : ' + parentElementId + '\n');
	if (requestFrame) {
    	requestFrame.setAttribute('inUse','false');
   	} 
  }
  
  function insertElement(treeElement) {
  
    tree.logData(tree.id + '.' + name + '.insertElement : ' + treeElement.elementId + '\n');
    
    // insert span / -
    var convertedTreeElementText = treeElement.text.replace(/\-/g, "-<span class='moz-break'></span>"); 

    // div for element
    var elementDiv = document.createElement('div');
    elementDiv.id = treeElement.elementId;
    elementDiv.className = 'myTreePanelElement';
    determineClassName(elementDiv);
    elementDiv.style.display = '';

    // onmouse event for element div
    elementDiv.onmouseover = function () { mouseOverElementDiv(this); };
    elementDiv.onmouseout = function() {mouseOutElementDiv(this);};

    myTreeElements[treeElement.parentId].getChildrenElement().appendChild(elementDiv);
    myTreeElements[treeElement.parentId].addChildrenTreeElement(treeElement);

    if (tree.getShowPuristic()) {

      // text anker
      var elementTextAnker = document.createElement('a');
      elementTextAnker.className = 'myElementTextAnker';
      determineClassName(elementTextAnker);
      elementTextAnker.href = tree.getBaseUrlSelect() + treeElement.selPath;
      elementTextAnker.target = treeElement.selTarget;
      // onclick event for element anker
      elementTextAnker.onclick = function () { expandElement(treeElement) };
      elementTextAnker.ondblclick = function () { collapseElement(treeElement) };
      
      elementTextAnker.innerHTML	= treeElement.text;	
      if (tree.getAppendElementId()) {
      	elementTextAnker.innerHTML = elementTextAnker.data + '- (' + treeElement.elementId + ')';
      }
      
      elementDiv.appendChild(elementTextAnker);
      treeElement.setTextAnkerElement(elementTextAnker);
    } else {
    
      if (tree.getShowTable()) {
        // table for element
        var elementTable = document.createElement('table'); 
        elementTable.className = 'myElementTable'; 
        determineClassName(elementTable);
        elementDiv.appendChild(elementTable);

        // table body for element
        var elementTableBody = document.createElement('tbody'); 
        elementTableBody.className = 'myElementTableBody'; 
        determineClassName(elementTableBody);
        elementTable.appendChild(elementTableBody);

        // table row for element
        var elementTableRow = document.createElement('tr'); 
        elementTableRow.className = 'myElementTableRow'; 
        determineClassName(elementTableRow);
        elementTableBody.appendChild(elementTableRow);
      }

      if (tree.getShowIndent()) {
        // table cells depending on level
        for (var i = 1; i < treeElement.level; i++) {
          if (tree.getShowTable()) {
            var elementTableCellLevel = document.createElement('td'); 
            elementTableCellLevel.className = 'myElementTableCellLevel';
            determineClassName(elementTableCellLevel);
            elementTableRow.appendChild(elementTableCellLevel);
          
            var elementTableCellLevelImage = document.createElement('img');
            elementTableCellLevelImage.className = 'myElementTableCellLevelImage';
            determineClassName(elementTableCellLevelImage);
            if (tree.getShowNavigation() && tree.getShowLine()) {
              determineLineImage(treeElement, elementTableCellLevelImage,  i);
            } else {
              elementTableCellLevelImage.src = tree.getSpaceImage();
            }
            elementTableCellLevel.appendChild(elementTableCellLevelImage);
          } else {
            var elementLevelImage = document.createElement('img');
            elementLevelImage.className = 'myElementLevelImage';
            determineClassName(elementLevelImage);
            if (tree.getShowNavigation() && tree.getShowLine()) {
              determineLineImage(treeElement, elementLevelImage,  i);
            } else {
              elementLevelImage.src = tree.getSpaceImage();
            }
            elementDiv.appendChild(elementLevelImage);
          }
        }
      }

      if (tree.getShowNavigation()) {
        // table cell navigate
        if (tree.getShowTable()) {
          var elementTableCellNavigate = document.createElement('td'); 
          elementTableCellNavigate.className = 'myElementTableCellNavigate'; 
          determineClassName(elementTableCellNavigate);
          elementTableRow.appendChild(elementTableCellNavigate);

          // table cell navigate image
          var elementTableCellNavigateImage = document.createElement('img');
          elementTableCellNavigateImage.className = 'myElementTableCellNavigateImage';
          determineClassName(elementTableCellNavigateImage);
          if (treeElement.expPath != '') {
            elementTableCellNavigateImage.onclick = function () { expandElement(treeElement) };
          }
          elementTableCellNavigate.appendChild(elementTableCellNavigateImage);
          treeElement.setNavImageElement(elementTableCellNavigateImage);
        } else {
          var elementNavigateImage = document.createElement('img');
          elementNavigateImage.className = 'myElementNavigateImage';
          determineClassName(elementNavigateImage);
          if (treeElement.expPath != '') {
            elementNavigateImage.onclick = function () { expandElement(treeElement) };
          }
          elementDiv.appendChild(elementNavigateImage);;
          treeElement.setNavImageElement(elementNavigateImage);
        }
      }

      if (tree.getShowFolder()) {
        // table cell folder
        if (tree.getShowTable()) {
          var elementTableCellFolder = document.createElement('td'); 
          elementTableCellFolder.className = 'myElementTableCellFolder';
          determineClassName(elementTableCellFolder);
          elementTableRow.appendChild(elementTableCellFolder);

          // table cell folder image
          var elementTableCellFolderAnker = document.createElement('a');
          elementTableCellFolderAnker.className = 'myElementTableCellFolderAnker';
          determineClassName(elementTableCellFolderAnker);
          elementTableCellFolderAnker.href = tree.getBaseUrlSelect() + treeElement.selPath;
          elementTableCellFolderAnker.target = treeElement.selTarget;
          elementTableCellFolder.appendChild(elementTableCellFolderAnker);        
          var elementTableCellFolderImage = document.createElement('img');
          elementTableCellFolderImage.className = 'myElementTableCellFolderImage';
          determineClassName(elementTableCellFolderImage);
          elementTableCellFolderImage.onclick = function () { clickElementTextAnker(treeElement) };
          elementTableCellFolderImage.ondblclick = function () { dblclickElementTextAnker(treeElement) };
          elementTableCellFolderAnker.appendChild(elementTableCellFolderImage);
          treeElement.setFolderImageElement(elementTableCellFolderImage);
        } else {
          var elementFolderImage = document.createElement('img');
          elementFolderImage.className = 'myElementFolderImage';
          determineClassName(elementFolderImage);
          elementFolderImage.onclick = function () { clickElementTextAnker(treeElement) };
          elementFolderImage.ondblclick = function () { dblclickElementTextAnker(treeElement) };
          elementDiv.appendChild(elementFolderImage);
          treeElement.setFolderImageElement(elementFolderImage);
        }

        switchFolderImage(treeElement, false);
      }

      if (tree.getShowTable()) {
        // table cell text
        var elementTableCellText = document.createElement('td'); 
        elementTableCellText.className = 'myElementTableCellText';
        determineClassName(elementTableCellText);
        elementTableRow.appendChild(elementTableCellText);

        // table cell text anker
        var elementTableCellTextAnker = document.createElement('a');
        elementTableCellTextAnker.className = 'myElementTableCellTextAnker';
        determineClassName(elementTableCellTextAnker);
        elementTableCellTextAnker.href = tree.getBaseUrlSelect() + treeElement.selPath;
        elementTableCellTextAnker.target = treeElement.selTarget;
        // onclick event for element anker
        elementTableCellTextAnker.onclick = function () { clickElementTextAnker(treeElement) };
        elementTableCellTextAnker.ondblclick = function () { dblclickElementTextAnker(treeElement) };
        elementTableCellText.appendChild(elementTableCellTextAnker);
        treeElement.setTextAnkerElement(elementTableCellTextAnker);
		elementTableCellTextAnker.title = treeElement.text;

		elementTableCellTextAnker.innerHTML	= convertedTreeElementText;	
        if (tree.getAppendElementId()) {
          elementTableCellTextAnker.innerHTML = elementTableCellTextAnkerText.data + '- (' + treeElement.elementId + ')';
        }
       } else {
        var elementTextAnker = document.createElement('a');
        elementTextAnker.className = 'myElementTextAnker';
        determineClassName(elementTextAnker);
        elementTextAnker.href = tree.getBaseUrlSelect() + treeElement.selPath;
        elementTextAnker.target = treeElement.selTarget;
        // onclick event for element anker
        elementTextAnker.onclick = function () { clickElementTextAnker(treeElement) };
        elementTextAnker.ondblclick = function () { dblclickElementTextAnker(treeElement) };
        elementDiv.appendChild(elementTextAnker);
        treeElement.setTextAnkerElement(elementTextAnker);
        elementTextAnker.title = treeElement.text;

		elementTextAnker.innerHTML	= convertedTreeElementText;	
        if (tree.getAppendElementId()) {
          elementTextAnker.innerHTML = elementTextAnker.data + '- (' + treeElement.elementId + ')';
        }
      }
    }
    
    treeElement.setElement(elementDiv);
    
    // div for children
    if (treeElement.expPath != '') {
      var childrenElementDiv = document.createElement('div');
      childrenElementDiv.id = treeElement.elementId + '_children';
      childrenElementDiv.className = 'myTreePanelElementChildren';
      determineClassName(childrenElementDiv);
      childrenElementDiv.style.display = 'none';
      if (treeElement.parentId == '') {
        panelDiv.appendChild(childrenElementDiv);
      } else {
        myTreeElements[treeElement.parentId].getChildrenElement().appendChild(childrenElementDiv);
      }
      treeElement.setChildrenElement(childrenElementDiv);
    }

    determineNavigationImage(treeElement);
    determineNavigationImage(myTreeElements[treeElement.parentId].getPreviousChildTreeElement(treeElement));
    
    if (selectedTreeElement != null) {
      defineSelectedTreeElements(selectedTreeElement);
    }
  }

  function determineNavigationImage(treeElement) {
    if (treeElement == null || treeElement.id == 'root') {
      return;
    }

    if (tree.getShowNavigation() == false || tree.getShowPuristic()) {
      return;
    }
    
    var parentTreeElement = myTreeElements[treeElement.parentId];
    if (tree.getShowLine()) {

      if (parentTreeElement.id == 'root' && tree.getRootImage() != ''){
        treeElement.getNavImageElement().src = tree.getRootImage();
        treeElement.setNavImageIndex(-1);
        return;
      }

      var previousChildTreeElement = parentTreeElement.getPreviousChildTreeElement(treeElement);
      var nextChildTreeElement = parentTreeElement.getNextChildTreeElement(treeElement);
      if (treeElement.getChildrenElement() != null ) {
        if (parentTreeElement.id == 'root' || tree.getIgnoreNavigationLevelConnection()) {
          if (treeElement.getExpanded()) {
            if (previousChildTreeElement == null) {
              if (nextChildTreeElement == null) {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[10];
                treeElement.setNavImageIndex(10);
              } else {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[13];
                treeElement.setNavImageIndex(13);
              }
            } else {
              if (nextChildTreeElement == null) {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[4];
                treeElement.setNavImageIndex(4);
              } else {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[7];
                treeElement.setNavImageIndex(7);
              }
            }
          } else {
            if (previousChildTreeElement == null) {
              if (nextChildTreeElement == null) {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[9];
                treeElement.setNavImageIndex(9);
              } else {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[12];
                treeElement.setNavImageIndex(12);
              }
            } else {
              if (nextChildTreeElement == null) {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[3];
                treeElement.setNavImageIndex(3);
              } else {
                treeElement.getNavImageElement().src = tree.getNavigationImages()[6];
                treeElement.setNavImageIndex(6);
              }
            }
          }
        } else {
          if (treeElement.getExpanded()) {
            if (nextChildTreeElement == null) {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[4];
              treeElement.setNavImageIndex(4);
            } else {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[7];
              treeElement.setNavImageIndex(7);
            }
          } else {
            if (nextChildTreeElement == null) {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[3];
              treeElement.setNavImageIndex(3);
            } else {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[6];
              treeElement.setNavImageIndex(6);
            }
          }
        }
      } else {
        if (parentTreeElement.id == 'root' || tree.getIgnoreNavigationLevelConnection()) {
          if (previousChildTreeElement == null) {
            if (nextChildTreeElement == null) {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[11];
              treeElement.setNavImageIndex(11);
            } else {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[14];
              treeElement.setNavImageIndex(14);
            }
          } else {
            if (nextChildTreeElement == null) {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[5];
              treeElement.setNavImageIndex(5);
            } else {
              treeElement.getNavImageElement().src = tree.getNavigationImages()[8];
              treeElement.setNavImageIndex(8);
            }
          }
        } else {
          if (nextChildTreeElement == null) {
            treeElement.getNavImageElement().src = tree.getNavigationImages()[5];
            treeElement.setNavImageIndex(5);
          } else {
            treeElement.getNavImageElement().src = tree.getNavigationImages()[8];
            treeElement.setNavImageIndex(8);
          }
        }
      }
    } else {
      if (treeElement.getChildrenElement() != null ) {
        if (treeElement.getExpanded()) {
          treeElement.getNavImageElement().src = tree.getNavigationImages()[1];
          treeElement.setNavImageIndex(1);
        } else {
          treeElement.getNavImageElement().src = tree.getNavigationImages()[0];
          treeElement.setNavImageIndex(0);
        }
      } else {
        treeElement.getNavImageElement().src = tree.getNavigationImages()[2];
        treeElement.setNavImageIndex(2);
      }
    }
  }
  
  function determineLineImage(treeElement, element, level) {
    if (tree.getShowIndent() && tree.getShowPuristic() == false) {
      element.src = tree.getSpaceImage();
      if (tree.getShowLine()) {
        var parentTreeElement = myTreeElements[treeElement.parentId];
        while (parentTreeElement != null) {
          if (parentTreeElement.level == level) {
            var grandParentTreeElement = myTreeElements[parentTreeElement.parentId];
            if (grandParentTreeElement != null) {
              if (grandParentTreeElement.getNextChildTreeElement(parentTreeElement) != null) {
                element.src = tree.getLineImage();
              }
            }
            break;
          } else {
            parentTreeElement = myTreeElements[parentTreeElement.parentId];
          }
        }
      }
      //treeElement.setLineImageElement(element, level);
    }
  }

  function setSpaceImage(treeElement, level) {
    if (treeElement == null || tree.getShowLine() == false || tree.getShowIndent() == false || tree.getShowPuristic()) {
      return;
    }
    
    var childrenTreeElements = treeElement.getChildrenTreeElements();
    for (var i=0; i<childrenTreeElements.length; i++) {
      setSpaceImage(childrenTreeElements[i], level);
    }
    
    if (treeElement.getLineImageElements().length > level) {
      treeElement.getLineImageElements()[level].src = tree.getSpaceImage();
    }
  }

  function setLineImage(treeElement, level) {
    if (treeElement == null || tree.getShowLine() == false || tree.getShowIndent() == false || tree.getShowPuristic()) {
      return;
    }
   
    var childrenTreeElements = treeElement.getChildrenTreeElements();
    for (var i=0; i<childrenTreeElements.length; i++) {
      setLineImage(childrenTreeElements[i], level);
    }
    
    if (treeElement.getLineImageElements().length > level) {
      treeElement.getLineImageElements()[level].src = tree.getLineImage();
    }
  }
    

  function mouseOverElementDiv(element) {
    switchClass(element, true, ' Hover');
  }

  function mouseOutElementDiv(element) {
    switchClass(element, false, ' Hover');
  }

  function clickElementTextAnker(treeElement) {
    defineSelectedTreeElements(treeElement);
    if (treeElement.getChildrenElement() != null ) {
      if (treeElement.getChildrenElement().style.display == 'none') {
        if (tree.getOpenOnClick()) {
          expandElement(treeElement);
        }
      } else {
        if (tree.getCloseOnClick()) {
            collapseElement(treeElement);
        }
      }
    }
  }

  function dblclickElementTextAnker(treeElement) {
    clickElementTextAnker(treeElement);
  }

  function expandElement(treeElement) {
    if (treeElement.getExpanded()) {
      return;
    }
    if (treeElement.getChildrenLoaded() == false) {
      runRequest(treeElement.expPath, treeElement.elementId);
      treeElement.getChildrenElement().style.display = '';
    } else {
      treeElement.getChildrenElement().style.display = '';
    }
    if (tree.getShowNavigation() && tree.getShowPuristic() == false) {
      treeElement.getNavImageElement().onclick = function () { collapseElement(treeElement) };
    }
    treeElement.setExpanded(true);
    determineNavigationImage(treeElement);
    if (tree.getSelectOnNavigate()) {
      defineSelectedTreeElements(treeElement);
    }
  }

  function collapseElement(treeElement) {
    if (treeElement.getExpanded() == false) {
      return;
    }
    var childrenTreeElements = treeElement.getChildrenTreeElements();
    for (var i=0; i<childrenTreeElements.length; i++) {
      collapseElement(childrenTreeElements[i]);
    }
    treeElement.getChildrenElement().style.display = 'none';
    if (tree.getShowNavigation() &&  tree.getShowPuristic() == false) {
      treeElement.getNavImageElement().onclick = function () { expandElement(treeElement) };
    }
    treeElement.setExpanded(false);
    determineNavigationImage(treeElement);
    if (tree.getSelectOnNavigate()) {
      defineSelectedTreeElements(treeElement);
    }
  }

  function determineClassName(element) {
    if (tree.getOwnClassForTree()) {
      element.className = element.className + '_' + tree.id;    
    }
    if (tree.getOwnClassForPanel()) {
      element.className = element.className + '_' + name;    
    }
  }

  function defineSelectedTreeElements(treeElement) {
    if (selectedTreeElement != null) {
    	var oldSelectedTreeElement = selectedTreeElement;
    	selectedTreeElement = null;
    	switchClass(oldSelectedTreeElement.getElement(), false);
    }
    
    if (selectedTreeElements.length > 0) {
      for (var i=0; i<selectedTreeElements.length; i++) {
        switchClass(selectedTreeElements[i].getTextAnkerElement(), false);
        switchFolderImage(selectedTreeElements[i], false);
      }
    }
    if (selectedTreeElementsForNavigationImage.length > 0) {
      for (var i=0; i<selectedTreeElementsForNavigationImage.length; i++) {
        switchNavigationImage(selectedTreeElementsForNavigationImage[i], false);
      }
    }
    if (selectedTreeElementsForLevelImage.length > 0) {
      for (var i=0; i<selectedTreeElementsForLevelImage.length; i++) {
        switchNavigationLevelImage(null, selectedTreeElementsForLevelImage[i], false);
      }
    }
    if (treeElement != null) {
      selectedTreeElements = getTreeElements('',treeElement.id,tree.getChangeSelectedPathClass());
      for (var i=0; i<selectedTreeElements.length; i++) {
        switchClass(selectedTreeElements[i].getTextAnkerElement(), true);
        switchFolderImage(selectedTreeElements[i], true);
      }
      selectedTreeElementsForNavigationImage = getTreeElements('',treeElement.id,tree.getChangeNavigationImageSelectedPath());
      for (var i=0; i<selectedTreeElementsForNavigationImage.length; i++) {
        switchNavigationImage(selectedTreeElementsForNavigationImage[i], true);
      }
      var parentTreeElement = myTreeElements[treeElement.parentId];
      selectedTreeElementsForLevelImage = parentTreeElement.getChildrenTreeElements();
      for (var i=0; i<selectedTreeElementsForLevelImage.length; i++) {
        switchNavigationLevelImage(treeElement, selectedTreeElementsForLevelImage[i], true);
      }
    }
    selectedTreeElement = treeElement;

    if (selectedTreeElement != null) {
    	switchClass(selectedTreeElement.getElement(), true);
    }
  }
  
  function switchClass( element, selected, ccsClassName ) {
    if ( element == null ) {
      return;
    }
    if ( ccsClassName == null ) {
    	ccsClassName = 'Selected';
    }
    var index = element.className.indexOf( ccsClassName );
    if (selected == true) {
      if ( index == -1 ) {
        element.className = element.className + ccsClassName;
      }
    } else if ( ccsClassName != ' Selected' || selectedTreeElement == null || selectedTreeElement.getElement() != element ){
      if ( index >= 0 ) {
	  	element.className = element.className.substr( 0, index )+element.className.substr( index + ccsClassName.length, element.className.length );
      }
    }
  }
  
  function switchHoverClass(element, selected) {
    if (element == null) {
      return;
    }
    
    var index = element.className.indexOf(' Hover');
    if (selected == true) {
      if (index == -1) {
        element.className = element.className + ' Hover';
      }
    } else {
      if (index >= 0) {
        element.className = element.className.substr(0, index)+element.className.substr(index+6, element.className.length);
      }
    }
  }
  
  function switchFolderImage(treeElement, selected) {
    if (tree.getShowFolder()) {
      if (selected == true) {
        treeElement.getFolderImageElement().src = tree.getNodeImages()[treeElement.selImg];
      } else {
        treeElement.getFolderImageElement().src = tree.getNodeImages()[treeElement.img];
      }
    }
  }

  function switchNavigationImage(treeElement, selected) {
    if (tree.getShowNavigation() && tree.getChangeNavigationImageSelectedPath() && treeElement.getNavImageIndex() >= 0) {
      if (selected == true) {
        treeElement.getNavImageElement().src = tree.getNavigationImagesSelectedPath()[treeElement.getNavImageIndex()];
      } else {
        treeElement.getNavImageElement().src = tree.getNavigationImages()[treeElement.getNavImageIndex()];
      }
    }
  }

  function switchNavigationLevelImage(baseTreeElement, treeElement, selected) {
    if (tree.getShowNavigation() && tree.getChangeNavigationImageSelectedLevel() && treeElement.getNavImageIndex() >= 0) {
      if (selected == true) {
        if (treeElement.elementId != baseTreeElement.elementId) {
          treeElement.getNavImageElement().src = tree.getNavigationImagesSelectedLevel()[treeElement.getNavImageIndex()];
        } else {
          if (tree.getChangeNavigationImageSelectedPath()) {
            treeElement.getNavImageElement().src = tree.getNavigationImagesSelectedPathAndLevel()[treeElement.getNavImageIndex()];
          } else {
            treeElement.getNavImageElement().src = tree.getNavigationImagesSelectedLevel()[treeElement.getNavImageIndex()];
          }
        }
      } else {
        treeElement.getNavImageElement().src = tree.getNavigationImages()[treeElement.getNavImageIndex()];
      }
    }
    switchNavigationLevelLineImages(treeElement, selected, treeElement.level);
  }

  function switchNavigationLevelLineImages(treeElement, selected, level) {
    if (tree.getShowIndent() && tree.getShowPuristic() == false && tree.getShowLine()) {
      var childrenTreeElements = treeElement.getChildrenTreeElements();
      for (var i=0; i<childrenTreeElements.length; i++) {
        if (selected == true) {
          if (childrenTreeElements[i].getLineImageElements().length > level) {
            var curImage = childrenTreeElements[i].getLineImageElements()[level].src;
            if (curImage.search(tree.getLineImage()) != -1) {
              childrenTreeElements[i].getLineImageElements()[level].src = tree.getLineImageSelectedLevel();
            }
          }
        } else {
          if (childrenTreeElements[i].getLineImageElements().length > level) {
            var curImage = childrenTreeElements[i].getLineImageElements()[level].src;
            if (curImage.search(tree.getLineImageSelectedLevel()) != -1) {
              childrenTreeElements[i].getLineImageElements()[level].src = tree.getLineImage();
            }
          }
        }
        switchNavigationLevelLineImages(childrenTreeElements[i], selected, level);
      }
    }
  }

  function getTreeElements(parentid, id, pathFlag) {
    var treeElementArray = new Array();
    for (var treeElementId in myTreeElements) {
      if (myTreeElements[treeElementId].id == id) {
        var idFound = true;

        if (parentid != '') {
          if (myTreeElements[myTreeElements[treeElementId].parentId].id != parentid) {
            idFound = false;
          }
        }

        if (idFound) {
          treeElementArray.push(myTreeElements[treeElementId]);

          if (pathFlag) {
            var tempTreeElement = myTreeElements[treeElementId];
            while (tempTreeElement.parentId != 'root') {
              treeElementArray.push(myTreeElements[tempTreeElement.parentId]);
              tempTreeElement = myTreeElements[tempTreeElement.parentId];
            }
          }
        }
      }
    }
    return treeElementArray;
  }
  
  function hasEntry(parentid, id) {
    var treeElementArray = getTreeElements(parentid,id,false);
    if (treeElementArray.length > 0) {
      return true;
    }
    return false;
  }
  
  function selectEntry(parentid, id) {
    var treeElementArray = getTreeElements(parentid,id,false);
    if (treeElementArray.length > 0) {
      defineSelectedTreeElements(treeElementArray[0]);
    }
  }

  function setEntryText(parentid, id, text) {
    var treeElementArray = getTreeElements(parentid,id,false);
    for (var i=0; i<treeElementArray.length; i++) {
      treeElementArray[i].text = text;
      if (treeElementArray[i].getTextAnkerElement() != null) {
        if (tree.getAppendElementId()) {
          text = text + '- (' + treeElementArray[i].elementId + ')';
        }
        if (treeElementArray[i].getTextAnkerElement().childNodes.length > 0) {
          treeElementArray[i].getTextAnkerElement().childNodes[0].data = text;
        }
      }
    }
  }

  function delEntry(parentid, id) {
    var treeElementArray = getTreeElements(parentid,id,false);
    for (var i=0; i<treeElementArray.length; i++) {
      delTreeElement(treeElementArray[i]);
    }
  }

  function delTreeElement(treeElement) {
    var childrenTreeElements = treeElement.getChildrenTreeElements();
    for (var i=0; i<childrenTreeElements.length; i++) {
      delTreeElement(childrenTreeElements[i]);
    }
      
    if (selectedTreeElement != null) {
      if (treeElement.elementId == selectedTreeElement.elementId) {
        defineSelectedTreeElements(null);
      }
    }

    var parentTreeElement = myTreeElements[treeElement.parentId];
    var previousChildTreeElement = parentTreeElement.getPreviousChildTreeElement(treeElement);
    var nextChildTreeElement = parentTreeElement.getNextChildTreeElement(treeElement);

    parentTreeElement.removeChildrenTreeElement(treeElement);

    if (previousChildTreeElement != null) {
      determineNavigationImage(previousChildTreeElement);
      if (nextChildTreeElement == null) {
        setSpaceImage(previousChildTreeElement, previousChildTreeElement.level);
      }
    }

    determineNavigationImage(parentTreeElement);

    delete myTreeElements[treeElement.elementId];
    myTreeElements[treeElement.elementId].destroy();
  }


  function invalidateEntry(id) {
    var treeElementArray = getTreeElements('',id,false);
    for (var i=0; i<treeElementArray.length; i++) {
      if (treeElementArray[i].getChildrenElement() != null) {
      
        collapseElement(treeElementArray[i]);
        
        var childrenTreeElements = treeElementArray[i].getChildrenTreeElements();
        for (var ie=0; ie<childrenTreeElements.length; ie++) {
          delTreeElement(childrenTreeElements[ie]);
        }

        var childrenElementDiv = document.createElement('div');
        childrenElementDiv.id = treeElementArray[i].elementId + '_children';
        childrenElementDiv.className = 'myTreePanelElementChildren';
        determineClassName(childrenElementDiv);
        childrenElementDiv.style.display = 'none';
        
        var parentTreeElement = myTreeElements[treeElementArray[i].parentId];
        var nextChildTreeElement = parentTreeElement.getNextChildTreeElement(treeElementArray[i]);
        if (nextChildTreeElement == null) {
          parentTreeElement.getChildrenElement().appendChild(childrenElementDiv);
        } else {
          parentTreeElement.getChildrenElement().insertBefore(childrenElementDiv, nextChildTreeElement.getElement());
        }

        treeElementArray[i].setChildrenElement(childrenElementDiv);

        determineNavigationImage(treeElementArray[i]);
      }
    }
  }
  
  function addEntry(parentid, id, text, img, selimg, exppath, selpath, seltarget) {
    if (parentid == '') {
      parentid = 'root';
    }

    var treeElementArray = getTreeElements('',parentid,false);
    for (var i=0; i<treeElementArray.length; i++) {

      if (treeElementArray[i].getChildrenElement() == null) {      
        var childrenElementDiv = document.createElement('div');
        childrenElementDiv.id = treeElementArray[i].elementId + '_children';
        childrenElementDiv.className = 'myTreePanelElementChildren';
        determineClassName(childrenElementDiv);
        childrenElementDiv.style.display = 'none';

        var parentTreeElement = myTreeElements[treeElementArray[i].parentId];
        var nextChildTreeElement = parentTreeElement.getNextChildTreeElement(treeElementArray[i]);
        if (nextChildTreeElement == null) {
          parentTreeElement.getChildrenElement().appendChild(childrenElementDiv);
        } else {
          parentTreeElement.getChildrenElement().insertBefore(childrenElementDiv, nextChildTreeElement.getElement());
        }
        treeElementArray[i].setChildrenElement(childrenElementDiv);
        treeElementArray[i].setChildrenLoaded(true);
      }

      if (treeElementArray[i].id != 'root') {
        expandElement(treeElementArray[i]);
      }

      var elementId = panelDiv.id + '_' + treeElementArray[i].id + '_' + id;
      if (myTreeElements[elementId] == null) {
        var treeElement = new myTreeElem(elementId,
                                         treeElementArray[i].level+1,
                                         treeElementArray[i].elementId,
                                         '',
                                         id,
                                         text,
                                         img,
                                         selimg,
                                         selpath,
                                         seltarget,
                                         exppath);
        myTreeElements[elementId] = treeElement;

        insertElement(treeElement);
      }

      var parentTreeElement = myTreeElements[treeElement.parentId];
      var previousChildTreeElement = parentTreeElement.getPreviousChildTreeElement(treeElement);
      if (previousChildTreeElement != null) {
        setLineImage(previousChildTreeElement, previousChildTreeElement.level);
      }
    }
  }

  function getFrameDocument() {
    if( !requestFrame ) {
    	return null;
    }
    try {
      if ( requestFrame.contentDocument) {
        return  requestFrame.contentDocument;
      } else if (document.frames[requestFrame.id].document) {
        return document.frames[requestFrame.id].document;
      } else {
        return null;
      }
    } catch (e) {
      return null;
    }
  }

  function destroy() {
    rootTreeElement.destroy();
    for (var treeElementId in myTreeElements) {
      myTreeElements[treeElementId] = null;
    }
    myTreeElements = null;
    requestFrame = null;
    panelDiv = null;
    tree = null;
  }

  //
  // public
  //

  this.show = function() {
    show();
  }

  this.hide = function() {
    hide();
  }

  this.isVisible = function() {
    return isVisible();
  }

  this.setPath = function(path) {
    setPath(path);
  }

  this.getPath = function() {
    return getPath();
  }

  this.getPath = function() {
    return getPath();
  }

  this.openPath = function(path) {
    openPath(path);
  }

  this.hasEntry = function(parentid, id) {
    return hasEntry(parentid, id);
  }

  this.selectEntry = function(parentid, id) {
    selectEntry(parentid, id);
  }

  this.setEntryText = function(parentid, id, text) {
    setEntryText(parentid, id, text);
  }

  this.delEntry = function(parentid, id) {
    delEntry(parentid, id);
  }

  this.invalidateEntry = function(id) {
    invalidateEntry(id);
  }

  this.addEntry = function(parentid, id, text, img, selimg, exppath, selpath, seltarget) {
    addEntry(parentid, id, text, img, selimg, exppath, selpath, seltarget);
  }

  this.destroy = function() {
    destroy();
  }
  
}

function myTreeElem(elementId, level, parentId, type, id, text,img, selImg, selPath, selTarget, expPath)
{
  //
  // variable
  //

  this.elementId = elementId;
  this.level = level;
  this.parentId = parentId;
  this.type = type;
  this.id = id;
  this.text = text;
  this.img = img;
  this.selImg = selImg;
  this.selPath = selPath;
  this.selTarget = selTarget;
  if (expPath == null) {
    this.expPath = '';
  } else {
    this.expPath = expPath;
  }
  
  var element = null;

  var childrenElement = null;
  var childrenLoaded = false;
  
  var expanded = false;
  
  var childrenTreeElements = new Array();
  var childrenTreeElementIndices = new Array();

  var lineImageElements = new Array();
  
  var navImageElement = null;
  var navImageIndex = -1;

  var folderImageElement = null;

  var textAnkerElement = null;

  //
  // private
  //

  function setElement(el) {
    element = el;
  }

  function getElement() {
    return element;
  }

  function setChildrenElement(el) {
    childrenElement = el;
  }

  function getChildrenElement() {
    return childrenElement;
  }

  function setChildrenLoaded(flag) {
    childrenLoaded = flag;
  }

  function getChildrenLoaded() {
    return childrenLoaded;
  }

  function setExpanded(flag) {
    expanded = flag;
  }

  function getExpanded() {
    return expanded;
  }

  function addChildrenTreeElement(treeElement) {
    childrenTreeElements[childrenTreeElements.length] = treeElement;
    childrenTreeElementIndices[treeElement.elementId] = childrenTreeElements.length-1;
  }

  function removeChildrenTreeElement(treeElement) {
    var newChildrenTreeElements = new Array();
    var newChildrenTreeElementIndices = new Array();
    for (var i=0; i<childrenTreeElements.length; i++) {
      if (childrenTreeElements[i].elementId == treeElement.elementId) {
        childrenTreeElements[i].destroy();
        childrenTreeElements[i] = null;
      } else {
        newChildrenTreeElements[newChildrenTreeElements.length] = childrenTreeElements[i];
        newChildrenTreeElementIndices[childrenTreeElements[i].elementId] = newChildrenTreeElements.length-1;
      }
    }
    childrenTreeElements = newChildrenTreeElements;
    childrenTreeElementIndices = newChildrenTreeElementIndices;

    if (childrenTreeElements.length == 0) {
      if (childrenElement != null) {    
        childrenLoaded = false;
        expanded = false;
        deleteElementTree(childrenElement);
        childrenElement = null;
      }
    }
  }

  function getPreviousChildTreeElement(treeElement) {
    var treeElementIndex = childrenTreeElementIndices[treeElement.elementId];
    if (treeElementIndex > 0) {
      return childrenTreeElements[treeElementIndex-1];
    }
    return null;
  }

  function getNextChildTreeElement(treeElement) {
    var treeElementIndex = childrenTreeElementIndices[treeElement.elementId];
    if (treeElementIndex < (childrenTreeElements.length-1)) {
      return childrenTreeElements[treeElementIndex+1];
    }
    return null;
  }

  function getChildrenTreeElements() {
    return childrenTreeElements;
  }

  function setLineImageElement(element, index) {
    while (lineImageElements.length < index)
      lineImageElements[lineImageElements.length] = null;
    lineImageElements[index] = element;
  }

  function getLineImageElements() {
    return lineImageElements;
  }

  function setNavImageElement(el) {
    navImageElement = el;
  }

  function getNavImageElement() {
    return navImageElement;
  }

  function setNavImageIndex(index) {
    navImageIndex = index;
  }

  function getNavImageIndex() {
    return navImageIndex;
  }

  function setFolderImageElement(el) {
    folderImageElement = el;
  }

  function getFolderImageElement() {
    return folderImageElement;
  }

  function setTextAnkerElement(el) {
    textAnkerElement = el;
  }

  function getTextAnkerElement() {
    return textAnkerElement;
  }

  function destroy() {
    for (var i=0; i<childrenTreeElements.length; i++) {
      childrenTreeElements[i].destroy();
      childrenTreeElements[i] = null;
    }
    childrenTreeElements = null;
    childrenTreeElementIndices = null;

    navImageElement = null;
    folderImageElement = null;
    textAnkerElement = null;

    for (var i=0; i<lineImageElements.length; i++) {
      lineImageElements[i] = null;
    }
    lineImageElements = null;
    
    deleteElementTree(element);
    element = null;
    deleteElementTree(childrenElement);
    childrenElement = null;
  }

  function deleteElementTree(element) {
    if (element == null)
      return;

    var childNode = element.firstChild;
    while (childNode != null) {
      deleteElementTree(childNode);
      childNode = childNode.nextSibbling;
    }
    element.onmouseover = null;
    element.onmouseout = null;
    element.onclick = null;
    element.ondblclick = null;
    
    if (element.parentNode != null)
      element.parentNode.removeChild(element);
    element = null;
  }

  //
  // public
  //

  this.setElement = function(element) {
    setElement(element);
  }

  this.getElement = function() {
    return getElement();
  }

  this.setChildrenElement = function(element) {
    setChildrenElement(element);
  }

  this.getChildrenElement = function() {
    return getChildrenElement();
  }

  this.setChildrenLoaded = function(flag) {
    setChildrenLoaded(flag);
  }

  this.getChildrenLoaded = function() {
    return getChildrenLoaded();
  }

  this.setExpanded = function(flag) {
    setExpanded(flag);
  }

  this.getExpanded = function() {
    return getExpanded();
  }

  this.addChildrenTreeElement = function(treeElement) {
    addChildrenTreeElement(treeElement);
  }

  this.removeChildrenTreeElement = function(treeElement) {
    removeChildrenTreeElement(treeElement);
  }

  this.getPreviousChildTreeElement = function(treeElement) {
    return getPreviousChildTreeElement(treeElement);
  }

  this.getNextChildTreeElement = function(treeElement) {
    return getNextChildTreeElement(treeElement);
  }

  this.getChildrenTreeElements = function() {
    return getChildrenTreeElements();
  }

  this.setLineImageElement = function(element, index) {
    setLineImageElement(element, index);
  }

  this.getLineImageElements = function() {
    return getLineImageElements();
  }

  this.setNavImageElement = function(element) {
    setNavImageElement(element);
  }

  this.getNavImageElement = function() {
    return getNavImageElement();
  }

  this.setNavImageIndex = function(index) {
    setNavImageIndex(index);
  }

  this.getNavImageIndex = function() {
    return getNavImageIndex();
  }

  this.setFolderImageElement = function(element) {
    setFolderImageElement(element);
  }

  this.getFolderImageElement = function() {
    return getFolderImageElement();
  }

  this.setTextAnkerElement = function(element) {
    setTextAnkerElement(element);
  }

  this.getTextAnkerElement = function() {
    return getTextAnkerElement();
  }
  
  this.destroy = function() {
    return destroy();
  }  
}

