/*
Package contents:

  GalleryItem
  Gallery
  ScrollGallery
  HScrollGallery
  VGalleryGallery
  DoubleScrollGallery
  
*/
var trace = function(str){

    try {
        opera.postError(str);
    } 
    catch (e) {
        try {
            console.log(str);
        } 
        catch (f) {
            //alert(str);
        }
    }

}

/**
 * @author Miroslaw Milewski
 * version: 0.1
 * last modified: 10.VII.2007
 * 
 * Description:
 * 
 * Image object. Contains basic image data, such as path, filename, background color and caption.
 * 
 * Changes:
 * Instructions: 
 * Required values:
 * Other values:
 *  
 */

 var GalleryImage = new Class({
 	
	/**
	 * Basic constructor.
	 * 
	 * @param {Object} _imagePath
	 * @param {Object} _fileName
	 * @param {Object} _backgroundColor
	 * @param {Object} _caption
	 */
	initialize: function(_imagePath, _filename, _backgroundColor, _caption) {
		
		this.imagePath = _imagePath;
		this.filename = _filename;
		this.backgroundColor = _backgroundColor;
		this.caption = _caption;
	},
	
	/**
	 * Getters and setters
	 */
	getImagePath: function() {
		return this.imagePath;
	},
	
	setImagePath: function(_imagePath) {
		this.imagePath = _imagePath;
	},
	
	getFilename: function() {
		return this.filename;
	},
	
	setFilename: function(_filename) {
		this.filename = _filename;
	},
	
	getBackgroundColor: function() {
		return this.backgroundColor;
	},
	
	setBackgroundColor: function(_backgroundColor) {
		this.backgroundColor = _backgroundColor;
	},
	
	getCaption: function() {
		return this.caption;
	},
	
	setCaption: function(_caption) {
		this.caption = _caption;
	},
	
	/**
	 * A convenience metod for returning full image path 
	 */
	getFullImagePath: function() {
		
		return this.imagePath+this.filename;
	},
	
	/**
	 * Overriden toString() function, provides full object property information.
	 */
	toString: function() {
		
		return "GalleryImage Path: " + this.imagePath + "; Filename: " + this.filename + "; Background Color: " + this.backgroundColor + "; Caption: " + this.caption;
	}
 });


