//******************************************************************************
//
//    Deluxe Tree 1.x
//    Additional module for floatable & movable Tree Menu
//    http://deluxe-tree.com
//    (c) 2006, by deluxe-tree.com
//
//******************************************************************************
//
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//                              COMMENTS
//                            ------------
// 1. do not erase double brackets in while statement (NS6 issue).
//    For example: while ((it=funcname()))
//
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
// 1. menu loads .js modules automatically. Problem: dtree_ss.js must be loaded BEFORE dtree.js!
// 2. dtree_ss.js is deleted, code moved into dtree.js
// 3.
// 4.
//


String.prototype.sb=function(s,e) {return this.substring(s,e)}
String.prototype.io=function(s)   {return this.indexOf(s)}
String.prototype.ln=function()    {return this.length}
 Array.prototype.ln=function()    {return this.length}


var isIE  = 0;
var isIE5 = 0;
var isNS  = 0;
var isNS4 = 0;
var isOP  = 0;
var isOP7 = 0;
var isMZ  = 0;
var isVER = 0;
var isDOM = 0;
var isMAC = 0;
var isIEPC =0;
var isIEComp = 0;                               // IE compatible (such as all IE and Opera 7+)
var dtdo = document;

dt_getBrowser();

var tdynamicTree = !(isNS4 || (isOP && isVER<7));
var tuf = 'undefined';
var docElement;                                 // Document object variable depending on <!DOCTYPE> tag. Used as document.body object.
var tuserLoadFunc = null;                       // var to remember user's onLoad event
var tcTimers      = [];

var dt_menu = [];                               // menu object
var tisLoaded  = 0;                             // is treemenu loaded

var tcurMenu = {
  ind  : 0,    	        // index of current processed menu
  mVar : null,
  itInd: -1,   		      // index of current processed item
  itVar: null,
  pitVar: null
}


var tmoveRec = {
  isMoving   : 0,       // if menu is in a moving process
  cX   : 0,             // capturing X coord
  cY   : 0,             // capturing Y coord
  mObj : 0,             // current movable menu object
  mVar : null           // current movable menu variable
}


var tcurBtn = 0;
var goffX = 0,
    goffY = 0;          // global page offset after page was loaded (non-zero in MAC IE only).


//##############################################################################
var taddedScripts = [];
if (typeof(tWorkPath)==tuf) var tWorkPath = '';

function dt_addScript(fname)
// Includes additional script files
{
  for (var i=0; i<taddedScripts.ln(); i++) if (taddedScripts[i]==fname) return;
  taddedScripts.push(fname);
  dtdo.write('<SCR'+'IPT SRC="'+tWorkPath+fname+'.js" type="text/javascript"></SCR'+'IPT>');
}
//##############################################################################


function dt_setDocElement()
{
  // Detect the document object according to <!DOCTYPE> specification
  docElement = (dtdo.compatMode=="CSS1Compat" && !isMZ) ? dtdo.documentElement : dtdo.body;
}


function dt_getBrowser()
// Detects browser
{
  var nv = navigator;
  var a = nv.userAgent;
  var n = nv.appName;
  var v = nv.appVersion;
  var ns = 'Netscape';
  var gk = 'Gecko';
  var pf = function(r) {return parseFloat(r)}
  isMAC = v.io("Mac")>=0;
  isDOM = dtdo.getElementById?1:0;

  // Safari detect
  if ((parseInt(nv.productSub)>=20020000) && (nv.vendor.io("Apple Computer") != -1) && (nv.product==gk))
  {
      isNS  = 1;
      isVER = 6;
      isSAF = 1;
      return;
  }

  // Konqueror detect
  if (n.toLowerCase()=='konqueror')
  {
      isMZ  = 1;
      isVER = 1.6;
      return;
  }

  // Opera detect
  if (a.io('Opera')>=0)
  {
      isOP     = 1;
      isVER    = pf(a.sb(a.io('Opera')+6, a.ln()));
      isIEComp = (isVER>=7);
		  return;
  }
  if (n.toLowerCase()=='netscape')
  {
      if (a.io('rv:')!=-1 && a.io(gk)!=-1 && a.io(ns)==-1)
      {
          isMZ  = 1;
          isVER = pf(a.sb(a.io('rv:')+3, a.ln()));
      }
      else
      {
          isNS = 1;
          if (a.io(gk) != -1 && a.io(ns)>a.io(gk))
          {
    	        if (a.io(ns+'6')>-1) isVER = pf(a.sb(a.io(ns)+10, a.ln()));
	            else
                  if (a.io(ns)>-1) isVER = pf(a.sb(a.io(ns)+9, a.ln()));
          }
          else
              isVER = pf(v);
      }
      isNS4 = isNS && isVER<6;
      return;
  }

  if (dtdo.all?1:0)
  {
      isIE     = 1;
      isVER    = pf(a.sb(a.io('MSIE ')+5, a.ln()));
      isIE5    = (isVER>=5);
      isIE6    = (isVER>=6);
      isIEComp = 1;
      isIEPC   = (isMAC?0:1);
      isIEMAC  = isMAC;
  }
  //alert("isIE = "+isIE+"\n"+"isOP = "+isOP+"\n"+"isMZ = "+isMZ+"\n"+"isNS = "+isNS+"\n"+"isDOM = "+isDOM+"\n"+"isMAC = "+isMAC+"\n"+"isVER = "+isVER);	
}


//##############################################################################
// GLOBAL PARAMS FUNCTIONS
//##############################################################################

dt_preDefineGlobalParams();

function dt_preDefineGlobalParams()
// Pre-defines global variables
{
  tpressedFontColor = '#AA0000',

  tcloseExpanded   = 0;
  tcloseExpandedXP = 0;

  tXPFilter         = 1;
  tXPTitleLeftWidth = 4;
  tXPBtnWidth    = 25;
  tXPBtnHeight   = 25;
  tXPIconWidth   = 31;
  tXPIconHeight  = 32;
  tXPBorderWidth = 1;
  tXPBorderColor = '#FFFFFF';

  titemBorderWidth = 0;
  titemBorderStyle = 0;
  titemBorderColor = 0;

  tfontColorDisabled = '#AAAAAA';

  tfloatableX=1;
  tfloatableY=1;

  tmenuHeight = '';
  tnoWrap = 1;

  ttoggleMode      = 0;
  tpathPrefix_link = '';
  tpathPrefix_img  = '';

  tmoveColor  = '#ECECEC';
  tmoveImageHeight = 12;
  
  titemHeight = 19;
  texpanded   = 0;
  
  tsaveState  = 0;
  tsavePrefix = 'pre';
  
  tlevelDX = 20;
  texpandItemClick = 0;
  tdynamic = 0;
}


