var arbrelistAutoCollapse = {'default':true};
var arbrelistBulletWidth = {'default':20};
var arbrelistIE7Supported = true; // allow style changes to occur if IE7 is in use
var arbrelistIE7Recalc = true; // recalculate the document at appropriate points if IE7 is in use

function arbrelistDocRecalc() {
  if (window.IE7 &&
      arbrelistIE7Supported &&
      (typeof document.recalc == 'function') &&
      arbrelistIE7Recalc) document.recalc();
}

// Refresh all explorer trees
function arbrelistRefreshAll() {
  // We don't actually need createElement, but we do
  // need good DOM support, so this is a good check.
  //if (!document.createElement) return;
  
  var ul, uls = document.getElementsByTagName('ul');
  for (var uli = 0; uli < uls.length; uli++) {
    ul = uls[uli];
    if (ul.nodeName.toLowerCase() == 'ul' && elementHasClass(ul, 'arbrelist')) {
      _arbrelistInitUL(ul);
    }
  }
  if (uls.length > 0) arbrelistDocRecalc();
}

// Refresh the specified explorer tree
function arbrelistRefresh(id) {
  _arbrelistInitUL(document.getElementById(id));
  arbrelistDocRecalc();
}

// Get the root element (<ul>) of the tree the given element is part of.
function _arbrelistGetRoot(element) {
  for (var e = element; e != null; e = e.parentNode) {
    if (e.nodeName.toLowerCase() == 'ul' && elementHasClass(e, 'arbrelist')) {
      break;
    }
  }
  return e;
}

// Get the ID of the tree the given element is part of. Returns the ID or
// 'default' if there is no ID.
function _arbrelistGetId(element) {
  var e = _arbrelistGetRoot(element);
  var id = e ? e.getAttribute('id') : '';
  return (!id || id == '') ? 'default' : id;
}
// Initialise the given list
function _arbrelistInitUL(ul)
 {
 if (window.IE7 && !arbrelistIE7Supported) return;
 if (navigator.userAgent.indexOf('Gecko') != -1)
 {
  addEvent(ul, 'mousedown', _arbrelistStopGeckoSelect, false);
 }
 if (!ul.childNodes || ul.childNodes.length == 0) return;
 // Iterate LIs
 for (var itemi = 0; itemi < ul.childNodes.length; itemi++)
 {
  var item = ul.childNodes[itemi];
  if (item.nodeName.toLowerCase() == 'li')
  {
   addEvent(item, 'click', _arbrelistOnClick, false);
   var hassubul = false;
   for (var subitemi = 0; subitemi < item.childNodes.length; subitemi++)
   {
    var subitem = item.childNodes[subitemi];
    if (subitem.nodeName.toLowerCase() == 'a')
    {
     addEvent(subitem, 'click', _arbrelistOnClick, false);
    }
    if (subitem.nodeName.toLowerCase() == 'ul')
    {
     hassubul = true;
     _arbrelistInitUL(subitem);
    }
   }
   if (hassubul)
   {
    // item is expandable, but don't change it if it's already been set to
    // something else
    if (!elementHasClass(item, 'arbrelist-open') && !elementHasClass(item, 'arbrelist-bullet'))
    {
     elementAddClass(item, 'arbrelist-closed');
    }
   }
   else
   {
    // item has no sub-lists, make sure it's non-expandable
    elementRemoveClass(item, 'arbrelist-open');
    elementRemoveClass(item, 'arbrelist-closed');
    elementAddClass(item, 'arbrelist-bullet');
   }
  }
 }
}

// Gecko selects text when bullets are clicked on - stop it!
function _arbrelistStopGeckoSelect(evt) {
  if (!evt) var evt = window.event;
  if (evt.preventDefault) {
    evt.preventDefault();
  }
  return true;
}

