/*
   CVS version:
   $Id: corefader.js,v 1.3 2009/03/31 11:21:47 john Exp $
   $Name: HEAD $
   
   Disclaimer
   
   While we make every effort to ensure that this code is fit for its intended
   purpose, we make no guarantees as to its functionality. CoreTrek AS will
   accept no responsibility for the loss of data or any other damage or
   financial loss caused by use of this code.
   
   Copyright
   
   This programming code is copyright of CoreTrek AS. Permission to run this
   code is given to approved users of CoreTrek's publishing system CorePublish.
   
   This source code may not be copied, modified or otherwise repurposed for use
   by a third party without the written permission of CoreTrek AS.
   
   Contact webmaster@coretrek.com for information.
  
*/

/*
   CoreFader
   
   ============================================================================
   IMPORTANT! This JavaScript is dependent on Prototype and Scriptaculous.
   ============================================================================
   
   Fades out a div, copies content from another div and fades back in.
   
   Example use:
   fader = new CoreFader('destination');
   fader.fadeTo('source1');
   
   This will use the default fade interval of 0.5 seconds.
   
   It is also possible to start a cycle toggeling between a given set of
   elements:
   
   fade.fadeBetween([element1, element2, element3], 5);
   
   This will start an infinite loop toggeling between the 3 element. There
   will be a 5 second pause between each toggle. The default pause, if no pause,
   is specified is 10 seconds.
      
*/

var CoreFader = Class.create({
   
   /**
    * Initialize the fader.
    *
    * @arg element - the container element
    * @arg number duration - the duration of each fade/appear, default 0.5 sec
    */
   initialize: function(element, duration) {
       this.element = $(element);
       
       if(typeof duration != 'undefined') {
           this.duration = duration;
       } else {
           this.duration = 0.5;
       }
   },
   
   /**
    * Fade a given elements content into the fade container
    */
   fadeTo: function(element) {
       // If there is an effect in progress we cancel it and start a new one
       if(typeof this.effect == 'object' && this.effect.state != 'finished') {
           this.effect.cancel();
       }
       element = $(element);
       this.effect = new Effect.Opacity(this.element, {
           from: 1.0,
           to: 0.0,
           duration: this.duration,
           queue: 'end',
           limit: 1,
           afterFinish: function() {
               this.element.update(element.innerHTML);
               this.effect = new Effect.Opacity(this.element, {
                   from: 0.0,
                   to: 1.0,
                   duration: this.duration,
                   queue: 'end',
                   limit: 1
               })
           }.bind(this)
       });
       
   },
   
   /**
    * Fade between an array of elements. Pause for the given amount
    * of seconds between each element
    *
    * @arg array elements - the elements to toggle between
    * @arg number pause - the pause between the each element toggle
    */
   fadeBetween: function(elements, pause) {
       // Default to 5 second delay between fades
       if(typeof pause == 'undefined') {
           pause = 10;
       }
       
       var interval = (this.duration * 2) + pause;
       elements.next = function() {
           if(typeof this.currentIndex == 'undefined') {
               this.currentIndex = 0;
           }
           
           if(this.currentIndex >= elements.length) {
               this.currentIndex = 0;
           }
               
           this.currentElement = this[this.currentIndex];
           this.currentIndex++;
           return this.currentElement;
       }.bind(elements);
       
       // Start the periodical update
       new PeriodicalExecuter(function(pe) {
           // Reset the interval to allow for fade/appear
           this.frequency = interval;
           this.fadeTo(elements.next());
       }.bind(this), pause);
   }
    
});