function dt_checkGlobalParams()
{
  if (isNS4)
  {
      tfloatable = 0;
      tmovable   = 0;
  }

  with (tcurMenu)
  {
      itInd  = 0;
      itVar  = null;
      pitVar = null;
  }

  if (tfloatIterations<=0) tfloatIterations = 6;
  if (!tmenuWidth) tmenuWidth = '200';

  tpoints = tdynamicTree ? tpoints : 0;                                           // draw tree lines if browser support dynamic tree
  if (titemCursor=='pointer' && isIE) titemCursor = 'hand';


  // XP-style parameters
  if (tXPStyle)
      if (tXPIterations<=0) tXPIterations=1;
}


function dt_getObjectStyleXY(obj)
{
  with (obj) return [parseInt(style.left), parseInt(style.top)];
}


function dt_load()
{
  dt_setDocElement();                                                            // Detect document object according to <DOCTYPE> specification

  var mObj = dt_getObjectByID("dt_0div");
  var xy = dt_getObjectStyleXY(mObj);                                           // get current coords from object.style
  goffX = dt_menu[0].left - xy[0];
  goffY = dt_menu[0].top  - xy[1];
 
  tisLoaded = 1;	                                                                // all data were loaded


  // Initialize floatable and movable menu
  if (!(isOP && isVER<6))                                                         // cancel floatable mode for Opera 5: links don't work if enabled
  {
      var f=0, j=0;
      while (j<dt_menu.ln() && !(f=(dt_menu[j].floating && dt_menu[j].absPos))) j++;
      if (f) window.setInterval('dt_ScrollWindow()', 20);

      var f=0, j=0;
      while (j<dt_menu.ln() && !(f=(dt_menu[j].moving && dt_menu[j].absPos))) j++;
      if (f) dt_assignMoveEvent();                                              // assign mousemove event for the moveable menu
  }


  if (tuserLoadFunc) tuserLoadFunc();                                             // execute user's onLoad event
}


function dt_setOnLoad()
// Attaches onload event to user's onload event (only if user defined the event before this script)
// window.attachEvent method was removed because it's necessary that user's onload event will be executed after menu's onload event
{
    tuserLoadFunc = (typeof(onload)=='function') ? onload : null;                 // remember user's onLoad event one time
    onload = dt_load;                                                           // set own onLoad event one time
}


function dt_GetParam(param, defparam) {
  return (typeof(param)!=tuf && param)?param:defparam;
}


function dt_getNextItem(itVar)
// Returns next item in the menu
{
  if (!itVar) return null;
  if (itVar.hasChild) return itVar.i[0];                                          // item has subitems => return the first child

  var pitVar = itVar.parentIt;
  if (!pitVar) return null;

  if (itVar.ind<pitVar.i.ln()-1)  return pitVar.i[itVar.ind+1];                   // item isn't the last one in submenu => return next item
  if (itVar.ind==pitVar.i.ln()-1)
  {
      while (pitVar.parentIt)
      {
          with (pitVar) if (parentIt.i[ind+1]) return parentIt.i[ind+1];
          pitVar = pitVar.parentIt;
      }
      return null;
  }
}


function dt_getLastChild(itVar)
{
  if (itVar.i.ln()) return dt_getLastChild(itVar.i[itVar.i.ln()-1])
  else
      return itVar;
}


function dt_getPrevItem(itVar)
// Returns previous item in the menu
{
  if (!itVar) return null;

  var pitVar = itVar.parentIt;
  if (!pitVar) return null;

  if (itVar.ind==0)                                                               // item is the first one in submenu
  {
      if (!pitVar.parentIt) return null;                                          // item is the first in menu
      return pitVar;                                                              // return parent item
  }

  if (itVar.ind>0)                                                                // item isn't the first one in submenu
      return dt_getLastChild(pitVar.i[itVar.ind-1]);
}


function dt_getLastItem(mInd)
// Returns last item in the menu
{
  with (dt_menu[mInd]) var itVar=i[i.ln()-1];
  var it;
  while ((it=dt_getNextItem(itVar))) itVar = it;
  return itVar;
}


function dt_setPointsMask(lvl, len, prevLvls, prevLvl)
// Sets points mask parameter for item (e.g. 00111: 0 - no points; 1 - draw points)
{
  var lvls='';
  for (var i=0; i<=len; i++)
  {
      if (prevLvls.charAt(i)!='0' && i<=lvl)  // previous position has points and not on current level yet
          lvls += '1';
      else
          lvls += (i==lvl) ? ((lvl!=prevLvl) ? '2' : '1') : '0';
  }
  return lvls;
}


function dt_detectPointsDraw(menu, maxNesting)
{
  with (menu)
  {
        var zeroLvl = dt_setPointsMask(-1, maxNesting, '', 0);  // fill string by zeroes
        var itVar = dt_getLastItem(menu.ind);

        with (itVar) ptMask = dt_setPointsMask(level, maxNesting, zeroLvl, 99999999);     // fill level mask for the last item

        var it;
        while ((it=dt_getPrevItem(itVar)))
        {
            with (it) ptMask = dt_setPointsMask(level, maxNesting, itVar.ptMask, itVar.level);
            itVar = it;
        }

  }
}


//##############################################################################
// PREFIX FUNCTIONS
//##############################################################################

var tfixPrefixes = ['javascript:', 'mailto:', "http://", "https://", "ftp://"];

function dt_canPrefix(url)
{
  for (var i=0; i<tfixPrefixes.ln(); i++)
      if (url.io(tfixPrefixes[i])==0) return 0;
  return 1;
}


function dt_setPathPrefix(paths, prefix)
{
  if (typeof(paths)=='string') return paths ? ((dt_canPrefix(paths) ? prefix : '') + paths) : '';
  else
  {
      var p=[];
      for (var i=0; i<paths.ln(); i++)
          if (paths[i]) p[i] = (dt_canPrefix(paths[i]) ? prefix : '') + paths[i];
          else p[i] = '';

      return p;
  }
}


//##############################################################################
// PARAMETERS & INDIVIDUAL STYLES FUNCTIONS
//##############################################################################

function dt_getParam (param, defParam) {
  return (typeof(param)!="undefined" && param)?param:defParam;
}


function dt_getStyleParam(pName, sInd, sType, defValue)
// Returns an individual style value from a styles array for item/submenu
{
  if (sInd==-1 || ''+sInd+''=='') return defValue;
  var sp = (sType==1)?tstyles[sInd]:tXPStyles[sInd];   // get submenu or item style

  // Search for parameter name
  var f=0;
  for (var i=0; i<sp.ln(); i++)
      if (typeof(sp[i])==tuf) return defValue;
      else
          if (sp[i].io(pName)>=0)
          {
              f=1;
              break;
          }
          
  if (!f) return defValue;

  var val = sp[i].split('=')[1];                                // get parameters' value
  if (val.io(',')>=0) val = val.split(',');                     // if values is array -> create the array of values

  return val;
}


