/**

 * Slideshow - a slideshow <http://www.electricprism.com/aeron/slideshow/> and

 * 		  smoothslideshow <http://smoothslideshow.jondesign.net/> fusion.

 *

 * Copyright (c) 2007 Olmo Maldonado

 * 

 * From version 3.0.3, fixes and enanchements from Djamil Legato

 */



var Slideshow = new Class({



	version: '3.0.3',

		

	options: {

		captions: true,

		showTitleCaption: true,

		classes: ['prev', 'next', 'active'],

		duration: [2000, 4000],

		path: '/',

		navigation: false,

		pan: 100,

		resize: true,

		thumbnailre: [/\./, 't.'],

		transition: Fx.Transitions.Sine.easeInOut,

		type: 'fade',

		zoom: 50,

		loadingDiv: true,

		removeDiv: true

	},

	

	styles: {

		caps: {

			div: {

				opacity: 0,

				position: 'absolute',

				width: '100%',

				margin: 0,

				left: 0,

				bottom: 0,

				height: 40,

				background: '#333',

				color: '#fff',

				textIndent: 0		

			},

			

			h2: {

				color: 'red',

				padding: 0,

				fontSize: '80%',

				margin: 0,

				margin: '2px 5px',

				fontWeight: 'bold'

			},

			

			p: {

				padding: 0,

				fontSize: '60%',

				margin: '2px 5px',

				color: '#eee'

			}

		}	

	},

	

	initialize: function(el, options) {

		this.setOptions($merge({

			onClick: this.onClick.bind(this)

		}, options));

		

		if(!this.options.images) return;

		this.options.pan = this.mask(this.options.pan);

		this.options.zoom = this.mask(this.options.zoom);

		

		this.el = $(el).empty();

		

		this.caps = {

			div: new Element('div', {

				styles: this.styles.caps.div,

				'class': 'captionDiv'

			}),

			h2: new Element('h2', {

				styles: this.styles.caps.h2,

				'class': 'captionTitle'

			}),

			p: new Element('p', {

				styles: this.styles.caps.p,

				'class': 'captionDescription'

			})

		};

		

		this.fx = [];



		var trash = new ImageLoader(this.el, this.options.images, {

			loadingDiv: this.options.loadingDiv,

			onComplete: this.start.bind(this),

			path: this.options.path,

			removeDiv: this.options.removeDiv

		});

	},

	

	start: function() {

		this.imgs = $A(arguments);

		this.a = this.imgs[0].clone().set({			

			styles: {

				display: 'block',

				position: 'absolute',

				left: 0,

				'top': 0,

				zIndex: 1

			}

		}).injectInside(this.el);

		

		var obj = this.a.getCoordinates();

		this.height = this.options.height || obj.height;

		this.width = this.options.width || obj.width;

		

		this.el.setStyles({

			display: 'block',

			position: 'relative',

			width: this.width

		});

		

		this.el.empty();

		this.el.adopt((new Element('div', {

			events: {

				'click': this.onClick.bind(this)

			},

			styles: {

				display: 'block',

				overflow: 'hidden',

				position: 'relative',

				width: this.width,

				height: this.height

			}

		})).adopt(this.a));

		

		this.resize(this.a, obj);

		this.b = this.a.clone().setStyle('opacity', 0).injectAfter(this.a);

		

		this.timer = [0, 0];

		this.navigation();

		

		this.direction = 'left';

		this.curr = [0,0];

		

		$(document.body).adopt(new Element('div', {

			id: 'hiddenDIV',

			styles: {

				visibility: 'hidden',

				height: 0,

				width: 0,

				overflow: 'hidden',

				opacity: 0

			}

		}));

		this.loader = this.imgs[0];

		$('hiddenDIV').adopt(this.loader);

		this.load();

	},

	

	load: function(fast) {

		if ($time() > this.timer[0]) {

			this.img = (this.curr[1] % 2) ? this.b : this.a;

			this.img.setStyles({

				opacity: 0,

				width: 'auto',

				height: 'auto',

				zIndex: this.curr[1]

			});

			

			var url = this.options.images[this.curr[0]].url;

			this.img.setStyle('cursor', (url != '#' && url != '') ? 'pointer' : 'default');

			

			this.img.setProperties({

				src: this.loader.src,

				title: this.loader.title,

				alt: this.loader.alt

			});

			

			this.resize(this.img, this.loader);

			

			if(fast){

				this.img.setStyles({

					top: 0,

					left: 0,

					opacity: 1

				});

				

				this.captions();

				this.loaded();			

				return;

			}

			

			this.captions();

			this[this.options.type.test(/push|wipe/) ? 'swipe' : 'kens']();

			this.loaded();

		} else {

			this.timeout = this.load.delay(100, this);

		}

	},

	

	loaded: function() {

		if(this.ul) {

			this.ul.getElements('a[name]').each(function(a, i) {

				a[(i === this.curr[0] ? 'add' : 'remove') + 'Class'](this.options.classes[2]);

			}, this);

		}

		

		this.direction = 'left';

		this.curr[0] = (this.curr[0] + 1) % this.imgs.length;

		this.curr[1]++;

		

		this.timer[0] = $time() + this.options.duration[1] + (this.options.type.test(/fade|push|wipe/) ? this.options.duration[0] : 0);		

		this.timer[1] = $time() + this.options.duration[0];

		

		this.loader = this.imgs[this.curr[0]];

		$('hiddenDIV').empty().adopt(this.loader);

		this.load();

	},

	

	kens: function() {

		this.img.setStyles({

			bottom: 'auto',

			right: 'auto',

			left: 'auto',

			top: 'auto'

		});

		

		var arr = ['left top', 'right top', 'left bottom', 'right bottom'].getRandom().split(' ');

		arr.each(function(p) {

			this.img.setStyle(p, 0);

		}, this);

		

		var zoom = this.options.type.test(/zoom|combo/) ? this.zoom() : {};

		var pan = this.options.type.test(/pan|combo/) ? this.pan(arr) : {};

		

		this.fx.push(this.img.effect('opacity', {duration: this.options.duration[0]}).start(1));

		this.fx.push(this.img.effects({duration: this.options.duration[0] + this.options.duration[1]}).start($merge(zoom, pan)));

	},

	

	zoom: function() {

		var n = Math.max(this.width / this.loader.width, this.height / this.loader.height);

		var z = (this.options.zoom === 'rand') ? Math.random() + 1 : (this.options.zoom.toInt() / 100.0) + 1;

		

		var eh = Math.ceil(this.loader.height * n);

		var ew = Math.ceil(this.loader.width * n);

		

		var sh = (eh * z).toInt();

		var sw = (ew * z).toInt();



		return {height: [sh, eh], width: [sw, ew]};

	},

	

	pan: function(arr) {

		var ex = this.width - this.img.width, ey = this.height - this.img.height;

		var p = this.options.pan === 'rand' ? Math.random() : Math.abs((this.options.pan.toInt() / 100) - 1);

		var sx = (ex * p).toInt(), sy = (ey * p).toInt();



		var x = this.width / this.loader.width > this.height / this.loader.height;

		var obj = {};

		obj[arr[x ? 1 : 0]] = x ? [sy, ey] : [sx, ex];

		return obj;

	},



	swipe: function() {

		var arr, p0 = {}, p1 = {}, x;

		this.img.setStyles({

			left: 'auto',

			right: 'auto',

			opacity: 1

		}).setStyle(this.direction, this.width);

		

		if(this.options.type === 'wipe') {

			this.fx.push(this.img.effect(this.direction, {

				duration: this.options.duration[0],

				transition: this.options.transition

			}).start(0));			

		} else {

			arr = [this.img, this.curr[1] % 2 ? this.a : this.b];

			p0[this.direction] = [this.width, 0];

			p1[this.direction] = [0, -this.width];

			

			if(arr[1].getStyle(this.direction) === 'auto') {

				x = this.width - arr[1].getStyle('width').toInt();

				

				arr[1].setStyle(this.direction, x);

				arr[1].setStyle(this.direction === 'left' ? 'right' : 'left', 'auto');

				

				p1[this.direction][0] = x;

			}

			

			this.fx.push(new Fx.Elements(arr, {

				duration: this.options.duration[0],

				transition: this.options.transition

			}).start({

				'0': p0,

				'1': p1

			}));

		}

	},

	

	captions: function(img) {

		img = img || this.img;

		if(!this.options.captions || (!img.title && !img.alt)) return;



		this.el.getFirst().adopt(this.caps.div.adopt(this.caps.h2, this.caps.p));

		

		(function () {

			if (this.options.showTitleCaption) this.caps.h2.setHTML(img.title);

			this.caps.p.setHTML(img.alt);

			this.caps.div.setStyle('zIndex', img.getStyle('zIndex')*2 || 10);

			

			this.capsHeight = this.capsHeight || this.options.captionHeight || this.caps.div.offsetHeight;

			

			var fx = this.caps.div.effects().set({'height': 0}).start({

				opacity: 0.7,

				height: this.capsHeight

			});

			

			(function(){

				fx.start({

					opacity: 0,

					height: 0

				});

			}).delay(1.00*(this.options.duration[1] - this.options.duration[0]));

		}).delay(0.75*(this.options.duration[0]), this);

	},

	

	navigation: function() {

		if(!this.options.navigation) return;

		var i, j, atemp;

		var fast = this.options.navigation.test(/fast/) ;

		this.ul = new Element('ul');

		var li = new Element('li'), a = new Element('a');

		

		if (this.options.navigation.test(/arrows/)) {

			this.ul.adopt(li.clone()

				.adopt(a.clone()

					.addClass(this.options.classes[0])

					.addEvent('click', function() {

						if (fast || $time() > this.timer[1]) {	

							$clear(this.timeout);

					

							// Clear the FX array only for fast navigation since this stops combo effects

							if(fast) {

								this.fx.each(function(fx) {

									fx.time = 0;

									fx.options.duration = 0;

									fx.stop(true);

								});

							}

		

							this.direction = 'right';

							this.curr[0] = (this.curr[0] < 2) ? this.imgs.length - (2 - this.curr[0]) : this.curr[0] - 2;

							this.timer = [0];

							

							this.loader = this.imgs[this.curr[0]];

							this.load(fast);

						}

					}.bind(this))

				)

			);

		}

		

		if (this.options.navigation.test(/arrows\+|thumbnails/)) {

			for (i = 0, j = this.imgs.length; i < j; i++) {

				atemp = a.clone().setProperty('name', i);

				if (this.options.navigation.test(/thumbnails/)) atemp.setStyle('background-image', 'url(' + this.imgs[i].src + ')');

				if(i === 0) a.className = this.options.classes[2];

				

				atemp.onclick = function(i) {

					if(fast || $time() > this.timer[1]) {

						$clear(this.timeout);

						

						if (fast) {

							this.fx.each(function(fx) {

								fx.time = 0;

								fx.options.duration = 0;

								fx.stop(true);

							});

						}

					

						this.direction = (i < this.curr[0] || this.curr[0] === 0) ? 'right' : 'left';

						this.curr[0] = i;

						this.timer = [0];			

						

						this.loader = this.imgs[this.curr[0]];							

						this.load(fast);

					}

				}.pass(i, this);

		

				this.ul.adopt(li.clone().adopt(atemp));

			}

		}

		

		if (this.options.navigation.test(/arrows/)) {

			this.ul.adopt(li.clone()

				.adopt(a.clone()

					.addClass(this.options.classes[1])

					.addEvent('click', function() {

						if (fast || $time() > this.timer[1]) {	

							$clear(this.timeout);

		

							// Clear the FX array only for fast navigation since this stops combo effects

							if (fast) {

								this.fx.each(function(fx) { 

									fx.time = 0;

									fx.options.duration = 0;

									fx.stop(true); 

								});

							}

		

							this.timer = [0];					

		

							this.load(fast);

						}

					}.bind(this))

				)

			);

		}



		this.ul.injectInside(this.el);

	},



	onClick: function(e) {

		e = new Event(e).stop();

		var cur = this.curr[1] % this.imgs.length;

		var index = this.curr[1] == 0 ? 1 : cur == 0 ? this.imgs.length : cur;

		var url = this.options.images[index - 1].url;

		if(url == '#' || url == '') return;

		window.location.href = url;

	},



	mask: function(val, set, lower, higher) {

		if(val != 'rand') {

			val = val.toInt();

			val = isNaN(val) || val < lower || val > higher ? set : val;

		}

		

		return val;

	},

	

	resize: function(obj, to) {

		var n;

		if(this.options.resize) {

			n = Math.max(this.width / to.width, this.height / to.height);

			obj.setStyles({

				height: Math.ceil(to.height*n),

				width: Math.ceil(to.width*n)

			});

		}

	}

});

