/* Constants */

var STATIC_STRING_TOC_SYNC = "TOC Sync";
var STATIC_STRING_TOC_SYNC_HELP = "Refresh / Show current topic";

/** TOC item element name. */
var TOC_ELEMENT_ITEM = "li";
/** TOC block element name. */
var TOC_ELEMENT_BLOCK = "ul";
/** TOC controller element name. */
var TOC_ELEMENT_CONTROL = "span";
/** TOC link element name. */
var TOC_ELEMENT_LINK = "a";
/** TOC controller expanded symbol. */
var TOC_SYMBOL_EXPANDED = "-";
/** TOC controller collapsed symbol. */
var TOC_SYMBOL_COLLAPSED = "+";

/* Move to common. */
var TOC_CLASS_ACTIVE = "on3";
var TOC_CLASS_COLLAPSED = "toc-controller-closed";
var TOC_CLASS_EXPANDED = "toc-controller-open";
var TOC_CLASS_CONTROL = "toc-controller";
var TOC_CLASS_SPACE = "toc-space";
var TOC_DISPLAY_COLLAPSED = "none";
var TOC_DISPLAY_EXPANDED = "block";

/* Variables */

/** Should TOC be initially fully collapsed. */
var initialCollapse = true;
/** Should node's children be collapsed upon expanding a node. */
var childCollapse = false;
/** Synchronize TOC automatically on link traversal. */
var automaticSync = true;
/** Add controllers to TOC on load. */
var addControllers = true;

/**
 * Add TOC controllers.
 */
function addTocControllers() {
    var nl = getFirstElementByClassName(document, "nav3", "div");
    if (nl === null) {
      return;
    }
    if (addControllers) {
        var lis = nl.getElementsByTagName(TOC_ELEMENT_ITEM);
        for (var j = 0; j < lis.length; j++) {
            var li = lis[j];
            //var a = li.getElementsByTagName(TOC_ELEMENT_LINK)[0];
            var a = getFirstChildElementByTagName(li, TOC_ELEMENT_LINK);
            if (a != null) {
                  var uls = li.getElementsByTagName(TOC_ELEMENT_BLOCK);        
                  if (uls.length !== 0) {
                      // add controller
                      var c = document.createElement(TOC_ELEMENT_CONTROL);
                      addClass(c, TOC_CLASS_CONTROL);
//                          if (initialCollapse) {
//                            addClass(c, TOC_CLASS_COLLAPSED);
//                              c.appendChild(document.createTextNode(TOC_SYMBOL_EXPANDED));
//                          }  else {
                          addClass(c, TOC_CLASS_EXPANDED);
                          c.appendChild(document.createTextNode(TOC_SYMBOL_COLLAPSED));
//                          }
                      attachEventListener(c, "click", toggleHandler);
                      li.insertBefore(c, li.firstChild);
                      // hide kids
                      if (initialCollapse) {
                          collapseChildBlocks(li);
                      }
                  } else {
                      // add space
                      var sp = document.createElement(TOC_ELEMENT_CONTROL);
                      addClass(sp, TOC_CLASS_SPACE);
                      var pls = document.createTextNode("x");
                      sp.appendChild(pls);
                      li.insertBefore(sp, li.firstChild);                        
                  }
                  // add state
                  if (!automaticSync) {
                      attachEventListener(a, "click", tocItemClickHandler);
                  }
            }
        }
    // hide kids
    } else if (initialCollapse) {
        var lis = nl.getElementsByTagName(TOC_ELEMENT_ITEM);
        for (var j = 0; j < lis.length; j++) {
            var li = lis[j];
            collapseChildBlocks(li);
        }
      
    }
    /*
    } else if (childCollapse) {
        var nl = getFirstElementByClassName(document, "nav3", "div");
        if (nl !== null) {
            var tocRoot = getFirstChildElementByTagName(nl, TOC_ELEMENT_BLOCK);
            if (tocRoot !== null) {
                var li = getChildElementsByTagName(tocRoot, TOC_ELEMENT_ITEM);
                for (var i = 0; i < li.length; i++) {
                    collapseChildBlocks(li[i]);
                }
            }
        }
    }
    */   
}

/**
 * Collapse child TOC blocks.
 *
 * @param li TOC item whose child TOC blocks to collapse.
 */
