
	/*
		----------------------------------------------------------------------
		Script		: slideshow.js
		Description	: Main client-side functionality for slideshow.
		----------------------------------------------------------------------
	*/

var SlideShow = new Class({
	Implements: [Options, Events],
	options: {
		modOptions: {
			stopOnStart: false,
			stopOnClick: false,
			moduleId: '',
			container: 'slideshow-box',
			loop: true,
			useThumbs: true,
			separation: 0,
			imageData: [],
			loadingClass: 'loading'
		},
		fxOptions: {
			imageFx: 'fade',
			thumbFx: 'slider',
			direction: 'right',
			fxParams: {
				duration: 2000,
				wait: 5000,
				transition: Fx.Transitions.linear
			}
		},
		imageOptions: {
			resize: [],
			styles: {
				backgroundImage: 'none',
				borderWidth: 0,
				paddingTop: 0, paddingRight: 0, paddingBottom: 0, paddingLeft: 0,
				marginTop: 0, marginRight: 0, marginBottom: 0, marginLeft: 0
			},
			useControls: true
		},
		thumbOptions: {
			userSupplied: false,
			mouseBehavior: true,
			thumbData: [],
			resize: [],
			useLinks: false,
			useTips: false,
			tipsText: {},
			links: [],
			ajaxLinks: [],
			bottomPosition: true,
			horizCenter: true,
			thumbCenter: true,
			containerStyles: {
				paddingTop: 0, paddingRight: 0, paddingBottom: 0, paddingLeft: 0,
				marginTop: 0, marginRight: 0, marginBottom: 0, marginLeft: 0
			},
			wrapperStyles: {
				borderWidth: 0,
				float: 'left',
				paddingTop: 0, paddingRight: 0, paddingBottom: 0, paddingLeft: 0,
				marginTop: 0, marginRight: 0, marginBottom: 0, marginLeft: 0,
				position: 'relative'
			},
			thumbStyles: {
				borderWidth: 0,
				padding: 0,
				position: 'absolute',
				left: '50%',
				top: '50%'
			},
			layout: {
				placement: 'out',
				location: 'left'
			},
			slider: {
				styles: {
					borderColor: '#115',
					borderStyle: 'solid',
					borderWidth: 2
				},
				className: 'outline'
			},
			mask: {
				tint: '#ccc',
				styles: {
					opacity: 0.7
				},
				className: 'overlay'
			}
		}
	},	//	end @options.

	initialize: function(options) {
		
		this.setOptions(options);
		
		if(!document.getElementById(this.options.modOptions.container) || this.options.modOptions.imageData.length == 0) {return}
		
		this.container = $(this.options.modOptions.container).set('styles', {overflow: 'hidden'});
		this.imageData = this.options.modOptions.imageData;
		this.fxParams = this.options.fxOptions.fxParams;
		this.useThumbs = this.options.modOptions.useThumbs;
		
		this.imageStyles = this.options.imageOptions.styles;
		
		var maxH = maxW = 0;
		this.imageData.each(function(image, i){
			if(i == 0){maxH = image.size.height; maxW = image.size.width}
			else {
				if(maxH < image.size.height){maxH = image.size.height}
				if(maxW < image.size.width){maxW = image.size.width}
			}
		}, this);
		
		this.imageStyles = $H(this.imageStyles).combine({height: maxH, width: maxW});
		
		if(this.imageStyles.backgroundImage != 'none'){
			this.getBgImage();
		} else {
			this.doLayout();
		}
		
		//this.fireEvent('onStartShow', '', 100);
		
	},	//	end @initialize.
	
	getBgImage: function() {	//	begin @getBgImage.
		
		this.bgImg = new Asset.image(this.imageStyles.backgroundImage, {
			onload: function(){
				this.imageStyles.paddingLeft = Math.round(Math.abs(this.imageStyles.width - this.bgImg.width) / 2);
				this.imageStyles.paddingRight = Math.abs(this.imageStyles.width - this.bgImg.width) - this.imageStyles.paddingLeft;
				this.imageStyles.paddingTop = Math.round(Math.abs(this.imageStyles.height - this.bgImg.height) / 2);
				this.imageStyles.paddingBottom = Math.abs(this.imageStyles.height - this.bgImg.height) - this.imageStyles.paddingTop;
				this.imageStyles.backgroundImage = 'url(' + this.imageStyles.backgroundImage + ')';
				this.doLayout();
			}.bind(this)
		});
	},	//	end @getBgImage.
	
	doLayout: function() {	//	begin @doLayout.
		
		this.imageContainer = new Element('div', {'class': 'slideshowContainer'}).set('styles', this.imageStyles);
		
		if(this.useThumbs){
			
			var thumbData = this.options.thumbOptions.thumbData;
			
			if(!this.options.thumbOptions.userSupplied || thumbData.length == 0)
				{this.options.thumbOptions.thumbData = this.imageData}
			
			if(this.options.fxOptions.thumbFx != 'none' && thumbData.length != this.imageData.length)
				{this.options.thumbOptions.thumbData = this.imageData}
			
			var obj = {
				fxOptions: this.options.fxOptions,
				thumbOptions: this.options.thumbOptions,
				onComplete: this.doThumbs.bind(this),
				onFailure: this.errorHandler.bind(this)
			};
			
			this.thumbManager = new ThumbManager(this.baseURI, obj);
		}
		
		this.loading = new Element('div', {'class': this.options.modOptions.loadingClass}).set('styles', {
			position: 'absolute',
			top: this.imageStyles.paddingTop,
			left: this.imageStyles.paddingLeft,
			zIndex: 3,
			display: 'none',
			width: this.imageStyles.width,
			height: this.imageStyles.height
		}).inject(this.imageContainer);
		
		if(this.options.imageOptions.useControls){this.setControls()}
			
		this.oldImage = new Element('div').set('styles', {
			position: 'absolute',
			overflow: 'hidden',
			top: this.imageStyles.paddingTop,
			left: this.imageStyles.paddingLeft,
			opacity: 0,
			width: this.imageStyles.width,
			height: this.imageStyles.height
		}).inject(this.imageContainer);
		
		this.newImage = this.oldImage.clone();
		this.newImage.inject(this.imageContainer);
				
		this.timer = 0;
		this.image = -1;
		this.imageLoaded = 0;
		this.stopped = true;
		this.started = false;
		this.animating = false;
		
		if(!this.useThumbs){
			this.imageContainer.inject(this.container);
			var imageSize = this.imageContainer.getSize();
			this.container.set('styles', {width: imageSize.x + this.imageStyles.marginLeft + this.imageStyles.marginRight, height: imageSize.y + this.imageStyles.marginTop + this.imageStyles.marginBottom});
			this.fireEvent('onStartShow', '', 100);
		}
	},	//	end @layout.
	
	doThumbs: function() {	//	begin @doThumbs.
		
		var thumbContainerStyles = this.options.thumbOptions.containerStyles;
		var wrapperStyles = this.thumbManager.wrapperStyles;
		var thumbStyles = this.thumbManager.thumbStyles;
		var thumbImages = this.thumbManager.thumbImages;
		var wrapOuter = wrapperStyles.marginLeft + wrapperStyles.marginRight + 2 * wrapperStyles.borderWidth + wrapperStyles.paddingLeft + wrapperStyles.paddingRight;
		var imageOuter = this.imageStyles.marginLeft + this.imageStyles.marginRight + 2 * this.imageStyles.borderWidth + this.imageStyles.paddingLeft + this.imageStyles.paddingRight;
		var numImages = thumbImages.length;
		var wrapperDims = {height: wrapperStyles.height + wrapOuter, width: wrapperStyles.width + wrapOuter};
		
		var thumbLocation = this.options.thumbOptions.layout.location;
		
		if(thumbLocation == 'left' || thumbLocation == 'right'){
			
			if((ratio = Math.floor(this.imageStyles.height / wrapperDims.height)) < 1) {ratio = 1}
			var numCols = Math.ceil(numImages / ratio);
			var numRows = Math.ceil(numImages / numCols);
		
			if(this.options.thumbOptions.bottomPosition) thumbContainerStyles.marginTop = imageOuter / 2 + this.imageStyles.height + wrapOuter / 2 - numRows * wrapperDims.height - thumbContainerStyles.paddingTop;
			thumbContainerStyles.width = numCols * wrapperDims.width;
			
			var containerWidth = thumbContainerStyles.width + thumbContainerStyles.paddingLeft + thumbContainerStyles.paddingRight + thumbContainerStyles.marginLeft + thumbContainerStyles.marginRight + this.imageStyles.width + imageOuter + this.options.modOptions.separation;
			this.container.set('styles', {width: containerWidth});
			
			this.thumbManager.thumbContainer.set('styles', thumbContainerStyles);
			
			if(thumbLocation == 'left'){
				this.imageContainer.addClass('right').inject(this.container);
				this.thumbManager.thumbContainer.addClass('left').inject(this.imageContainer, 'before');
			} else {
				this.imageContainer.addClass('left').inject(this.container);
				this.thumbManager.thumbContainer.addClass('right').inject(this.imageContainer, 'after');
			}
		} else {
			
			if((ratio = Math.floor((this.imageStyles.width + imageOuter) / wrapperDims.width)) < 1) {ratio = 1}
			var numRows = Math.ceil(numImages / ratio);
			var numCols = Math.ceil(numImages / numRows);
			
			this.container.set('styles', {width: this.imageStyles.width + imageOuter});
			this.imageContainer.inject(this.container);
			thumbContainerStyles.width = numCols * (wrapOuter + wrapperStyles.width);
			if(this.options.thumbOptions.horizCenter) thumbContainerStyles.margin = '0pt auto';
			this.thumbManager.thumbContainer.set('styles', thumbContainerStyles);
			this.thumbManager.thumbContainer.inject(this.container, thumbLocation);
		}
		
		if(this.options.thumbOptions.mouseBehavior) this.setBehaviors();
		
		if(this.thumbManager.thumbFx) {
			this.thumbManager.thumbFx.setPosition(this.thumbManager.thumbImages[0]);
		}
		
		this.fireEvent('startShow', '', 100);
		
	},	//	end @doThumbs.
	
	setBehaviors: function() {	//	begin @setBehaviors.
		
		if(this.thumbManager.thumbWrappers.length != 0){
			if(this.options.fxOptions.thumbFx != 'mask'){
				this.thumbManager.thumbWrappers.each(function(wrapper, i){
					if(!this.options.modOptions.stopOnClick) {
					wrapper.set('events', {
						'mouseenter': function(){
							this.stopped = false;	//	In case loop has been set to false.
							this.resetAnimation();
							this.image = i - 1;
							this.next(false);
							if(this.options.fxOptions.thumbFx == 'none'){this.stop()}
						}.bind(this),
						'mouseleave': function(){
							if(this.options.fxOptions.thumbFx == 'none' && !this.options.modOptions.stopOnStart){
								this.stopped = false;
								//this.resetAnimation();
								this.next(true);
							}
						}.bind(this)
					});
					}
					if(this.options.modOptions.stopOnClick) {
						wrapper.addEvent('click', function(e) {
							e.stop();
							var target = e.target.src.split('/');
							$('selectedImage').value = 'images/' + target[target.length - 1].substr(2);
							this.stopped = false;
							this.resetAnimation();
							this.image = i - 1;
							this.next(false);
							this.stop();
						}.bind(this));
					}
				}, this);
			}
		}
		
		if(this.thumbManager.thumbFx){
			switch(this.options.fxOptions.thumbFx){
			case 'slider':
				this.thumbManager.thumbFx.slider.set('events', {
					'mouseenter': function(){
						this.stop();
					}.bind(this),
					'mouseleave': function(){
						if(!this.options.modOptions.stopOnStart) {
							this.stopped = false;
							this.resetAnimation();
							this.next(true);
						}
					}.bind(this)
				});
				break;
			case 'mask':
				this.thumbManager.thumbFx.masks.each(function(mask, i){
					mask.set('events', {
						'mouseenter': function(){
							this.stopped = false;	//	In case loop has been set to false.
							this.resetAnimation();
							this.image = i - 1;
							this.next(false);
							this.stop();
						}.bind(this),
						'mouseleave': function(){
							if(!this.options.modOptions.stopOnStart) {
								this.stopped = false;
								this.resetAnimation();
								this.next(true);
							}
						}.bind(this)
					});
				}, this);
				break;
			case 'strip':
			case 'none':
			default:
				break;
			}
		}
	},	//	end @setBehaviors.
	
	setControls: function(){	//	begin @setControls.
		
		var buttons = $H({start:'img/start.gif', previous:'img/previous.gif', pause:'img/pause.gif', next:'img/next.gif', end:'img/end.gif'});
		var controls = new Element('div', {'class': 'controls'}).set('styles', {
			bottom: '10%',
			left: '50%',
			zIndex: 3,
			opacity: 0
		}).inject(this.imageContainer);
		
		controls.set('styles', {marginLeft: -Math.floor(controls.getStyle('width').toInt() / 2)});
			
		var ctrlWrap = new Element('div', {'class': 'ctrlWrap'}).inject(controls);
		
		buttons.each(function(src, id){
			var button = new Element('a', {'id': id, 'class': 'ctrlButton', 'href': '#', 'title': id}).inject(ctrlWrap);
			new Element('img', {'src':src, 'alt':id}).inject(button);
			button.addEvent('click', function(event){
				event.stop();
				switch(id){
				case 'start':
					this.stopped = false;
					this.image = -1;
					this.next(false);
					break;
				case 'previous':
					this.stopped = false;
					this.previous();
					break;
				case 'pause':
					this.stop();
					break;
				case 'next':
					this.stopped = false;
					this.next();
					break;
				case 'end':
					this.stopped = false;
					this.image = this.imageData.length - 2;
					this.next(false);
					break;
				default:
					break;
				}
			}.bind(this));
		}, this);
		
		this.imageContainer.addEvent('mouseenter', function(){
			controls.fade('in');
		}.bind(this));
		
		this.imageContainer.addEvent('mouseleave', function(){
			controls.fade('out');
		}.bind(this));
	},	//	end @setControls.
	
	load: function(){
		$clear(this.timer);
		this.loading.set('styles', {display: 'block'});
		this.image++;
		
		delete this.imageObj;
		
		doLoad = true;
		if(el = this.imageContainer.retrieve(this.image)){
			this.imageObj = el;
			doLoad = false;
			this.add = false;
			this.show();
		}
		
		if(doLoad){
			this.add = true;
			this.imageObj = new Asset.image('images/' + this.imageData[this.image].name, {onload: this.show.bind(this)});
		}
		
	},	//	end @load.

	show: function(add){	//	begin @show.
		
		if(this.add){this.imageContainer.store(this.image, this.imageObj)}
		
		this.newImage.set('styles', {zIndex: 1, opacity: 0});
		
		var img = this.newImage.getElement('img');
		if(img){
			this.imageObj.clone().replaces(img);
		}else{
			var obj = this.imageObj.clone();
			obj.inject(this.newImage);
		}
		this.imageLoaded = this.image;
		this.loading.set('styles', {display: 'none'});
		
		if(this.useThumbs && this.options.fxOptions.thumbFx != 'none'){
			if(this.image != 0 || this.thumbManager.thumbFx){
				var target = this.thumbManager.thumbImages[this.image];
				this.thumbManager.thumbFx.move(target);
			}
		}
		this.effect();
	},	//	end @show.
	
	wait: function(){
		this.timer = this.load.delay(this.fxParams.wait,this);
	},	//	end @wait.
	
	play: function(num){
		if(this.stopped){
			if(num > -1){this.image = num-1};
			if(this.image < this.imageData.length){
				this.stopped = false;
				if(this.started){
					this.next();
				}else{
					this.load();
				}
				this.started = true;
			}
		}
	},	//	end @play.
	
	stop: function(){
		$clear(this.timer);
		this.stopped = true;
	},	//	end @stop.
	
	next: function(wait){
		var doNext = true;
		if(wait && this.stopped){
			doNext = false;
		}
		if(this.animating){
			doNext = false;
		}
		if(doNext){
			if(this.imageObj) this.cloneImage();
			$clear(this.timer);
			if(this.image < this.imageData.length-1){
				if(wait){
					this.wait();
				}else{
					this.load();	
				}
			}else{
				if(this.options.modOptions.loop){
					this.image = -1;
					if(wait){
						this.wait();
					}else{
						this.load();	
					}
				}else{
					this.stopped = true;
				}
			}
		}
	},	//	end @next.
	
	previous: function(){
		if(this.imageLoaded == 0){
			this.image = this.imageData.length-2;	
		}else{
			this.image = this.imageLoaded-2;
		}
		this.next();
	},	//	end @previous.
	
	cloneImage: function(){
		var img = this.oldImage.getElement('img');
		if(img){
			this.imageObj.clone().replaces(img);
		}else{
			var obj = this.imageObj.clone();
			obj.inject(this.oldImage);
		}
		
		this.oldImage.setStyles({
			zIndex: 0,
			opacity: 1
		});
		
		Browser.Engine.trident4 ? this.newImage.set('styles', {opacity: 1}) : this.newImage.set('styles', {opacity: 0});
		//this.newImage.set('styles', {opacity: 0});
	},	//	end @cloneImage.
	
	
	effect: function(){
		
		var imageFx = this.options.fxOptions.imageFx;
		var direction = this.options.fxOptions.direction;
		this.animating = true;
		this.effectObj = this.newImage.get("morph", {
			link: 'chain',
			duration: this.fxParams.duration,
			transition: this.fxParams.transition
		});
		var myFxTypes = ['fade','wipe','slide'];
		var myFxDir = ['top','right','bottom','left'];
		
		if(imageFx == 'fade'){
			this.fade();
			
		}else if(imageFx == 'wipe'){
			if(direction == 'random'){
				this.setup(myFxDir[Math.floor(Math.random()*(3+1))]);
			}else{
				this.setup(direction);
			}
			this.wipe();
			
		}else if(imageFx == 'slide'){
			if(direction == 'random'){
				this.setup(myFxDir[Math.floor(Math.random()*(3+1))]);
			}else{
				this.setup(direction);
			}
			this.slide();
			
		}else if(imageFx == 'random'){
			var type = myFxTypes[Math.floor(Math.random()*(2+1))];
			if(type != 'fade'){
				var dir = myFxDir[Math.floor(Math.random()*(3+1))];
				if(direction == 'random'){
					this.setup(dir);
				}else{
					this.setup(direction);
				}
			}else{
				this.setup();
			}
			this[type]();
		}
	},	//	end @effect.
	
	setup: function(dir){
		if(dir == 'top'){
			this.top = -this.imageContainer.getStyle('height').toInt();
			this.left = 0;
			this.topOut = this.imageContainer.getStyle('height').toInt();
			this.leftOut = 0;
			
		}else if(dir == 'right'){
			this.top = 0;
			this.left = this.imageContainer.getStyle('width').toInt();
			this.topOut = 0;
			this.leftOut = -this.imageContainer.getStyle('width').toInt();
			
		}else if(dir == 'bottom'){
			this.top = this.imageContainer.getStyle('height').toInt();
			this.left = 0;
			this.topOut = -this.imageContainer.getStyle('height').toInt();
			this.leftOut = 0;
			
		}else if(dir == 'left'){
			this.top = 0;
			this.left = -this.imageContainer.getStyle('width').toInt();
			this.topOut = 0;
			this.leftOut = this.imageContainer.getStyle('width').toInt();
			
		}else{
			this.top = 0;
			this.left = 0;
			this.topOut = 0;
			this.leftOut = 0;
		}
	},	//	end @setup.
	
	fade: function(){
		this.effectObj.start({opacity: [0, 1]});
		this.resetAnimation.delay(this.fxParams.duration + 90, this);
		if(this.options.modOptions.stopOnStart) {
			this.stop();
		} else {
			if(!this.stopped){
			this.next.delay(this.fxParams.duration + 100, this, true);
			}
		}
	},	//	end @fade.
	
	wipe: function(){
		this.oldImage.set("morph", {
			duration: this.fxParams.duration,
			transition: this.fxParams.transition
		}).morph({
			top: [0,this.topOut],
			left: [0, this.leftOut]
		})
		this.effectObj.start({
			top: [this.top,0],
			left: [this.left,0],
			opacity: [1,1]
		},this);
		this.resetAnimation.delay(this.fxParams.duration + 90, this);
		if(!this.stopped){
		this.next.delay(this.fxParams.duration + 100,this, true);
		}
	},	//	end @wipe.
	
	slide: function(){
		this.effectObj.start({
			top: [this.top,0],
			left: [this.left,0],
			opacity: [1,1]
		},this);
		this.resetAnimation.delay(this.fxParams.duration + 90, this);
		if(!this.stopped){
		this.next.delay(this.fxParams.duration + 100, this, true);
		}
	},	//	end @slide.
	
	resetAnimation: function(){
		this.animating = false;
	},	//	end @resetAnimation.
	
	errorHandler: function(){
	}	//	end @errorHandler.

});	//	end @Slideshow.


/*************************************************************/

