var inlineLightbox = Class.create();

inlineLightbox.prototype = {

  initialize: function() { },
  
  create: function(elm, i, noarrows, autoplay) {
    this.index = i;
    this.noarrows = noarrows;
    this.autoplay = autoplay;
    this.fadespeed = 2.3;
    this.waitspeed = 0.1
	this.isFirstPreLoad  = true;
    
    this.objLightbox = document.createElement("div");
    this.objLightbox.className = 'lightbox';
    this.objLightbox.style.display = 'none';
    elm.insertBefore(this.objLightbox, elm.firstChild);

    this.objOuterImageContainer = document.createElement("div");
    this.objOuterImageContainer.className = 'outerImageContainer';
    this.objLightbox.appendChild(this.objOuterImageContainer);

    this.objImageContainer = document.createElement("div");
    this.objImageContainer.className = 'imageContainer';
    this.objOuterImageContainer.appendChild(this.objImageContainer);

    this.objLightboxImage = document.createElement("img");
    this.objLightboxImage.className = 'lightboxImage';
    this.objLightboxImage.setAttribute('lbId',i);
    this.objImageContainer.appendChild(this.objLightboxImage);
    
    // START: fade effect...
    this.objLightboxImageBuffer = document.createElement("img");
    this.objLightboxImageBuffer.className = 'lightboxImageBuffer';
    this.objLightboxImageBuffer.style.display = 'none'
    this.lightboxFirstLoad = true
    this.objImageContainer.appendChild(this.objLightboxImageBuffer);
    // END: fade effect...

    if(!noarrows) {
      this.objHoverNav = document.createElement("div");
      this.objHoverNav.className = 'hoverNav';
      this.objImageContainer.appendChild(this.objHoverNav);
  
      this.objPrevLink = document.createElement("a");
      this.objPrevLink.className = 'prevLink';
      this.objPrevLink.setAttribute('href','#');
      this.objPrevLink.setAttribute('lbId',i);
      this.objHoverNav.appendChild(this.objPrevLink);
  
      this.objNextLink = document.createElement("a");
      this.objNextLink.className = 'nextLink';
      this.objNextLink.setAttribute('href','#');
      this.objNextLink.setAttribute('lbId',i);
      this.objHoverNav.appendChild(this.objNextLink);
    }

    this.objLoading = document.createElement("div");
    this.objLoading.className = 'loading';
    this.objImageContainer.appendChild(this.objLoading);

    this.objLoadingLink = document.createElement("a");
    this.objLoadingLink.className = 'loadingLink';
    this.objLoadingLink.setAttribute('href','#');
    this.objLoadingLink.setAttribute('lbId',i);
    this.objLoadingLink.onclick = function() { myInlineLightbox.lightboxes[this.getAttribute("lbId")].end(); return false; };
    this.objLoading.appendChild(this.objLoadingLink);

    this.objLoadingImage = document.createElement("img");
    this.objLoadingImage.setAttribute('src', fileLoadingImage);
    this.objLoadingLink.appendChild(this.objLoadingImage);

    this.objImageDataContainer = document.createElement("div");
    this.objImageDataContainer.className = 'imageDataContainer';
    this.objImageDataContainer.setAttribute('lbId',i);
    this.objLightbox.appendChild(this.objImageDataContainer);

    this.objImageData = document.createElement("div");
    this.objImageData.className = 'imageData';
    this.objImageDataContainer.appendChild(this.objImageData);

    this.objImageDetails = document.createElement("div");
    this.objImageDetails.className = 'imageDetails';
    this.objImageData.appendChild(this.objImageDetails);

    this.objCaption = document.createElement("span");
    this.objCaption.className = 'caption';
    this.objImageDetails.appendChild(this.objCaption);
  },

  //
  //  start()
  //  Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
  //
  start: function(imageLink) {
    // START: fade effect...
    if(this.fading)
      return;
    
    this.fading = true;
    
    // END: fade effect...

    hideSelectBoxes();
    
    this.imageArray = [];
    this.imageNum = 0;

    if (!this.objLightbox.parentNode.getElementsByTagName){ return; }
    var anchors = this.objLightbox.parentNode.getElementsByTagName('a');

    // if image is NOT part of a set..
    if((imageLink.getAttribute('rel') == 'inlinebox')){
      // add single image to imageArray
      this.imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title')));     
    } else {
    // if image is part of a set..

      // loop through anchors, find other images in set, and add them to imageArray
      for (var i=0; i<anchors.length; i++){
        var anchor = anchors[i];
        if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){
          this.imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
        }
      }
      this.imageArray.removeDuplicates();
      while(this.imageArray[this.imageNum][0] != imageLink.getAttribute('href')) { this.imageNum++;}
    }

    Element.show(this.objLightbox);

    this.changeImage(this.imageNum);
  },

  //
  //  changeImage()
  //  Hide most elements and preload image in preparation for resizing image container.
  //
  changeImage: function(imageNum) {
    
    if(imageNum > this.imageArray.length - 1) imageNum = 0;
    if(imageNum < 0) imageNum = this.imageArray.length - 1;

    this.activeImage = imageNum;  // update global var

    // hide elements during transition
    Element.show(this.objLoading);
    
    Element.hide(this.objLightboxImage);
	
	// START: fade effect...
	this.objLightboxImageBuffer.src = this.objLightboxImage.src;
    
    var enableFade = function() {
      this.fading = false;
    }
    window.setTimeout(enableFade.bind(this), this.fadespeed*1000);
    // END: fade effect...
	
    if(!this.noarrows) {
      Element.hide(this.objHoverNav);
      Element.hide(this.objPrevLink);
      Element.hide(this.objNextLink);
    }
    Element.hide(this.objImageDataContainer); 

    this.imgPreloader = new Image();
    this.imgPreloader.index = this.index;

    // once image is preloaded, resize image container
    this.imgPreloader.onload=function(){
      lb = myInlineLightbox.lightboxes[this.index];
      Element.setSrc(lb.objLightboxImage, lb.imageArray[lb.activeImage][0]);
      lb.resizeImageContainer(this.width, this.height, lb);
    }
    this.imgPreloader.src = this.imageArray[this.activeImage][0];
  },
  
  // START: fade effect...
    alignmentImage: function(){
    con_w = this.objImageContainer.offsetWidth
    
    img_w = this.objLightboxImage.width
    this.objLightboxImage.style.position = 'absolute'
    this.objLightboxImage.style.left = '0px';
    this.objLightboxImage.style.top  = '0px'
    this.objLightboxImage.style.zIndex  = '2'
    
    img_w = this.objLightboxImageBuffer.width
    this.objLightboxImageBuffer.style.display = 'none'
    this.objLightboxImageBuffer.style.position = 'absolute'
    this.objLightboxImageBuffer.style.left = '0px';
    this.objLightboxImageBuffer.style.top  = '0px'
    this.objLightboxImageBuffer.style.zIndex  = '1'
  },
  // END: fade effect...

  //
  //  resizeImageContainer()
  //
  resizeImageContainer: function(imgWidth, imgHeight) {
    
    // get current height and width
    hCur = Element.getHeight(this.objOuterImageContainer);

    // scalars based on change from old to new
    yScale = (imgHeight / hCur) * 100;

    // calculate size difference between new and old image, and resize if necessary
    hDiff = hCur - imgHeight;

    if(!( hDiff == 0)){ new Effect.Scale(this.objOuterImageContainer, yScale, {scaleX: false, duration: resizeDuration, queue: 'front'}); }
    
    // if new and old image are same size and no scaling transition is necessary, 
    // do a quick pause to prevent image flicker.
    if(hDiff == 0){
      if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);} 
    }

    if(!this.noarrows) {
      Element.setHeight(this.objPrevLink, imgHeight);
      Element.setHeight(this.objNextLink, imgHeight);
    }

    this.showImage();
  },

  //
  //  showImage()
  //  Display image and begin preloading neighbors.
  //
  showImage: function(){
    this.alignmentImage();
    Element.hide(this.objLoading);
    var finish = function(effect){
      myInlineLightbox.lightboxes[effect.element.getAttribute("lbId")].updateDetails();
      
      var after = function(){
        this.objLightboxImageBuffer.style.display = 'none';
        this.objLightboxImageBuffer.style.opacity = 1;
      }
      if(!this.autoplay)this.objLightboxImageBuffer.style.display = 'none';
    }
    if(!this.lightboxFirstLoad){
      this.objLightboxImageBuffer.style.display = 'block';
	  new Effect.Appear(this.objLightboxImage, { queue: 'end', duration: this.fadespeed, afterFinish: finish.bind(this)});
      this.preloadNeighborImages();
    } else {
	  this.lightboxFirstLoad = false;
	  this.changeImage(this.activeImage+1);
	}
  },

  //
  //  updateDetails()
  //  Display caption, image number, and bottom nav.
  //
  updateDetails: function() {
    
    if(this.imageArray[this.activeImage][1]) {
      Element.show(this.objCaption);
      Element.setInnerHTML(this.objCaption, this.imageArray[this.activeImage][1]);

      new Effect.Parallel(
        [ new Effect.SlideDown(this.objImageDataContainer, { sync: true, duration: resizeDuration + 0.25, from: 0.0, to: 1.0 }), 
          new Effect.Appear(this.objImageDataContainer, { sync: true, duration: 1.0 }) ], 
        { duration: 0.65, afterFinish: function(effect) { myInlineLightbox.lightboxes[effect.effects[0].element.getAttribute("lbId")].updateNav();} } 
      );
    } else if(!this.noarrows)
      this.updateNav();
    
  },

  //
  //  updateNav()
  //  Display appropriate previous and next hover navigation.
  //
  updateNav: function() {
    Element.show(this.objHoverNav);       

    Element.show(this.objPrevLink);
    this.objPrevLink.onclick = function() {
      lb = myInlineLightbox.lightboxes[this.getAttribute("lbId")];
      lb.changeImage(lb.activeImage - 1); return false;
    }

    Element.show(this.objNextLink);
    this.objNextLink.onclick = function() {
      lb = myInlineLightbox.lightboxes[this.getAttribute("lbId")];
      lb.changeImage(lb.activeImage + 1); return false;
    }
  },

  //
  //  preloadNeighborImages()
  //  Preload previous and next images.
  //
  preloadNeighborImages: function(){

    preloadNextImage = new Image();
    preloadNextImage.src = this.imageArray[(((this.imageArray.length - 1) > this.activeImage) ? this.activeImage + 1 : 0)][0];
    
    preloadPrevImage = new Image();
    preloadPrevImage.src = this.imageArray[(this.activeImage > 0 ? this.activeImage - 1 : this.imageArray.length - 1)][0];
    
    if(this.autoplay) {
      var next = function() {
        this.changeImage(this.activeImage + 1);
      }
		/*
		if(this.isFirstPreLoad){
		  this.isFirstPreLoad = false;
		  this.changeImage(this.activeImage + 1);
		}
		*/
        this.waitspeed = Math.floor(Math.random()*16)+9;
        window.setTimeout(next.bind(this), this.fadespeed*1000+this.waitspeed*1000);
    }

  },

  setFadeeable: function(eable){
    this.fadeeable = eable;
  },

  //
  //  end()
  //
  end: function() {
    Element.hide(this.objLightbox);
    showSelectBoxes();
  }
};

