function PromoBox(containerId, displayTime, promos)
{
  // params
  this.container = $(containerId);
  this.displayTime = displayTime;
  this.promos = promos;

  // init
  this.index = 0;
  this.currentOpac = 100;
  this.speed = 20;   // must divide evenly into 100
  this.fadeDelay = 5;
  
  // methods
  this.show = show;
  this.fadeOut = fadeOut;
  this.fadeIn = fadeIn;
  this.setOpac  = setOpac;
  
  // preload all the images
  for (i = 0; i < this.promos.length; i++)
  {
    MM_preloadImages(this.promos[i].image);
    if (this.promos[i].rating_image)
    {
      MM_preloadImages(this.promos[i].rating_image);
    }
  }
  this.show();
  setTimeout(this.fadeOut.bind(this), this.displayTime);
    
  function show()
  {
    // all links
    var aTags = this.container.getElementsBySelector("a.cycle");
    for (i = 0; i < (len = aTags.length); i++)
    {
      aTags[i].href = this.promos[this.index].url;
    }
    
    // image
    this.container.getElementsBySelector("img").first().src = this.promos[this.index].image;
    
    // product name
    if (this.promos[this.index].name)
    {
      this.container.getElementsBySelector("a.name").first().innerHTML = this.promos[this.index].name;
    }
    
    // price
    if (this.promos[this.index].price)
    {
      if (this.promos[this.index].is_on_special)
      {
        price = '<span class="priceCut">' + this.promos[this.index].original_price + '</span><br />' + this.promos[this.index].price;
      }
      else
      {
        price = this.promos[this.index].price;
      }
      this.container.getElementsBySelector("div.price").first().innerHTML = price;
    }
    
    // review text
    if (this.promos[this.index].review_text)
    { 
      this.container.getElementsBySelector("a.reviewText").first().innerHTML = '"' + this.promos[this.index].review_text + '"';
    }
    
    // review star image
    if (this.promos[this.index].rating_image)
    {
      this.container.getElementsBySelector("img.ratingImage").first().src = this.promos[this.index].rating_image;
    }
  }
  
  function fadeOut()
  {
    if (this.currentOpac > 0)
    {  
      this.currentOpac -= this.speed;
      this.setOpac(this.currentOpac);
      this.fadeDelay++;
      setTimeout(this.fadeOut.bind(this), this.fadeDelay);
    }
    else if (this.currentOpac <= 0)
    {
      this.index++;
      if (this.index > (this.promos.length - 1))
      {
        this.index = 0;
      }
      this.show();
      this.fadeDelay = 0;
      this.fadeIn();
    }
  }

  function fadeIn()
  {
    if (this.currentOpac < 100)
    {
      this.currentOpac += this.speed;
      this.setOpac(this.currentOpac);
      this.fadeDelay++;
      setTimeout(this.fadeIn.bind(this), this.fadeDelay);
    }
    else if (this.currentOpac >= 100)
    {
     this.fadeDelay = 0;
     setTimeout(this.fadeOut.bind(this), this.displayTime);
    }
  }      
  
  function setOpac(opacity)
  {
    this.container.style.opacity = (opacity / 100);
    this.container.style.MozOpacity = (opacity / 100);
    this.container.style.KhtmlOpacity = (opacity / 100);
    this.container.style.filter = "alpha(Opacity=" + opacity + ")";
  }
}
