/**
 * MooBox v1.0
 * by Cornel Boudria - http://www.3-prime.com, http://www.spidergourmet.com
 *
 * For more information on this script-port/application, visit:
 * http://www.3-prime.com/moobox/
 *
 * This represents a port of Lightbox v2.03 (http://huddletogether.com/projects/lightbox2/)
 * created by Lokesh Dhakar (http://www.huddletogether.com)
 * from the Prototype JS (http://www.prototypejs.org) and Scriptaculous (http://script.aculo.us/) libraries
 * over to the Mootools JS Framework (http://www.mootools.net).
 *
 * I Love the original Lightbox Application, but wanted a version that implements Mootools,
 * since I employed Mootools in Applications that I had pre-built for one of my clients.
 * This port represents an alternative to those in a similar situation: you inherited a great
 * script, but your investement in another framework rendered the great script unworkable.
 *
 * Enjoy MooBox.
 *
 * -C
 */

// ----------------- START CONFIGURATION AND GLOBAL VARIABLES -------------------------
/**
 * Configuration
 */
var gMBox_fileLoadingImage = "/moobox/loading2.gif";
var gMBox_fileBottomNavCloseImage = "/moobox/closelabel.gif";

var gMBox_animate = true;    // toggles resizing animations
var gMBox_resizeSpeed = 1;   // controls the speed of the image resizing animations (1=slowest and 10=fastest)

var gMBox_borderSize = 10;   //if you adjust the padding in the CSS, you will need to update this variable

/**
 * Global Variables
 */
var gMBox_imageArray = new Array;
var gMBox_activeImage;

var gMBox_overlayDuration = 200;
var gMBox_resizeDuration = 500;
// -----------------  END CONFIGURATION AND GLOBAL VARIABLES  -------------------------

/* -------------------------- START Native Object Extensions -------------------------- */
if( !Array.removeDuplicates || Array.removeDuplicates == "undefined" )
Array.prototype.removeDuplicates = function () {
    for(i = 0; i < this.length; i++){
        for(j = this.length-1; j>i; j--){        
            if(this[i][0] == this[j][0]){
                this.splice(j,1);
            }
        }
    }
};

Element.extend({
  show: function() {
    this.setStyles({
	  display: "block"
    });
  },
  hide: function() {
    this.setStyles({
	  display: "none"
    });
  }
});
/* --------------------------  END Native Object Extensions  -------------------------- */

/** --- Future API for exposing Animation Effects and Customizing MooBox HTML Elements ---
 * ## Note: All Options are based on Mootools Fx.Base Options ##
 * overlayOptions      = { duration: <duration milliseconds>, transition: <Transition Type> };
 * resizeImageOptions  = { duration: <duration milliseconds>, transition: <Transition Type> };
 * imageDetailsOptions = { duration: <duration milliseconds>, transition: <Transition Type> };
 * MooBox.setOverlayEffect(overlayOptions);
 * MooBox.setResizeImageEffect(resizeImageOptions);
 * MooBox.setImageDetailsTransition(imageDetailsOptions);
 *
 * OR, alternatively, set them all at once,
 *
 * MooBox.setEffects( { overlay: overlayOptions, resizeImage: resizeImageOptions, imageDetails: imageDetailsOptions } );
 *
 * ## HTML Elements ##
 * MooBox.setLoadingImageSrc( <loading image src> );
 * MooBox.setBottomNavCloseImageSrc( <bottom nav close image src> );
 *
 * OR, alternatively, specify graphical elements in CSS (preferred)
 */

