var ImageViewer = Class.create();
Object.extend(ImageViewer.prototype, {
  initialize: function (positionTo, background, loading) {
    this._images    = {};
    this._pos       = $(positionTo);
    this._posWidth  = Element.getDimensions(this._pos).width;
    this._back      = $(background);
    this._back.style.display  = 'none';
    this._back.style.zIndex   = 5;
    this._loading             = $(loading);
    Element.hide(this._loading);
    Event.observe(window, 'scroll', this._resetBackSize.bind(this));
  },
  show: function (url) {
    this._resetBackSize();
    if (this._images[url]) {
      this._show(this._images[url]);
    }
    else {
      var img = document.createElement('IMG');
      img.src = url;
      img.style.position  = 'absolute';
      img.style.cursor    = 'pointer';
      img.style.display   = 'none';
      img.title           = 'Click to Close';
      Event.observe(img, 'click', this.hide.bindAsEventListener(this));
      this._images[url]   = img;
      document.body.insertBefore(img, document.body.childNodes[0]);
      Element.show(this._loading);
      this._showIfLoaded(img);
    }
  },
  hide: function () {
    if (this._showing) {
      new Effect.Fade(this._showing, { duration: 0.6 });
      new Effect.Fade(this._back, { duration: 0.6 });
      this._showing = null;
    }
  },
  _showIfLoaded: function (el) {
    var elSize = Element.getDimensions(el);
    if (elSize.width > 100 && elSize.height > 100) {
      Element.hide(this._loading);
      var setX = parseInt((this._posWidth / 2) - (elSize.width / 2));
      setX = ( setX < 0 ) ? this._pos.offsetLeft : this._pos.offsetLeft + setX;
      var setY = (this._pos.offsetTop > document.documentElement.scrollTop) ? this._pos.offsetTop : document.documentElement.scrollTop;
      el.style.left   = setX + 'px';
      el.style.top    = setY + 'px';
      el.style.zIndex = 8;
      this._show(el);
    }
    else {
      setTimeout(function () { this._showIfLoaded(el); }.bind(this), 200);
    }
  },
  _show: function (el) {
    if (this._showing) {
      new Effect.Fade(this._showing, { duration: 0.6, afterFinish: function () { new Effect.Appear(this._showing, { duration: 0.6 }); }.bind(this) });
    }
    else {
      new Effect.Appear(this._back, { duration: 0.6, to: 0.7 });
      new Effect.Appear(el, { duration: 0.6 });
    }
    this._showing = el;
  },
  _resetBackSize: function () {
    if (! this._showing) {
      var backSize    = Element.getDimensions(this._back);
      var docSize     = Element.getDimensions(document.documentElement);
      var compareY    = docSize.height + document.documentElement.scrollTop;
      var compareX    = docSize.width + document.documentElement.scrollLeft;
      if (backSize.height < compareY) {
        this._back.style.height = compareY + 'px';
      }
      if (backSize.width < compareX) {
        this._back.style.width  = compareX + 'px';
      }
    }
  }
} );