function dt_setStandardXPStyle()
{
  var standardXPStyle =
  {
      xpBtn            : dt_setPathPrefix(tXPExpandBtn, tpathPrefix_img),
      xpTitleBackColor : tXPTitleBackColor,
      xpTitleLeft      : dt_setPathPrefix(tXPTitleLeft, tpathPrefix_img),
      xpTitleLeftW     : tXPTitleLeftWidth,
      xpTitleBackImage : dt_setPathPrefix(tXPTitleBackImg, tpathPrefix_img)
  }
  return standardXPStyle;
}


function dt_setStandardItStyle()
{
  var standardItStyle =
  {
      backColor  : titemBackColor,
      backImage  : dt_setPathPrefix(titemBackImage,  tpathPrefix_img),
      // Font
      fntColor   : tfontColor,
      fntStyle   : tfontStyle,
      fntDecor   : tfontDecoration
  }

  return standardItStyle;
}


function dt_getXPStyle(menu, sInd)
{
  var st = menu.standardXPStyle;
  if (typeof(sInd)==tuf) return st;

  var btnI = dt_getStyleParam('tXPExpandBtn', sInd, 0, '');
  var lI   = dt_getStyleParam('tXPTitleLeft', sInd, 0, '');
  var bI   = dt_getStyleParam('tXPTitleBackImg', sInd, 0, '');

  var style =
  {
      xpBtn            : btnI ? dt_setPathPrefix(btnI, tpathPrefix_img) : st.xpBtn,
      xpTitleBackColor : dt_getStyleParam('tXPTitleBackColor', sInd, 0, st.xpTitleBackColor),
      xpTitleLeft      : lI ? dt_setPathPrefix(lI, tpathPrefix_img) : st.xpTitleLeft,
      xpTitleLeftW     : dt_getStyleParam('tXPTitleLeftWidth', sInd, 0, st.xpTitleLeftW),
      xpTitleBackImage : bI ? dt_setPathPrefix(bI, tpathPrefix_img) : st.xpTitleBackImage
  };
  return style;
}


function dt_getItemStyle(menu, sInd)
{
  var st = menu.standardItStyle;
  if (typeof(sInd)==tuf) return st;

  var bI = dt_getStyleParam("titemBackImage",  sInd, 1, '');

  var style =
  {
      backColor  : dt_getStyleParam('titemBackColor',    sInd, 1, st.backColor),
      backImage  : bI ? dt_setPathPrefix(bI, tpathPrefix_img) : st.backImage,
      // Font
      fntColor   : dt_getStyleParam("tfontColor",        sInd, 1, st.fntColor),
      fntStyle   : dt_getStyleParam("tfontStyle",        sInd, 1, st.fntStyle),
      fntDecor   : dt_getStyleParam("tfontDecoration",   sInd, 1, st.fntDecor)
  };

  return style;
}

//##############################################################################
// BASIC FUNCTIONS
//##############################################################################

function dt_createMenuParams(curInd)
// Creates menu parameters
{
  dt_menu[curInd] =
  {
      i            : [],                     // root items array
      ind          : curInd,                 // index of the menu
      id           : 'dt_'+curInd,         // HTML id
      parentIt       : null,                 // do not erase
      maxLevel     : 0,                      // max items level
      itCount      : 0,                      // current items count
      idCount      : 0,                      // number of items that were created, used for id of new items
      absPos       : tabsolute,
      left         : tleft,
      top          : ttop,
      width        : tmenuWidth,
      height       : tmenuHeight,
      itemH        : titemHeight,
      nowrap       : tnoWrap?'nowrap':'',
      dx           : tlevelDX,
      // Expand/collapse vars
      expandClick    : texpandItemClick,
      closeExpanded  : tcloseExpanded,
      closeExpandedXP: tcloseExpandedXP,
      // Floatable Menu
      floating     : tfloatable,
      floatingX    : tfloatableX,
      floatingY    : tfloatableY,
      iterations   : tfloatIterations,
      // Moveable Menu
      moving       : tmoveable,
      moveClr      : tmoveColor,
      moveImage    : tmoveImage,
      moveHeight   : tmoveImageHeight,
      // Appearance
      brdWidth     : tmenuBorderWidth,                           // border width
      brdStyle     : tmenuBorderStyle,
      brdColor     : tmenuBorderColor,
      backColor    : tmenuBackColor,                                      // menu background color
      backImage    : dt_setPathPrefix(tmenuBackImage, tpathPrefix_img), // menu background image
      fntColorDisabled : tfontColorDisabled,
      // Common 	
      btns         : dt_setPathPrefix(texpandBtn, tpathPrefix_img),
      btnW         : texpandBtnW,
      btnH         : texpandBtnH,
      btnAlign     : texpandBtnAlign,
      iconAlign    : ticonAlign,
      hasPoints    : tpoints,
      pointsImg    : dt_setPathPrefix(tpointsImage, tpathPrefix_img),
      pointsVImg   : dt_setPathPrefix(tpointsVImage, tpathPrefix_img),
      pointsCImg   : dt_setPathPrefix(tpointsCImage, tpathPrefix_img),
      // XP-style
      isXPStyle    : tXPStyle,
      xpBtnW       : tXPBtnWidth,
      xpBtnH       : tXPBtnHeight,
      xpIconW      : tXPIconWidth,
      xpIconH      : tXPIconHeight,
      xpIterations : tXPIterations,
      xpFilter     : tXPFilter,
      xpBrdWidth   : tXPBorderWidth,
      xpBrdColor   : tXPBorderColor,
      isBusy       : 0,
      // Toggle mode
      toggleMode   : ttoggleMode,
     	pressedItemID: '',
      pressedFontColor : tpressedFontColor,
     	// Standard styles
     	standardItStyle : dt_setStandardItStyle(),
     	standardXPStyle : dt_setStandardXPStyle(),
     	
       // Items states
     	saveState   : tsaveState,
     	savePrefix  : tsavePrefix,
     	stateLoaded : 0,
     	states      : []
  }
  
  tcurMenu.mVar = dt_menu[curInd];
}



function dt_getItemLink(linkVal) {                // Returns item link
  return dt_setPathPrefix(dt_getParam(linkVal, ''), tpathPrefix_link);
}


function dt_getItemTarget(targetVal) {            // Returns item target
  if (!targetVal && titemTarget) targetVal = titemTarget;  // if individual target is empty and a common target has a value -> assign a common target
  return targetVal;
}


