/**
 * This file contains the PhotoBiz PMsLIDEsHOW JavaScript Interface 
 * for adding functionality to HTML Image Slideshow capabilities to pages
 *
 * The file contains a single JavaScript Class that provides the said 
 * functionality
 *
 * Language: JavaScript
 * Dependancies: MooTools 1.11
 *
 * LICENSE: This source file is subject to version 1.11 of the MooTools creative 
 * Commons license that is available through the world-wide-web at the following URI:
 * http://creativecommons.org/licenses/by-nc-sa/3.0/  
 *
 * @package    pmSlideshow
 * @author     ProjectMiso.net <email@projectmiso.net>
 * @copyright  2009 PhotoBiz, LLC
 * @version    1.1
 * @since      July 23, 2009
 * @Last_Updated March 3, 2011
 * @deprecated N/A
*/

 
/**
* Properties - Public Variables: 
	container: 		"",			//id of the image container
	images:			[],			//an array containing the images
	interval:		5000,		//the integer with the time interval for each slide to occur
	transition:		Fx.Transitions.Expo.easeInOut,			//MooTools transition object for defining hte style of transition
	affectDuration:	600,		//the duration of the effect
	randomize:		false,		//bool for randomizing the image sequence
	autoPlay:		true,		//bool start playing once loaded?
	effect:			true,		//show fade-in / fade-out affect?
	slideTogether:	false,		//slide both slides at the same time
	loop:			true		//start at the beginning, only needed if randomize is false.
*/


 
/**
* Public Methods: 
 	--------------------------
	play()
	
	Description:
		This method can be called to to start playing the slideshow. Once method call the next image will 
		be displayed right away
	
	Syntext:
		classInstanceName.play()
			
	Arguments:
		None
	--------------------------
	
	stop()
	
	Description:
		If hte slideshow is currently playing, this method call will pause the slideshow. If the slideshow 
		is not playing, it has no effect
	
	Syntext:
		classInstanceName.stop()
			
	Arguments:
		None
	--------------------------
	
	next()
	
	Description:
		Will load and display the next image. If the slideshow is playing, the method call will pause play and load next. 
		If at the end of image array, will load the first image
	
	Syntext:
		classInstanceName.next()
			
	Arguments:
		None
	--------------------------
	
	previous()
	
	Description:
		Will load and display the previous image. If the slideshow is playing, the method call will pause play and load previous.
		If at hte beginning of image array, will load the last one.
	
	Syntext:
		classInstanceName.previous()
			
	Arguments:
		None
	--------------------------
	
	slideTo(int)
	
	
	Description:
		Will load a specific image within the array
	
	Syntext:
		classInstanceName.slideTo(int)
			
	Arguments:
		'int' is a number wiithin the image array index. If there is overflow, the next image will be loaded. 
 	
*/

 
/**
* Events: 
 	--------------------------
	onStart
	
	Syntext:
		onStart: customFunctionName
			[or]
		onStart: function(selectedMenu){
			... custom code here ....
		}
		
	Arguments:
		None. 
	
 	--------------------------
	
	onComplete
	
	Syntext:
		onComplete: customFunctionName
			[or]
		onComplete: function(){
			... custom code here ....
		}
		
	Arguments:
		None. 
		
		
 	--------------------------
	onRelease
	
	Syntext:
		onRelease: customFunctionName
			[or]
		onRelease: function(dropType, selectedMenu, dropLocation, dropLevel, menuTop, menuBottom){
			... custom code here ....
		}
		
	Arguments:
		dropType: A String. Range of values "move" and "reorder". "reorder" when dropped using the cursor. "move" for 
				dropping on top of drop-down-holders
		selectedMenu:	A String. A String value containing the DIV ID for the selected menu
		dropLocation: A String. Value is null when dropType is "reorder". Holds the DIV ID for the drop-down-holder when a menu is drop on it
		dropLevel: An Integer. Value range is 1 or 2. 1 for levle 1 drop and 2 for level 2 drop
		menuTop: A String. Holds DIV ID for menu on top from drop location. Value is null if dropped in first position of level 1 
				or dropped on top of a drop-down-holder
		menuBottom: A String. Holds DIV ID for menu below the drop location. Value is null if dropped in last position of level 1 
*/

 