// Handle clicking on LI and A elements in the tree.
function _arbrelistOnClick(evt) {
  if (!evt) var evt = window.event;
  var element = (evt.target) ? evt.target : evt.srcElement;
  if (this != element) {
    return true;
  }
  if (element.nodeName.toLowerCase() == 'li') {
    var href = element.getAttribute('href');
    if (href)
    {
      var target = element.getAttribute('target');
      if (!target)
      {
        target = '_self';
      }
      switch (target)
      {
        case '_blank':
          window.open(href);
          break;
        case '_self':
          window.location.href = href;
          break;
        case '_parent':
          window.parent.location.href = href;
          break;
        case '_top':
          window.top.location.href = href;
          break;
        default:
          window.open(href, target);
          break;
      }
    }
    // toggle open/closed state, if possible
    if (elementHasClass(element, 'arbrelist-open')) {
      elementRemoveClass(element, 'arbrelist-open');
      elementAddClass(element, 'arbrelist-closed');
    } else if (elementHasClass(element, 'arbrelist-closed')) {
      elementRemoveClass(element, 'arbrelist-closed');
      elementAddClass(element, 'arbrelist-open');
    } else {
      return true;
    }
    if (arbrelistAutoCollapse[_arbrelistGetId(element)]) {
      _arbrelistCollapseAllButElement(element);
    }
    arbrelistDocRecalc();
  } else if (element.nodeName.toLowerCase() == 'a') {
    // let hyperlinks work as expected
    // TO DO: target support untested!!!
    var href = element.getAttribute('href');
    if (href) {
      var target = element.getAttribute('target');
      if (!target) {
        target = '_self';
      }
      switch (target) {
        case '_blank':
          window.open(href);
          break;
        case '_self':
          window.location.href = href;
          break;
        case '_parent':
          window.parent.location.href = href;
          break;
        case '_top':
          window.top.location.href = href;
          break;
        default:
          window.open(href, target);
          break;
      }
    }
  } else {
    return true;
  }
  // we handled the event - stop it from propagating any further
  evt.cancelBubble = true;
  if (evt.stopPropagation) {
    evt.stopPropagation();
  }
  return false;
}

// Open the specified tree branch
function _arbrelistOpen(li) {
  if (!elementHasClass(li, 'arbrelist-bullet')) {
    elementRemoveClass(li, 'arbrelist-closed');
    elementAddClass(li, 'arbrelist-open');
  }
}

// Close the specified tree branch
function _arbrelistClose(li) {
  if (!elementHasClass(li, 'arbrelist-bullet')) {
    elementRemoveClass(li, 'arbrelist-open');
    elementAddClass(li, 'arbrelist-closed');
  }
}

// Collapse the specified tree
function arbrelistCollapse(id) {
  _arbrelistSetState(document.getElementById(id), true, null);
  arbrelistDocRecalc();
}

// Fully expand the specified tree
function arbrelistExpand(id) {
  if (!arbrelistAutoCollapse[id]) {
    _arbrelistSetState(document.getElementById(id), false, null);
    arbrelistDocRecalc();
  }
}

// Collapse all the branches of tree except for those leading to the specified
// element. 
function _arbrelistCollapseAllButElement(e) {
  var excluded = new Array();
  var tree = null;
  for (var element = e; element != null; element = element.parentNode) {
    if (element.nodeName.toLowerCase() == 'li') {
      excluded[excluded.length] = element;
    }
    if (element.nodeName.toLowerCase() == 'ul' && elementHasClass(element, 'arbrelist')) {
      tree = element;
    }
  }
  if (tree) {
    _arbrelistSetState(tree, true, excluded)
  }
}

// Set the open/closed state of all the LIs under the tree.
// The excludedElements parameter is used to implement the auto-collapse feature
// that automatically collapses tree branches other than the one actively being
// opened by the user.
function _arbrelistSetState(ul, collapse, excludedElements) {
  if (window.IE7 && !arbrelistIE7Supported) return;
  if (!ul.childNodes || ul.childNodes.length == 0) return;
  // Iterate LIs
  for (var itemi = 0; itemi < ul.childNodes.length; itemi++) {
    var item = ul.childNodes[itemi];
    if (item.nodeName.toLowerCase() == 'li') {
      var excluded = false;
      if (excludedElements) {
        for (var exi = 0; exi < excludedElements.length; exi++) {
          if (item == excludedElements[exi]) {
            excluded = true;
            break;
          }
        }
      }
      if (!excluded) {
        if (collapse) {
          _arbrelistClose(item);
        } else {
          _arbrelistOpen(item);
        }
      }
      for (var subitemi = 0; subitemi < item.childNodes.length; subitemi++) {
        var subitem = item.childNodes[subitemi];
        if (subitem.nodeName.toLowerCase() == 'ul') {
          _arbrelistSetState(subitem, collapse, excludedElements);
        }
      }
    }
  }
}