function collapseChildBlocks(li) {
    for (var k = li.firstChild; k != null; k = k.nextSibling) {
        if (k.nodeType == 1 && k.nodeName.toLowerCase() == TOC_ELEMENT_CONTROL && isClass(k, TOC_CLASS_CONTROL)) {
            tocNodeCollapse(k);
            break;  
        }
        /*
         else if (k.nodeType == 1 && k.nodeName.toLowerCase() == TOC_ELEMENT_BLOCK) {
            k.style.display = "none";
        }
        */
    }
}

/**
 * Toggle child node display.
 */
function toggleHandler(event) {
    toggle(getTargetNode(event));
}

/**
 * Set current node as current.
 */
function tocItemClickHandler(event) {
    highlightTocItem(getTargetNode(event));
    //toggleHandler(getTargetNode(event).previousNodeThatIsController)
}

/**
 * Generate TOC synchronization button.
 */
function addSyncButton() {
    if (!automaticSync) {
        //var b = document.createElement("img");
        //b.src = "images/xhtml/e_synch_nav.gif";
        var b = document.createElement("button");
        b.appendChild(document.createTextNode(STATIC_STRING_TOC_SYNC));
        b.title = STATIC_STRING_TOC_SYNC_HELP;
        addClass(b, "button-manual_sync");
        attachEventListener(b, "click", manualSyncTocHandler);
        var bc = document.createElement("div");
        addClass(bc, "button-manual_sync-container");
        bc.appendChild(b);
        var nav3 = getFirstElementByClassName(document, "nav3", "div");
        if (nav3 !== null) {
          nav3.insertBefore(bc, nav3.firstChild);
        }
    }
}

/**
 * Button listener for manual TOC sync.
 */
function manualSyncTocHandler(event) {
    startProcess("Synchronizing TOC");
    var b = getTargetNode(event);
    var baseUrl = getBaseUrl();
    var contentUrl = String(window.top.frames.main.location.href);
    var href = getRelativeUrl(contentUrl, baseUrl);
    findTocItem(href);
    endProcess("Done");    
}

/**
 * Initialize TOC.
 */
function initToc() {
    if (tocSupported) {
        startProcess("Initializing TOC");
        addTocControllers();
        addSyncButton();
        endProcess("Done");
    }    
}

/* Move to common. */

/**
 * Toggle child node display.
 *
 * @param n Target node of the event.
 */
function toggle(n) {
	if (isClass(n, TOC_CLASS_EXPANDED)) {
		tocNodeCollapse(n);
	} else {
	  tocNodeExpand(n);
	}
}

/**
 * Expand TOC node.
 *
 * @param n TOC node
 */
function tocNodeExpand(n, collapseOverride) {
  if (collapseOverride === undefined) {
    collapseOverride = true;
  }
  n.firstChild.data = TOC_SYMBOL_EXPANDED;
  switchClass(n, TOC_CLASS_EXPANDED, TOC_CLASS_COLLAPSED);
  var ul = getNextSiblingByTagName(n.nextSibling, TOC_ELEMENT_BLOCK);
  if (ul !== null) {
    /*
    if (childCollapse && collapseOverride) {
      var li = getChildElementsByTagName(ul, "li");
      for (var i = 0; i < li.length; i++) {
        collapseChildBlocks(li[i]);
      }
    }
    */
    ul.style.display = TOC_DISPLAY_EXPANDED;
    //switchClass(ul, "toc-expanded", "toc-collapsed");
  }
}

/**
 * Collapse TOC node.
 *
 * @param n TOC node
 */
function tocNodeCollapse(n) {
  n.firstChild.data = TOC_SYMBOL_COLLAPSED;
  switchClass(n, TOC_CLASS_COLLAPSED, TOC_CLASS_EXPANDED);
  var ul = getNextSiblingByTagName(n.nextSibling, TOC_ELEMENT_BLOCK);
  if (ul !== null) {
    ul.style.display = TOC_DISPLAY_COLLAPSED;
    //switchClass(ul, "toc-collapsed", "toc-expanded");
  }
}

var processStart;
var processEnd;
var processDuration

/**
 * Signal start of processing.
 *
 * @param message Message description of the process start
 */
function startProcess(message) {
    processStart = new Date();
    window.status = (message === undefined ? "" : message);    
}

/**
 * Signal end of processing.
 *
 * @param message Message description of the process result
 */
function endProcess(message) {
    processEnd = new Date();
    window.status = (message === undefined ? "" : message);
    processDuration = processEnd - processStart;
}
