/*
 Slideshow v0.4
 
 CHANGES
 ==============
 - Images can now hold data.
 - Images height and width are held in the image object
 ==============
 Lightweight slideshow made by Adam Hutchinson.
 www.adamhutchinson.co.uk
 Requires Prototype(1.6.1) + Scriptaculous(1.8.3)
*/	
window.slideshows = [];
var Slideshow = function(parentId,opt){
	// We need an opt object...
	if(typeof(opt) != 'object') opt = {};
	
	this.parent          = (typeof(parentId) == "string") ? $(parentId) : parentId ;
	this.images          = new Array;
	this.slideTime       = (opt.interval < 100) ? opt.interval * 1000 : opt.interval|| 2000; // Change this for a longer timeout
	this.fadeDuration    = (this.slideTime < 2000) ? this.slideTime /4000 : 1;
    this.timeout         = null;
	this.currPos         = null;
	this.lastPos         = null;
	this.started         = false;
	this.imageFolder     = opt.folder || '/images/'; //Change these to match site config
	this.imageExtension  = (typeof opt.extension == "string") ? opt.extension : '.jpg';
	this.toBackground    = (opt.background == 1) ? 1 : 0 || 0;
    this.repeat          = opt.repeat || 'no-repeat';
	this.onChange        = (typeof(opt.onChange) == 'function') ? opt.onChange : function(){} || function(){} // Empty function for onChange if it's needed.
	this.maxDimensions   = [opt.x || 0,opt.y || 0]; // These don't do anything yet... :P
	this.imgLoadFunc     = typeof opt.imgLoadFunc == 'function' ? opt.imgLoadFunc : function(){} || function(){} // Function used each time an image loads (incase we need to dynamically resize something that's not involved in the main slideshow logic.)
	
	window.slideshows.push(this);
}

// Add Image to Slideshow
Slideshow.prototype.addImg = function(src,opt){
	if(typeof(src) == 'string' || typeof(src) =='number'){
		src=src.toString();
		// If src isn't a direct url then make the src based on the folder and extension specified in the slideshow object.
		if(src.indexOf('http://') == -1){
			src = this.imageFolder+src+this.imageExtension;	
		}
		
		// Get the options (if there are any)
		var opt = (typeof(opt) == "object") ? opt : {};
		var onClick = opt.onClick || null;
		var data	= opt.data	  || null;
		
		var new_img = new Img(src,onClick,data,this);
		
		// Add the image to images array
		this.images.push(new_img);
	}
}

// Swap Image with another image by 'images' array position (old Position, new Position)
Slideshow.prototype.swapImg = function(oPos,nPos){
	// Hide image
	if(typeof(this.images[oPos]) !== "undefined" && this.toBackground == 0){
		this.images[oPos].hide(this.parent,this.fadeDuration);
	}
	
	// Show image
	// If we're doing the slideshow as background images then run different function
	if(this.toBackground == 1){
		this.images[nPos].showBg(this.parent,this.fadeDuration,this.repeat);	
	}else{
		this.images[nPos].show(this.parent,this.fadeDuration);
	}
	
	// Call onChange function, pass the current image and this slideshow to it.
	this.onChange(this.images[nPos],this);
}

// Main slideshow logic
Slideshow.prototype.run = function(){
	if(this.started == true){
		clearTimeout(this.timeout);
		this.swapImg(this.lastPos,this.currPos);
		this.changePos();
		// pre load next image
		this.images[this.currPos].loadMe();
		this.timeout = setTimeout(this.run.bind(this),this.slideTime);	
	}
}

// Change 'currPos' variable and matching lastPos variable. They loop round once they reach the end of the array.
Slideshow.prototype.changePos = function(){
	this.lastPos = this.currPos;
	if(this.currPos == this.images.length - 1 || this.currPos == null){
		this.currPos = 0;	
	}else this.currPos++;
}

// Slideshow start logic
Slideshow.prototype.start = function(){
	// If there are images
	if(this.images.length !==0 && this.started==false){	
		this.currPos = 0;
		this.started = true;
		this.run();		
	}
}

Slideshow.prototype.stop = function(){
	clearTimeout(this.timeout);
	this.started=false;
}

// An image used in the slideshow
var Img = function(src,onClick,data,sshow){
	this.src = src;
	this.data = data;
	this.onClick = typeof(onClick == "function") ? onClick : function(){};
	this.img = null;
	this.h   = null;
	this.w   = null;
	this.slideshow = sshow;
}

// Load the actual Image element if you haven't already.
Img.prototype.loadMe = function(){
	if(this.img == null){
		var img = new Image();
		img.src = this.src;
		img.style.position='absolute';
		this.img = img;	
		
		// Check for image load and when loaded, adjust image height and width vars
		var self = this;
		img.onload = function(){
			self.h = img.height;
			self.w = img.width;
			// Call the slideshows 'image load function' and pass this image to it
			self.slideshow.imgLoadFunc(self,self.slideshow);
		}
	}
}

// Fade in an image and add it to the element specified by parent
Img.prototype.show = function(parent,duration){
	//If the image is not loaded then load it
	this.loadMe();	
	this.img.style.display = 'none';
	this.img.onclick = this.onClick;
	if(this.onClick) this.img.style.cursor = 'pointer';
	parent.appendChild(this.img);
	new Effect.Appear(this.img,{
		duration:duration
	});
}

// Fade out an image and remove from parent
Img.prototype.hide = function(parent,duration){
	// this.img is needed by afterFinish callback
	var img = this.img;
	new Effect.Fade(img,{
		duration:duration,
		afterFinish: function(){
			parent.removeChild(img);
		}
	});	
}

Img.prototype.showBg = function(parent,duration,repeat){
	// Load image
	this.loadMe();
	// we need the image src in the afterFinish function of the fade
	var src=this.src;
	
	var self = this;
	// fade out parent as we're using background images.
	parent.fade({afterFinish:function(){
		parent.style.backgroundImage = 'url('+src+')';
        parent.style.backgroundRepeat= repeat;
		// If it has an onclick function
		parent.onclick = self.onClick || null;
		parent.style.cursor = (self.onClick) ? 'pointer' : 'auto';
		parent.appear({duration:duration});	
	}});
}

