/* Cycle
   By Paul Stoaks
   Allows cycling through a list of content in a div.

   Divs that will contain cyclable content should have the "cycle" attribute
   with a numeric value which is the display period in seconds.

   Each displayable item in the div will be cycled through.  Each one should be
   positioned explicitly for display within the div.

   For example:
      <div class="foo" cycle="5">
         <p style="position: absolute; top: 0px; left: 0px;">
            Hello
         </p>
         <p style="position: absolute; top: 3px; left: 5px;">
            World!
         </p>
      </div>

   NOTE: NOTE:  The comments labeled IE are the "right" code according
   to the W3C DOM standard.  The code left in is what "almost" works
   in IE7.

*/

var xhtmlNS = "http://www.w3.org/1999/xhtml";

// Add a listener to onLoad so that we can initialize our functionality.
if (typeof document.attachEvent!='undefined') {
   window.attachEvent('onload',init);
}
else {
   window.addEventListener('load',init,false);
}

var cycleObjs = new Array(); // List of cycle objects

// Cycle Object

// Constructor.
//    div : The div that has the content to be cycled.
//
 function Cycle(div) {
   this.div = div;
   this.idx = 0;  // Last/current index displayed
   this.period = parseFloat(this.div.getAttribute("cycle")); // In seconds
   this.tickCnt = 0;  // Current tick count
   this.elements = new Array();  // Elements that we can cycle through
   this.method = "fade"; // Visual change method, (flip, wipe, or fade)
   this.op = 0;       // Opacity percentage

   // Loop through the nodes in the div and turn off visibility for all but one
   var oneVis = false;
   for (var i=0; i < this.div.childNodes.length; i++) {
     if ( typeof this.div.childNodes[i].style != 'undefined' ) {
       if (!oneVis) {
         this.div.childNodes[i].style.visibility = 'visible';
         oneVis = true;
       }
       else
         this.div.childNodes[i].style.visibility = 'hidden';
       this.elements.push(this.div.childNodes[i]);
     }
   }

//     alert("Cyclable elements: "+this.elements.length);

 } // ctor()

 Cycle.prototype.tick = function(idx) {
   if (++this.tickCnt % this.period == 0) {
     if (this.method == "flip")
       this.flip();
     else if (this.method == "wipe")
       this.wipe();
     else if (this.method == "fade")
       this.startFade(idx);
     else
       alert("Unknown visual change method '"+this.method+"'.  Must be 'flip', 'fade', or 'wipe'");
   }
 } // tick()

 Cycle.prototype.startFade = function(idx) {
   var nextIdx = (this.idx+1) % this.elements.length;
   // Set the opacity of the new item to 0 and make it visible
   this.op = 0;
   this.elements[nextIdx].style.filter = 'alpha(opacity='+this.op+')';
   this.elements[nextIdx].style.opacity = this.op/100.0;
   this.elements[nextIdx].style.visibility = 'visible';
   this.fade(idx);
 } // startFade()

 Cycle.prototype.fade = function(idx) {
   // Reduce the opacity of the outgoing element and increase the opacity of
   // the incoming element, then reset the timer.
   var nextIdx = (this.idx+1) % this.elements.length;
   this.op += 4;
   this.op = this.op > 100 ? 100 : this.op;

   this.elements[this.idx].style.filter = 'alpha(opacity='+(100-this.op)+')';
   this.elements[this.idx].style.opacity = 1.0 - this.op/100.0;
//     alert(this.elements[this.idx].style.opacity);
   
   this.elements[nextIdx].style.filter = 'alpha(opacity='+this.op+')';
   this.elements[nextIdx].style.opacity = this.op/100.0;
//     alert(this.elements[this.idx].style.opacity);
   
   if (this.op < 100)
      setTimeout("cycleObjs["+idx+"].fade("+idx+")", 20);
   else {
      this.elements[this.idx].style.visibility = 'hidden';
      this.idx = nextIdx;
   }
 } // fade()

 Cycle.prototype.flip = function() {
   this.elements[this.idx++].style.visibility = 'hidden';
   this.idx = this.idx % this.elements.length;
   this.elements[this.idx].style.visibility = 'visible';
 } // flip()

 Cycle.prototype.wipe = function() {
 } // wipe()

 function oneSecTick() {
   // Loop through cycle objects and do it.
   for (var i=0; i < cycleObjs.length; i++) {
     cycleObjs[i].tick(i);
   }

  setTimeout("oneSecTick()", 1000);
 } // oneSecTick()


function init() {
  // Go through the divs in the document and setup the cycles for
  // each one that has the "cycle" attribute.
  var divs = document.getElementsByTagName("div");

  for (var i=0; i < divs.length; i++) {
    if (divs[i].getAttributeNode("cycle") != null) {
      // This is a div that should be cycled.
      // Add this object to the list
      cycleObjs.push(new Cycle(divs[i]));
    }
  }
  
  // Set the timer to get things going
  setTimeout("oneSecTick()", 1000);
  
} // init()