Slideshow.implement(new Options);



/**

 * ImageLoader, Image preloader with progress reporting, with small 

 * 		changes by Olmo Maldonado, <http://olmo-maldonado.com/> (denoted by 

 * 		// at the end of the line)

 * 

 * 

 * @author tomocchino, <http://www.tomocchino.com/>

 *

 */

var ImageLoader = new Class({

	

	version:'.5-olmo-ver',

	

	options: {

		loadingDiv    : false,

		loadingPrefix : 'loading images: ',

		loadingSuffix : '',

		path		  : '',

		removeDiv	  : true

	},

	

	initialize: function(container, sources, options){

		this.setOptions(options);

		this.loadingDiv = (this.options.loadingDiv) ? $(container) : false;

		this.images     = [];

		this.index      = 0;

		this.total      = sources.length;

		

		if(this.loadingDiv) {

			this.loadingText = new Element('div').injectInside(this.loadingDiv);

			this.progressBar = new Element('div', {

				styles: {

					width: 100,

					padding: 1,

					margin: '5px auto',

					textAlign: 'left',

					overflow: 'hidden',

					border: 'solid 1px #333'

				}

			}).adopt(new Element('div', {

				styles: {

					width: '0%',

					height: 10,

					backgroundColor: '#333'

				}

			})).injectInside(this.loadingDiv);

		}

		

		this.loadImages.delay(200, this, [sources]);

	},

	

	reset: function() {

		this.index = 0;

		if(this.loadingDiv) {

			this.progressBar.getFirst().setStyle('width', '0%');

			this.loadingText.setHTML(this.options.loadingPrefix);

		}

	},

	

	loadImages: function(sources) {

		var self = this;

		this.reset();

		this.images  = [];

		this.sources = sources;

		

		this.timer = setInterval(this.loadProgress.bind(this), 100);

		for(var i = 0, j = sources.length; i < j; i++) {

			this.images[i] = new Asset.image((this.sources[i].path || this.options.path) + this.sources[i].file, {

				title: self.sources[i].title,

				alt: self.sources[i].desc,

				'onload'  : function(){ self.index++; },

				'onerror' : function(){ self.index++; self.images.splice(i,1); },

				'onabort' : function(){ self.index++; self.images.splice(i,1); }

			});

		}

	},

	

	loadProgress: function() {

		if(this.loadingDiv) {

			this.loadingText.setHTML(this.options.loadingPrefix + this.index + '/' + this.total + this.options.loadingSuffix);

			this.progressBar.getFirst().setStyle('width', (!this.total ? 0 : this.index.toInt()*100 / this.total) + '%');

		}



		if(this.index >= this.total) {

			this.loadComplete();

		} 

	},

	

	loadComplete: function(){

		$clear(this.timer);

		if(this.loadingDiv) {

			this.loadingText.setHTML('Loading Complete');

			

			if(this.options.removeDiv) {

				this.loadingText.empty().remove();

				this.progressBar.empty().remove();

			}

		}

		this.fireEvent('onComplete', this.images);

	},

	

	cancel: function(){

		$clear(this.timer);

	}

	

});



ImageLoader.implement(new Events, new Options);

