/*
Author:
	luistar15, <leo020588 [at] gmail.com>
License:
	MIT License
 
Class
	noobSlide (rev.19-06-08)

Arguments:
	Parameters - see Parameters below

Parameters:
	box: dom element | required
	items: dom collection | required
	size: int | item size (px) | default: 240
	mode: string | 'horizontal', 'vertical' | default: 'horizontal'
	addButtons:{
		previous: single dom element OR dom collection| default: null
		next:  single dom element OR dom collection | default: null
		play:  single dom element OR dom collection | default: null
		playback:  single dom element OR dom collection | default: null
		stop:  single dom element OR dom collection | default: null
	}
	button_event: string | event type | default: 'click'
	handles: dom collection | default: null
	handle_event: string | event type| default: 'click'
	fxOptions: object | Fx.Tween options | default: {duration:500,wait:false}
	interval: int | for periodical | default: 5000
	autoPlay: boolean | default: false
	onWalk: event | pass arguments: currentItem, currentHandle | default: null
	startItem: int | default: 0

Properties:
	box: dom element
	items: dom collection
	size: int
	mode: string
	buttons: object
	button_event: string
	handles: dom collection
	handle_event: string
	previousIndex: int
	nextIndex: int
	fx: Fx.Tween instance
	interval: int
	autoPlay: boolean
	onWalk: function
	
Methods:
	previous(manual): walk to previous item
		manual: bolean | default:false
	next(manual): walk to next item
		manual: bolean | default:false
	play (interval,direction,wait): auto walk items
		interval: int | required
		direction: string | "previous" or "next" | required
		wait: boolean | required
	stop(): stop auto walk
	walk(item,manual,noFx): walk to item
		item: int | required
		manual: bolean | default:false
		noFx: boolean | default:false
	addHandleButtons(handles):
		handles: dom collection | required
	addActionButtons(action,buttons):
		action: string | "previous", "next", "play", "playback", "stop" | required
		buttons: dom collection | required

Requires:
	mootools 1.2 core
*/
var noobSlide = new Class({

	initialize: function(params){
		this.items = params.items;
		this.mode = params.mode || 'horizontal';
		this.modes = {horizontal:['left','width'], vertical:['top','height']};
		this.size = params.size || 240;
		this.box = params.box.setStyle(this.modes[this.mode][1],(this.size*this.items.length)+'px');
		this.button_event = params.button_event || 'click';
		this.handle_event = params.handle_event || 'click';
		this.onWalk = params.onWalk || null;
		this.currentIndex = null;
		this.previousIndex = null;
		this.nextIndex = null;
		this.interval = params.interval || 5000;
		this.duration = params.duration || 500;
		this.autoPlay = params.autoPlay || false;
		this._play = null;
		this.handles = params.handles || null;
		if(this.handles){
			this.addHandleButtons(this.handles);
		}
		this.buttons = {
			previous: [],
			next: [],
			play: [],
			playback: [],
			stop: []
		};
		if(params.addButtons){
			for(var action in params.addButtons){
				this.addActionButtons(action, $type(params.addButtons[action])=='array' ? params.addButtons[action] : [params.addButtons[action]]);
			}
		}
		this.fx = new Fx.Tween(this.box,$extend((params.fxOptions||{duration:this.duration,wait:false}),{property:this.modes[this.mode][0]}));
		this.walk((params.startItem||0),true,true);
	},

	addHandleButtons: function(handles){
		for(var i=0;i<handles.length;i++){
			handles[i].addEvent(this.handle_event,this.walk.bind(this,[i,true]));
		}
	},

	addActionButtons: function(action,buttons){
		for(var i=0; i<buttons.length; i++){
			switch(action){
				case 'previous': buttons[i].addEvent(this.button_event,this.previous.bind(this,[true])); break;
				case 'next': buttons[i].addEvent(this.button_event,this.next.bind(this,[true])); break;
				case 'play': buttons[i].addEvent(this.button_event,this.play.bind(this,[this.interval,'next',false])); break;
				case 'playback': buttons[i].addEvent(this.button_event,this.play.bind(this,[this.interval,'previous',false])); break;
				case 'stop': buttons[i].addEvent(this.button_event,this.stop.bind(this)); break;
			}
			this.buttons[action].push(buttons[i]);
		}
	},

	previous: function(manual){
		this.walk((this.currentIndex>0 ? this.currentIndex-1 : this.items.length-1),manual);
	},

	next: function(manual){
		this.walk((this.currentIndex<this.items.length-1 ? this.currentIndex+1 : 0),manual);
	},

	play: function(interval,direction,wait){
		this.stop();
		if(!wait){
			this[direction](false);
		}
		this._play = this[direction].periodical(interval,this,[false]);
	},

	stop: function(){
		$clear(this._play);
	},

	walk: function(item,manual,noFx){
		if(item!=this.currentIndex){
			this.currentIndex=item;
			this.previousIndex = this.currentIndex + (this.currentIndex>0 ? -1 : this.items.length-1);
			this.nextIndex = this.currentIndex + (this.currentIndex<this.items.length-1 ? 1 : 1-this.items.length);
			if(manual){
				this.stop();
			}
			if(noFx){
				this.fx.cancel().set((this.size*-this.currentIndex)+'px');
			}else{
				this.fx.start(this.size*-this.currentIndex);
			}
			if(manual && this.autoPlay){
				this.play(this.interval,'next',true);
			}
			if(this.onWalk){
				this.onWalk((this.items[this.currentIndex] || null), (this.handles && this.handles[this.currentIndex] ? this.handles[this.currentIndex] : null));
			}
		}
	}
	
});
/*
---

script: mootools.slideGallery.js

description: Multifunctional slide carousel for MooTools.

license: MIT-style license

authors:
- Sergii Kashcheiev

requires:
- core/1.2.4: Fx.Tween
- core/1.2.4: Fx.Transitions

provides: [slideGallery, fadeGallery]

...
*/
var slideGallery = new Class({
	Version: "1.2.3",
	Implements: [Options],
	options: {
		holder: ".holder",
		elementsParent: "ul",
		elements: "li",
		nextItem: ".next",
		prevItem: ".prev",
		stop: ".stop",
		start: ".start",
		speed: 600,
		duration: 4000,
		steps: 1,
		current: 0,
		transition: Fx.Transitions.linear,
		direction: "horizontal",
		mode: "callback",
		disableClass: "disable",
		currentClass: "current",
		random: false,
		paging: false,
		autoplay: false,
		autoplayOpposite: false,
		onStart: function(current, visible, length) {},
		onPlay: function(current, visible, length) {}
	},
	initialize: function(gallery, options) {
		this.gallery = gallery;
		this.setOptions(options);
		this.holder = this.gallery.getElement(this.options.holder);
		this.itemsParent = this.holder.getElement(this.options.elementsParent);
		this.items = this.itemsParent.getElements(this.options.elements);
		this.next = this.gallery.getElement(this.options.nextItem);
		this.prev = this.gallery.getElement(this.options.prevItem);
		this.stop = this.gallery.getElement(this.options.stop);
		this.start = this.gallery.getElement(this.options.start);
		this.current = this.options.current;
		this.bound = { rotate: this.rotate.bind(this) }
		
		if(this.options.direction == "horizontal") {
			this.direction = "margin-left";
			this.size = this.items[0].getWidth();
			this.visible = Math.round(this.holder.getWidth()/this.size);
		}
		else {
			this.direction = "margin-top";
			this.size = this.items[0].getHeight();
			this.visible = Math.round(this.holder.getHeight()/this.size);
		}
		
		if(this.next == null) this.next = new Element("a").injectInside(this.gallery);
		if(this.prev == null) this.prev = new Element("a").injectInside(this.gallery);
		this.next.cl = this.next.className;
		this.prev.cl = this.prev.className;

		if(this.visible < this.items.length) {
			if(this.options.random) {
				Array.prototype.shuffle = function(b) {
					var i = this.length, j, t;
					while(i) {
						j = Math.floor( ( i-- ) * Math.random() );
						t = b && typeof this[i].shuffle!=="undefined" ? this[i].shuffle() : this[i];
						this[i] = this[j];
						this[j] = t;
					}
					return this;
				};
				this.items.shuffle(this.items);
				this.hidden = new Element("div");
				this.items.each(function(el, i) {
					this.wrap = new Element("div").adopt(el);
					this.hidden.set("html", this.hidden.get("html"), this.wrap.get("html"));
				}.bind(this));
				this.itemsParent.set("html", this.hidden.get("html"));
				this.items = this.itemsParent.getElements(this.options.elements);
			}
		
			this.options.steps = this.options.steps > this.visible ? this.visible : this.options.steps;
			this.options.duration = this.options.duration < 1000 ? 1000 : this.options.duration;
			this.options.speed = this.options.speed > 6000 ? 6000 : this.options.speed;
			
			for(var i=0; i<this.items.length; i++) {
				if(this.items[i].hasClass(this.options.currentClass)) this.current = i;
			}
			if(this.options.mode != "circle") {
				if(this.visible+this.current >= this.items.length) {
					this.margin = (this.items.length-this.visible)*this.size;
					this.current = this.items.length-this.visible;
				}
				else this.margin = this.current*this.size;
				
				if(this.options.paging) {
					this.paging = new Element("ul").injectInside(this.gallery).addClass("paging");
					for(var i=0; i<Math.ceil((this.items.length-this.visible)/this.options.steps)+1; i++) {
						this.paging.innerHTML += '<li><a href="#">' + parseInt(i+1) + '</a></li>';
					}
					this.paging = this.paging.getElements("a");
					this.paging.each(function(el, i) {
						el.addEvent("click", function() {
							if(i*this.options.steps+this.visible >= this.items.length) {
								this.margin = (this.items.length-this.visible)*this.size;
								this.current = this.items.length-this.visible;
							}
							else this.current = i*this.options.steps;
							this.margin = this.current*this.size;
							
							this.play(this.options.speed);
							return false;
						}.bind(this));
					}.bind(this));
				}
				this.play(0);
			}
			else {
				for(; this.items.length < this.options.steps+this.visible;) {
					this.items.clone().inject(this.itemsParent, "bottom");
					this.items = this.itemsParent.getElements(this.options.elements);
				}
				if(this.current > this.items.length-1) this.current = this.items.length - 1;
				if(this.current < 0) this.current = 0;
				for(var i=0; i<this.current; i++) {
					this.items[i].inject(this.itemsParent, "bottom");
				}
				this.options.paging = false;
			}
			
			this.next.addEvent("click", function() {
				if(this.options.mode != "circle") {
					if(this.visible+this.current >= this.items.length) {
						if(this.options.mode == "callback") {
							this.margin = 0;
							this.current = 0;
						}
					}
					else if(this.visible+this.current+this.options.steps >= this.items.length) {
						this.margin = (this.items.length-this.visible)*this.size;
						this.current = this.items.length-this.visible;
					}
					else	{
						this.current = this.current+this.options.steps;
						this.margin = this.current*this.size;
					}
					this.play(this.options.speed);
				}
				else {
					var _this = this;
					this.margin = this.size*this.options.steps;
					this.itemsParent.set("tween", {
						duration: this.options.speed,
						transition: this.options.transition,
						property: this.direction,
						onComplete: function()	{
							for(var i=0; i<_this.options.steps; i++) {
								if(_this.current >= _this.items.length) _this.current = 0;
								_this.current++;
								_this.items[_this.current-1].inject(_this.itemsParent, "bottom");
							}
							this.set(0);
							_this.options.onPlay(_this.current, _this.visible, _this.items.length);
						},
						onCancel: function() {	this.onComplete(); }
					});
					this.itemsParent.tween(-this.margin);
				}
				return false;
			}.bind(this));
			
			this.prev.addEvent("click", function() {
				if(this.options.mode != "circle") {
					if(this.current <= 0) {
						if(this.options.mode == "callback") {
							this.margin = (this.items.length-this.visible)*this.size;
							this.current = this.items.length-this.visible;
						}
					}
					else if(this.current-this.options.steps <= 0) {
						this.margin = 0;
						this.current = 0;
					}
					else	{
						this.current = this.current-this.options.steps;
						this.margin = this.current*this.size;
					}
					this.play(this.options.speed);
				}
				else {
					for(var i=0; i<this.options.steps; i++) {							
						if(this.current-1 < 0) this.current = this.items.length;
						--this.current;
						this.items[this.current].inject(this.itemsParent, "top");
					}
					this.itemsParent.setStyle(this.direction, -this.size*this.options.steps + "px");
					this.margin = 0;
					this.play(this.options.speed);
				}
				return false;
			}.bind(this));

			if(this.options.autoplay || this.start || this.stop) {
				if(!this.options.autoplay) this.gallery.addClass("stopped");
				this.timer = this.bound.rotate.delay(this.options.duration);
				this.gallery.addEvent("mouseenter", function() {
					this.options.autoplay = false;
					$clear(this.timer);
				}.bind(this));
				this.gallery.addEvent("mouseleave", function() {
					if(!this.gallery.hasClass("stopped")) {
						$clear(this.timer);
						this.options.autoplay = true;
						this.timer = this.bound.rotate.delay(this.options.duration);
					}
				}.bind(this));
			}
			if(this.stop) {
				this.stop.addEvent("click", function() {
					this.gallery.addClass("stopped").fireEvent("mouseenter");
					return false;
				}.bind(this));
			}
			if(this.start) {
				this.start.addEvent("click", function() {
					this.gallery.removeClass("stopped").fireEvent("mouseenter");
					return false;
				}.bind(this));
			}
		}
		else {
			this.next.addClass(this.next.cl + "-" + this.options.disableClass);
			this.prev.addClass(this.prev.cl + "-" + this.options.disableClass);
			this.next.addEvent("click", function() {return false;}.bind(this));
			this.prev.addEvent("click", function() {return false;}.bind(this));
			if(this.stop) this.stop.addEvent("click", function() {return false;}.bind(this));
			if(this.start) this.start.addEvent("click", function() {return false;}.bind(this));
			this.gallery.addClass("stopped");
		}
		this.options.onStart(this.current, this.visible, this.items.length);
	},
	play: function(speed) {
		this.sidesChecking();
		this.itemsParent.set("tween", {
			duration: speed,
			transition: this.options.transition
		});
		this.itemsParent.tween(this.direction, -this.margin);
		if(this.options.paging) {
			this.paging.removeClass("active");
			this.paging[Math.ceil(this.current/this.options.steps)].addClass("active");
		}
		this.options.onPlay(this.current, this.visible, this.items.length);
	},
	rotate: function() {
		if(this.options.autoplay) {
			if(!this.options.autoplayOpposite) this.next.fireEvent("click");
			else this.prev.fireEvent("click");
			this.timer = this.bound.rotate.delay(this.options.duration);
		}
	},
	sidesChecking: function() {
		if(this.options.mode == "line") {
			this.next.removeClass(this.next.cl + "-" + this.options.disableClass);
			this.prev.removeClass(this.prev.cl + "-" + this.options.disableClass);
			if(this.visible+this.current >= this.items.length) this.next.addClass(this.next.cl + "-" + this.options.disableClass);
			else if(this.current==0) this.prev.addClass(this.prev.cl + "-" + this.options.disableClass);
		}
	}
});
var fadeGallery = new Class({
	Extends: slideGallery,
	initialize: function(gallery, options) {
		this.previous = null;
		if(options.mode == "circle") options.mode = "callback";
		options.steps = 1;
		this.parent(gallery, options);
		this.visible = 1;
	},
	play: function(speed) {
		if(this.previous == null) this.previous = this.items;
		this.sidesChecking();
		this.previous.set("tween", {
			duration: speed,
			transition: this.options.transition
		});
		this.previous.tween("opacity", 0);
		this.items[this.current].set("tween", {
			duration: speed,
			transition: this.options.transition
		});
		this.items[this.current].tween("opacity", 1);
		if(this.options.paging) {
			this.paging.removeClass("active");
			this.paging[Math.ceil(this.current/this.options.steps)].addClass("active");
		}
		this.previous = this.items[this.current];
		this.options.onPlay(this.current, this.visible, this.items.length);
	}
});