/**
 * @author Miroslaw Milewski
 * version: 0.1
 * last modified: 10.VII.2007
 * 
 * Description:
 * 
 * The Gallery object contains a collection of Image objects plus the loading, transition and additional effect logic.
 * This is the parent class for a number of other classes, such as VerticalScrollGallery, HoriontalScrollGallery,  RevealGallery etc.
 * 
 * Changes:
 * Instructions: 
 * Required values:
 * Other values:
 *  
 */

 var Gallery = new Class({
 	
	initialize: function(_imageDataArray) {
		
		this.imageDataArray = _imageDataArray;
		this.imageObjectArray = [];
		this.views = [];
		
		// call
		this.createImageObjectArray();
	},


	/**
	 * Takes an array of image data and creates an array of Image objects.
	 * 
	 * Image data array may be created server side and printed out into the page, or fetched from a remote server upon class 
	 * initialization. In the latter case, the createImageObjectArray should be overloaded and reimplemented in a way allowing
	 * the creation of an Image object array from JSON or XML-based data.
	 * 
	 * The remaining logic in this class is based on an Image object array, oblivious of the way it was created. 
	 */
	createImageObjectArray: function() {
		
		// check if arary not empty
		if(this.imageDataArray.length <= 0) return;

		for(var i=0; i<this.imageDataArray.length; i++) {
			var image = new GalleryImage(
				this.imageDataArray[i][0], 
				this.imageDataArray[i][1], 
				this.imageDataArray[i][2], 
				this.imageDataArray[i][3]
			);
			
			this.imageObjectArray[i] = image;
		}
	},
	
	/**
	 * Uses the mootools Asset object to preload a specified number of images from the image array.
	 * The noOfImagesToPreload parameter specifies the number of images to preload (i.e. 3, 2, 55).
	 * If zero is passed or the passed number is higher than the imageDataArray length, all images
	 * are preloaded. 
	 * 
	 * The onPreloadProgressFunc and onPreloadCompleteFunc are references to functions called on, respectively
	 * completing of the preload and upon loading each of the preloaded images. The onPreloadProgress
	 * should be implemented with a single parameter (i), through wich the index of the currently
	 * preloaded image is being passed.
	 * 
	 * This method is intended to be called from a concrete-ish subclass of the Gallery class, after
	 * the image object array was created, since it uses GalleryImage objects.
	 * 
	 * @param {Object} noOfImagesToPreload
	 * @param {Object} onPreloadProgressFunc
	 * @param {Object} onPreloadCompleteFunc
	 */
	preloadImages: function(noOfImagesToPreload, onPreloadProgressFunc, onPreloadCompleteFunc) {
		
		var iOALength = this.imageObjectArray.length;
		var imageObjectsToPreload = [];
		var imagesToPreload = [];
		
		// check for imageObjectArray length
		if(iOALength == 0) { return; }
		
		// we want to preload all images
		if(noOfImagesToPreload == 0 || noOfImagesToPreload >= iOALength) {
			imageObjectsToPreload = this.imageObjectArray;
		} else { // we only want some of them
			for(var i=0; i<noOfImagesToPreload; i++) {
				imageObjectsToPreload[i] = this.imageObjectArray[i];
			}
		}
		
		// get the paths
		for(var i=0; i<imageObjectsToPreload.length; i++) {
			imagesToPreload[i] = imageObjectsToPreload[i].getFullImagePath();
		}
		// preload
		new Asset.images(imagesToPreload, {
			onProgress: onPreloadProgressFunc,
			onComplete: onPreloadCompleteFunc
		});
	},

	createThumbnailGallery: function(imgPerRow) {

		var numberOfImages = this.imageObjectArray.length;
		var containerEl = $(this.thumbnailDivId); // set in some subclass
		
		if (!containerEl) {
			return false; } // return when there's no element to write to
		
		for(var i=0; i<numberOfImages; i++) {

			var splitImageName = this.imageObjectArray[i].getFilename().split(".");		

			// create an image row for every imagesInRow thumbs
			if(i%imgPerRow == 0) {
				thRowEl = new Element('div', {'id': "thRow"+i, 'class': 'thgRow'});
				containerEl.adopt(thRowEl);
			}		
	
			// create <a>
			var thAnchor = new Element('a', {
				'id': i+'_Anchor',
				'href': '#'
			});

			// create <img>
			var thElement = new Element('img', {
				'id': 'th_'+splitImageName[0]+'Img',
				'class': 'thumbImg',
				'src':  this.imageObjectArray[i].getImagePath() + "thumbs/" +  this.imageObjectArray[i].getFilename()
			});

			// adopt
			thAnchor.adopt(thElement);
			thRowEl.adopt(thAnchor);
		}
	},
	
	/**
	 * Wires functions to appropriate events.
	 */
	wireEvents: function() {

		var numberOfImages = this.imageObjectArray.length;

		for(var i=0; i<numberOfImages; i++) {
			var anchorEl = $(i+'_Anchor');
			anchorEl.addEvent('click', this.onClickThumbFunc.bind(this, i, true));
		}
	},

	toString: function() {
		
		var galleryString = "Image data array: " + this.imageDataArray;
		
		for(var i=0; i<this.imageObjectArray.length; i++) {
			galleryString += "; Image object " + i + ": " + this.imageObjectArray[i].toString();
		}
		
		return galleryString;
	}
 });
 
Gallery.implement(new Events, new Options);


/**
 * @author Miroslaw Milewski
 * version: 0.1
 * last modified: 10.VII.2007
 * 
 * Description:
 * 
 * Parent class for a family of scroll galleries.
 * Extend Gallery.
 * 
 * Changes:
 * Instructions: 
 * Required values:
 * Other values:
 *  
 */

