var LightBox = Class.create({
  initialize: function(element) {
    this.element = element;
    this.background = $('lightbox_background');
    this.spinner = $('lightbox_spinner');
    this.lightbox = $('lightbox');

    this.element.observe('click', this.showLightBox.bindAsEventListener(this));
    this.element.setStyle({ cursor: 'pointer' });

    if (this.element.hasClassName('missing_credit')) {
      // Internet Explorer 6 doesn't handle PNG transparency
      var ext = (navigator.userAgent.indexOf('MSIE 6') != -1) ? 'gif' : 'png';
      var missing_credit = new Element('img', { src: '/images/error-large.' + ext, alt: 'Photo credit missing', title: 'Photo credit missing', style: 'position: absolute; z-index: 10;' });
      missing_credit.clonePosition(this.element, { setWidth: false, setHeight: false });
      missing_credit.observe('click', this.addPhotoCredit.bindAsEventListener(this));
      missing_credit.setStyle({ cursor: 'pointer' });
      this.element.insert({ after: missing_credit });
    }
  },

  addPhotoCredit: function(event) {
    document.location.href = this.getAddPhotoCreditURL();
    event.stop();
  },

  getAddPhotoCreditURL: function() {
    var parts = this.getGalleryAndImage();
    return '/photo-credits/new/gallery/' + parts.gallery + '/prefix/' + parts.image.split('_')[0] + '?' + Object.toQueryString({ referrer: document.location.href });
  },

  showLightBox: function(event) {
    this.background.observe('click', this.hideLightBox.bindAsEventListener(this));

    // Internet Explorer 6 doesn't support fixed positioning, so we have to fake it by using absolute positioning and calculating the top and left offsets ourselves
    if (navigator.userAgent.indexOf('MSIE 6') != -1) {
      var dims = document.viewport.getDimensions();
      var scroll = document.viewport.getScrollOffsets();

      this.background.setStyle({ position: 'absolute', width: dims.width + 'px', height: dims.height + 'px', top: scroll.top + 'px', left: scroll.left + 'px' });
      this.spinner.setStyle({ position: 'absolute', top: (scroll.top + (dims.height / 2) - 24) + 'px', left: (scroll.left + (dims.width / 2) - 24) + 'px', margin: 0 });
      this.lightbox.setStyle({ position: 'absolute', top: (scroll.top + (dims.height / 2) - 340) + 'px', left: (scroll.left + (dims.width / 2) - 340) + 'px', margin: 0 });
    }

    Effect.Appear(this.background, { duration: 0.15, to: 0.85 });
    Effect.Appear(this.spinner, { duration: 0.01, delay: 0.15 });

    new Ajax.Updater(this.lightbox, this.getLightBoxURL(), { method: 'get', onComplete: this.onLightBoxLoaded.bindAsEventListener(this) });
  },

  // inspect this image's src and class attributes to determine the URL for the lightbox AJAX request
  getLightBoxURL: function() {
    var parts = this.getGalleryAndImage();
    var skip_nav = this.element.hasClassName('skip_nav') ? '?skip_nav' : '';
    return '/lightbox/' + parts.gallery + '/' + parts.image + skip_nav;
  },

  getGalleryAndImage: function() {
    var parts = this.element.getAttribute('src').split('/');
    return { gallery: parts[parts.length-2], image: parts[parts.length-1] };
  },

  onLightBoxLoaded: function(transport) {
    this.lightbox.observe('mouseover', this.showPrevNext.bindAsEventListener(this));
    this.lightbox.observe('mouseout', this.hidePrevNext.bindAsEventListener(this));

    var prev = $('lightbox_prev');
    if (prev) prev.observe('click', this.goPrev.bindAsEventListener(this));

    var next = $('lightbox_next');
    if (next) next.observe('click', this.goNext.bindAsEventListener(this));

    if (navigator.userAgent.indexOf('Opera') != -1) {
      this.onLightBoxImageLoaded('event');
    } else {
      // this event doesn't seem to fire on Opera 9.62 on Linux
      $('lightbox_image').observe('load', this.onLightBoxImageLoaded.bindAsEventListener(this));
    }
  },

  showPrevNext: function(event) {
    var prev = $('lightbox_prev');
    if (prev) prev.show();

    var next = $('lightbox_next');
    if (next) next.show();
  },

  hidePrevNext: function(event) {
    var prev = $('lightbox_prev');
    if (prev) prev.hide();

    var next = $('lightbox_next');
    if (next) next.hide();
  },

  goPrev: function(event) {
    new Ajax.Updater(this.lightbox, $('lightbox_prev').href, { method: 'get', onComplete: this.onLightBoxLoaded.bindAsEventListener(this) });
    event.stop();
  },

  goNext: function(event) {
    new Ajax.Updater(this.lightbox, $('lightbox_next').href, { method: 'get', onComplete: this.onLightBoxLoaded.bindAsEventListener(this) });
    event.stop();
  },

  onLightBoxImageLoaded: function(event) {
    this.lightbox.observe('click', this.hideLightBox.bindAsEventListener(this));

    Effect.Appear(this.lightbox, { duration: 0.25 });
  },

  hideLightBox: function(event) {
    this.spinner.hide();

    this.background.stopObserving();
    this.lightbox.stopObserving();

    Effect.Fade(this.lightbox, { duration: 0.25 });
    Effect.Fade(this.background, { duration: 0.15, from: 0.85, delay: 0.25 });
  }
});

Event.observe(window, 'load',
  function(event) {
    var body = $$('body')[0];
    body.insert({ 'top': new Element('div', { id: 'lightbox', style: 'display: none; position: fixed; z-index: 200; top: 50%; left: 50%; width: 680px; height: 680px; margin: -340px 0 0 -340px; text-align: center; overflow: visible;' }) });
    body.insert({ 'top': new Element('img', { id: 'lightbox_spinner', style: 'display: none; position: fixed; z-index: 150; top: 50%; left: 50%; margin: -24px 0 0 -24px;', src: '/images/lightbox_spinner.gif', alt: 'Loading...', height: 48, width: 48 }) });
    body.insert({ 'top': new Element('div', { id: 'lightbox_background', style: 'display: none; position: fixed; z-index: 100; top: 0; left: 0; width: 100%; height: 100%;' }) });

    $$('img.lightbox').each(
      function(element) { new LightBox(element); }
    );
  }
);