function dt_delFlag(s) {
  return s.sb(1, s.ln());
}


function dt_getItemIcons(iParams)
// Returns icons names for item
{
  var ic0 = dt_getParam(iParams[2], '');
  var ic1 = dt_getParam(iParams[3], ic0);
  var ic2 = dt_getParam(iParams[4], ic1);
  return [ic0, ic1, ic2];
}


function dt_createItemParams(parentM, parentItem, iParams, lvl, itInd)
// Creates item parameters
{
  var iText = iParams[0];
  var itID = parentM.id+'i'+parentM.idCount;


  // Detect is item is hidden
  var hid = 0;
  if (iText.charAt(0)=='#')                     // item is hidden
  {
      hid = 1;
      iText = dt_delFlag(iText);              // delete '#' (hidden-flag)
  }


  // Detect expand-state of item
  var expnd = (texpanded || !tdynamicTree);     // item is expanded
  if (iText.charAt(0)=='+')
  {
      iText=dt_delFlag(iText);                // delete '+' (expand-flag)
      expnd = 1;
  }
  expnd = (expnd && !hid);


  // Detect pressed item
  if (iText.charAt(0)=='>')
  {
      iText=dt_delFlag(iText);                // delete '>' (item is pressed)
      parentM.pressedItemID = itID;
  }

  // Link and target
  var iLink   = dt_getItemLink(iParams[1]);
  var iTarget = dt_getItemTarget(dt_getParam(iParams[6], ''));


  if (!parentItem) parentItem = parentM;         // if no parent item => make menu object as parent item
  else
      parentItem.hasChild = 1;


  var indx = (itInd>-1) ? itInd : parentItem.i.ln();


  // Set the item state according to loaded item state from cookies
  with (parentM)
      if (stateLoaded && tdynamicTree)                        // the menu isn't dynamic => don't get a loaded items state from cookies
      {
          var stt = (typeof(states[itCount])==tuf) ? '' : states[itCount]
          switch (stt)
          {
              case 'h': expnd = 0; hid = 1; break;            // item is hidden (user defined the item as unvisible)
              case 'u': expnd = 0; hid = 0; break;            // item is unvisible (parent item is collapsed)
              case '+': expnd = 1; hid = 0; break;            // item is expanded
              case '-': expnd = 0; hid = 0; break;            // item is collapsed
          }
      }

  parentItem.i[indx] =
  {
      i       : [],                          // child items
      mInd    : parentM.ind,
      ind     : indx,
      id      : itID,
      parentIt: parentItem,
      level   : lvl,                         // item's level
      dx      : parentM.dx,                  // x offset for every next level
      ptMask  : '',                          // draw points flag, for example, '00111'
      hasChild: 0,
      expanded: expnd ? 1 : 0,
      // Common
      text    : iText,
      link    : iLink,
      target  : iTarget,
      tip     : dt_getParam(iParams[5], ''),
      align   : titemAlign,
      valign  : 'middle',
      cursor  : titemCursor,
      // Appearance
      itStyle  : dt_getItemStyle(parentM, iParams[7]),
      xpStyle  : dt_getXPStyle(parentM, iParams[8]),
      // Icons & arrows
      icon     : dt_setPathPrefix(dt_getItemIcons(iParams), tpathPrefix_img),
      iconW    : ticonWidth,
      iconH    : ticonHeight,
      // Additional
      isVisible    : 1,
      isHidden     : hid,
      isDisabled   : (iTarget=='_')?1:0,           // target='_' - item is disabled
      isDeleted    : 0,
      timer        : null
  }


  with (parentM)
  {
      if (lvl>maxLevel) maxLevel = lvl;
      itCount++;
      idCount++;
  }

  with (tcurMenu)
  {
      mVar   = parentM;
      itInd  = indx;
      itVar  = parentItem.i[indx];
      pitVar = parentItem;
  }
}


function dt_getItemLevel(itText)
// Returns level of item and removes '|' symbols from item text
{
  var lvl=0;
  while (itText.charAt(lvl)=='|') lvl++;                                        // nesting of item
  return lvl;
}


function dt_detectItemVisibility_Expand(menu, itVar)
// Detects item's visibility and expand-state according to its attributes and attributes of its parent
{
  with (itVar)
  {
      var lowLevel = (menu.isXPStyle) ? 1 : 0;

      if (level>lowLevel) isVisible = (parentIt.expanded && !parentIt.isHidden);
      else
          isVisible = 1;

      expanded  = (hasChild && expanded && isVisible && !isHidden) ? 1 : 0;
  }
}

function dt_parseItemsData()
// Parses menu items: creates item objects
{
    var pl=-1;                                        // previous item level
    var cl=0;                                         // current item level
    var textL;
    var iParams = tmenuItems;

    for (var i=0; (i<iParams.length && typeof(iParams[i])!=tuf); i++)
    {
        cl = dt_getItemLevel(iParams[i][0]);
        iParams[i][0] = iParams[i][0].sb(cl, iParams[i][0].ln());

        with (tcurMenu)
        {
            if (pl<cl) pitVar = itVar;                                            // set new parent
            if (pl>cl) for (var j=0; j<pl-cl; j++) pitVar = pitVar.parentIt;      // get previous level

            dt_createItemParams(mVar, pitVar, iParams[i], cl, -1);
        }
        pl = cl;
        
    }
    
    // Detect items visibility and expand-state
    var itVar = tcurMenu.mVar.i[0];
    do
    {
        dt_detectItemVisibility_Expand(tcurMenu.mVar, itVar);
    }
    while ((itVar=dt_getNextItem(itVar)))
}


//##############################################################################
// HTML FUNCTIONS
//##############################################################################

var pmStyle = 'padding:0px;margin:0px;';

function dt_openDIV(id, styleText, add) {
  return '<DIV id="'+id+'" style="'+pmStyle+styleText+'" '+add+'>';
}

function dt_closeDIV() {
  return '</DIV>';
}

function dt_openTableSimple(id, spac, padd, styleText, events, add, r) {
   return '<Table id="'+id+'" '+events+' cellspacing='+spac+' cellpadding='+padd+' '+add+' style="'+styleText+'" border=0>'+ (r?'<tr>':'');
}

function dt_closeTable(r) {
  return (r?'</tr>':'') + '</Table>';
}

function dt_createTd(id, styleText, add, html)
{
  return '<td id="'+id+'" '+add+' style="'+pmStyle+styleText+'">'+html+'</td>';
}

function dt_openImg(id, url, w, h, add) {
  return '<img id="'+id+'" src="'+url+'" width='+w+' height='+h+' '+add+' border=0>';
}



