var Growl = new Class({
  Implements: [Events, Options],
  options: {
    type: 'notice',
    position: 'right',
    sticky: false,
    header: '',
    lifetime: 3000,
    margin: '20px',
    effect: ''
  },
  initialize: function(message, options){
    this.setOptions(options);
    this.message   = message;
    this.wrapper   = $('ui-growl-place') || this._createWrapper();
    this.container = this._draw();
    this._show();
    if (!this.options.sticky){
      this._hide();
    };
  },
  _createWrapper: function(){
    var wrapper = new Element('div', {id: 'ui-growl-place'});

    switch(this.options.position){
      case 'right':
        wrapper.setStyle('right', this.options.margin);
        break;
      case 'left':
        wrapper.setStyle('left', this.options.margin);
        break;
      case 'center':
        wrapper.setStyle('left', '45%');
        break;
    }
    wrapper.inject(document.body);
    return wrapper;
  },
  _draw: function(){
    var options = this.options,
        self    = this;

    // Create main container
    var body = new Element('div', {
      class: 'ui-growl',
      styles: {
        opacity: 0
      }
    })

    var container = new Element('div', {class: 'ui-growl-' + options.type})

    // Create content container
    var content = new Element('div').addClass('ui-growl-content');

    if (options.header != ''){
      new Element('h4').set('text', options.header).inject(content);
    }

    new Element('span').set('text', this.message).inject(content)

    // Create close button
    var close = new Element('div', {
      class: 'ui-growl-close',
      events: {
        click: function(e){
          e.stop();
          body.destroy();
          self._checkWrapper();
          return false;
        }
      }
    }).set('text', '×');

    // Build complete notification
    close.inject(container);
    content.inject(container);

    body.addEvents({
      mouseover: function(){
        self._pause();
      },
      mouseout: function(){
        self._hide();
      }
    });

    container.inject(body);
    body.inject(this.wrapper);
    return body;
  },
  _show: function(){
    new Fx.Tween(this.container).start('opacity', 0, 1);
  },
  _hide: function(){
    var self     = this;
    this.timeout = setTimeout(function(){
      new Fx.Tween(self.container).start('opacity', 0).chain(function(){
        self.container.destroy();
        self._checkWrapper();
      });
    }, this.options.lifetime);
  },
  _pause: function(){
    var self = this;
    clearTimeout(self.timeout);
  },
  _checkWrapper: function(){
    if (this.wrapper.childElementCount == 0){
      this.wrapper.destroy();
    }
  }
});