
/**************************************************************

	/// ORIGINAL ///
	Script		: SlideShow
	Version		: 1.3
	Authors		: Samuel Birch
	Desc		: 
	Licence		: Open Source MIT Licence
	
	/// MODIFICATIONS ///
	Author		: Sebastian Bork
	Date		: June 2008
	Desc		: - some changes to fit into the module	- each image as link
				  - modificate the images array to use array(object({url, link}), ...)
				  
	//// ORIGINAL OPTIONS ////
	effect    			the transition effect to use (fade|wipe|slide|random). default: 'fade'
	
	duration    		the length of the transition. default: 2000
	
	transition   		default: Fx.Transitions.linear
	
	direction	    	the direction of the transition if wipe or slide is used 
						(top|right|bottom|left|random). default: 'right'
						
	wait		    	the length of time to waqit before going to the next image. default: 5000
	
	loop		    	when the last image is reached it will go back to the start. default: false
	
	thumbnails	    	using thumbnails or not. default: false
	
	thumbnailCls    	the name of the class to use for showing the current image. default: 'outline'
	
	backgroundSlider    use the backgroundSlider class for the thumbnails. default: false
	
	onClick			    the function called when the image is clicked. The index of the image is passed 
						to the function.

**************************************************************/

var SlideShow = new Class({
	
	getOptions: function(){
		return {
			effect: 'fade', //fade|wipe|slide|random
			duration: 2000,
			transition: Fx.Transitions.linear,
			direction: 'right', //top|right|bottom|left|random
			color: false,
			wait: 5000,
			loop: false,
			thumbnails: true,
			thumb_tips: true,
			loadingCls: 'loading',
			onClick: false,
			showInfo: true,
			infoPosition: 'bottom',
			infoHeight: '20px',
			infoOpaque: 0.9,
			infoAlign: 'left'
		};
	},

	initialize: function(container, imgs, options){
		this.setOptions(this.getOptions(), options);
		
		this.container = $(container+'_inner');
		this.container_outer = $(container);
		this.container.setHTML('');
		this.container.setStyles({
			position: 'relative',
			overflow: 'hidden'
		});
				
		this.imagesHolder = new Element('div').setStyles({
			position: 'absolute',
			overflow: 'hidden',
			top: this.container.getStyle('height'),
			left: 0,
			width: '0px',
			height: '0px',
			display: 'none'
		}).injectInside(this.container);
		
		this.images = Json.evaluate(imgs);
		
		this.loading = new Element('div').addClass(this.options.loadingCls).setStyles({
			position: 'absolute',
			top: 0,
			left: 0,
			zIndex: 3,
			display: 'none',
			width: this.container.getStyle('width'),
			height: this.container.getStyle('height')
		}).injectInside(this.container);
		
		this.oldImage = new Element('div').setStyles({
			position: 'absolute',
			overflow: 'hidden',
			top: 0,
			left: 0,
			width: this.container.getStyle('width'),
			height: this.container.getStyle('height')
		}).injectInside(this.container);
		this.oldImage.setOpacity(0);
		
		if(this.options.showInfo) {
			this.imageInfoContainer = new Element('div').setStyles({
					position: 'absolute',
					left: '0px',
					zIndex: 20,
					width: this.container.getStyle('width'),
					height: this.options.infoHeight,
					'text-align': this.options.infoAlign
				}).addClass('imageinfocontainer');
			this.imageInfoContainer.setOpacity(1);
			if(this.options.infoPosition == 'top') {
				this.imageInfoContainer.setStyle('top', '0px');
			} else {
				this.imageInfoContainer.setStyle('bottom', '-4px');
			}
			this.imageInfoContainerbg = new Element('div').setStyles({
					position: 'absolute',
					zIndex: 1,
					left: this.imageInfoContainer.getStyle('left'),
					width: this.container.getStyle('width'),
					height: this.imageInfoContainer.getStyle('height')
				}).addClass('imageinfocontainer_bg');
			if(this.options.infoPosition == 'top') {
				this.imageInfoContainerbg.setStyle('top', this.imageInfoContainer.getStyle('top'));
			} else {
				this.imageInfoContainerbg.setStyle('bottom', this.imageInfoContainer.getStyle('bottom'));
			}
			this.imageInfoContainerbg.setOpacity(this.options.infoOpaque);

			this.imageInfoText = new Element('div').setStyles({
					position: 'absolute',
					clear: 'both',
					left: '0px',
					zIndex: 2,
					width: this.imageInfoContainer.getStyle('width')
				}).addClass('imageinfotext');
			this.imageInfoContainerbg.setOpacity(0);
			this.imageInfoContainerbg.injectInside(this.imageInfoContainer);
			this.imageInfoText.injectInside(this.imageInfoContainer);
			this.imageInfoContainer.injectInside(this.container);
		}
		
		if(this.options.thumbnails) {
			this.thumbnailContainer = new Element('div');
			this.thumbnailContainer.setStyles({
					clear: 'both',
					width: this.container.getStyle('width')
				}).addClass('thumbnailcontainer');
			this.imageInfoContainerbg.setOpacity(1);
			
			for(var t=0; t<this.images.length; t++) {
				var tmpimg = this.images[t];
				var thumbnail = new Element('div');
				thumbnail.setProperty('id', 'thumb_'+t );
				
				var thumbImg = new Asset.image(this.urldecode(tmpimg.thumb));
				thumbImg.setProperty('title', tmpimg.title);
				thumbImg.addClass('rs2slide_thumbnail');
				thumbImg.injectInside(thumbnail);
				
				thumbnail.injectInside(this.thumbnailContainer);
			}
						
			this.thumbnailContainer.injectInside(this.container_outer);
			
			$$('#'+this.container_outer.id +' img.rs2slide_thumbnail').each(function(el,i){
				el.addEvent('click',function(){
					this.stop();
					this.play(i);				 
				}.bind(this,el,i));
			},this);

		}
		
		this.newImage = this.oldImage.clone();
		this.newImage.injectInside(this.container);
		
		
		
		this.timer = 0;
		this.image = -1;
		this.imageLoaded = 0;
		this.stopped = true;
		this.started = false;
		this.animating = false;
	},
	
	load: function(){
		$clear(this.timer);
		this.loading.setStyle('display','block');
		this.image++;
		var img = this.urldecode(this.images[this.image].image);
		//add linking
		if(this.images[this.image].imagelink) {
			this.location = this.images[this.image].imagelink;
		}
		delete this.imageObj;
		
		var doLoad = true;
		this.imagesHolder.getElements('img').each(function(el){
			var src = this.images[this.image]['image'];
			if(el.src == src){
				this.imageObj = el;
				doLoad = false;
				this.add = false;
				this.show();
			}
		},this);
		
		if(doLoad){
			this.add = true;
			this.imageObj = new Asset.image(img, {onload: this.show.bind(this)});
		}
		
	},

	show: function(add){
		if(this.add){
			this.imageObj.injectInside(this.imagesHolder);
		}
		this.newImage.setStyles({
			zIndex: 1
		});
		this.newImage.setOpacity(0);
		var img = this.newImage.getElement('img');
		if(img){
			img.replaceWith(this.imageObj.clone());
		}else{
			var obj = this.imageObj.clone();
			obj.injectInside(this.newImage);
		}
		this.imageLoaded = this.image;
		this.loading.setStyle('display','none');
		
		if(this.location) {
			this.container.addEvent('click', function() { window.location.href = this.location;}.bind(this));
		}
		this.effect();
		
		if(this.options.showInfo) {
			this.imageInfoText.innerHTML = '<h2 class="imageinfo_title">'+this.images[this.image].title+'</h2><span class="imageinfor_description">'+this.images[this.image].desc+'</span>';
			this.imageInfoText.setOpacity(0);
			this.fadeinfo();
		}

		
	},
	
	fadeinfo: function(){
		var infoFX = new Fx.Style(this.imageInfoText, 'opacity', {duration: this.options.duration, transition: this.options.transition} );
		infoFX.start(0,1);
	},
	
	wait: function(){
		this.timer = this.load.delay(this.options.wait,this);
	},
	
	play: function(num){
		if(this.stopped){
			if(num > -1){this.image = num-1};
			if(this.image < this.images.length){
				this.stopped = false;
				if(this.started){
					this.next();
				}else{
					this.load();
				}
				this.started = true;
			}
		}
	},
	
	stop: function(){
		$clear(this.timer);
		this.stopped = true;
	},
	
	next: function(wait){
		var doNext = true;
		if(wait && this.stopped){
			doNext = false;
		}
		if(this.animating){
			doNext = false;
		}
		if(doNext){
			this.cloneImage();
			$clear(this.timer);
			if(this.image < this.images.length-1){
				if(wait){
					this.wait();
				}else{
					this.load();	
				}
			}else{
				if(this.options.loop){
					this.image = -1;
					if(wait){
						this.wait();
					}else{
						this.load();	
					}
				}else{
					this.stopped = true;
				}
			}
		}
	},
	
	previous: function(){
		if(this.imageLoaded == 0){
			this.image = this.images.length-2;	
		}else{
			this.image = this.imageLoaded-2;
		}
		this.next();
	},
	
	cloneImage: function(){
		var img = this.oldImage.getElement('img');
		if(img){
			img.replaceWith(this.imageObj.clone());
		}else{
			var obj = this.imageObj.clone();
			obj.injectInside(this.oldImage);
		}
		
		this.oldImage.setStyles({
			zIndex: 0,
			top: 0,
			left: 0
		});
		this.oldImage.setOpacity(1);
		this.newImage.setOpacity(0);
	},
	
	
	effect: function(){
		this.animating = true;
		this.effectObj = this.newImage.effects({
			duration: this.options.duration,
			transition: this.options.transition
		});
		
		var myFxTypes = ['fade','wipe','slide'];
		var myFxDir = ['top','right','bottom','left'];
		
		if(this.options.effect == 'fade'){
			this.fade();
			
		}else if(this.options.effect == 'wipe'){
			if(this.options.direction == 'random'){
				this.setup(myFxDir[Math.floor(Math.random()*(3+1))]);
			}else{
				this.setup(this.options.direction);
			}
			this.wipe();
			
		}else if(this.options.effect == 'slide'){
			if(this.options.direction == 'random'){
				this.setup(myFxDir[Math.floor(Math.random()*(3+1))]);
			}else{
				this.setup(this.options.direction);
			}
			this.slide();
			
		}else if(this.options.effect == 'random'){
			var type = myFxTypes[Math.floor(Math.random()*(2+1))];
			if(type != 'fade'){
				var dir = myFxDir[Math.floor(Math.random()*(3+1))];
				if(this.options.direction == 'random'){
					this.setup(dir);
				}else{
					this.setup(this.options.direction);
				}
			}else{
				this.setup();
			}
			this[type]();
		}
	},
	
	setup: function(dir){
		if(dir == 'top'){
			this.top = -this.container.getStyle('height').toInt();
			this.left = 0;
			this.topOut = this.container.getStyle('height').toInt();
			this.leftOut = 0;
			
		}else if(dir == 'right'){
			this.top = 0;
			this.left = this.container.getStyle('width').toInt();
			this.topOut = 0;
			this.leftOut = -this.container.getStyle('width').toInt();
			
		}else if(dir == 'bottom'){
			this.top = this.container.getStyle('height').toInt();
			this.left = 0;
			this.topOut = -this.container.getStyle('height').toInt();
			this.leftOut = 0;
			
		}else if(dir == 'left'){
			this.top = 0;
			this.left = -this.container.getStyle('width').toInt();
			this.topOut = 0;
			this.leftOut = this.container.getStyle('width').toInt();
			
		}else{
			this.top = 0;
			this.left = 0;
			this.topOut = 0;
			this.leftOut = 0;
		}
	},
	
	fade: function(){
		this.effectObj.start({
			opacity: [0,1]
		});
		this.resetAnimation.delay(this.options.duration+90,this);
		if(!this.stopped){
		this.next.delay(this.options.duration+100,this,true);
		}
	},
	
	wipe: function(){
		this.oldImage.effects({
			duration: this.options.duration,
			transition: this.options.transition
		}).start({
			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.options.duration+90,this);
		if(!this.stopped){
		this.next.delay(this.options.duration+100,this,true);
		}
	},
	
	slide: function(){
		this.effectObj.start({
			top: [this.top,0],
			left: [this.left,0],
			opacity: [1,1]
		},this);
		this.resetAnimation.delay(this.options.duration+90,this);
		if(!this.stopped){
		this.next.delay(this.options.duration+100,this,true);
		}
	},
	
	resetAnimation: function(){
		this.animating = false;
	},
	
	
	//***************************** HELPERS */
	substr:function( f_string, f_start, f_length ) {
		// http://kevin.vanzonneveld.net
		// +     original by: Martijn Wieringa
		// +     bugfixed by: T.Wild
		// +      tweaked by: Onno Marsman
		// *       example 1: substr('abcdef', 0, -1);
		// *       returns 1: 'abcde'
		// *       example 2: substr(2, 0, -6);
		// *       returns 2: ''
	 
		f_string += '';
	 
		if(f_start < 0) {
			f_start += f_string.length;
		}
	 
		if(f_length == undefined) {
			f_length = f_string.length;
		} else if(f_length < 0){
			f_length += f_string.length;
		} else {
			f_length += f_start;
		}
	 
		if(f_length < f_start) {
			f_length = f_start;
		}
	 
		return f_string.substring(f_start, f_length);
	},
	urldecode: function ( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brettz9.blogspot.com)
    // +      input by: travc
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Lars Fischer
    // %          note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urldecode('Kevin+van+Zonneveld%21');
    // *     returns 1: 'Kevin van Zonneveld!'
    // *     example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
    // *     returns 2: 'http://kevin.vanzonneveld.net/'
    // *     example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
    // *     returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
    
    var histogram = {}, ret = str.toString(), unicodeStr='', hexEscStr='';
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urlencode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
    histogram['\u00DC'] = '%DC';
    histogram['\u00FC'] = '%FC';
    histogram['\u00C4'] = '%D4';
    histogram['\u00E4'] = '%E4';
    histogram['\u00D6'] = '%D6';
    histogram['\u00F6'] = '%F6';
    histogram['\u00DF'] = '%DF'; 
    histogram['\u20AC'] = '%80';
    histogram['\u0081'] = '%81';
    histogram['\u201A'] = '%82';
    histogram['\u0192'] = '%83';
    histogram['\u201E'] = '%84';
    histogram['\u2026'] = '%85';
    histogram['\u2020'] = '%86';
    histogram['\u2021'] = '%87';
    histogram['\u02C6'] = '%88';
    histogram['\u2030'] = '%89';
    histogram['\u0160'] = '%8A';
    histogram['\u2039'] = '%8B';
    histogram['\u0152'] = '%8C';
    histogram['\u008D'] = '%8D';
    histogram['\u017D'] = '%8E';
    histogram['\u008F'] = '%8F';
    histogram['\u0090'] = '%90';
    histogram['\u2018'] = '%91';
    histogram['\u2019'] = '%92';
    histogram['\u201C'] = '%93';
    histogram['\u201D'] = '%94';
    histogram['\u2022'] = '%95';
    histogram['\u2013'] = '%96';
    histogram['\u2014'] = '%97';
    histogram['\u02DC'] = '%98';
    histogram['\u2122'] = '%99';
    histogram['\u0161'] = '%9A';
    histogram['\u203A'] = '%9B';
    histogram['\u0153'] = '%9C';
    histogram['\u009D'] = '%9D';
    histogram['\u017E'] = '%9E';
    histogram['\u0178'] = '%9F';
 
    for (unicodeStr in histogram) {
        hexEscStr = histogram[unicodeStr]; // Switch order when decoding
        ret = replacer(hexEscStr, unicodeStr, ret); // Custom replace. No regexing
    }
    
    // End with decodeURIComponent, which most resembles PHP's encoding functions
    ret = decodeURIComponent(ret);
 
    return ret;
}
	
});
SlideShow.implement(new Options);
SlideShow.implement(new Events);


/*************************************************************/