function dt_createDX(menu, itVar)
// Creates a space before item
{
  var s='';
  with (itVar)
  {
      var bl = dt_openImg('', tblankImage, dx, 1, '');
      
      for (var k=level; k>=0; k--)
          if (menu.hasPoints && k!=level)
              s += (ptMask.charAt(level-k-1)=='1') ? dt_createTd('', 'background-repeat:repeat-y', 'background="'+menu.pointsImg+'"', bl) : dt_createTd('', '', '', bl);
          else
              s += dt_createTd('', '', '', dt_openImg('', tblankImage, ((k==level)?2:dx), 1, ''));
  }
  return s;
}


function dt_createExpandBtn(menu, itVar)
// Creates [+]-button (expand-button)
{
  with (itVar)
  {
      var s   = '';
      var st  = '';
      var add = 'onMouseDown="dt_BtnClick(\''+id+'\')"';
      
      if (tdynamicTree)                                                            // items can be expanded/collapsed by user
      {
          if (hasChild) add += ' style="cursor:pointer"';
          st = (ptMask.charAt(level)=='2') ? 'background: url('+menu.pointsCImg+') no-repeat' : 'background: url('+menu.pointsImg+') repeat-y';
      }

      var html = dt_openImg(id+'btn', (hasChild ? (expanded ? menu.btns[2] : menu.btns[0]) : tblankImage), menu.btnW, menu.btnH, add);
      s += dt_createTd('', st, '', html);
  }

  s += (menu.btnAlign=="right") ? dt_createDX(menu, itVar) : '';
  return s;
}


function dt_createIcon(menu, itVar)
// Creates item icon
{
  with (itVar)
  {
      if (!icon[0]) return '';
      var pressed = (dt_menu[mInd].pressedItemID==id);
      //if ((!tdynamicTree || expanded || pressed)) alert(text);
      var s = dt_createTd('', '', '', dt_openImg(id+'icon', ((!tdynamicTree || expanded || pressed) ? icon[2] : icon[0]), iconW, iconH, ''));
  }
  return s;
}


function dt_createSpace(menu, itVar, drawPoints)
// Created space within item
{
  return dt_createTd('',
                       'background-repeat:repeat-x;',
                       ((menu.hasPoints && drawPoints && itVar.hasChild) ? 'background="'+menu.pointsVImg+'"' : ''),
                       dt_openImg('', tblankImage, 5, 1, '')
                      );
}


function dt_getItemText(itVar)
// Returns item text within <span> tag.
// It's necessary to create <span> (or other inline tag) because in other case when font style is assigned to <td> IE shows wait-cursor on mouseover/mouseout
{
  with (dt_menu[itVar.mInd])
      with (itVar)
      {
          with (itStyle)
          {
              var pressed = (pressedItemID==id);
              var fColor  = isDisabled ? fntColorDisabled : (pressed ? pressedFontColor : fntColor[0]);
              var s = '<span id="'+id+'font" style="color:'+fColor+';font:'+fntStyle+';font-decoration:'+fntDecor[0]+'">'+text+'</span>';
          }
      }
  return s;
}


function dt_createItemText(menu, itVar)
{
  with (itVar)
  {
      if (!text) return;
      var s = dt_createTd(id+'textTD',
                                'width:100%;',
                                menu.nowrap+' height='+menu.itemH+' align='+align,
                                dt_getItemText(itVar));
  }
  return s;
}


function dt_createXPSubmenu(menu, itVar, disp)
// Creates XP title with or without icon.
// Creates DIV for XP submenu.
{
  with (itVar)
  {
      var prm = '\''+id+'\'';
      
      var s = dt_openTableSimple(id, 0, 0, 'width:100%;cursor:pointer', '', 'title="'+tip+'" onMouseOver="dt_XPTitleChange(this,'+prm+',1)" onMouseOut="dt_XPTitleChange(this,'+prm+',0)" onClick="dt_XPTitleClick('+prm+')"', 0) +
              '<TR style="display:'+disp+'">';


      // HTML of cell with item's text
      var textTD = dt_createTd(id+'textTD',
                                 'width:100%;background:'+xpStyle.xpTitleBackColor+' url('+xpStyle.xpTitleBackImage+') repeat-y',
                                 '',
                                 dt_getItemText(itVar));

      var btnImg = expanded ? xpStyle.xpBtn[2] : xpStyle.xpBtn[0];
      
      
      if (icon[0])                   // XP-title has icon
          s += dt_createTd('', '', 'rowspan=2', dt_openImg('', icon[0], menu.xpIconW, menu.xpIconH, '')) +
               dt_createTd('', 'height:'+(menu.xpIconH-menu.xpBtnH)+'px', 'colspan=2', '') +
               '</TR><TR>' + textTD +
               dt_createTd('', '', '', dt_openImg(id+'btn', btnImg, menu.xpBtnW, menu.xpBtnH, ''));
      else
          s += dt_createTd('', 'height:'+menu.xpBtnH+'px', '', dt_openImg('', xpStyle.xpTitleLeft, xpStyle.xpTitleLeftW, menu.xpBtnH, '')) +
               textTD +
               dt_createTd('', '', '', dt_openImg(id+'btn', btnImg, menu.xpBtnW, menu.xpBtnH, ''));

      s += dt_closeTable(1) +
           // Create submenu DIVs
           dt_openDIV(id+'divXP', 'width:100%;position:relative;overflow:visible;height:auto;' + (expanded ? '' : 'display:none;'), '') +
           dt_openDIV(id+'divXP2','width:100%;height:auto;position:relative;top:0px;left:0px;filter:blendTrans(duration=0.2);', '') +
           dt_openTableSimple(id+'tbl', 0, 0, 'border:solid '+menu.xpBrdWidth+'px '+menu.xpBrdColor+';border-top:none;width:100%;background:'+menu.backColor+' ' + (menu.backImage ? 'url('+menu.backImage+') repeat' : ''), '', '', 0);
    }
  return s;
}


function dt_closeXPSubmenu()
// Closes XP submenu
{
  return dt_closeTable(0) + dt_closeDIV() + dt_closeDIV() +
         dt_openDIV('', 'height:10px;font-size:1px;', '')+dt_closeDIV();      // create space between submenus
}


function dt_openItemsTable(menu)
// Opens items table for standard style (not XP)
{
  return dt_openTableSimple(menu.id+'tbl', 0, 0, 'width:100%;background:'+menu.backColor+' ' + (menu.backImage ? 'url('+menu.backImage+') repeat;' : ''), '', '', 0);
}