// Open the tree out so the list item with the link with the specified HREF is
// visible. Optionally scrolls so the item is visible. Optionally opens the
// found branch. Returns the LI that contains the specified HREF, or null if
// unsuccessful.
function arbrelistOpenTo(id, href, scroll, expand) {
  var li = _arbrelistSearch(document.getElementById(id), _arbrelistNormalizeHref(href));
  if (li) {
    if (!window.IE7 || arbrelistIE7Supported) { 
      if (arbrelistAutoCollapse[id]) {
        _arbrelistCollapseAllButElement(li);
        arbrelistDocRecalc();
      }
      if (expand) {
        _arbrelistOpen(li);
        arbrelistDocRecalc();
      }
    }
    if (scroll) {
      // get height of window we're in
      var h;
      if (window.innerHeight) {
        // Netscape, Mozilla, Opera
        h = window.innerHeight;
      } else if (document.documentElement && document.documentElement.clientHeight) {
        // IE6 in 'standards' mode
        h = document.documentElement.clientHeight;
      } else if (document.body && document.body.clientHeight) {
        // other IEs
        h = document.body.clientHeight;
      } else {
        h = 0;
      }
      // scroll so the list item is centered on the window
      window.scroll(0, li.offsetTop - h / 2);
    }
  }
  return li;
}

// Search the list (and sub-lists) for the given href. Returns the LI object if
// found, otherwise returns null.
function _arbrelistSearch(ul, href) {
  if (!ul.childNodes || ul.childNodes.length == 0) return null;
  // Iterate LIs
  for (var itemi = 0; itemi < ul.childNodes.length; itemi++) {
    var item = ul.childNodes[itemi];
    if (item.nodeName.toLowerCase() == 'li') {
      for (var subitemi=0; subitemi < item.childNodes.length; subitemi++) {
        var subitem = item.childNodes[subitemi];
        if (subitem.nodeName.toLowerCase() == 'a') {
          if (_arbrelistNormalizeHref(subitem.getAttribute('href')) == href) {
            return item;
          }
        }
        if (subitem.nodeName.toLowerCase() == 'ul') {
          var found = _arbrelistSearch(subitem, href);
          if (found) {
            _arbrelistOpen(item);
            return found;
          }
        }
      }
    }
  }
  return null;
}

// When Opera performs HTMLElement.getAttribute('href'), it *doesn't* actually
// return the raw HREF like it's supposed to. It 'normalizes' it, adding in any
// missing protocol, host name/port, and converts relative HREFs (eg
// '../../index.html') into absolute HREFs (eg '/index.html'). It does exactly
// the same thing in CSS generated content for the attr(href) function. If all
// browsers did that it would make URL comparisons trivial. Unfortunately, other
// browsers don't, and they're probably doing the right thing too by returning
// the href as it appears in the HTML.
// What this function does is normalize HREFs so we can do a meaningful
// comparison in *all* browsers.
function _arbrelistNormalizeHref(href) {
  var i, h = href, l = window.location;
  
  // immediately return explicit protocols
  if (href.substring(0, 7) == 'telnet:') return href;
  if (href.substring(0, 7) == 'mailto:') return href;
  if (href.substring(0, 7) == 'gopher:') return href;
  if (href.substring(0, 5) == 'http:'  ) return href;
  if (href.substring(0, 5) == 'news:'  ) return href;
  if (href.substring(0, 5) == 'rtsp:'  ) return href;
  
  // handle absolute references
  if (h.charAt(0) == '/') {
    return l.protocol + '//' + l.host + h;
  }
  
  // strip off the filename (if any) of the location to leave the folder we're in
  l = l.toString();
  i = l.lastIndexOf('/');
  if (i != -1) {
    l = l.substring(0, i + 1);
  }
  
  // handle any relative directory references, i.e. '../'
  while (h.substring(0, 3) == '../') {
    h = h.substring(3);
    i = l.lastIndexOf('/', l.length - 2);
    if (i != -1) {
      l = l.substring(0, i + 1);
    }
  }
  
  return l + h;
}

function convertPreBlocks() {}

function bigger()
{
  if (!evt) var evt = window.event;
  var element = (evt.target) ? evt.target : evt.srcElement;
  if (this != element) {
    return true;
  }
  element.style.fontSize = "large";
}

function normal()
{
  if (!evt) var evt = window.event;
  var element = (evt.target) ? evt.target : evt.srcElement;
  if (this != element) {
    return true;
  }
  element.style.fontSize = "small";
}

addEvent(window, 'load', arbrelistRefreshAll, false);
