(function($) {
  OverlayObject = function(el, options) {
    this.create(el, options);
  };

  $.extend(OverlayObject.prototype, {
    create: function(options) {
      this.options = options;
      this.element = $('<div id="'+new Date().getTime()+'" class="'+this.options.name+'-overlay"></div>');
      this.element.css($.extend({}, {
        'position'  : 'fixed',
        'top'       : 0,
        'left'      : 0,
        'opacity'   : 0,
        'display'   : 'none',
        'z-index'   : this.options.zIndex
      }, this.options.style));

      this.element.click( $.proxy(function(event) {
        if (this.options.hideOnClick)
        {
          if ($.isFunction(this.options.callback))
          {
            this.options.callback();
          }
          else
          {
            this.hide();
          }
        }
        event.preventDefault();
      }, this));
      
      this.hidden = true;
      this.inject();
      return this;
    },

    inject: function() {
      this.target = $(document.body);
      this.target.append(this.element);

      if((jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 7 && parseInt(jQuery.browser.version, 10) > 4))
      {
        this.element.css({'position': 'absolute'});
        var zIndex = parseInt(this.element.css('zIndex'));
        if (!zIndex)
        {
          zIndex = 1;
          var pos = this.element.css('position');
          if (pos == 'static' || !pos)
          {
            this.element.css({'position': 'relative'});
          }
          this.element.css({'zIndex': zIndex});
        }
        zIndex = (!!(this.options.zIndex || this.options.zIndex === 0) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
        if (zIndex < 0)
        {
          zIndex = 1;
        }
        this.shim = $('<iframe id="IF_'+new Date().getTime()+'" scrolling="no" frameborder=0 src=""></iframe>');
        this.shim.css({
          zIndex    : zIndex,
          position  : 'absolute',
          top       : 0,
          left      : 0,
          border    : 'none',
          width     : 0,
          height    : 0,
          opacity   : 0
        });
        this.shim.insertAfter(this.element);
        $('html, body').css({
          'height'      : '100%',
          'width'       : '100%',
          'margin-left' : 0,
          'margin-right': 0
        });
      }
    },

    resize: function(x, y) {
      this.element.css({ 'height': 0, 'width': 0 });
      if (this.shim) { this.shim.css({ 'height': 0, 'width': 0 }); };

      var win = { x: $(document).width(), y: $(document).height() };
      
      this.element.css({
        'width'   : '100%',
        'height'  : y ? y : win.y
      });
      
      if (this.shim)
      {
        this.shim.css({ 'height': 0, 'width': 0 });
        this.shim.css({
          'position': 'absolute',
          'left'    : 0,
          'top'     : 0,
          'width'   : this.element.width(),
          'height'  : y ? y : win.y
        });
      }
      return this;
    },

    show: function(callback) {
      if (!this.hidden) { return this; };
      if (this.transition) { this.transition.stop(); };
      if (this.shim) { this.shim.css({'display': 'block'}); };
      this.element.css({'display':'block', 'opacity':0});

      this.target.bind('resize', $.proxy(this.resize, this));
      this.resize();
      this.hidden = false;

      this.transition = this.element.fadeTo(this.options.showDuration, this.options.style.opacity, $.proxy(function(){
        if (this.options.style.opacity) { this.element.css(this.options.style) };
        this.element.trigger('show');
        if ($.isFunction(callback)) { callback(); };
      }, this));
      
      return this;
    },

    hide: function(callback) {
      if (this.hidden) { return this; };
      if (this.transition) { this.transition.stop(); };
      if (this.shim) { this.shim.css({'display': 'none'}); };
      this.target.unbind('resize');
      this.hidden = true;

      this.transition = this.element.fadeTo(this.options.closeDuration, 0, $.proxy(function(){
        this.element.trigger('hide');
        if ($.isFunction(callback)) { callback(); };
        this.element.css({ 'height': 0, 'width': 0, 'display': 'none' });
      }, this));

      return this;
    }
  });
})(jQuery);