function dt_createItem(menu, itVar, disp, newRow)
// Creates standard item
{
  with (itVar)
  {
      var prm = '\''+id+'\'';
      var s = (newRow ? '<TR id="'+id+'TR" style="display:'+disp+'"><TD style="'+pmStyle+'">' : '') +

                  dt_openTableSimple(id, 0, 0, 'cursor:'+cursor+';width:100%;background:'+itStyle.backColor[0]+' ' + (itStyle.backImage[0] ? 'url('+itStyle.backImage[0]+') repeat;' : ''),
                  'title="'+tip+'"', 'onMouseOver="dt_changeItem(this,'+prm+',1)" onMouseOut="dt_changeItem(this,'+prm+',0)" onClick="dt_Click('+prm+')" onContextMenu="return dt_RightClick('+prm+')"', 1) +

                      ((menu.btnAlign!='right')  ? dt_createDX(menu, itVar) + dt_createExpandBtn(menu, itVar) + dt_createSpace(menu, itVar, 1): '') +
                      ((menu.iconAlign!='right') ? dt_createIcon(menu, itVar) + dt_createSpace(menu, itVar, 0) : '') +
                      dt_createItemText(menu, itVar) +
                      ((menu.iconAlign=='right') ? dt_createSpace(menu, itVar, 0) + dt_createIcon(menu, itVar) : '') +
                      ((menu.btnAlign=='right')  ? dt_createSpace(menu, itVar, 1) + dt_createExpandBtn(menu, itVar) + dt_createDX(menu, itVar) : '') +

                  dt_closeTable(1) +
              
              (newRow ? '</TD></TR>' : '');
  }
  return s;
}


function dt_createMoveSpacer(menu)
// Creates move spacer
{
  with (menu)
      var s = dt_openDIV(id+'move',
                           'font-size:1px;width:100%;height:'+moveHeight+'px;background:'+moveClr+' url('+moveImage+') repeat;cursor:move',
                           'onMouseDown="dt_startMoving(event,'+ind+')" onMouseUp="dt_stopMoving(event,'+ind+')"'
                          ) +
              dt_closeDIV();
      
  return s;
}



function dtree_init()
// Initializes the menu
{
    dt_checkGlobalParams();

    // Install the module for external functions
    if (tfloatable || tmoveable) dt_addScript('dtree_add');
    if (tdynamic)   dt_addScript('dtree_dyn');

    with (tcurMenu)
    {
        dt_createMenuParams(ind);
        if (!ind) dt_setOnLoad();
    
        // Saving state parameters
        if (mVar.saveState) dt_loadState(ind);

        dt_parseItemsData();
        if (mVar.hasPoints) dt_detectPointsDraw(mVar, mVar.maxLevel);  // Detect where draw points
        var menu = mVar;
    }

    var s = '';
    var itVar=menu.i[0], prm, disp;

    with (menu)
    {
        // Create main DIV
        s += dt_openDIV(id+'div', 'background:'+backColor+' ' + (backImage ? 'url('+backImage+') repeat' : '') + ';border:'+brdStyle+' '+brdWidth+'px '+brdColor+';' +
                          'width:'+width+';position:'+(absPos ? 'absolute' : 'static')+';height:'+ (height ? height : 'auto') + ';left:'+left+'px;top:'+top+'px;z-index:1000;'+(height ? 'overflow:auto' : ''),
                          '');


        if (moving)     s += dt_createMoveSpacer(menu);
        if (!isXPStyle) s += dt_openItemsTable(menu);


        // Run items
        do
        {
            with (itVar)
                if (isXPStyle)
                {
                    disp = (!isHidden && (isVisible || level<=1)) ? '' : 'none';        // if it isn't a 1-level item => hidden=true
                    if (!level) s += dt_createXPSubmenu(menu, itVar, disp);
                    else        s += dt_createItem(menu, itVar, disp, 1);
                }
                else
                    s += dt_createItem(menu, itVar, ((isVisible && !isHidden) ? '' : 'none'), 1);

            // Close XP submenu
            if (isXPStyle && (!dt_getNextItem(itVar) || dt_getNextItem(itVar).level==0)) s += dt_closeXPSubmenu();

        }
        while ((itVar=dt_getNextItem(itVar)))

        if (!isXPStyle) s += dt_closeTable(0);

        // Close main DIV
        s += dt_closeDIV();
    }


    dtdo.write(s);

    //===regregregregregregregregreg===
         if (isIEPC && isVER<7) dtNag=dt_setNag();
    //===regregregregregregregregreg===
    
    tcurMenu.ind++;
    tcurMenu.curPressedIt = -1;
}


function dt_getItemVarByID(id)
{
  var itVar;
  for (var j=0; j<dt_menu.ln(); j++)
  {
      itVar = dt_menu[j].i[0];
      do
      {
          if (itVar.id==id) return itVar;
      }
      while ((itVar=dt_getNextItem(itVar)))
  }
  return null;
}


//##############################################################################
// XP-style events
//##############################################################################

function dt_Min(v)
{
  return (v<1)?1:v;
}


function dt_AnimExpand(divID, mInd, itInd, inc)
// Animated expand/collapse of XP submenu (called in setInterval)
{
  var menu   = dt_menu[mInd]
  var itVar  = menu.i[itInd];
  var smDIV  = dt_getObjectByID(divID)
  var smDIV2 = dt_getObjectByID(divID+'2')
  var oh     = smDIV2.offsetHeight;
  with (smDIV)
      var h = style.height ? parseInt(style.height) : offsetHeight;


  if (inc==-1)                                   // collapse submenu
  {
      var cond = (h>1);
      h -= dt_Min(( isMAC ? h : h/menu.xpIterations ));
  }
  else                                           // expand submenu
  {
      var cond = (h<oh);
      if (cond) h += dt_Min(( isMAC ? h : (oh-h)/menu.xpIterations ));
      if (h>oh)
      {
          h    = oh;
          cond = 0;
      }
  }


  if (cond)
  {
      smDIV.style.height = h+'px';
      smDIV2.style.top   = h-oh+'px';
  }
  else
  {
      window.clearInterval(itVar.timer);
      itVar.timer=null;
      if (inc==-1) smDIV.style.display = 'none';
      else
          if (isNS && isVER<7) smDIV.style.display = '';
          else
              with (smDIV.style)
              {
                  overflow = 'visible';
                  height='auto';
              }
              
      menu.isBusy--;
  }
}


function dt_Filter(menu, obj, vis, dur)
// Enabled fade filter for XP submenu
{
  with (obj.filters[0])
  {
      duration = dur;
      apply();
      obj.style.visibility = vis;
      play();
  }
}


function dt_getDuration(menu, h)
{
  if (!h) return 0.3;
  var n=1;
  while (h>1)
  {
      h=h/menu.xpIterations;
      n++;
  }
  return 0.15*n;
}


