function Scroller (el, items, type, delay, step)
{
   this.el = get_by_id(el);

   this.items = items;
   this.type = type;
   this.delay = delay * 1000;
   this.step = step;

   this.id = ++Scroller.prototype.ids;

   this.init();
}

Scroller.prototype = {
   ids : 0, id : 0,
   items : [],
   type : 1, delay : 1, step : 5,
   cur : 1, l : 0, r : 0, t : 0,
   b : 0, w : 0, h : 0,
   visible : null, hidden : null,
   stopped : false, progress : 0,

   init : function ()
   {
      style_el(this.el, {overflow : 'hidden', position : 'relative'});

      if (!this.el.style.width)
         style_el(this.el, {width : '100%'});

      if (!this.el.style.height)
         style_el(this.el, {height : '1em'});

      var me = this;

      this.t = parseInt(CurrentStyle(this.el, isIE ? 'paddingTop' : 'padding-top'));
      this.l = parseInt(CurrentStyle(this.el, isIE ? 'paddingLeft' : 'padding-left'));
      this.r = parseInt(CurrentStyle(this.el, isIE ? 'paddingRight' : 'padding-right'));
      this.b = parseInt(CurrentStyle(this.el, isIE ? 'paddingBottom' : 'padding-bottom'));
      this.w = (this.el.offsetWidth - this.l - this.r);
      this.h = (this.el.offsetWidth - this.t - this.b);

      if (this.type == 0)
      {
         var s1 = {display : 'none'};
         var s2 = {top : this.t + 'px', left : this.l + 'px'};
      }
      else if (this.type == 1)
      {
         var s1 = {top : this.t + 'px', left : this.l + 'px'};
         var s2 = {top : this.el.offsetHeight + 'px', left : this.l + 'px'};
      }
      else if (this.type == 2)
      {
         var s1 = {top : this.t + 'px', left : this.l + 'px'};
         var s2 = {top : (-1 * this.el.offsetHeight) + 'px'};
      }
      else if (this.type == 3)
      {
         var s1 = {left : this.l + 'px', top : this.t + 'px'};
         var s2 = {left : this.el.offsetWidth + 'px', top : this.t + 'px'};
      }
      else if (this.type == 4)
      {
         var s1 = {left : this.l + 'px', top : this.t + 'px'};
         var s2 = {left : (-1 * this.el.offsetWidth) + 'px', top : this.t + 'px'};
      }

      s1.height = s2.height = this.h + 'px';
      s1.width = s2.width = this.w + 'px';
      s1.position = s2.position = 'absolute';

      this.visible = make_el('DIV', {style : s1, className : 'scroller-item', innerHTML : ''}, this.el);
      this.hidden = make_el('DIV', {style : s2, className : 'scroller-item', innerHTML : this.items[0]}, this.el);

      this.stopped = false;
      this.cur = 1;

      addEvent(this.el, 'mouseover', function (e) { me.mouseover(e) }, false);
      addEvent(this.el, 'mouseout', function (e) { me.mouseout(e) }, false);

      if (this.type == 0)
      {
         set_opacity(this.hidden, 0);
         window.setTimeout(function () { me.fadeIn(); }, 50);
      }
      else
         window.setTimeout(function () { me.move(); }, 50);
   },

   fadeIn : function ()
   {
      var me = this;
      var fadeIn = function ()
      {
         if (me.progress >= 100)
         {
            me.progress = 100;
            set_opacity(me.hidden, 100);
            window.clearInterval(fadeInId);
         }
         else
         {
            me.progress += 10;
            set_opacity(me.hidden, me.progress);
         }
      }

      this.progress = 0;
      var fadeInId = window.setInterval(fadeIn, 50);
      window.setTimeout(function () { me.fadeOut(); }, this.delay);
   },

   fadeOut : function ()
   {
      var me = this;
      var fadeOut = function ()
      {
         if (me.progress <= 0)
         {
            me.progress = 0;
            set_opacity(me.hidden, 0);
            window.clearInterval(fadeOutId);
         }
         else
         {
            me.progress -= 10;
            set_opacity(me.hidden, me.progress);
         }
      }

      if (this.stopped == true)
      {
         window.setTimeout(function () { me.fadeOut() }, 100);
      }
      else
      {
         this.progress = 100;
         var fadeOutId = window.setInterval(fadeOut, 50);

         window.setTimeout(function () {
            me.hidden.innerHTML = me.getNextItem();
            me.fadeIn();
         }, 1000);
      }
   },

   move : function ()
   {
      var me = this;

      if (this.type == 1 && parseInt(this.hidden.style.top) > (this.step + this.t))
      {
         this.visible.style.top = (parseInt(this.visible.style.top) - this.step) + 'px';
         this.hidden.style.top = (parseInt(this.hidden.style.top) - this.step) + 'px';
         window.setTimeout(function () { me.move(); }, 50);
      }
      else if (this.type == 2 && parseInt(this.hidden.style.top) < (this.step - this.t))
      {
         this.visible.style.top = (parseInt(this.visible.style.top) + this.step) + 'px';
         this.hidden.style.top = (parseInt(this.hidden.style.top) + this.step) + 'px';
         window.setTimeout(function () { me.move(); }, 50);
      }
      else if (this.type == 3 && parseInt(this.hidden.style.left) > (this.step + this.l))
      {
         this.visible.style.left = (parseInt(this.visible.style.left) - this.step) + 'px';
         this.hidden.style.left = (parseInt(this.hidden.style.left) - this.step) + 'px';
         window.setTimeout(function () { me.move(); }, 50);
      }
      else if (this.type == 4 && parseInt(this.hidden.style.left) < 0)
      {
         this.visible.style.left = (parseInt(this.visible.style.left) + this.step) + 'px';
         this.hidden.style.left = (parseInt(this.hidden.style.left) + this.step) + 'px';
         window.setTimeout(function () { me.move(); }, 50);
      }
      else
      {
         this.swap();
         window.setTimeout(function () { me.pause(); }, this.delay);
      }
   },

   pause : function ()
   {
      var me = this;

      if (this.stopped == true) // mouseover so keep holding
         window.setTimeout(function () { me.pause(); }, 100);
      else
      {
         this.hidden.innerHTML = this.getNextItem();
         this.move();
      }
   },

   swap : function ()
   {
      if (this.type == 1)
      {
         this.hidden.style.top = this.t + 'px';
         this.visible.style.top = this.el.offsetHeight + 'px';
      }
      else if (this.type == 2)
      {
         this.hidden.style.top = this.t + 'px';
         this.visible.style.top = (-1 * this.el.offsetHeight) + 'px';
      }
      else if (this.type == 3)
      {
         this.hidden.style.left = this.l + 'px';
         this.visible.style.left = this.el.offsetWidth + 'px';
      }
      else if (this.type == 4)
      {
         this.hidden.style.left = this.l + 'px';
         this.visible.style.left = (-1 * this.el.offsetWidth) + 'px';
      }

      var temp = this.visible;
      this.visible = this.hidden;
      this.hidden = temp;
   },

   getNextItem : function ()
   {
      if (this.cur == (this.items.length))
         this.cur = 0;

      return this.items[this.cur++];
   },

   mouseover : function (e)
   {
      this.stopped = true;
   },

   mouseout : function (e)
   {
      this.stopped = false;
   }
}