
var Overlay = new Class({

  Implements: [Options, Events],
  
  options: {
    opacity: 0.5,
    className: 'overlay',
    background: '',
    zIndex: 100,
    closeByClick: true
  },

  initialize: function(options) {
    this.setOptions(options);
    this.overlay = null;
    this.listeners = {
      resize: this.resize.bind(this),
      click: this.click.bind(this)
    };
  },

  toggleListeners: function(state) {
    var task = state ? 'addEvent' : 'removeEvent';
    window[task]('resize', this.listeners.resize);
    window[task]('scroll', this.listeners.resize);
  },

  build: function() {
    if (!this.overlay) {
      this.overlay = new Element('div', {
        'class': this.options.className,
        'styles': {
          'position': Browser.Engine.trident4 ? 'absolute' : 'fixed',
          'left': 0,
          'top': 0,
          'width': 1,
          'height': 1,
          'padding': 0,
          'margin': 0,
          'opacity': 0,
          'visibility': 'hidden',
          'z-index': this.options.zIndex
        }
      }).inject(document.body, 'top');
      if (this.options.background != '') {
        this.overlay.setStyle('background', this.options.background);
      }
      this.overlay.addEvent('click', this.listeners.click);
      this.overlay.addEvent('mouseup', function(event) { new Event(event).stop(); } );
    }
  },

  resize: function() {
    if (this.overlay) {
      var sizes = {
        scroll: window.getScroll(),
        scrollSize: window.getScrollSize(),
        size: window.getSize()
      }
      if (Browser.Engine.trident4) {
        this.overlay.setStyles({
          'left': sizes.scroll.x,
          'top': sizes.scroll.y
        });
      }
      this.overlay.setStyles({
        'width': sizes.size.x,
        'height': sizes.size.y
      });
    }
  },
  
  show: function() {
    if (this.overlay && this.overlay.getStyle('visibility') != 'hidden') return;
    this.fireEvent('show');
    this.build();
    if (this.overlay) {
      this.resize();
      this.toggleListeners(true);
      this.overlay.setStyle('visibility', 'visible').effect('opacity', {duration: 250}).start(this.options.opacity);
    }
  },
  
  hide: function() {
    if (!this.overlay || this.overlay.getStyle('visibility') == 'hidden') return;
    this.fireEvent('hide');
    if (this.overlay) {
      this.toggleListeners(false);
      this.overlay.effect('opacity', {duration: 250}).start(0).chain(function() {
        this.overlay.setStyles({
          'visibility': 'hidden',
          'left': 0,
          'top': 0,
          'width': 0,
          'height': 0
        });
      }.bind(this));
    }
  },
  
  click: function() {
    this.fireEvent('click');
    if (this.options.closeByClick) {
      this.hide();
    }
  },
  
  destroy: function() {
    if (this.overlay) {
      this.toggleListeners(false);
      this.overlay.removeEvent('click', this.listeners.click);
      this.overlay.destroy();
      this.overlay = null;
    }
  }

});