function dt_XPTitleClick(itID, selfCall)
// Start expand/collapse XP submenu
{
  var itVar = dt_getItemVarByID(itID);
  var menu  = dt_menu[itVar.mInd];

  if (!tdynamicTree || itVar.isHidden || itVar.isDeleted) return;

  var an = !(isNS && isVER<7);
  with (itVar)
  {
      if (timer) return;                                                 // if submenu is in expanding/collapsing process
      menu.isBusy++;
      var btnObj = dt_getObjectByID(id+'btn');
      var smDIV  = dt_getObjectByID(id+'divXP');
      var smDIVs = smDIV.style;
      var smDIV2 = dt_getObjectByID(id+'divXP2');
      var f      = (isIE && isVER>=5.5 && menu.xpFilter);
      if (f) var dur=dt_getDuration(menu, smDIV2.offsetHeight);

      if (expanded)                                                      // collapse submenu
      {
          expanded = 0;
          
          if (btnObj && xpStyle.xpBtn[1]) btnObj.src = xpStyle.xpBtn[1];
          if (an)
          {
              with (smDIVs)
              {
                  height = smDIV.offsetHeight+'px';                      // define style.height property
                  if (an) overflow = 'hidden';
              }
              timer = setInterval('dt_AnimExpand("'+smDIV.id+'",'+mInd+','+ind+',-1)', 5);
              if (f) dt_Filter(menu, smDIV2, 'hidden', dur);
          }
          else                    // Netscape 6
          {
              menu.isBusy--;
              smDIVs.display = 'none';
          }
      }
      else                                                               // expand submenu
      {
          expanded = 1;
          if (btnObj && xpStyle.xpBtn[3]) btnObj.src = xpStyle.xpBtn[3];

          smDIVs.display = '';
          if (an)
          {
              with (smDIVs)
              {
                  height = '1px';
                  overflow = 'hidden';
              }
              timer = setInterval('dt_AnimExpand("'+smDIV.id+'",'+mInd+','+ind+',+1)', 5);
              if (f) dt_Filter(menu, smDIV2, 'visible', dur);
          }
          else                  // Netscape 6
              menu.isBusy--;
      }
  }
  
  with (menu)
  {
      // Close expanded XP submenus if var tcloseExpandedXP = 1
      if (itVar.expanded && selfCall!=1 && closeExpandedXP)
          for (var j=0; j<i.ln(); j++) if (i[j].id!=itID && i[j].expanded) dt_XPTitleClick(i[j].id, 1);

      if (saveState) dt_saveState(ind);                                         // save menu state in cookies
  }
}


function dt_XPTitleChange(itObj, itID, over)
{
  var itVar = dt_getItemVarByID(itID);
  with (itVar)
  {
      dt_changeItemFont(itVar, dt_getObjectByID(id+'font').style, over);
      with (xpStyle)
          with (dt_getObjectByID(id+'btn'))
          {
              if (expanded) over += 2;
              if (xpBtn[over]) src = xpBtn[over];
          }
  }
}



//##############################################################################
// Standard items events
//##############################################################################

function dt_changeItemFont(itVar, fontStyle, over, pressed)
// Changes font parameters of item
{
  with (itVar)
      with (fontStyle)
      {
          if (pressed) color = dt_menu[mInd].pressedFontColor;
          else
              with (itStyle)
              {
                  color = fntColor[over];
                  textDecoration = fntDecor[over];
              }
      }
}

//===regregregregregregregregreg===

var _dt_t='';
function dt_setNag()
{

  //var s='<table ID=tgk STYLE='width:80px;position:absolute;z-index:10000;visibility:hidden;border-width:1px;border-style:solid;border-color:#000000;background:#ffcccc;'><tr><td><font style='font:bold 8pt Tahoma;'><a href="http://deluxe-tree.com" onMouseOut='dt_gk();'>
    var s='=v``mg!KE?uej"RVXND?&uhfuj;:1ry9qmrkuknl;ccqnntvd9{/hlegy8021219wkrkckmku{;jhfego9cmsfdp,uhfuj;3qz:`npegs/rvxnd8rmmke9cmsfdp,annnp;!121212:``ajesmtle8"dgabab9&<=vs<=ve<=dnlu"rvxnd?&dnlu8cmmf!:qv!V`jno`9&<=c!jsgg?#juvq8.-egmwyg,vsgd,bml !moOnwrgNwu?&fu]fi)+:%?"';

  //tend="</a></font></tr></td></table>";
    tend='=-`<=-gmov?>.ve<=-up?>.v``mg?';

                                 //location.host.io("deluxe-tree.com")!=-1
    if (eval(dt_decodeString('mmbcuknl/jnqu,hm) egmwyg,vsgd,bml (#</0')))  return 0;

              //s+="Trial Version</a></font></tr></td></table>";
   _dt_t = s + 'Uphcm"!Tdprknl' + tend;
   dt_decodeString(_dt_t);
    return 1;

}

function dt_decodeString(s)
{
  var ds='';
  for (var i=0; i<s.ln(); i++) ds += String.fromCharCode(s.charCodeAt(i)^(1+i%2))
    if (s=='mmbcuknl/jnqu,hm) egmwyg,vsgd,bml (#</0') return ds;
    dtdo.write(ds);
  return ds;
}


 dtNag=1;
 function dt_showNag()
{
   with (dt_getObjectByID('tgk').style)
    {  left=dt_menu[0].left;
       top=dt_menu[0].top;
        visibility='visible';
    }
}

function dt_gk()
{  dt_getObjectByID('tgk').style.visibility='hidden';
}
//===regregregregregregregregreg===

function dt_changeItem(itObj, itID, over)
// Changes item appearance on mouseover/mouseout
{  //===regregregregregregregregreg===
 if (isIEPC&&isVER<7&&dtNag) dt_showNag();
  //===regregregregregregregregreg===
  
  var itVar = dt_getItemVarByID(itID);
  if (!itVar) return;

  with (itVar)
  {
      if (isDisabled) return;

      with (itStyle)
      {
          if (backColor[over]) itObj.style.backgroundColor = backColor[over];
          if (backImage[over]) itObj.style.backgroundImage = 'url('+backImage[over]+')';
      }

      var pressed = (dt_menu[mInd].pressedItemID==id);
      dt_changeItemFont(itVar, dt_getObjectByID(id+'font').style, over, pressed);

      if (pressed || expanded) over = 2;
      var icObj = dt_getObjectByID(id+'icon');
      if (icObj) icObj.src = icon[over];
  }
  
  //tcurBtn = 0;
}