var pmSlideshow = new Class({		
	options: {
		container: 		"",			//id of the image container
		images:			[],			//ann array containing the images
		links:			[],			//an array containing the links
		interval:		5000,		//the integer with the time interval for each slide to occur
		transition:		Fx.Transitions.Expo.easeInOut,			//MooTools transition object for defining hte style of transition
		affectDuration:	600,		//the duration of the effect
		randomize:		false,		//bool for randomizing the image sequence
		autoPlay:		true,		//bool start playing once loaded?
		effect:			true,		//show fade-in / fade-out affect?
		slideTogether:	false,		//slide both slides at the same time
		loop:			true,		//start at the beginning, only needed if randomize is false.
		startIndex:		null		//will start at the index position of the array regardless of random or not
	},
	initialize: function (options){
		var clss = this;
		this.setOptions(options);
		this.parseOptions(this.options);
		
		if (this.interval < 2000){
			alert("'interval' value must be at least 2000 ms.")	
		}
		
		//the main container
		this.container = $(this.container);
		
		//private variables
		this.loaded_images = [];
		this.curr_image = "";
		this.curr_index = -1;
		this.loadStatus = 0;  //0 = no value, 1 = loading, 2 = done loading
		this.slide_1 = new Element("div", {id: "slide_1"}).inject(this.container);
		this.slide_2 = new Element("div", {id: "slide_2"}).inject(this.container);
		this.activeSlide = this.slide_1;
		this.inactiveSlide = this.slide_2;
		
		this.randomLoop = [];
		this.resetRandomSet();
		
		//create the class events
		this.addEvent("onStart", function(event){});
		this.addEvent("onComplete", function(event){});
		
		//call the render function
		this.render();
		
		//create the timer component
		this.timer = {};
		this.timer.start = function(){
			this.active = true;
			//clss.play();
			this.timerID = clss.play.periodical(clss.interval, clss);
		};
		this.timer.stop = function(){
			$clear(this.timerID)
			this.active = false;
		};
		//if auto play
		if (this.autoPlay){
			this.timer.start();
		}
		
		//if only 1 image
		
		
	},
	parseOptions: function(optionsObj, ignoreUndefinedProps){
		if (!optionsObj){ return; } else {
			for (var optionName in optionsObj){
				if (ignoreUndefinedProps && optionsObj[optionName] == undefined){ continue; } else { this[optionName] = optionsObj[optionName]; }
			}
		}
	},
	render: function(){
		//size the inner contianers
		var coords = this.container.getCoordinates(), alpha = 1;
		if (!this.effect){ alpha = 1; }
		var attributes = {
			position: 'absolute',
			left: 0,
			top: 0,
			width: coords.width,
			height:coords.height,
			opacity: alpha
		}
		this.slide_1.setStyles(attributes);
		this.slide_2.setStyles(attributes);
		
		//load the first image
		if (this.randomize){
			var index = (this.startIndex) ? this.startIndex : this.getRandom();
		} else {
			var index = (this.startIndex) ? this.startIndex : 0;
		}
		this.slideTo(index);
	},
	loadImage: function(index){
		var clss = this;
		var loadResponse = function(){
			//set loaded images
			if (!clss.loaded_images.contains(index)){
				clss.loaded_images[clss.loaded_images.length] = index;
			}
			clss.loadStatus = 2; //loaded
			clss.showImage();
			
			if (clss.links.length) {
		
				clss.activeSlide.removeEvents('click').addEvent('click', function() {
					window.location.href = clss.links[index];
				});
		
			}
			
		}		
		
		if (this.curr_image.length){
			this.loadStatus = 1; //loading
			//alert("loading: " + this.curr_image);
			new Asset.image(this.curr_image, {id: 'myImage', title: 'myImage', onload: loadResponse});
		}
	},
	showImage: function(){
		var slideTurns = 0, clss = this;
		
		//assign image to active slide
		this.activeSlide.setStyle("background", "url(" + this.curr_image + ") no-repeat 50% 50%");
		//alert("1 " + clss.activeSlide.id)
		
		//fade in active slide + fade out in active slide
		var slideFinish = function(){
			slideTurns++;	//keep count of how may times it happend - 2 is the finish
			
			if (slideTurns == 1 && clss.slideTogether == false){
				clss.activeSlide.fx.start({"opacity": 1});
			}
			
			if (slideTurns == 2){ // sliding is all done
				//switch the active slide
				if (clss.activeSlide == clss.slide_1) { 
					clss.activeSlide = clss.slide_2;
					clss.inactiveSlide = clss.slide_1;
					//alert("1 " + clss.activeSlide.id)
				} else if (clss.activeSlide == clss.slide_2) { 
					clss.activeSlide = clss.slide_1;
					clss.inactiveSlide = clss.slide_2;
					//alert("2 " + clss.activeSlide.id)
				}	
				
				//fire the complete event
				clss.fireEvent("onComplete");
				clss.loadStatus = 0; //reset status
				slideTurns = 0;
			}
		}
		
		//create teh FX objects
		if (!this.slide_1.fx){
			this.slide_1.fx = new Fx.Styles(this.slide_1, {transition: this.transition, duration: this.affectDuration, wait: false, onComplete: slideFinish });
		}
		if (!this.slide_2.fx){
			this.slide_2.fx = new Fx.Styles(this.slide_2, {transition: this.transition, duration: this.affectDuration, wait: false, onComplete: slideFinish});
		}
		
		if (this.effect){
			if (this.slideTogether){ //slide together
				this.activeSlide.fx.start({"opacity": 1});
				this.inactiveSlide.fx.start({"opacity": 0});
			} else { //separate the sliding
				this.inactiveSlide.fx.start({"opacity": 0});
				//rest will happen from the FX onComplete event
			}
		} 
		
	},
	slideTo: function(index){
		if ($type(index) == "string"){
			index = index.toInt();
		}
		if (!this.images.length) return;
		if (this.loadStatus != 0) return;
		
		if (index > this.images.length-1){ index = 0; } //catch overflow
		if (index < 0){ index = this.images.length-1; } //catch overflow
		
		this.curr_index = index;
		this.curr_image = this.images[index];
		
		this.loadImage(index);
		this.fireEvent("onStart");
	},
	play: function(){
		//make sure to restart the time if it was disabled
		if (!this.timer.active){
			this.timer.start();	
		}
		
		//stop the animation if all is done
		if (!this.loop && this.curr_index >= this.images.length-1){
			this.stop();
			this.curr_index = 0;	//reset the index so it can start again
			return;
		}
		
		//play the next image
		if (!this.randomize){
			this.slideTo(this.curr_index + 1);
		} else {
			this.slideTo(this.getRandom());
		}
		
	},
	stop: function(){
		this.timer.stop();
	},
	next: function(){
		this.stop(); //first stop the play()
		
		if (!this.randomize){
			this.slideTo(this.curr_index + 1);
		} else {
			alert("'Next' command is disabled when the 'randomize' option is set to true.");
		}
	},
	previous: function(){
		this.stop(); //first stop the play()
		
		if (!this.randomize){
			this.slideTo(this.curr_index - 1);
		} else {
			alert("'Previous' command is disabled when the 'randomize' option is set to true.");
		}
		
	},
	getRandom: function(){ //function for true random
		var rnd;
		//reset if no more items in the loop set
		if (!this.randomLoop.length){
			this.resetRandomSet();
		}
		
		rnd = $random(0, this.randomLoop.length-1);
		rnd = this.randomLoop[rnd];
		
		this.randomLoop.remove(rnd);
		
		//window.console.log( "Set: " + this.randomLoop);
		//window.console.log( "RND: " + rnd + " CURR: " + this.curr_index);
		
		return rnd;
		
		/*
		rnd = $random(0, this.images.length-1);
		window.console.log( "RND: " + rnd + " CURR: " + this.curr_index);
		
		if (rnd == this.curr_index){
			//return this.randomize();
			return this.getRandom();
		} else {
			//return rnd;
			//window.console.log( rnd);
			return rnd;
		}
		*/
	},
	resetRandomSet: function(){ //resets the random array for loop + random (true random)
		this.randomLoop = [];
		for (var i=0; i<this.images.length;i++){
			this.randomLoop[i] = i;
		}
	},
	unload: function(){
		
	}
});

// implementing the events and options to the color picker class
pmSlideshow.implement(new Events, new Options);


