/**
 *  Lightbox Extension
 *
 *  this file extends the lightbox script with
 *    - and navigational elements moved to bottomNav container
 *    - special sizing option: image stays in viewport constraints
 *
 *  @author:  tommy(at)profi(dot)it
 *  @since:   05.09.2008 15:57:35
 *  @edited:  2010-06-22 23:47:34 reviewed and adjusted for perfectlightbox 3.0.1
 *
 */

var Lightbox = Class.create(Lightbox, {

  initialize: function($super) {
    // call super class method
    $super();

    // modify controls
    this.modifyControls();
  },

  /**
   * modifies controls of the lightbox skeleton
   *
   */
  modifyControls: function() {
    // remove elements but store reference to re-add 'em in lbBottomNav later
    // @note: as we store a reference and re-add it later, we didn't need to
    // re-bind the observers and "elementsToObjects call"
    var pauseLinkRef = $('pauseLink').remove();
    var playLinkRef = $('playLink').remove();
    var saveLinkRef = $('saveLink').remove();
    var nextLinkRef = $('nextLink').remove();
    var prevLinkRef = $('prevLink').remove();

    $('lbBottomNav').insert({ 
      bottom: pauseLinkRef 
    }).insert({ 
      bottom: playLinkRef 
    }).insert({ 
      bottom: saveLinkRef 
    }).insert({ 
      bottom: nextLinkRef 
    }).insert({ 
      bottom: prevLinkRef 
    });
  },

  //
  //  start()
  //  Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
  //
  start: function(imageLink) {
    $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

    // stretch overlay to fill page and fade in
    var arrayPageSize = this.getPageSize();
    $('overlay').setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });

    new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: LightboxOptions.overlayOpacity });

    this.imageArray = [];
    var imageNum = 0;

    if ((imageLink.rel == 'lightbox')){
      // if image is NOT part of a set, add single image to imageArray
      this.imageArray.push([imageLink.href, imageLink.title]);
    } else {
      // if image is part of a set..
      this.imageArray =
          $$(imageLink.tagName + '[href][rel="' + imageLink.rel + '"]').
          collect(function(anchor){ return [anchor.href, anchor.title]; }).
          uniq();

      while (this.imageArray[imageNum][0] != imageLink.href) { imageNum++; }
    }

    // calculate top and left offset for the lightbox
    var arrayPageScroll = document.viewport.getScrollOffsets();
    //var lightboxTop = arrayPageScroll[1] + (document.viewport.getHeight() / 10);
    // upper lightbox edge sticks at upper viewport edge...
    var lightboxTop = arrayPageScroll[1]; // + ((arrayPageScroll[1] - this.lightbox.getHeight()) / 2);
    var lightboxLeft = arrayPageScroll[0];
    this.lbLightbox.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();

    this.changeImage(imageNum);
  },

  /**
   * overridden changeImage method
   *
   */
  changeImage: function(imageNum) {
    this.activeImage = imageNum; // update global var

    // mod in lightbox script (BEN)
		this.prevImage = (this.activeImage || (LightboxOptions.loop ? this.imageArray.length : 0)) - 1;
		this.nextImage = ((this.activeImage + 1) % this.imageArray.length) || (LightboxOptions.loop ? 0 : -1);

    // hide elements during transition
    if (LightboxOptions.animate) this.lbLoading.show();
    this.lbLightboxImage.hide();
    this.lbHoverNav.hide();
    this.prevLink.hide();
    this.nextLink.hide();

    // HACK: Opera9 does not currently support scriptaculous opacity and appear fx
    this.lbImageDataContainer.setStyle({opacity: .0001});
    this.lbNumberDisplay.hide();

    var imgPreloader = new Image();

    // once image is preloaded, resize image container

    imgPreloader.onload = (function(){
      // set img element src
      this.lbLightboxImage.src = this.imageArray[this.activeImage][0];

      // check if size of image + border + data container height is taller than viewport size
      var overallSize = imgPreloader.height + (LightboxOptions.borderSize * 2) + $('lbImageDataContainer').getHeight();
      if (overallSize > document.viewport.getHeight())
      {
        var oldHeight = imgPreloader.height;
        this.lbLightboxImage.height = imgPreloader.height = document.viewport.getHeight() - (LightboxOptions.borderSize * 2) - $('lbImageDataContainer').getHeight();
        this.lbLightboxImage.width = imgPreloader.width = imgPreloader.width / (oldHeight / imgPreloader.height);
      }
      // else, reset to constraints of image
      else
      {
        this.lbLightboxImage.height = imgPreloader.height;
        this.lbLightboxImage.width = imgPreloader.width;
      }

      this.resizeImageContainer(imgPreloader.width, imgPreloader.height);
    }).bind(this);

    imgPreloader.src = this.imageArray[this.activeImage][0];

		/* perfectlightbox mod: saveLink (BEN) */
    if (LightboxOptions.allowSave) {
      this.saveLink.setAttribute('href',this.imageArray[this.activeImage][0]);
      this.saveLink.setStyle({'display':''});
    }
    else
    {
      this.saveLink.setStyle({'display':'none'});
		}
  },

  /**
   * overridden resizeImageContainer method
   *
   */
  resizeImageContainer: function(imgWidth, imgHeight) {
    // get current width and height
    var widthCurrent  = this.lbOuterImageContainer.getWidth();
    var heightCurrent = this.lbOuterImageContainer.getHeight();

    // get new width and height
    var widthNew  = (imgWidth  + LightboxOptions.borderSize * 2);
    var heightNew = (imgHeight + LightboxOptions.borderSize * 2);

    // scalars based on change from old to new
    var xScale = (widthNew  / widthCurrent)  * 100;
    var yScale = (heightNew / heightCurrent) * 100;

    // calculate size difference between new and old image, and resize if necessary
    var wDiff = widthCurrent - widthNew;
    var hDiff = heightCurrent - heightNew;

    if (hDiff != 0) new Effect.Scale(this.lbOuterImageContainer, yScale, {scaleX: false, duration: this.resizeDuration, queue: 'front'});
    if (wDiff != 0) new Effect.Scale(this.lbOuterImageContainer, xScale, {scaleY: false, duration: this.resizeDuration, delay: this.resizeDuration});

    // if new and old image are same size and no scaling transition is necessary,
    // do a quick pause to prevent image flicker.
    var timeout = 0;
    if ((hDiff == 0) && (wDiff == 0)){
        timeout = 100;
        if (Prototype.Browser.IE) timeout = 250;
    }

    (function(){
        // this is not needed any more, because we don't display the links in the hoverNav,
        // instead we make a text link navigation in the bottom area
        //this.prevLink.setStyle({ height: imgHeight + 'px' });
        //this.nextLink.setStyle({ height: imgHeight + 'px' });
        this.lbImageDataContainer.setStyle({ width: widthNew + 'px' });

        this.showImage();
    }).bind(this).delay(timeout / 1000);
  }
});