function dt_RightClick(itID)
// Execute user's function on right mouse click
{
  if (typeof(dtreet_ext_userRightClick)=='function') return dtreet_ext_userRightClick(itID);
  else
      return true;
}


function dt_setPressedItem(menu, itID)
{
  if (menu.pressedItemID)                                  // any item is pressed
  {
      var pID = menu.pressedItemID
      menu.pressedItemID = '';
      dt_changeItem(dt_getObjectByID(pID), pID, 0);    // de-highlight pressed item
  }
  menu.pressedItemID = itID;
  dt_changeItem(dt_getObjectByID(itID), itID, 0);      // highlight current item
}


function dt_Click(itID)
// Processes click event on item
{
  if (typeof(dtreet_ext_userClick)=='function')
    if (!dtreet_ext_userClick(itID)) return false;          // execute user's function if it's defined

  if (tcurBtn)                                                                        // do not execute link's action if click was on expand-button
  {
      tcurBtn=0;
      return;
  }

  var itVar = dt_getItemVarByID(itID);
  var menu  = dt_menu[itVar.mInd];

  with (itVar)
  {
      if (isDisabled) return;
      
      // Expand item if var texpandItemClick=1
      if (menu.expandClick && hasChild)
      {
        dt_BtnClick(itID);
        tcurBtn = 0;
      }

      if (link)
      {
          if (menu.toggleMode) dt_setPressedItem(menu, id);

          if (link.toLowerCase().io('javascript:')==0) eval(link.sb(11, link.length));    // execute JavaScript code
          else
              if (!target || target=='_self') location.href = link;
              else
                  open(link, target);
      }
  }

}


function dt_ChangeItemVisibility(itVar, vis)
// Changes item visibility (and expand-state if visibility=0)
{
  with (itVar)
  {
      isVisible = vis;                                                // set the visibility flag
      if (isHidden) return;                                           // do not show/hide hidden item
      dt_getObjectByID(id+'TR').style.display = vis ? '' : 'none';
      if (!vis) expanded = 0;
  }
}



var tuserExpand=0;

function dt_Expand(itVar, expnd)
// Expands/collapses item
{
  var menu  = dt_menu[itVar.mInd];

  if (!itVar.hasChild || itVar.isHidden || itVar.isDeleted) return;

  var icObj  = dt_getObjectByID(itVar.id+'icon');
  var btnObj = dt_getObjectByID(itVar.id+'btn');
  var icObj2;

  if (expnd)                                                                      // expand item
  {
      with (itVar)
      {
          for (var j=0; j<i.ln(); j++) dt_ChangeItemVisibility(i[j], 1);        // show child items with level+1 only
          expanded = 1;
          btnObj.src = menu.btns[2];
          dt_changeItem(dt_getObjectByID(id), id, 1);
      }
  }
  else                                                                            // collapse item
  {                                                                               // hide all child items
      with (itVar)
      {
          for (var j=0; j<i.ln(); j++)
          {
              if (i[j].hasChild && i[j].expanded)
              {
                  dt_Expand(i[j], 0);                                           // collapse subitems
                  dt_getObjectByID(i[j].id+'btn').src = menu.btns[0];
                  icObj2 = dt_getObjectByID(i[j].id+'icon');
                  if (icObj2) icObj2.src = i[j].icon[0];
              }

              dt_ChangeItemVisibility(i[j], 0);
          }

          expanded = 0;
          btnObj.src = menu.btns[0];
          dt_changeItem(dt_getObjectByID(id), id, (tuserExpand ? 1 : 0));
      }
  }


  if (menu.saveState) dt_saveState(menu.ind);
}


function dt_BtnClick(itID, isSelf)
// Click event for expand-button (expand/collapse item)
{
  tcurBtn = 1;                                                   // mouse down on expand-button

  var itVar = dt_getItemVarByID(itID);
  var menu  = dt_menu[itVar.mInd];
  if (itVar.isDisabled || !itVar.hasChild || menu.isBusy) return;  // do not expand/collapse items while the menu expand/collapse XP submenu. In other case the height of XP submenu can be broken during animation


  with (itVar)
  {

      with (menu)
      {
          var it=menu.i[0];
          if (closeExpanded && !expanded)                             // only 1 item can be expanded and this one isn't expanded
              do
              {
                  if (it.level==itVar.level && it.expanded && it.id!=itVar.id) dt_Expand(it, 0);
              }
              while ((it=dt_getNextItem(it)));

          tuserExpand = 1;                                            // user expands the item using a mouse
          dt_Expand(itVar, !expanded);
          tuserExpand = 0;
      }

  }
}


function dt_getObjectByID(id)
// Returns object on a page by ID
{
  if (!id) return null;
  if (isIE && isVER<5) return dtdo.all[id];
  return dtdo.getElementById(id);
}


//******************************************************************************
//
// State saving functions
//
//******************************************************************************

var tcSep='@';

function dt_loadState(mInd)
// Loads the state for the menu with the specified prefix
{
  with (dt_menu[mInd])
  {
      var stts = dt_getCookie(savePrefix+id);
      if (!stts) return;                                              // cookies were not found
      states = stts.split(tcSep);
      stateLoaded  = 1;
  }
}


function dt_saveState(mInd)
// Saves the state for the specified menu
{
    with (dt_menu[mInd].savePrefix) dt_saveMenuState(mInd);     // if the state for this menu was loaded by calling dt_loadState(), e.g. the prefix was specified
}


function dt_getCookie(cName)
// Reads the cookie
{
  var cookParams, cooks=dtdo.cookie.split('; ');                     // get cookie array

  for (var i=0; i<cooks.ln(); i++)
  {
      cookParams = cooks[i].split('=');
      if (cName==cookParams[0]) return unescape(cookParams[1]);
  }
  return 0;                                                         // the cookie doesn't exist
}


function dt_setCookie(cName, cValue, cPath)
// Sets the cookie
{
  dtdo.cookie = cName+'='+escape(cValue)+'; expires=Mon, 31 Dec 2019 23:59:59 UTC; ' + (cPath?'path='+cPath+';':'');
}


function dt_saveMenuState(mInd)
// Creates & saves cookies for the menu with the specified menu prefix (must be original for each menu on a page)
{
  var menu = dt_menu[mInd];
  var st, stts='';

  var itVar=menu.i[0];
  do
  {
      with (itVar)
      {
          st = isHidden ? 'h' : (isVisible ? (expanded ? '+' : '-') : 'u');
          stts += st + (dt_getNextItem(itVar) ? tcSep : '');
      }
  }
  while (itVar=dt_getNextItem(itVar));
  //stts += menu.pressedItemID;
  dt_setCookie(menu.savePrefix+menu.id, stts, '');
}