var MooBox = {
    initialize: function(){
        if (!document.getElementsByTagName){ return; }
        var anchors_areas = $$('a[href]', 'area[href]'); // ( All ANCHORS or AREAS containing the "rel" and "href" properties set.

        call_start = function(el) { this.start(el); }.bind(this);
		
		call_changeImage = function( imageIndex ) {
          this.changeImage(imageIndex);
		}.bind(this);

		call_end = function() { this.end(); }.bind(this);

        anchors_areas.each( function(anchor) {
		  if( anchor.getProperty("rel") && anchor.getProperty("rel").toLowerCase().match(/\bmoobox\b/) )
		  {			
            anchor.addEvent( 'click', function(event) {
              new Event(event).stop();
              call_start(this);
              return false;
            });
           };
        });

        // The rest of this code inserts html at the bottom of the page that looks similar to this:
        //
        //    <div id="overlay"></div>
        //    <div id="moobox">
        //        <div id="outerImageContainer">
        //            <div id="imageContainer">
        //                <img id="mooboxImage">
        //                <div style="" id="hoverNav">
        //                    <a href="#" id="prevLink"></a>
        //                    <a href="#" id="nextLink"></a>
        //                </div>
        //                <div id="loading">
        //                    <a href="#" id="loadingLink">
        //                        <img src="images/loading.gif">
        //                    </a>
        //                </div>
        //            </div>
        //        </div>
        //        <div id="imageDataContainer">
        //            <div id="imageData">
        //                <div id="imageDetails">
        //                    <span id="caption"></span>
        //                    <span id="numberDisplay"></span>
        //                    <div id="logoDisplay"></div>
        //                </div>
        //                <div id="bottomNav">
        //                    <a href="#" id="bottomNavClose">
        //                        <img src="images/close.gif">
        //                    </a>
        //                </div>
        //            </div>
        //        </div>
        //    </div>


        var objBody = document.getElementsByTagName("body").item(0);        
		
        /* Overlay Element */
        var objOverlay = new Element( "div", {
          "id":"overlay",
          "styles": { "display": "none" },
          "events": {
            "click": function() { call_end(); }
          }
        });
        objBody.appendChild(objOverlay);

        /* MooBox Container Element */
        var objMooBox = new Element( "div", {
          "id":"moobox",
          "styles": { "display": "none" },
          "events": {
            "click": function(event) {
              var e = new Event(event);
              if( e.target.getProperty('id') == "moobox" ) { call_end(); };
            }
          }
        });
        objBody.appendChild(objMooBox);

        /* OuterImageContainer Element */
        var objOuterImageContainer = new Element( "div", { "id":"outerImageContainer", "styles":{"display":"none"} });        
        objMooBox.appendChild(objOuterImageContainer);

        // When MooBox starts it will resize itself from 250 by 250 to the current image dimension.
        // If animations are turned off, it will be hidden as to prevent a flicker of a
        // white 250 by 250 box.
        if(gMBox_animate){
            objOuterImageContainer.setStyle('width', 250);
            objOuterImageContainer.setStyle('height', 250);
        } else {
            objOuterImageContainer.setStyle('width', 1);
            objOuterImageContainer.setStyle('height', 1);
        }
        
        /* ImageContainer Element */
        var objImageContainer = new Element( "div", { "id":"imageContainer" });        
        objOuterImageContainer.appendChild(objImageContainer);
        
        /* MooBoxImage Element */
        var objMooBoxImage = new Element( "img", { "id":"mooboxImage" });        
        objImageContainer.appendChild(objMooBoxImage);
        
        /* HoverNav Element */
        var objHoverNav = new Element( "div", { "id":"hoverNav" });        
        objImageContainer.appendChild(objHoverNav);
    
        /* PrevLink Element */
        var objPrevLink = new Element( "a", {
          "id":"prevLink",
          "href": "#",
		  "events": {
			"click": function(event) {
				var e = new Event(event).stop();
				prevIndex = gMBox_activeImage-1;
				call_changeImage(prevIndex);
				return false;
			}
		  }
        });
        objHoverNav.appendChild(objPrevLink);
        
        /* NextLink Element */
        var objNextLink = new Element( "a", {
          "id":"nextLink",
          "href": "#",
		  "events": {
			"click": function(event) {
				var e = new Event(event).stop();
				nextIndex = gMBox_activeImage+1;
				call_changeImage(nextIndex);				
				return false;
			}
		  }
        });
        objHoverNav.appendChild(objNextLink);
    
        /* Loading Element */
        var objLoading = new Element( "div", { "id":"loading" });
        objImageContainer.appendChild(objLoading);
    
        /* LoadingLink Element */
        var objLoadingLink = new Element( "a", {
          "id":"loadingLink",
          "href": "#",
          "events": {
            "click": function(event) {
              var e = new Event(event).stop();
              call_end();
              return false;
            }
          }
        });
        objLoading.appendChild(objLoadingLink);
        
        /* LoadingImage Element */
		var objLoadingImage = new Element( "img", { "src": gMBox_fileLoadingImage } );
        objLoadingLink.appendChild(objLoadingImage);
        
        /* ImageDataContainer Element */
        var objImageDataContainer = new Element( "div", {
          "id":"imageDataContainer",
          "class": "clearfix"
        });
        objMooBox.appendChild(objImageDataContainer);

        /* ImageData Element */
        var objImageData = new Element( "div", { "id":"imageData" } );
        objImageDataContainer.appendChild(objImageData);
    
        /* ImageDetails Element */
        var objImageDetails = new Element( "div", { "id":"imageDetails" } );
        objImageData.appendChild(objImageDetails);

        /* Caption, Number Display, and Logo Display Element */
        var objCaption = new Element( "span", { "id": "caption" } );
		var objNumberDisplay = new Element( "span", { "id": "numberDisplay" } );
		var objLogoDisplay = new Element( "div", { "id": "logoDisplay" } );

        objImageDetails.adopt( objCaption, objNumberDisplay, objLogoDisplay );
        //objImageDetails.setHTML('<span id="caption"></span><span id="numberDisplay"></span><div id="logoDisplay"></div>');
        
        /* BottomNav Element */
        var objBottomNav = new Element( "div", { "id":"bottomNav" } );
        objImageData.appendChild(objBottomNav);
    
        /* BottomNavCloseLink Element */
        var objBottomNavCloseLink = new Element( "a", {
          "id":"bottomNavClose",
          "href": "#",
          "events": {
            "click": function(event) {
              var e = new Event(event).stop();
              call_end();
              return false;
            }
          }
        });
        objBottomNav.appendChild(objBottomNavCloseLink);
        
        /* BottomNavCloseImage Element */
		var objBottomNavCloseImage = new Element( "img", { "src": gMBox_fileBottomNavCloseImage } );
		objBottomNavCloseLink.appendChild(objBottomNavCloseImage);
        //objBottomNavCloseLink.setHTML('<img src="'+gMBox_fileBottomNavCloseImage+'" />');
    },
    
    start: function(imageLink) {
        hideSelectBoxes();
        hideFlash();

        // stretch overlay to fill page and fade in
        var arrayPageSize = getPageSize();
        $('overlay').setStyles( {display: "block", height: arrayPageSize[1], opacity:0} );

        call_show_changeImage = function()
		{
          gMBox_imageArray = [];
          imageNum = 0;

          if (!document.getElementsByTagName){ return; }
          var anchors = $$(document.getElementsByTagName('a'));

          // if image is NOT part of a set..
          if((imageLink.getAttribute('rel') == 'moobox')){
            // add single image to gMBox_imageArray
            gMBox_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 gMBox_imageArray
            anchors.each( function(anchor) {
              if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){
                    gMBox_imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
                }
            });
            gMBox_imageArray.removeDuplicates();
            while(gMBox_imageArray[imageNum][0] != imageLink.getAttribute('href')) { imageNum++;}
          }

          // calculate top offset for the moobox and display 
          var arrayPageScroll = getPageScroll();
          var mooboxTop = arrayPageScroll[1] + 14;//(arrayPageSize[3] / 10);
        
		  // hide elements during transition
          if(gMBox_animate) { $('loading').show(); }

		  //$('imageDataContainer').setStyle("visibility", "hidden");
		
		  $('moobox').setStyle("top", mooboxTop);
		  $('moobox').setStyle("display", "block");
          $('moobox').show();
		
          this.changeImage(imageNum);

		};
		call_show_changeImage = call_show_changeImage.bind(this);

        //new Fx.Style($('overlay'), 'opacity', { duration: gMBox_overlayDuration }).start(0,0.8);
	    $('overlay').effects({ duration: gMBox_overlayDuration }).start({'opacity':[0,0.8]}).chain( call_show_changeImage );
    },
	
	hideFeedbackElements: function() {
	  var hidden = $$( ['mooboxImage', 'hoverNav', 'prevLink', 'nextLink', 'imageDataContainer', 'numberDisplay'] );
		
	  hidden.each( function(hide) {
	    hide.hide();
	  });
	},
	
    changeImage: function(imageNum) {
        gMBox_activeImage = imageNum;    // update global var
		$('loading').show();

		this.hideFeedbackElements();

		imgPreloader = new Image();
		// once image is preloaded, resize image container
		imgPreloader.onload=function(){
			$('mooboxImage').src = gMBox_imageArray[gMBox_activeImage][0];
            this.resizeImageContainer(imgPreloader.width, imgPreloader.height);
		}.bind(this);
		imgPreloader.src = gMBox_imageArray[gMBox_activeImage][0];
    },

    resizeImageContainer: function( imgWidth, imgHeight) {
        // get curren width and height
        this.widthCurrent = $('outerImageContainer').getStyle("width").toInt();
        this.heightCurrent = $('outerImageContainer').getStyle("height").toInt();

        // get new width and height
        var widthNew = (imgWidth  + (gMBox_borderSize * 2));
        var heightNew = (imgHeight  + (gMBox_borderSize * 2));

		call_showImage = function() {
			$('prevLink').setStyle("height",imgHeight);
            $('nextLink').setStyle("height",imgHeight);
            $('imageDataContainer').setStyle("width",widthNew);

            this.showImage();
		};
        call_showImage = call_showImage.bind(this);
		
        $('outerImageContainer').show();
		
        var fx_styles = new Fx.Styles( $('outerImageContainer'),{duration: gMBox_resizeDuration, transition: Fx.Transitions.Back.easeInOut} ).start({
          'height': [this.heightCurrent, heightNew],
		  'width': [this.widthCurrent, widthNew]
	    }).chain( function() {
		  call_showImage.delay(250);
	    });
        
    },
    
    showImage: function() {
        $('loading').hide();
		$('mooboxImage').show();
		$('mooboxImage').setOpacity(0);
		
		call_updateDetails = function() { this.updateDetails(); }.bind(this);
		
        new Fx.Style( $('mooboxImage'), 'opacity', { duration: gMBox_resizeDuration }).start(0,1).chain( function() { call_updateDetails(); } );
        this.preloadNeighborImages();
    },
    
    updateDetails: function() {
		$('caption').setHTML(gMBox_imageArray[gMBox_activeImage][1]);
        $('caption').show();
        
        // if image is part of set display 'Image x of x' 
        if(gMBox_imageArray.length > 1){
            $('numberDisplay').show();
            $('numberDisplay').setText( "Image " + eval(gMBox_activeImage + 1) + " of " + gMBox_imageArray.length);
        }
        
		$('imageDataContainer').hide();

		var options = {duration: 250, transition: Fx.Transitions.Cubic.easeOut};
		var fx = new Fx.Styles( $('imageDataContainer'), options );
		children = $('imageDataContainer').getChildren();
		children.each( function(child) { child.setStyle('opacity',0); } );
				
		$('imageDataContainer').setStyle("visibility","hidden");
		$('imageDataContainer').show();
		h = $('imageDataContainer').offsetHeight;
		$('imageDataContainer').setStyles({visibility:"visible", height:0});
		
		call_updateNav = function() { this.updateNav(); }.bind(this);
		
		$('imageDataContainer').effects({duration: 500, transition: Fx.Transitions.Back.easeOut}).start({'height': [0,h]}).chain( function() {
          children.each( function(child) { child.effects(options).start({'opacity':[0,1]}); } );
		  var arrayPageSize = getPageSize();
		  $('overlay').setStyle('height', arrayPageSize[1]);
		  call_updateNav();
        });
    },
    
    updateNav: function() {
      $('hoverNav').show();

        // if not first image in set, display prev image button
        if(gMBox_activeImage != 0){
            $('prevLink').show();
        }

        // if not last image in set, display next image button
        if(gMBox_activeImage != (gMBox_imageArray.length - 1)){
            $('nextLink').show();
        }
        
        this.enableKeyboardNav();
    },
    
    enableKeyboardNav: function() { document.addEvent( 'keydown', this.keyboardAction.bind(this) ); },    
    disableKeyboardNav: function() { document.removeEvent( 'keydown' ); },
    
    keyboardAction: function(event) {
        var e = new Event(event);
        key = e.key;
        
        switch( key )
        {
          case 'x' : this.end(); break;
          case 'o' : this.end(); break;
          case 'c' : this.end(); break;
          case 'esc' : this.end(); break;
          case 'p':
            if(gMBox_activeImage != 0){
                this.disableKeyboardNav();
                this.changeImage(gMBox_activeImage - 1);
            }
          break;
          case 'n':
            if(gMBox_activeImage != (gMBox_imageArray.length - 1)){
                this.disableKeyboardNav();
                this.changeImage(gMBox_activeImage + 1);
            }
          break;
          default: break;
        };
    },
    
    preloadNeighborImages: function() {
      if((gMBox_imageArray.length - 1) > gMBox_activeImage){
        preloadNextImage = new Image();
        preloadNextImage.src = gMBox_imageArray[gMBox_activeImage + 1][0];
      }
      if(gMBox_activeImage > 0){
        preloadPrevImage = new Image();
        preloadPrevImage.src = gMBox_imageArray[gMBox_activeImage - 1][0];
      }
    },
    end: function() {
        this.disableKeyboardNav();
		$('imageDataContainer').hide();
        $('moobox').hide();		
        new Fx.Style('overlay', 'opacity', { duration: gMBox_overlayDuration}).start(0);
        showSelectBoxes();
        showFlash();
    }
};

