/*
 * Image rotation script
 *
 * @author Andrew Maughan
 */

  function ImageRotator()
  {
    // ------------------------------------------------------------------------------
    // Configurable properties
    // ------------------------------------------------------------------------------
    this.fade_duration       = 1 // Time (in seconds) the whole fading takes place
    this.view_duration       = 3 // Time (in seconds) between transitions
    // ------------------------------------------------------------------------------
    
    var prv_img_position    = 1;
    var prv_img_opacity     = 0;
    var prv_opacity_step    = 100 / (this.fade_duration * 1000);
    var prv_image_list;
    var prv_link_list;
    var prv_preloaded;
    var prv_max_height      = 0;
    
    // Initialisation
    // ------------------------------------------------------------------------------
    // This takes an element defined by an id, and places the relevant stuff inside.
    this.init = function (container_id, image_list, url_list)
    {
      // Check for a valid element and array.
      if ($(container_id) == null)
      {
        throw "Container element does not exist";
      }
      if (typeof image_list != 'object')
      {
        throw "Image URLs required as an object";
      }
      
      // Create an inner container for the images, which we will set to position: relative.
      new Insertion.Top(container_id, '<div id="rotator-inner"></div>');
      $('rotator-inner').setStyle({ 'position': 'relative' });
      
      // Create two DIV tags and an A tag inside the container.
      new Insertion.Bottom('rotator-inner', '<div id="img_rotate_back"></div>');
      new Insertion.Bottom('rotator-inner', '<div id="img_rotate_front"></div>');
      new Insertion.Bottom('rotator-inner', '<a href="" id="img_rotate_url"></a>');
      
      // Preload the images used for rotating, then set the starting front and back images.
      prv_image_list = image_list;
      prv_link_list = url_list;
      _preloadImages();
      $('img_rotate_front').setStyle({backgroundImage : 'url("' + prv_image_list[0] + '")'});
      $('img_rotate_back').setStyle({backgroundImage : 'url("' + prv_image_list[1] + '")' });
      $('img_rotate_url').href   = prv_link_list[0];
      $('rotator-inner').setStyle({height :  prv_max_height + 'px'});
    }
    
    // Start rotating 
    // ------------------------------------------------------------------------------
    this.begin = function ()
    {
      // Do not bother with rotation if there are less than two images.
      if (prv_image_list.length >= 2)
      {
        new PeriodicalExecuter(_rotate, this.view_duration + this.fade_duration);
      }
    }

    function _rotate()
    {
      // This function is called after the pause between transitions.
      $('img_rotate_url').href = prv_link_list[prv_img_position];
      new PeriodicalExecuter(_processRotate, prv_opacity_step);
    }
    
    function _processRotate(pe)
    {
      // This function handles the transition between images.
      // The front image fades out to reveal the next image, which is then swapped with
      // the previous image. The image after that is placed behind the current one.
      
      $('img_rotate_front').setStyle({ 'opacity': 1 - prv_img_opacity });
      prv_img_opacity += prv_opacity_step;
      
      // When the front image is completely transparent...
      if (prv_img_opacity >= 1)
      {
        // stop the function from periodically executing
        pe.stop();
        
        // reset the opacity value for the next time
        prv_img_opacity = 0;
        
        // display the image previously at the back in front
        $('img_rotate_front').setStyle({backgroundImage : 'url("' + prv_image_list[prv_img_position] + '")'});
        $('img_rotate_front').setStyle({ 'opacity': 1 });
        
        // figure out which image comes next.
        prv_img_position++;
        if (typeof prv_image_list[prv_img_position] == 'undefined')
        {
          prv_img_position = 0;
        }
        $('img_rotate_back').setStyle({backgroundImage : 'url("' + prv_image_list[prv_img_position] + '")'});
      }
    }
  
    function _preloadImages() {
      // This function handles the pause between transitions.
      
      // We have to preload the images, otherwise IE6 has a nasty flickering effect.
      prv_preloaded = new Object();
      
      for (i = 0; i < prv_image_list.length; i++)
      {
        prv_preloaded[i] = new Image();
        prv_preloaded[i].src = prv_image_list[i];
        if (prv_preloaded[i].height > prv_max_height)
        {
          prv_max_height = prv_preloaded[i].height;
        }
      }
    }
    
  }
