HM.FullScreenFader = Class.create({
  
  initialize: function() {
    if(!(this.element = $(arguments[0]))) return false;
    
    this.array = this.element.select("img");
    if(!this.array.size())  return;
    
    if(this.element.HM_AutoFader_initialized) return;
    
    this.options = Object.extend({
      fadeEventsHolder    : null,
      scrollElement       : null,
      opacity             : 0.6,
      duration            : 0.6,
      transitionTime      : 2,
      activeID            : 'hm_activeFaderElement'
    }, arguments[1] || {});
    
    this.pointer  = 0;

    this.array.each(function(el,index) {
      el.setStyle({
        position: 'absolute',
        top       : '0px',
        left      : '0px',
        display   : index ? 'none' : 'block',
        zIndex    : index ? 0 : 2 
      });
    }.bind(this));
    
    this.array[0].id = this.options.activeID;
    
    if(this.options.fadeEventsHolder = $(this.options.fadeEventsHolder)) {
      this.initializeEvents();
    }
    
    if($(this.options.scrollElement)) this.initScroller();

    this.element.HM_AutoFader_initialized = true;
    
    this.start();
    
  },
  
  doFade: function() {
    if(this.array[this.pointer]) {

      var _old = $(this.options.activeID),
          _new = this.array[this.pointer];
      
      _old.setStyle({
        zIndex : 0
      });
      _new.setStyle({
        zIndex    : 2
      });
       _old.id = this._uniqueString("notActive");
      _new.id  = this.options.activeID;
      
      new Effect.Appear(_new, {
        duration: this.options.duration,
        afterFinish: function() {
          _old.hide();
          
          if(this.areEvents) {
            this.fadeEvents.each(function(el,index) {
              if(index == this.pointer) {
                el.addClassName('currentFadeItem');
                this.appear(el);
                if(this.element.HM_Scroller_initialized) {
                  this.Scroller.doMoveToElement(el);
                }
              }else{
                el.removeClassName('currentFadeItem');
                this.fade(el,this.options.opacity);
              }
            }.bind(this));
          }
          
        }.bind(this)
      });

    }else {
      this.stop();
      this.start();
    }
  },
  
  doFadeToFirst: function() {
    this.setPointer(0);
    this.doFade();
    this.pauze();
    this.start();
  },
  
  toFirst: function() {
    this.doFadeToFirst();
  },
  
  toStart: function() {
    this.doFadeToFirst();
  },
  
  doFadeToLast: function() {
    this.setPointer(this.array.size() - 1);
    this.doFade();
    this.pauze();
    this.start();
  },
  
  toLast: function() {
    this.doFadeToLast();
  },
  
  toEnd: function() {
    this.doFadeToLast();
  },
  
  start: function() {
    if(this.array.size()) {
    
      if(this.timeout) {
        this.timeout.stop();
      }
      
      this.timeout = new PeriodicalExecuter(function() {
        this.increment();
        this.doFade();
      }.bind(this),this.options.transitionTime);
      
    }
  },
  
  pauze: function() {
    if(this.timeout) {
      this.timeout.stop();
    }
  },
  
  stop: function() {
    this.pauze();
    this.resetPointer();
  },
  
  setPointer: function() {
    var pos = arguments[0] || 0;
    if(pos < this.array.size() && pos >= 0) {
      this.pointer = pos;
    }else {
      this.resetPointer();
      this.start();
    }
  },
  
  decrement: function() {
    this.setPointer(this.pointer-1);
  },
  
  increment: function() {
    this.setPointer(this.pointer+1);
  },
  
  resetPointer: function() {
    this.pointer = 0;
  },
      
  moveScroller: function(event) {
    var element = Event.element(event);
    this.Scroller.doMoveToElement(element);
  },
  
  onClick: function(event) {
    var element = Event.element(event),
        pos;
    
    if(element.hasClassName('currentFadeItem')) return;
    
    this.fadeEvents.each(function(el,index) {
      if(el == element) {
        pos = index;
        return;
      }
    });
    
    this.setPointer(pos);
    this.doFade();
    this.pauze();
    this.start();
  },
  onMouseOver: function(event) {
    var element = Event.element(event)
    this.appear(element);
  },
  onMouseOut: function(event) {
    var element = Event.element(event),
        to      = this.options.opacity;

    this.fade(element,to);
  },
  
  appear: function(element) {
    new Effect.Appear(element,{
      duration:  0.5
    });
  },
  
  fade: function(element,to) {
    if(element.hasClassName('currentFadeItem')) return;
    new Effect.Fade(element,{
      duration: 0.5,
      to      : to || 0.5
    });
  },
  
  initScroller: function() {
    this.Scroller = new HM.NewsScroller(this.options.scrollElement, {
      direction: "horizontal",
      interval    : 1500,
      isDraggable : true,
      autostart   : false,
      autorewind  : false
    });
    
    if(this.areEvents) {
      
      this.fadeEvents.each(function(el) {
        Event.observe(el, "click",this.moveScroller.bindAsEventListener(this));
      }.bind(this));
      
    }
    
    this.element.HM_Scroller_initialized = true;
  },
  
  initializeEvents: function() {
    if(!(this.fadeEvents = $(this.options.fadeEventsHolder).select("img"))) return;
    
    this.fadeEvents.each(function(el, index) {
      if(index == 0) el.addClassName('currentFadeItem');
      el.addClassName('fadeItem');
      if(!el.hasClassName('currentFadeItem')) {
        el.setStyle({
          opacity: this.options.opacity
        });
      }
      
      Event.observe(el, "click",this.onClick.bindAsEventListener(this));
      Event.observe(el, "mouseover",this.onMouseOver.bindAsEventListener(this));
      Event.observe(el, "mouseout",this.onMouseOut.bindAsEventListener(this));
    }.bind(this));
    this.areEvents = true;
  },
  
  images: function() {
    return this.array;
  },
  
  _uniqueString: function() {
    var string = arguments[0] || 'empty';
    return string + new Date().getTime();
  },
  
  nop: function() {
  }
  
});