var ScrollGallery = Gallery.extend({
 	
	/**
	 * Sets scrollDown flag value.
	 * @param {Object} elementsCount
	 */
	setScrollDirectionFlag: function(elementsCount) {

		if(this.currentIndex == elementsCount-1) { return false; }
		else if(this.currentIndex == 0) { return true; }
		else { return this.scrollDown; }
	},
	
	/**
	 * Increments/decrements the currentIndexValue according to scrollDown value.
	 */
	modifyIndexValue: function() {

		if(this.scrollDown == true) { this.currentIndex++; }
		else { this.currentIndex--; }
	},
	
	getCurrentIndex: function() {
		return this.currentIndex;
	},
	
	getCurrentImage: function() {
		return this.imageObjectArray[this.currentIndex]
	},
	
	scrollStart: function() {
		// if (window.debugging) trace('scrollStart');
		this.fireEvent('onScrollStart',{target:this, type:'onScrollStart'});
	},
	
	scrollComplete: function() {
		// if (window.debugging) trace('scrollComplete');
		this.fireEvent('onScrollComplete',{target:this, type:'onScrollComplete'});
	},
	
	/**
	 * Stop scroll mid scroll and start a new one.
	 * 
	 * @param {Object} id
	 */
	onClickThumbFunc: function(id) {

		this.currentIndex = id;
		this.imgScrollFx.stop();
		this.scrollImages();
	}
});


