var CollectionHandler = {
  sections: [],
  curSection: null,
  timerID: null,
  animateList: [],
  init: function() {
    document.write('<style type="text/css">dl.collection dd { visibility: hidden; height: 0; overflow: hidden; } dl.collection dt { position: relative; } dl.collection dt .introText { position: absolute; font-size: 80%; padding: 3px; left: 8px; font-weight: normal; font-style: italic; } </style>');
    this.addEvent(window, 'load', this.startup, false);
  },
  startup: function() {
    var dls = document.getElementsByTagName("dl");
    for (var i=0; i<dls.length; i++) {
      if ( (' '+dls[i].className+' ').indexOf(' collection ') > -1) {
        CollectionHandler.initList(dls[i]);
      }
    }
    CollectionHandler.finalize();
		//CollectionHandler.showSection(0);
		CollectionHandler.showElement(CollectionHandler.sections[0].bodyEls[0], false);
  },
  finalize: function() {
    for (var i=0; i<this.sections.length; i++) {
      (function(section) {
        section.titleEl.style.cursor = 'pointer';

        var introText = CollectionHandler.getIntroText(section.bodyEls[0]);
        section.introTextEl = document.createElement("span");
        section.introTextEl.className = "introText";
        section.introTextEl.appendChild(document.createTextNode(introText));
        section.titleEl.appendChild(section.introTextEl);

        CollectionHandler.addEvent(section.titleEl, 'click', new Function("CollectionHandler.showSection(" + i + ");"), false);
        CollectionHandler.addEvent(section.titleEl, 'mouseover', function() { section.introTextEl.style.textDecoration = 'underline'; }, false);
        CollectionHandler.addEvent(section.titleEl, 'mouseout', function() { section.introTextEl.style.textDecoration = 'none'; }, false);
        
      })(this.sections[i]);
    }
  },
  timerCallback: function() {

    var newAnimList = [];
    
    for (var i=0; i<this.animateList.length; i++) {
      var finished = false;
      //var diff = (1.0 - this.animateList[i].pos) / 3.0; if (diff <= 0.0125) { diff = 0.0125; }
      var diff = 0.125;
      this.animateList[i].pos += diff;
      if (this.animateList[i].pos >= 1.0) { finished = true; }
      switch (this.animateList[i].type) {
      case "hide":
        if (finished) {
          this.animateList[i].el.style.height = "0";
          this.animateList[i].el.style.visibility = "hidden";
        }
        else {
          var pct = (1.0-this.animateList[i].pos);
          pct = pct * pct * pct;
          pct = Math.sin(pct * Math.PI * 0.5);
          this.animateList[i].el.style.height = Math.floor(0.5 + this.animateList[i].el.scrollHeight * pct) + "px";
        }
        break;
      case "show":
        if (finished) {
          this.animateList[i].el.style.height = "auto";
          if (window.ss && this.animateList[i].scrollToEl) { window.ss.scrollToElement(this.animateList[i].scrollToEl); }
        }
        else {
          var pct = (this.animateList[i].pos);
          pct = pct * pct * pct;
          pct = Math.sin(pct * Math.PI * 0.5);
          this.animateList[i].el.style.height = Math.floor(0.5 + this.animateList[i].el.scrollHeight * pct) + "px";
        }
        this.animateList[i].el.style.visibility = "visible";
        break;
      case "fadeIn":
        this.setOpacity(this.animateList[i].el, (this.animateList[i].pos));
        break;
      case "fadeOut":
        this.setOpacity(this.animateList[i].el, (1.0-this.animateList[i].pos));
        break;
      }
      if (!finished) {
        newAnimList[newAnimList.length] = this.animateList[i];
      }
    }
    
    this.animateList = newAnimList;
    if (this.animateList.length == 0) {
      window.clearInterval(this.timerID);
      this.timerID = null;
    }
  },
	setOpacity: function(el, opacity) {
    if (opacity == 1 && (/Firefox/.test(navigator.userAgent))) {
      el.style.opacity = "";
      if (el.style.visibility != "visible") el.style.visibility = "visible";
      return;
    }
		if (opacity == 0 && el.style.visibility != "hidden") el.style.visibility = "hidden";
		else if (el.style.visibility != "visible") el.style.visibility = "visible";
		if (window.ActiveXObject) el.style.filter = "alpha(opacity=" + opacity*100 + ")";
		el.style.opacity = opacity;
	},
  findElementAnimationIndex: function(el) {
    for (var i=0; i<this.animateList.length; i++) {
      if (this.animateList[i].el == el) {
        return i;
      }
    }
    return this.animateList.length;
  },
  showElement: function(el, scrollToEl) {
    var slot = this.findElementAnimationIndex(el);
    if (slot == this.animateList.length) {
      // New animation
      this.animateList[slot] = {
        el: el,
        type: 'show',
        pos: 0.0,
        scrollToEl : scrollToEl
      };
      el.style.visibility = "visible";
    }
    else {
      if (this.animateList[slot].type == 'show') return;
      this.animateList[slot].type = 'show';
      this.animateList[slot].pos = 1.0 - this.animateList[slot].pos;
    }
    if (this.timerID == null) {
      this.timerID = window.setInterval(function() { CollectionHandler.timerCallback(); }, 50);
    }
  },
  hideElement: function(el) {
    var slot = this.findElementAnimationIndex(el);
    if (slot == this.animateList.length) {
      // New animation
      this.animateList[slot] = {
        el: el,
        type: 'hide',
        pos: 0.0
      };
    }
    else {
      if (this.animateList[slot].type == 'hide') return;
      this.animateList[slot].type = 'hide';
      this.animateList[slot].pos = 1.0 - this.animateList[slot].pos;
    }
    if (this.timerID == null) {
      this.timerID = window.setInterval(function() { CollectionHandler.timerCallback(); }, 50);
    }
  },
  fadeInElement: function(el) {
    var slot = this.findElementAnimationIndex(el);
    if (slot == this.animateList.length) {
      // New animation
      this.animateList[slot] = {
        el: el,
        type: 'fadeIn',
        pos: 0.0
      };
      el.style.visibility = "hidden";
    }
    else {
      if (this.animateList[slot].type == 'fadeIn') return;
      this.animateList[slot].type = 'fadeIn';
      this.animateList[slot].pos = 1.0 - this.animateList[slot].pos;
    }
    if (this.timerID == null) {
      this.timerID = window.setInterval(function() { CollectionHandler.timerCallback(); }, 50);
    }
  },
  fadeOutElement: function(el) {
    var slot = this.findElementAnimationIndex(el);
    if (slot == this.animateList.length) {
      // New animation
      this.animateList[slot] = {
        el: el,
        type: 'fadeOut',
        pos: 0.0
      };
      el.style.visibility = "visible";
    }
    else {
      if (this.animateList[slot].type == 'fadeOut') return;
      this.animateList[slot].type = 'fadeOut';
      this.animateList[slot].pos = 1.0 - this.animateList[slot].pos;
    }
    if (this.timerID == null) {
      this.timerID = window.setInterval(function() { CollectionHandler.timerCallback(); }, 50);
    }
  },
  initList: function(list) {
    var kids = list.childNodes;
    
    for (var i=0; i<kids.length; i++) {
      if (kids[i].nodeName.toLowerCase() == 'dt') {
        this.sections[this.sections.length] = {
          titleEl: kids[i],
          bodyEls: [],
          visible: false
        };
      }
      else if (kids[i].nodeName.toLowerCase() == 'dd') {
        if (this.sections.length > 0) {
          this.push(this.sections[this.sections.length-1].bodyEls, kids[i]);
        }
      }
    }
  },
  push: function(arr, el) {
    arr[arr.length] = el;
  },
  showSection: function(sectionIdx) {
    //alert("Showing section " + sectionIdx + "[count=" + this.sections.length + "] [current = " + this.curSection + "]");
    
    if (this.curSection != null) {
      for (var i=0; i<this.sections[this.curSection].bodyEls.length; i++) {
        //this.sections[this.curSection].bodyEls[i].style.display = 'none';
        
        /*
        with (this.sections[this.curSection].bodyEls[i].style) {
          height = "0";
          visibility = "hidden";
        }
        */
        
        this.hideElement(this.sections[this.curSection].bodyEls[i]);
      }
      //this.sections[this.curSection].introTextEl.style.visibility = 'visible';
      this.sections[this.curSection].introTextEl.style.textDecoration = '';
      //this.fadeInElement(this.sections[this.curSection].introTextEl);
      if (this.curSection == sectionIdx) { this.curSection = null; return; }
    }
    
    this.curSection = sectionIdx;
    
    //alert(this.sections[this.curSection]);
    
    if (this.curSection != null) {
      for (var i=0; i<this.sections[this.curSection].bodyEls.length; i++) {
        //this.sections[this.curSection].bodyEls[i].style.display = 'block';
        
        /*
        with (this.sections[this.curSection].bodyEls[i].style) {
          height = "auto";
          visibility = "visible";
        }
        */
        this.showElement(this.sections[this.curSection].bodyEls[i], this.sections[this.curSection].titleEl);
      }
      //this.sections[this.curSection].introTextEl.style.visibility = 'hidden';
      this.sections[this.curSection].introTextEl.style.textDecoration = 'underline';
      //this.fadeOutElement(this.sections[this.curSection].introTextEl);
      
      //if (window.ss) { window.ss.scrollToElement(this.sections[this.curSection].introTextEl); }
    }
  },
  getIntroText: function(element) {
    var maxLen = 75;
    //var text = CollectionHandler.extractText(element).split("\n")[0];
    var text = CollectionHandler.extractText(element);
    
    if (text.length <= maxLen) {
      return text;
    }
    return text.substr(0, maxLen-1) + "...";
  },
  extractText: function(element) {
  	if(typeof element == "string")
  		return element;
  	else if(typeof element == "undefined")
  		return element;
  	//else if(element.innerText)
  	//	return element.innerText;

  	var text = "";
  	var kids = element.childNodes;
  	for(var i=0;i<kids.length;i++)
  	{
  		if(kids[i].nodeType == 1)
  		text += ' ' + this.extractText(kids[i]);
  		else if(kids[i].nodeType == 3)
  		text += ' ' + kids[i].nodeValue;
  	}

  	return text;
  },
	addEvent: function(elm, evType, fn, useCapture){
		if (elm.addEventListener)
		{
			elm.addEventListener(evType, fn, useCapture);
			return true;
		} else if (elm.attachEvent) {
			var r = elm.attachEvent('on' + evType, fn);
			return r;
		} else {
			elm['on' + evType] = fn;
		}
	}
};
CollectionHandler.init();