var inlineLightboxFactory = Class.create();
inlineLightboxFactory.prototype = {

  initialize: function() { },
  
  create: function() {
    if (!document.getElementsByTagName){ return; }
    var anchors = document.getElementsByTagName('a');
    
    this.lightboxes = new Array();

    // loop through all anchor tags
    var n = -1;
    for (var i=0; i<anchors.length; i++){
      var anchor = anchors[i];
    
      var relAttribute = String(anchor.getAttribute('rel'));
    
      // use the string.match() method to catch 'lightbox' references in the rel attribute
      if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('inlinebox'))){
        anchor.onclick = function () { myInlineLightbox.lightboxes[this.getAttribute("lbId")].start(this); return false;}
        var elm = this.getContainer($(anchor));
        if(!elm.select('.lightbox').length) {
          n++;
          this.lightboxes[n] = new inlineLightbox();
          this.lightboxes[n].create(elm, n, elm.hasClassName('noarrows'), elm.hasClassName('autoplay'));
          if(elm.hasClassName('autostart'))
            this.lightboxes[n].start(anchor);
        }
        anchor.setAttribute("lbId", n);
      }
    }
  },

  getContainer: function(elm) {
    while(!elm.hasClassName('lightboxContainer') &&
          elm.tagName != 'body' &&
          !elm.hasClassName('innerarticle'))
      elm = $(elm.parentNode);
    return elm;
  }
};

function initInlineLightbox() { myInlineLightbox = new inlineLightboxFactory(); myInlineLightbox.create(); }
Event.observe($(window), 'load', initInlineLightbox, false);