/**
 * @author Miroslaw Milewski
 * version: 0.1
 * last modified: 10.VII.2007
 * 
 * Description:
 * 
 * Gallery with a horizontal scroll, extends base Gallery class.
 * 
 * Changes:
 * Instructions: 
 * Required values:
 * Other values:
 *  
 */


 var HorizontalScrollGallery = ScrollGallery.extend({
 	
	initialize: function(_imageDataArray, _createThumbnails, _thumbnailDiv, _sliderDiv, _delay) {
		
		// call parent initializer
		this.parent(_imageDataArray);
		
		this.createThumbnails = _createThumbnails;
		this.thumbnailDivId = _thumbnailDiv;
		this.sliderDivId = _sliderDiv;
		if (window.debugging) { trace('$(this.sliderDivId)'+$(this.sliderDivId)); }
		this.containerDiv = $(this.sliderDivId).getParent();
		this.currentIndex = 0;
		this.scrollDown = false;

		// grabs slider parent and creates an FX instance
		this.imgScrollFx = new Fx.Scroll(this.containerDiv.id, {
			wait: true,
			duration: 1500,
			transition: Fx.Transitions.Quad.easeInOut
		});
		
		this.imgScrollFx.addEvent('onStart', this.scrollStart.bind(this));
		this.imgScrollFx.addEvent('onComplete', this.scrollComplete.bind(this));
		
		if(this.createThumbnails === true && this.thumbnailDivId !== undefined) {
			this.createThumbnailGallery(200);
			this.wireEvents();
		}

		this.createDivs();
		this.scrollImages();
		this.scrollImages.periodical(_delay, this);
	},

	/**
	 * Creates image holders in specified container
	 */
	createDivs : function() {

		var containerEl = $(this.sliderDiv);
		var iOA = this.imageObjectArray;
	
		// loop over image paths array
		for(var i=0; i<iOA.length; i++) {
	
			var imageName = iOA[i].getFilename().split(".");
			var imgEl = new Element('img', {'id': imageName[0], 'src': iOA[i].getImagePath() + iOA[i].getFilename()}); // image

			$(this.sliderDivId).adopt(imgEl); // put div in container
		}
	},
	
	/**
	 * Executes horizontal and vertical scrolls.
	 */
	scrollImages: function() {
	
		var elementArrayString = "#" + this.sliderDivId + " img";
		var elements = $$(elementArrayString);
		var elementsCount = elements.length;

		var slideDistance = this.calculateSlideDistance(elements);
		this.imgScrollFx.scrollTo(slideDistance, 0);
	
		// set scrollDown flag
		this.scrollDown = this.setScrollDirectionFlag(elementsCount);
				
		// increment/decrement
		this.modifyIndexValue();
	},
	
	
	/**
	 * Calculates required slide distance based on image widths from passed image element collection.
	 * Required only for the horizontal slideDirection. 
	 * 
	 * @param {Object} elements
	 */
	calculateSlideDistance: function(elements) {
	
		var maxAllowedSlideDistance = this.calculateMaxAllowedSlideDistance(elements);
		var slideDistance = 0;
		
		for(var i=0; i<this.currentIndex; i++) {
			var imgEl = elements[i];
			imgWidth = imgEl.width;

			// crude hack to avoid the first slider element - refactor upwards, get the proper collection in parent method
			if(imgWidth == undefined) { continue; }
	
			slideDistance += imgWidth;
		}
	
		if(slideDistance > maxAllowedSlideDistance)
			return maxAllowedSlideDistance;
		
		return slideDistance;
	},

	/**
	 * Calculates the maximum slide distance possible as a sum of contained image widths.
	 * 
	 * @param {Object} elements
	 */
	
	calculateMaxAllowedSlideDistance: function(elements) {
	
		var containerDivWidth = $(this.containerDiv).getCoordinates().width;
		var maxSlideDistance = 0;
	
		for(var i=0; i<elements.length; i++) {
			var imgEl = elements[i];
			imgWidth = imgEl.width;
			maxSlideDistance += imgWidth;
		}
	
		return maxSlideDistance-containerDivWidth;
	},
	toString: function() {
		return "HorizontalScrollGallery";
	}	
	
 });
 
 
 /**
 * @author Miroslaw Milewski
 * version: 0.1
 * last modified: 24.VII.2007
 * 
 * Description:
 * 
 * Gallery with a vertical scroll, extends base Gallery class.
 * 
 * Changes:
 * Instructions: 
 * Required values:
 * Other values:
 *  
 */

 var VerticalScrollGallery = ScrollGallery.extend({
 	
	initialize: function(_imageDataArray, _createThumbnails, _thumbnailDivId, _containerDivId, _delay) {
		
		// call parent initializer
		this.parent(_imageDataArray);
		
		this.createThumbnails = _createThumbnails;
		this.thumbnailDivId = _thumbnailDivId;
		this.containerDivId = _containerDivId;
		this.delay = _delay;
		this.currentIndex = 0;
		this.scrollDown = false;

		// grabs slider parent and creates an FX instance
		this.imgScrollFx = new Fx.Scroll(this.containerDivId, {
			wait: true,
			duration: 1500,
			transition: Fx.Transitions.Quad.easeInOut
		});

		this.imgScrollFx.addEvent('onStart', this.scrollStart.bind(this));
		this.imgScrollFx.addEvent('onComplete', this.scrollComplete.bind(this));

		if(this.createThumbnails == true && this.thumbnailDivId !== undefined) {
			this.createThumbnailGallery(2);
			this.wireEvents();	
		}

		var inst = this;

		// Example application of the preload method.
		// The preloader div may contain a flash movie or some other more visually pleasing content.
		this.preloadImages(5, 
			
			// called on preload
			function(i) {
				if ( $chk($('preloaderDiv')) ) $('preloaderDiv').setStyles({
					'left': ($(inst.containerDivId).getCoordinates().width / 2) - ($('preloaderDiv').getCoordinates().width / 2),
					'top': ($(inst.containerDivId).getCoordinates().height / 2) - ($('preloaderDiv').getCoordinates().height / 2),
					'visibility': 'visible'
				});
			}, 
			
			// called on complete
			function() {
				if ( $chk($('preloaderDiv')) ) $('preloaderDiv').setStyles({'visibility': 'hidden', 'display': 'none'});
				
				inst.createDivs();
				inst.scrollImages();
				inst.timeout = inst.scrollImages.periodical(_delay, inst);
			}
		);
	},
	

	/**
	* Creates a column of divs used for scrolling.
	* 
	*/
	createDivs: function() {
	
		var containerEl = $(this.containerDivId);
		var iOA = this.imageObjectArray;
	
		// loop over GalleryImage array
		for(var i=0; i<iOA.length; i++) {
			
			var imageName = iOA[i].getFilename().split(".");
			var divEl = new Element('div', 	{'id': imageName[0]}); // imageHolder div
			var imgEl = new Element('img', 	{'id': imageName[0]+'Image', 'src': iOA[i].getImagePath() + iOA[i].getFilename()}); // image
			
			divEl.adopt(imgEl); // put image in div
			
			// create caption paragraph
			var capEL = new Element('p',	{'id': imageName[0]+'Caption'});
			
			if(iOA[i].getCaption()) {
				capEL.setHTML(iOA[i].getCaption());	
			} else {
				capEL.setHTML("  ");
			}

			divEl.adopt(capEL); // put p in div

			containerEl.adopt(divEl); // put div in container
		}
		
		// set proper container size for first element
		//this.sizeContainer.delay(500,this);
	},
	
	/**
	 * Executes vertical scrolls. 
	 * 
	 */
	scrollImages: function() {
	
		var elementsCount = this.imageObjectArray.length;
		var nextId = this.imageObjectArray[this.currentIndex].getFilename().split('.');
		this.imgScrollFx.toElement(nextId[0]);

		// set scrollDown flag
		this.scrollDown = this.setScrollDirectionFlag(elementsCount);

		// set proper container size
		this.sizeContainer.delay(100,this);
		
		// increment/decrement
		this.modifyIndexValue();
		
	},
	
	/**
	 * Dynamically resizes the container based on image and caption height.
	 */
	sizeContainer: function() {
		// get preset container height
		var containerHeight = $(this.containerDivId).getSize().size.y;
//		if (window.debugging) trace('$(this.containerDivId) '+$(this.containerDivId));
//		if (window.debugging) trace('containerHeight '+containerHeight);
//		if (window.debugging) trace('this.currentIndex '+this.currentIndex);
		
		// calculate actual container height
		var imgBaseName = this.imageObjectArray[this.currentIndex].getFilename().split('.')[0];
		var divElHeight = $(imgBaseName).getSize().size.y;
		var imgElHeight = $(imgBaseName + "Image").getSize().size.y;
		var capElHeight = $(imgBaseName + "Caption").getSize().size.y;
		
//		if (window.debugging) trace('$(imgBaseName) '+$(imgBaseName));
//		if (window.debugging) trace('divElHeight '+divElHeight);
//		if (window.debugging) trace('imgElHeight '+imgElHeight);
//		if (window.debugging) trace('capElHeight '+capElHeight);

		if(containerHeight != divElHeight) {
			
			// SAFARI bugfix: check for image element height
			if(imgElHeight == 0) { divElHeight = 0; }
			
			$(this.containerDivId).effect('height',{duration:500}).start(containerHeight, divElHeight);
		}
	}
	
 });
 
 
 /**
 * @author Miroslaw Milewski
 * version: 0.1
 * last modified: 10.VII.2007
 * 
 * Description:
 * 
 * 
 * 
 * Changes:
 * Instructions: 
 * Required values:
 * Other values:
 *  
 */

 var DoubleRevealGallery = Gallery.extend({
 	
	initialize: function(_imageDataArray) {

		// call parent initializer
		this.parent(_imageDataArray);
		
		// way of keeping track of image to pass back colour - will set to the upper image index in each case
		this.currentIndex=-1;
		
		this.displayHeight=600;
		
		// this should be accessible via getters and setters
		this.imagesInRow = 0;
		
	},
	
	/**
	* Listen for Fx slide to finish & fire event
	*/
	slideStart: function() {
		this.slidersMoving = true;
		this.fireEvent('onSlideStart',{target:this, type:'onSlideStart'});
	},
	
	slideComplete: function() {
		this.slidersMoving = false;
		this.slidersOpen = !this.slidersOpen; // flip whatever the state was
		
		this.fireEvent('onSlideComplete',{target:this, type:'onSlideComplete'});
		if(this.slidersOpen) this.changeComplete();

	},
	
	changeComplete: function() {
		this.fireEvent('onChangeComplete',{target:this, type:'onChangeComplete'});
	}, 
	
	createGallery: function(_containerDivId) {
		this.containerDiv  = $(_containerDivId);
		if (!$chk(this.containerDiv)) { return; }
	
		this.upperContainerDiv = new Element('div', {
			'id' : 'upperContainer'
		});
		
		this.lowerContainerDiv = new Element('div', {
			'id' : 'lowerContainer'
		});

		this.upperImageElement = new Element('img', { 'id' : 'upperImage' });
		this.upperMask = new Element('div', { 'id' : 'upperContainerMask' });
		
		this.upperContainerDiv.adopt(this.upperImageElement);
		this.upperContainerDiv.adopt(this.upperMask);
		
		
		this.lowerImageElement = new Element('img', { 'id' : 'lowerImage' });
		this.lowerMask = new Element('div', { 'id' : 'lowerContainerMask'});
		
		this.lowerContainerDiv.adopt(this.lowerImageElement);
		this.lowerContainerDiv.adopt(this.lowerMask);
		
		this.upperContainerDiv.setStyles({
			'position': 'relative',
			'top': '0px',
			'left': '0px',
			'z-index': '20'
		});
		this.lowerContainerDiv.setStyles({
			'position': 'relative',
			'z-index': '20'
		});
		
		
		this.captionContainerDiv= new Element('div', { 'id' : 'captionContainer'});

		this.containerDiv.adopt(this.upperContainerDiv);
		this.containerDiv.adopt(this.lowerContainerDiv);
		
		this.captionContainerDiv.injectBefore(this.lowerMask);

		this.upperMask.setStyle('display', 'block');
		this.lowerMask.setStyle('display', 'block');
		
		this.loadingContainerDiv= new Element('div', { 'id' : 'loadingContainer'});
		this.loadingContainerDiv.setStyles({
			'position': 'absolute',
			'top': '5px',
			'left': '5px',
			'z-index': '21'
		});
		this.loadingContainerDiv.setHTML('loading...');
		this.containerDiv.adopt(this.loadingContainerDiv);
		
		this.upperImgLoaded=false;
		this.lowerImgLoaded=false;
		
		// private attributes - make a kind of 'state machine' onStart & onComplete events 
		this.slidersOpen = false;
		this.slidersMoving = false;
		
		this.upperSlide 	= new Fx.Styles(this.upperMask, 			{duration: 500, transition: Fx.Transitions.Quad.easeInOut});
		this.lowerSlide 	= new Fx.Styles(this.lowerMask, 			{duration: 500, transition: Fx.Transitions.Quad.easeInOut});
		this.captionFade 	= new Fx.Styles(this.captionContainerDiv, 	{duration: 500, transition: Fx.Transitions.Quad.easeInOut});
		this.containerSize 	= new Fx.Styles(this.containerDiv, 			{duration: 500, transition: Fx.Transitions.Quad.easeInOut});
		
		this.upperSlide.addEvent('onStart', this.slideStart.bind(this));
		this.upperSlide.addEvent('onComplete', this.slideComplete.bind(this));
		
		this.containerSize.addEvent('onComplete', this.showImages.bind(this));
		
	},
	
	start: function() {
		this.newImages(0,1);
	},

	 /**
	 * 
	 * Creates the thumbnail gallery in specified container.
	 * Overrides 'native' method from Gallery.
	 * 
	 * @param {Object} containerId
	 * @param {Object} imagePath
	 * @param {Object} imageArray
	 */
	createThumbnailGallery: function(_thumbnailDivId, _imagesInRow) {
		
		this.thumbnailDiv = $(_thumbnailDivId);
		if (!$chk(this.thumbnailDiv)) { return; }
		
		this.imagesInRow = (_imagesInRow)? _imagesInRow : this.imagesInRow;
	
		var numberOfImages = this.imageObjectArray.length;
		var numberOfImagePairs = Math.ceil(numberOfImages/2);
		var numberOfRows = 0;
		
		var thRowEl = null;

		var inst = this;
		
		for(var i=0; i<numberOfImagePairs; i++) {
	
			var splitImageName = this.imageObjectArray[i].getFilename().split(".");
			var upperImageIndex = i*2;
			var lowerImageIndex = upperImageIndex+1;
			
			// create an image row for every three thumbs
			if (window.debugging) trace(i%this.imagesInRow);
			if(i%this.imagesInRow == 0 || !thRowEl) {
				thRowEl = new Element('div', {'id': "thRow"+i, 'class': 'thgRow'});
				this.thumbnailDiv.adopt(thRowEl);
			}		
	
			// create <divs> - made <a> to trigger pointer/finger
			var thDiv = new Element('a', {
				'class': 'thumbsHolderDiv',
				'id': upperImageIndex + "_" + lowerImageIndex,
				'href' : '#',
				'events': {
					'click': function() {
						imageIndexes = this.id.split("_");
						inst.newImages(imageIndexes[0], imageIndexes[1]);
						return false;
					}
				}
			});
			
			// create upper <img>
			var upperImage = new Element('img', {
				'id': 'thr_'+splitImageName[0]+'Upper', 
				'class': 'upperThumbImg',
				'src': this.imageObjectArray[upperImageIndex].getImagePath() + "thumbs/" + this.imageObjectArray[upperImageIndex].getFilename()
			});
	
			// create lower <img>
			var lowerImage = new Element('img', {
				'id': 'thr_'+splitImageName[0]+'Lower', 
				'class': 'lowerThumbImg',
				'src': this.imageObjectArray[lowerImageIndex].getImagePath() + "thumbs/" + this.imageObjectArray[lowerImageIndex].getFilename()
			});
			
			
			// adopt
			thDiv.adopt(upperImage);
			thDiv.adopt(lowerImage);
			thRowEl.adopt(thDiv);
		}
	},
	
	
	newImages: function(upperImageIndex, lowerImageIndex) {
		if (window.debugging) trace('newImages: '+upperImageIndex+','+lowerImageIndex);	
		if (this.currentIndex!=upperImageIndex) {
			if (window.debugging) trace('this.slidersOpen '+this.slidersOpen);
			if(this.slidersOpen) {
				var tempEvent=function() {
					this.loadNewImages(upperImageIndex, lowerImageIndex);
				  this.removeEvent('onSlideComplete', tempEvent );
				}.bind(this);
						
				this.addEvent('onSlideComplete', tempEvent);
				this.hideImages();
				
			} else {
				this.loadNewImages(upperImageIndex, lowerImageIndex)
			}
		}
	},
	
	loadNewImages: function(upperImageIndex, lowerImageIndex) {
		
	  if (window.debugging) trace('load new');
		this.upperImgLoaded=false;
		this.lowerImgLoaded=false;
		
		this.currentIndex=upperImageIndex;
		
		this.upperImageElement.onload=function() {
			this.upperImgLoaded=true;
			if (window.debugging) trace('upperImageElement.onload');
			if (this.lowerImgLoaded) this.resize();
		}.bind(this);
		
		this.lowerImageElement.onload=function() {
			this.lowerImgLoaded=true;
			if (window.debugging) trace('lowerImageElement.onload');
			if (this.upperImgLoaded) this.resize();
		}.bind(this);
		
		this.loadingContainerDiv.setStyle('display', 'block');
		
		this.upperImageElement.src = this.imageObjectArray[upperImageIndex].getImagePath()+this.imageObjectArray[upperImageIndex].getFilename();
		this.lowerImageElement.src = this.imageObjectArray[lowerImageIndex].getImagePath()+this.imageObjectArray[lowerImageIndex].getFilename();
		this.captionFade.set({ 'opacity': 0 });
		this.captionContainerDiv.setHTML(this.imageObjectArray[upperImageIndex].getCaption());
		this.captionContainerDiv.setStyle('display', this.imageObjectArray[upperImageIndex].getCaption()==""? 'none' : 'block ');
	},
	
	
	hideImages: function() {
   if (window.debugging) trace('hideImages');
		if(this.slidersOpen && !this.slidersMoving) {
			this.upperSlide.start({ 'top': 0 });
			this.lowerSlide.start({ 'top': 0 });
			this.captionFade.start({ 'opacity': 0 });
		}
	},
	
	showImages: function() {
	    if (window.debugging) trace('showImages');
		if(!this.slidersOpen && !this.slidersMoving) {
			this.upperSlide.start({ 'top': -(this.upperContainerDiv.getSize().size.y) });
			this.lowerSlide.start({ 'top': this.lowerContainerDiv.getSize().size.y });
			this.captionFade.start({ 'opacity': 100 });
		}
	},
	
	showOrHideImages: function() {
		if(!this.slidersOpen) {
			this.showImages();
		} else {
			this.hideImages();
		}
	},
	
	getCurrentIndex: function() {
		return this.currentIndex;
	},
	getCurrentImage: function() {
		return this.imageObjectArray[this.currentIndex]
	},
	

	/**
	 * Dynamically resizes the container based on image and caption height.
	 */
	resize: function() {
		if (window.debugging) trace('resize');
		
		this.loadingContainerDiv.setStyle('display', 'none');

		var imgOneHeight = this.upperContainerDiv.getSize().size.y;
		var imgTwoHeight = this.lowerContainerDiv.getSize().size.y;
		
		if (window.debugging) trace('imgOneHeight '+imgOneHeight);
		if (window.debugging) trace('imgTwoHeight '+imgTwoHeight);
		
		this.displayHeight = imgOneHeight + imgTwoHeight;

		this.containerSize.start({ 'height': this.displayHeight });

		this.upperMask.setStyle('height', imgOneHeight);
		this.lowerMask.setStyle('height', imgTwoHeight);

	}

});

DoubleRevealGallery.implement(new Events, new Options);
