/***************************************************************************
/Copyright TPWD™ (tpwd.pt) 2009
/Contact: hellow@tpwd.pt
/
/Slideshow effect for Mootools V1.2
/Usage: set the first set of variables, define your files and directories
/(this part can be done on the destination file using php) and create a
/container div for the slides
/
***************************************************************************/

var MooSlideshow = new Class({      
    //implement
	Implements: [Chain, Options, Events],
	
	//------------------------------------------------------------------------------
	//variables
	main_container: null,
	images: [],

    options: {
    	slideMode: 0,
		autoSlideshow: true,
	    slideDuration: 5000,
		fadeDuration: 800,
		nextId: null,
		previousId: null,
		selectorsId: null,
		showSelectors: false,
		showPrevNext: false,
		selectorPrevHtml: '&lt;',
		selectorNextHtml: '&gt;'
    },

	assets: [],
    effects: [],
    effectsChain: new Chain(),
	slides_container: null,
	selectors_container: null,
	currentSlide: 0,
	totalSlides: 0,
	
    

	//------------------------------------------------------------------------------
	//init function
    initialize: function(main_container, images, options) {
    	this.setOptions(options);

		this.main_container = typeof main_container == "string" ? $(main_container) : main_container;
		if (this.main_container) {
			this.images = images;

			this.assets = Asset.images(images, { onComplete: function() { this.startTasks(); }.bind(this) })
			this.totalSlides = this.assets.length;
		} else {
			alert("MooSlideshow error: container not found.")
		}
     },


	//------------------------------------------------------------------------------
	//methods
	startTasks: function() {
		var selector_class, functionToChain, height = 0;
        
        // CALC IMAGE HEIGHT AND SET CONTAINER TO THE HIGHEST
/*
        this.assets.each(function(obj, index) {
            if (obj.getStyle('height').toInt() > height) height = obj.getStyle('height').toInt();
        });
*/

		// CREATE SLIDES CONTAINER
		//this.slides_container = new Element('div', { 'class': 'slides_container', 'style': 'height: '+height+'px' });
		this.slides_container = new Element('div', { 'class': 'slides_container' });
		
		// CREATE SELECTORS CONTAINER
		if (this.options.selectorsId == null) this.selectors_container = new Element('div', { 'class': 'selectors_container' });
		else                                  this.selectors_container = $(this.options.selectorsId);
		

		// FOR EACH IMAGE LOADED...
		this.assets.each(function(obj, index) {
			
			// CREATE AND INSERT SLIDES
			fadeDuration = this.fadeDuration;
			effectsChain = this.effectsChain;
			var newslide = new Element('div', {
				'class': 'slide',
				'styles': {
					'visibility': 'visible',
					'opacity': '1',
					'display': 'block',
					'position': 'absolute'
				},
				'id': 'slide'+index,
				'morph': {  
		            duration: 1500,
		            onComplete: function(){ this.changeToSlide() }.bind(this)
		        }
				//'html': '<img src="'+obj.get('src')+'" />',
			}).inject(this.slides_container, 'top');
			// INJECT ASSET INTO NEW SLIDE CONTAINER
			this.assets[index].inject(newslide)
			

			//this.effects[index] = new Fx.Tween($('slide'+index), 'opacity', { duration: 'short', onComplete: function() { this.callChain();}.bind(this)});
 
			// EFFECTS
			if (index < (this.assets.length)-1) {
	        	this.effectsChain.chain(
	        		function() { newslide.morph({ opacity: 0 }); }
	        	);
	        	
	        } else {
	        	this.effectsChain.chain(
					function() {
	        			this.slides_container.getChildren().getLast().morph({ opacity: 1 });
		        	}.bind(this),
					function() {
	        			this.slides_container.getChildren().each(function(el) { el.setStyle('opacity', 1); });
	        			this.changeToSlide()
		        	}.bind(this)

		        );
	        }
        	var nextSlide = newslide;
		    
			
			// CREATE AND INSERT SELECTORS
			if (this.options.showSelectors == true) new Element('a', {
				'events': {
					'click': this.onSelectorClick.bindWithEvent(this)
				},
				'rel': index,
				'class': "selector selector"+index,
				'id': "selector"+index,
				'href': "javascript:;",
				'html': index+1
			}).inject(this.selectors_container, 'bottom');

		}, this);


		// SELECT FIRST SELECTOR
		if (this.options.showSelectors == true) this.selectors_container.getChildren()[0].addClass('selected')


		//PREVIOUS / NEXT BUTTONS
		if (this.options.showPrevNext == true && this.options.previousId == null) new Element('a', {
			'events': {
				'click': this.onPrevImageClick.bindWithEvent(this)
			},
			'class': "prev_image",
			'href': "javascript:;",
			'html': this.options.selectorPrevHtml
		}).inject(this.selectors_container, 'top');
		else if (this.options.previousId != null) $(this.options.previousId).addEvent('click', this.onPrevImageClick.bindWithEvent(this))
		
		if (this.options.showPrevNext == true && this.options.nextId == null) new Element('a', {
			'events': {
				'click': this.onNextImageClick.bindWithEvent(this)
			},
			'class': "next_image",
			'href': "javascript:;",
			'html': this.options.selectorNextHtml
		}).inject(this.selectors_container, 'bottom');
		else if (this.options.nextId != null) $(this.options.nextId).addEvent('click', this.onNextImageClick.bindWithEvent(this))
        
        
        // EMPTY CONTAINER AND ADD NEW CONTENT
		this.main_container.empty();
		this.slides_container.inject(this.main_container)
		if (this.options.showSelectors == true && this.options.selectorsId == null && this.assets.length > 1) this.selectors_container.inject(this.main_container)
		
		// AUTOSTART SLIDESHOW
		if (this.options.autoSlideshow == true && this.assets.length > 1) this.start();
		
		//(function(){this.effectsChain.callChain();}).delay(1000, this);
		
		this.fireEvent('startTasks');
	},
	
	
	// SELECTORS EVENTS
	onSelectorClick: function(evt) {
		this.changeToSlide(parseInt(evt.target.getProperty('rel')));
		this.reset();
	},
	onPrevImageClick: function(evt) {
		this.changeToSlide(this.p());
		if (this.options.autoSlideshow != false) this.reset();
	},
	onNextImageClick: function(evt) {
		this.changeToSlide(this.n());
		if (this.options.autoSlideshow != false) this.reset();
	},
	
	
	// RETURN THE NEXT AND PREVIOUS SLIDES (PREPARED FOR LOOP)
	n: function() { if (this.currentSlide<this.images.length-1) return this.currentSlide+1; else if (this.currentSlide==this.images.length-1) return 0; },
	p: function() { if (this.currentSlide>0) return this.currentSlide-1; else if (this.currentSlide==0) return this.images.length-1; },
	
		
	// CHANGE TO SPECIFIC SLIDE
	changeToSlide: function(target_slide) {
		// defaults the target slide to the next slide in line
		target_slide = (target_slide == null) ? this.n() : target_slide;
	
		switch (this.options.slideMode) {
			case 0: // JUMP TO SLIDE
				// go through all slides and hide all those above selected
				this.slides_container.getChildren().each(function(el, index) {
		    		if (parseInt(el.get('id').substring(5)) >= target_slide) el.setStyles({'opacity': 1, 'visibility': 'visible'});
		    		else el.setStyles({'opacity': 0, 'visibility': 'hidden'});
		    	})
				break;
				
			case 1: // CROSSFADE
				//this.options.slideMode = 0;
				//this.changeToSlide();
				this.effectsChain.callChain();
				break;
				
			case 2: // FADE FROM WHITE
				this.slides_container.getChildren('.slide')[this.currentSlide].setStyles({'opacity': 0, 'visibility': 'hidden'});
				this.slides_container.getChildren('.slide')[target_slide].fade(1);
				break;
		}

		this.currentSlide = target_slide;
		if (this.options.showSelectors == true) this.updateSelectors(this.currentSlide);
        this.fireEvent('changedSlide');
	},


	// UPDATE SELECTOR CLASS
	updateSelectors: function(currentSlide) {
		// change selectors "selected" class
		this.selectors_container.getChildren().each(function(el) {
			if (el.hasClass('selector'+currentSlide)) el.addClass('selected')
			else el.removeClass('selected');
		})
	},
	
	
	// SLIDESHOW FUNCTIONS
	start: function() {
		if (this.options.autoSlideshow == true) {
			this.options.autoSlideshow = this.changeToSlide.periodical(this.options.slideDuration, this); //else this.stop();
		}
	},
	stop: function() {
		this.options.autoSlideshow = $clear(this.options.autoSlideshow);
		this.options.autoSlideshow = true;
	},
	reset: function() {
		this.stop();
		(function() { this.start(); }).delay(this.options.slideDuration, this)
	}
	
});