//
// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.org
//
function getPageScroll(){

    var yScroll;

    if (self.pageYOffset) {
        yScroll = self.pageYOffset;
    } else if (document.documentElement && document.documentElement.scrollTop){     // Explorer 6 Strict
        yScroll = document.documentElement.scrollTop;
    } else if (document.body) {// all other Explorers
        yScroll = document.body.scrollTop;
    }

    arrayPageScroll = new Array('',yScroll) 
    return arrayPageScroll;
}

// -----------------------------------------------------------------------------------

//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
    
    var xScroll, yScroll;
    
    if (window.innerHeight && window.scrollMaxY) {    
        xScroll = document.body.scrollWidth;
        yScroll = window.innerHeight + window.scrollMaxY;
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
        xScroll = document.body.scrollWidth;
        yScroll = document.body.scrollHeight;
    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
        xScroll = document.body.offsetWidth;
        yScroll = document.body.offsetHeight;
    }
    
    var windowWidth, windowHeight;
    if (self.innerHeight) {    // all except Explorer
        windowWidth = self.innerWidth;
        windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
        windowWidth = document.documentElement.clientWidth;
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
        windowWidth = document.body.clientWidth;
        windowHeight = document.body.clientHeight;
    }    
    
    // for small pages with total height less then height of the viewport
    if(yScroll < windowHeight){
        pageHeight = windowHeight;
    } else { 
        pageHeight = yScroll;
    }

    // for small pages with total width less then width of the viewport
    if(xScroll < windowWidth){    
        pageWidth = windowWidth;
    } else {
        pageWidth = xScroll;
    }

    arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
    return arrayPageSize;
}

// -----------------------------------------------------------------------------------

function showSelectBoxes(){
    var selects = document.getElementsByTagName("select");
    for (i = 0; i != selects.length; i++) {
        selects[i].style.visibility = "visible";
    }
}

// ---------------------------------------------------

function hideSelectBoxes(){
    var selects = document.getElementsByTagName("select");
    for (i = 0; i != selects.length; i++) {
        selects[i].style.visibility = "hidden";
    }
}

// ---------------------------------------------------

function showFlash(){
    var flashObjects = document.getElementsByTagName("object");
    for (i = 0; i != flashObjects.length; i++) {
        flashObjects[i].style.visibility = "visible";
    }

    var flashEmbeds = document.getElementsByTagName("embeds");
    for (i = 0; i != flashEmbeds.length; i++) {
        flashEmbeds[i].style.visibility = "visible";
    }
}

// ---------------------------------------------------

function hideFlash(){
    var flashObjects = document.getElementsByTagName("object");
    for (i = 0; i != flashObjects.length; i++) {
        flashObjects[i].style.visibility = "hidden";
    }

    var flashEmbeds = document.getElementsByTagName("embeds");
    for (i = 0; i != flashEmbeds.length; i++) {
        flashEmbeds[i].style.visibility = "hidden";
    }

}

// ---------------------------------------------------

window.onload = function() { MooBox.initialize(); }.bindAsEventListener(window);
