/*
	Filename: moo.rd - A lightweight Mootools extension
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/> and the moo.rd Team
	
	License: GNU GPL License
	
	Copyright: copyright 2007 Riccardo Degni
	
	[Credits]
		[li] moo.rd is based on the MooTools framework <http://mootools.net/>, and uses the MooTools syntax
		[li] moo.rd constructors extends some of the MooTools Classes
		[li] moo.rd Documentation is written by Riccardo Degni
	[/Credits]
*/

var Moo = {};

Moo.Rd = {
	version: '1.3.2',
	author: 'Riccardo Degni',
	members: [
		'Cristiano Fino',
		'Moocha'
	]
};

/*
	Filename: constructors.js
	
	[Description] 
		Contains some of the moo.rd native Constructors based on the MooTools Class. It permits a major modularity.
	[/Description]
	
	Contains: Class Table, Class Make
*/
/*
	Class: Table
	Description: Allows you to customize tables, tables rows, cells and columns 
*/
var Table = new Class({	
	initialize: function(element) {
		this.element = $(element);
		this.rows = this.element.getElements('tr');
		this.cells = this.element.getElements('tr').getElements('td');
	}
});

/*
	Class: Make
	Description: Wrapper to create Classes that make dinamically Elements.  
*/
var Make = new Class({
	Implements: [Options],
	options: {
		content: 'text'
	}
});

/*
	Filename: browser.js
	
	[Description]
		Contains some Browser properties to ease the detection of the browser which is working
	[/Description]
	
	Contains: Hash Browser
	
	[Summary]
		Browser ::: Extends the Browser Hash with new properties 
	[/Summary]
*/
/*
	Hash: Browser
	
	[Description]  
		Extends the Browser Hash with new properties, to speed up and ease the detection of the browser which is working.
	[/Description]
	
	[Hash]
		 Browser.ie : alias of Browser.Engine.trident
		 Browser.ie6 : alias of Browser.Engine.trident4
		 Browser.ie7 : alias of Browser.Engine.trident5
		 Browser.firefox : alias of Browser.Engine.gecko
		 Browser.safari : alias of Browser.Engine.webkit
		 Browser.safari2 : alias of Browser.Engine.webkit419
		 Browser.safari3 : alias of Browser.Engine.webkit420
		 Browser.opera : alias of Browser.Engine.presto
		 Browser.opera925 : alias of Browser.Engine.presto925
		 Browser.opera950 : alias of Browser.Engine.presto950
	[/Hash]
*/
Browser.ie = Browser.Engine.trident;
Browser.ie6 = Browser.Engine.trident4;
Browser.ie7 = Browser.Engine.trident5;
Browser.firefox = Browser.Engine.gecko;
Browser.safari = Browser.Engine.webkit;
Browser.safari2 = Browser.Engine.webkit419;
Browser.safari3 = Browser.Engine.webkit420;
Browser.opera = Browser.Engine.presto;
Browser.opera925 = Browser.Engine.presto925;
Browser.opera950 = Browser.Engine.presto950;

/*
	Filename: effects_base.js
	
	[Description] 
		Contains a collection of methods and utilities to work with effects based on Fx Classes.
	[/Description]
	
	[Credits]
		[li] some Fx Classes of the moo.rd Fx Repository are slightly inspired on those found in the Script.aculo.us library
	[/Credits]
	
	Contains: Class Fx, Class Element, Function fxToHash
	
	Requires: string.js
	
	[Summary]
		Fx ::: Extends the Fx Class for creating the moo.rd Effects Repository and fully-customizable effects
		Element ::: Adds Fx utility methods to the Element prototypes
		fxToHash --- Extends the Element.Properties Hash for using all the Fx effects as Element's dynamic shortcuts
	[/Summary]
*/
/*
	Class: Fx
	
	Description: Extends the Fx Class for creating the moo.rd Effects Repository and fully-customizable effects. 
	
	Extends: Class Fx
	
	[Methods]
		initStyles -- initializes all the styles you want for later usages
		removeAuto -- removes the 'auto' value from all the styles you want, to obtain a cross-browser feeling
		setPosition -- sets position's value to 'relative' if the element isn't positioned
	[/Methods]
*/
Fx.implement({
	
	/*
	Method: initStyles
	Description:  initializes all the styles you want for later usages
	*/
	initStyles: function() {
		this.init = {};
		$A(arguments).each(function(a) {
			if(a == 'opacity') this.init['opacity'] = this.element.get('opacity');
			else (this.element.getStyle(a).test('px')) ? this.init[a] = this.element.getStyle(a).toInt() : this.init[a] = this.element.getStyle(a);
		}, this);
		return this;
	},
	
	/*
	Method: removeAuto
	Description:  removes the 'auto' value from all the styles you want, to obtain a cross-browser feeling
	*/
	removeAuto: function() {
		if(!this.init) this.init = {};
		$A(arguments).each(function(a) {
			if(this.element.getStyle(a) == 'auto') { 
				this.element.setStyle(a, '0px');
				this.init[a] = 0;
			}
		}, this);
		return this;
	},
	
	/*
	Method: setPosition
	Description:  sets position's value to 'relative' if the element isn't positioned
	*/
	setPosition: function() {
		if(this.element.getStyle('position') == 'static') this.element.setStyle('position', 'relative');	
		return this;
	}
});

/*
	Class: Element
	
	[Description] 
		Adds Fx utility methods to the Element prototypes
	[/Description]
	
	Extends: Class Element
	
	[Methods]
		fx -- returns a determinate Fx instance you can pick out from the moo.rd Effects Repository
		effect -- sets a determinate Fx instance and start the effect immediately. Returns the element instead of fx method which returns an instance
		removeAuto -- removes the 'auto' value from all the styles you want of this element
	[/Methods]
*/	
Element.implement({
	
	/*
	Method: fx
	Description:  returns a determinate Fx instance you can pick out from the moo.rd Effects Repository
	[Arguments]
		eff :: the fx effect
		options :: optional. the effect options. Either if you use this argument or not, the instance will be the same
	[/Arguments]
	[Example]  
		> // use Fx.Fade
		> var fade = element.fx('fade');
		> fade.start('toggle');
		>  
		> // use Fx.Move
		> var move = element.fx('move', {duration:2000});
		> move.start(120, 58);
	[/Example]
	*/
	fx: function(eff, options) {
		if(!this.retrieve(eff)) this.store(eff, new Fx[eff.upperFirst()](this, options));
		return this.retrieve(eff);
	},
	
	/*
	Method: effect
	Description:  sets a determinate Fx instance and start the effect immediately. Returns the element instead of fx method which returns an instance
	[Arguments]
		eff :: the fx effect
		arguments :: the arguments to apply to the start method
	[/Arguments]
	[Example]  
		> // call an effect immediately
		> el.effect('fade');
		>
		> // set the instance options first
		> el.set('fade', {duration: 2000});
		> // call the effect later
		> el.effect('fade');
		> el.effect('fade', 'toggle');
		>
		> // move an element immediately
		> el.effect('move', 40, 440);
	[/Example]
	*/
	effect: function(fx) {
		this.get(fx).start.pass(Array.slice(arguments, 1), this.get(fx))();
		return this;
	},
	
	/*
	Method: removeAuto
	Description:  removes the 'auto' value from all the styles you want of this element.
	*/
	removeAuto: function() {
		$A(arguments).each(function(a) {
			if(this.element.getStyle(a) == 'auto') this.element.setStyle(a, '0px');
		}, this);
		return this;
	}
});

/*
	Function: fxToHash
	Description: Extends the Element.Properties Hash for using all the Fx effects as Element's dynamic shortcuts
	[Example]  
		> var el = $('element');
		>
		> // sets a Fx.Pulsate instance for later usage
		> el.set('pulsate', {times: 24});
		> // pulsate an element 24 times
		> el.effect('pulsate');
		>
		> // sets a Fx.SwitchOff instance an use it immediately
		> el.get('switchOff', {duration: 2000}).start();
	[/Example]
*/
var fxToHash = function(hash, effects) {
	Array.each(effects, function(fx, i) {
		var fx = fx.toString();
		var props = {
			set: function(options) {
				var tween = this.retrieve(fx);
				if (tween) tween.cancel();
				return this.eliminate(fx).store(fx + ':options', options);
			},
			
			get: function(options){
				if (options || !this.retrieve(fx)){
					if (options || !this.retrieve(fx + ':options')) this.set(fx, options);
					this.store(fx, new Fx[fx.upperFirst()](this, this.retrieve(fx + ':options')));
				}
				return this.retrieve(fx);
			}
		};
		hash.set(fx, props);
	});
};

/*
	Filename: effects_fade.js
	
	[Description] 
		Contains a collection of effects based on fade transitions, for all fade needs.
	[/Description]
	
	Contains: Class Fx.Bubble, Class Fx.Fade, Class Fx.DropOut, Class Fx.Squish, Class Fx.Puff, Class Element
	
	Requires: effects_base.js
	
	[Summary]
		Fx.Bubble ::: Smoothly fades and close an element horizontally or vertically
		Fx.Fade ::: Smoothly fades the element in, out or toggle. Provides a similar functionality to Element.fade but as Class
		Fx.DropOut ::: Smoothly drops an element out, either down or up
		Fx.Squish ::: Smoothly resizes an element with a 'squish' transition
		Fx.Puff ::: Smoothly fades an element with a 'puff' transition
		Element ::: Extends the Element Class with Fx shortcuts
		Element.Properties ::: Extends the Element.Properties Hash with effects_fade.js Fx effects
	[/Summary]
*/
/*
	Class: Fx.Bubble
	
	[Description] 
		Smoothly fades and close an element horizontally or vertically
	[/Description]
	
	Extends: Fx.Morph
	
	Constructor: new Fx.Bubble (element, options)
	
	[Properties] 
		element - the element
		options - the Fx Options plus 'mode'
	[/Properties]
	
	[Options]
		mode : the effect mode. Can be 'vertical' (height transition, default) or 'horizontal' (width transition)
	[/Options]
	
	[Methods]
		start -- starts the Fx.Bubble effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Bubble effect
	[Arguments]
		mode :: optional. the effect mode
	[/Arguments]
	[Example]  
		> var fx = new Fx.Bubble('box');
		> fx.start();
	[/Example]
*/
Fx.Bubble = new Class({
					   
	Extends: Fx.Morph,
	
	options: {
		mode: 'vertical',
		duration: 3000
	},
					   
	initialize: function(element, options) {
		this.parent(element, $merge(this.options, options));
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function(mode) {
		var mode = mode || this.options.mode;
		var styles = {'font-size': 0, 'opacity': 0};
		switch(mode) {
			case 'vertical':
				this.parent($merge({'height': 0}, styles));
				break;
			case 'horizontal':
				this.parent($merge({'width': 0}, styles));
				break;
		}
	}
});

/*
	Class: Fx.Fade
	
	[Description] 
		Smoothly fades the element in, out or toggle. Provides a similar functionality of Element.fade but as Class
	[/Description]
	
	Extends: Fx.Tween
	
	Constructor: new Fx.Fade (element, options)
	
	[Properties] 
		element - the element
		options - the Fx Options
	[/Properties]
	
	[Methods]
		start -- starts the Fx.Fade effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Fade effect
	[Arguments]
		where :: a string which can be 'in', 'out' or 'toggle' (default)
	[/Arguments]
	[Example]  
		> var fx = new Fx.Fade('box');
		> // fade in
		> fx.start('in');
		> // fade out
		> fx.start('out');
		> // fade toggle
		> fx.start('toggle');
	[/Example]
*/
Fx.Fade = new Class({
					
	Extends: Fx.Tween,
	
	initialize: function(element, options) {
		this.parent(element, options);
	},
	
	start: function(where) {
		switch(where) {
			case 'in': this.parent('opacity', 1); 
					   break;
			case 'out': this.parent('opacity', 0); 
					   break;
			case 'toggle': 
			default: this.parent('opacity', (this.element.get('opacity') == 0) ? 1 : 0); 
					   break;
		}
	}
});

/*
	Class: Fx.DropOut
	
	[Description] 
		Smoothly drops an element out, either down or up
	[/Description]
	
	Extends: Fx.Morph
	
	Constructor: new Fx.DropOut (element, options)
	
	[Properties] 
		element - the element
		options - the Fx Options plus some others
	[/Properties]
	
	[Options]
		size : how far the element will be dropped. Default is 40
		where : the direction of the effect. Can be 'down' (default) or 'up'
	[/Options]
	
	[Methods]
		start -- starts the Fx.DropOut effect
	[/Methods]

	Method: start
	Description:  starts the Fx.DropOut effect
	[Arguments]
		where :: optional. Identical to the where option
	[/Arguments]
	[Example]  
		>  var fx = new Fx.DropOut('box', {where:'up', size:140});
		>  fx.start();
	[/Example]
*/
Fx.DropOut = new Class({
					   
	Extends: Fx.Morph,
	
	options: {
		size: 40,
		where: 'down'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.setPosition().initStyles('top').removeAuto('top');
	},
	
	start: function(where) {
		var where = where || this.options.where;
		switch(where) {
			case 'down':
				var fullTop = this.init.top + this.options.size;
				break;
			case 'up':
				var fullTop = this.init.top - this.options.size;
				break;
		}
		this.parent({
			'top': fullTop,
			'opacity': 0
		});
	}
});

/*
	Class: Fx.Squish
	
	[Description] 
		Smoothly resizes an element with a 'squish' transition
	[/Description]
	
	Extends: Fx.Morph
	
	Constructor: new Fx.Squish (element, options)
	
	[Properties] 
		element - the element
		options - the Fx Options
	[/Properties]
	
	[Methods]
		start -- starts the Fx.Squish effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Squish effect
	[Example]  
		>  var fx = new Fx.Squish('box', {duration:2000});
		>  fx.start();
	[/Example]
*/
Fx.Squish = new Class({
					  
	Extends: Fx.Morph,
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.initStyles('fontSize').setPosition();
		this.element.setStyles({overflow: 'hidden'});
	},
	
	start: function() {
		this.parent({
			'height': 0,
			'width': 0,
			'opacity': 0,
			'font-size': [this.init.fontSize, 0]
		});
	}		
});

/*
	Class: Fx.Puff
	
	[Description] 
		Smoothly fades an element with a 'puff' transition
	[/Description]
	
	Extends: Fx.Morph
	
	Constructor: new Fx.Puff (element, options)
	
	[Properties] 
		element - the element
		options - the Fx Options plus 'increase'
	[/Properties]
	
	[Options]
		increase : The amount for increasing css properties. Default is 1.3
	[/Options]
	
	[Methods]
		start -- starts the Fx.Puff effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Puff effect
	[Arguments]
		increase :: optional. The amount for increasing css properties
	[/Arguments]
	[Example]  
		>  var fx = new Fx.Puff('box', {increase: 1.6});
		>  fx.start();
	[/Example]
*/
Fx.Puff = new Class({
					
	Extends: Fx.Morph,
	
	options: {
		increase: 1.3
	},
					
	initialize: function(element, options) {
		this.parent(element, options);
		this.initStyles('height', 'width', 'fontSize').setPosition();
		this.element.setStyles({overflow: 'hidden'});
	},
	
	start: function(increase) {
		var increase = increase || this.options.increase;
		this.parent({
			'height': [this.init.height*increase],
			'width': [this.init.width*increase],
			'font-size': [this.init.fontSize*increase],
			'opacity': 0
		}).chain(function() { this.element.setStyle('display', 'none'); });
	}			
});

/*
	Class: Element
	
	[Description] 
		Extends the Element Class with Fx shortcuts. 
		All these methods accept the same arguments of the relative Fx effect (obviously without the element)
	[/Description]
	
	Extends: Class Element
	
	[Methods]
		bubble -- returns an Fx.Bubble instance
		fading -- returns an Fx.Fade instance
		dropOut -- returns an Fx.DropOut instance
		squish -- returns an Fx.Squish instance
		puff -- return an Fx.Puff instance
	[/Methods]
*/	
Element.implement({
	
	/*
	Method: bubble
	Description:  returns an Fx.Bubble instance
	*/
	bubble: function(options) {
		return new Fx.Bubble(this, options);	
	},
	
	/*
	Method: fading
	Description:  returns an Fx.Fade instance (note that this method is called 'fading' and doesn't overwrite the 'fade' method)
	*/
	fading: function(options) {
		return new Fx.Fade(this, options);	
	},
	
	/*
	Method: dropOut
	Description:  returns an Fx.DropOut instance
	*/
	dropOut: function(options) {
		return new Fx.DropOut(this, options);	
	},
	
	/*
	Method: squish
	Description:  returns an Fx.Squish instance
	*/
	squish: function(options) {
		return new Fx.Squish(this, options);	
	},
	
	/*
	Method: puff
	Description:  returns an Fx.Puff instance
	*/
	puff: function(options) {
		return new Fx.Puff(this, options);	
	}
});

/*
	Hash: Element.Properties
	Description: Extends the Element.Properties Hash for using the effects_fade.js Fx Classes as Element's dynamic shortcuts with the Element.effect method
*/
fxToHash(Element.Properties, ['bubble', 'fading', 'dropOut', 'squish', 'puff']);

/*
	Filename: effects_cycle.js
	
	[Description] 
		Contains the Fx.Cycle Class and the Fx.Cycle extensions for creating powerful cycle effects, based on different 
		style transitions.
	[/Description]
	
	Contains: Class Fx.Cycle and its extensions, Class Element
	
	[Summary]
		Fx.Cycle ::: A wrapper which allows you to create powerful cycle effects
		Element ::: Contains the cycle method which returns a determinate Fx.Cycle instance
	[/Summary]
*/
/*
	Class: Fx.Cycle
	
	[Description]  
		With the Fx.Cycle extensions, you can create the "cycle effect" which means a slideshow based on a particular
		style transition. This file contains 14 Fx.Cycle extensions, like Fx.Cycle.zoom and Fx.Cycle.fade.
		In addiction, you can create your own cycle effect, either customizing an existing one or creating a new one.
		Below you can find all the Fx.Cycle extensions.
	[/Description]
	
	Extends: Fx.Morph
	
	Constructor: new Fx.Cycle.cycleType (element, options)
	
	[Properties] 
		element - the wrapper which contains your slides
		options - optional. The Fx options plus those described below
	[/Properties]
	
	[Options]
		animeOut : an object whose properties are the styles to alter when the slide gets out.
		animeIn : an object whose properties are the styles to alter when the slide comes in.
		cssBefore : an object whose properties are the styles to alter immediately before the slide comes in.
		animeInType : indicates the method to use with the animeIn object. It can be 'set' (default) or 'start' 
		overflow : the overflow of the wrapper. Depends on the type of cycle effect.
		steps : the timer used by autostart to change periodically the slides. Default is 2000 ms
		handles : an object which attaches events to elements passed in as values. The keywords represent the Fx.Cycle's methods
		autostart : if true the slides will be changed automatically. Deafult is true
		enable : an object containing some keywords to enable extra features. See below.
	[/Options]
	
	>> enable:
	[List]
		[li] keyboard: if true you can navigate with the keyboard too. In addition to the arrows, you can use the following keys. 'a' for autostart, 's' for stop, 'f' to go to the first slide and 'l' to go to the last slide. 
	[/List]
	
	[Events]
		onAnimeIn : function fired immediately before the element is animed in. The current and the next slide will be passed in
		onAnimeOut : function fired immediately before the element is animed out. The current and the next slide will be passed in
	[/Events]
	
	[Methods]
		next -- switches to the next slide
		prev -- switches to the previous slide
		goTo -- swicthes to the given slide
		toFirst -- switches to the first slide
		toLast -- switches to the last slide
		autostart -- enables the cycle slideshow
		stop -- stops the slideshow either if start method has been called or autostart option has been enabled
		animeIn -- sets the animeIn properties
		animeOut -- sets the animeOut properties
		cssBefore -- sets the cssBefore properties
	[/Methods]
	
	[Note]
		You can use the keywords 'this.height' and 'this.width' into the animeIn, animeOut and cssBefore methods,
		to refer respectively to the images' height and width. Using the keyword 'this.parentHeight' and 'this.parentWidth'
		you can refer to the parent element dimensions.
		In addiction, you can use the keywords 'this.currSlide' and 'this.nextSlide' to refer respectively to the current and
		the next slide.
	[/Note]
	
	Method: next
	Description:  switches to the next slide
	[Example]  
		> fx.next();
	[/Example]
	
	Method: prev
	Description:  switches to the previous slide
	[Example]  
		> fx.prev();
	[/Example]
	
	Method: goTo
	Description:  swicthes to the given slide
	[Arguments]
		num :: the position of the needed slide
	[/Arguments]
	[Example]  
		> fx.goTo(2);
	[/Example]
	
	Method: toFirst
	Description:  switches to the first slide
	[Example]  
		> fx.toFirst();
	[/Example]
	
	Method: toLast
	Description:  switches to the last slide
	[Example]  
		> fx.toLast();
	[/Example]
	
	Method: autostart
	Description:  enables the cycle slideshow
	[Example]  
		> fx.autostart();
	[/Example]
	
	Method: stop
	Description:  stops the slideshow either if start method has been called or autostart option has been enabled
	[Example]  
		> fx.stop();
	[/Example]
	
	Method: animeIn
	Description:  sets the animeIn properties
	[Arguments]
		styles :: an object which contains the animeIn css styles
	[/Arguments]
	[Example]  
		> fx.animeIn({top: 200, left: 200});
	[/Example]
	
	Method: animeOut
	Description:  sets the animeOut properties
	[Arguments]
		styles :: an object which contains the animeOut css styles
	[/Arguments]
	[Example]  
		> fx.animeOut({top: -200, opacity: 0});
	[/Example]
	
	Method: cssBefore
	Description:  sets the cssBefore properties
	[Arguments]
		styles :: an object which contains the cssBefore css styles
	[/Arguments]
	[Example]  
		> fx.cssBefore({left: 200, opacity: 1, height: 0, width: 0});
	[/Example]
*/
Fx.Cycle = new Class({
	
	Extends: Fx.Morph,
	
	options: {
		animeOut: {},
		animeIn: {},
		cssBefore: {},
		//cssAfter: {},
		animeInType: 'set',
		overflow: 'visible',
		autostart: true,
		steps: 2000,
		handles: {
			next: false,
			prev: false,
			toFirst: false,
			toLast: false,
			autostart: false,
			stop: false
		},
		enable: {
			keyboard: false	
		},
		onAnimeIn: $empty,
		onAnimeOut: $empty
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.imgs = this.element.getChildren();
		this.uimgs = this.element.getChildren().reverse();
		this.element.setStyles({'position': 'relative', 'overflow': this.options.overflow});
		this.first = this.element.getFirst();
		
		this.height = this.first.getStyle('height').toInt();
		this.width = this.first.getStyle('width').toInt();
		this.parentHeight = this.element.getStyle('height').toInt();
		this.parentWidth = this.element.getStyle('width').toInt();
		
		this.uimgs.each(function(img, i) {
			img.setStyles({'position': 'absolute', 'top': '0px', 'left': '0px', 'z-index': i});
		}, this);
		this.count = 0;
		this.length = this.imgs.length-1;
		this.fullLength = this.imgs.length;
		if(this.options.autostart) this._autostart = this.next.periodical(this.options.steps, this);
		this.attachHandles();
		if(this.options.enable.keyboard) this.attachKeys.bindWithEvent(this)();
	},
	
	next: function() {
		if(!this.timer) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			(this.count != this.length) ? this.count++ : this.count = 0;
			this.main();
		}
	},
	
	prev: function() {
		if(!this.timer) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			(this.count == 0) ? this.count = this.length : this.count--;
			this.main();
		}
	},
	
	goTo: function(to) {
		if(!this.timer && to != this.count) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			this.count = to;
			this.main();
		}
	},
	
	toFirst: function() {
		if(!this.timer && this.count != 0) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			this.count = 0;
			this.main();
		}
	},
	
	toLast: function() {
		if(!this.timer && this.count != this.length) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			this.count = this.length;
			this.main();
		}
	},
	
	autostart: function() {
		this._autostart = this.next.periodical(this.options.steps, this);
	},
	
	stop: function() {
		this._autostart = $clear(this._autostart);	
	},
	
	checkAutostart: function() {
		if(this._autostart) {
			this._autostart = $clear(this._autostart);
			this._autostart = this.next.periodical(this.options.steps, this);
		}
	},
	
	attachHandles: function() {
		for(var mtd in this.options.handles) {
			var method = mtd.toString();
			if(this.options.handles[mtd] && $function(this[method])) {
				$(this.options.handles[mtd]).addEvent('click', function(event, method) {
					event.preventDefault();	
					this[method]();
				}.bindWithEvent(this, method));	
			}
		}
	},
	
	attachKeys: function(event) {
		$(document).addEvent('keydown', function(event) {
			switch(event.key) {
				case 'left': this.prev();
					break;
				case 'right': this.next();
					break;
				case 'a': this.autostart();
					break;
				case 's': this.stop();
					break;
				case 'f': this.toFirst();
					break;
				case 'l': this.toLast();
					break;
			}
		}.bind(this));
	},
	
	main: function() {
		this.element.setStyle('z-index', this.fullLength);
		this.imgs[this.count].setStyle('z-index', 1);
		
		this.currSlide = this.element;
		this.nextSlide = this.imgs[this.count];
		
		this.fireEvent('onAnimeOut', [this.currSlide, this.nextSlide]);
		this.start(this.options.animeOut).chain(
			function() {
				var type = this.options.animeInType;
				if(type == 'set') this.fireEvent('onAnimeIn', [this.currSlide, this.nextSlide]);
				this.element.setStyle('z-index', 0);
				this.imgs.each(function(img, i) {
					if(i != this.count) img.setStyle('z-index', 0).setStyles(this.options.cssBefore);
				}, this);
				if(type == 'set') this[type](this.options.animeIn); // set instead of start
				if(type == 'start') this[type](this.options.animeIn).chain(function() { this.fireEvent('onAnimeIn', [this.currSlide, this.nextSlide]); });
			}
		);
	}
					 
});

(function() {
var methods = {};

['animeOut', 'animeIn', 'cssBefore'].each(function(method) {
	methods[method] = function(styles) {
		for(var style in styles)
			if($defined(styles[style])) this.options[method][style] = styles[style]; 
	}					
});

Fx.Cycle.implement(methods);
})();

/* 
Class: Fx.Cycle.shuffle 
*/
Fx.Cycle.shuffle = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeInType: 'start',
		animeIn: {
			top: 0,
			left: 0
		},
		sizes: [20, -110]
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({top: this.options.sizes[0], left: this.options.sizes[1]});
	}
});

/* 
Class: Fx.Cycle.fade 
*/
Fx.Cycle.fade = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeOut: {
			opacity: 0
		},
		cssBefore: {
			opacity: 1	
		}
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
	}
});

/* 
Class: Fx.Cycle.slideUp 
*/
Fx.Cycle.slideUp = new Class({

	Extends: Fx.Cycle,
	
	options: {
		cssBefore: {
			top: 0, left:0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({top: -this.parentHeight});
	}
});

/* 
Class: Fx.Cycle.slideDown 
*/
Fx.Cycle.slideDown = new Class({

	Extends: Fx.Cycle,
	
	options: {
		cssBefore: {
			top: 0, left:0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({top: this.parentHeight});
	}
});

/* 
Class: Fx.Cycle.slideRight 
*/
Fx.Cycle.slideRight = new Class({

	Extends: Fx.Cycle,
	
	options: {
		cssBefore: {
			top: 0, left:0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({left: this.parentWidth});
	}
});

/* 
Class: Fx.Cycle.slideLeft 
*/
Fx.Cycle.slideLeft = new Class({

	Extends: Fx.Cycle,
	
	options: {
		cssBefore: {
			top: 0, left:0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({left: -this.parentWidth});
	}
});

/* 
Class: Fx.Cycle.foldUp 
*/
Fx.Cycle.foldUp = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeOut: {
			height: 0
		},
		animeIn: {
			left: 0, top: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.cssBefore({top: 0, height: this.height});
	}
});

/* 
Class: Fx.Cycle.foldDown 
*/
Fx.Cycle.foldDown = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeIn: {
			left: 0, top: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({height: 0, top: this.height});
		this.cssBefore({top: 0, height: this.height});
	}
});

/* 
Class: Fx.Cycle.foldRight 
*/
Fx.Cycle.foldRight = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeOut: {
			width: 0
		},
		animeIn: {
			left: 0, top: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.cssBefore({top: 0, width: this.width});
	}
});

/* 
Class: Fx.Cycle.foldLeft 
*/
Fx.Cycle.foldLeft = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeIn: {
			left: 0, top: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({width: 0, left: this.width});
		this.cssBefore({top: 0, width: this.width});
	}
});

/* 
Class: Fx.Cycle.zoom 
*/
Fx.Cycle.zoom = new Class({

	Extends: Fx.Cycle,
	
	options: {
		cssBefore: {
			top: 0, left: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({width: 0, height: 0, top: this.height/2, left: this.width/2});
		this.animeIn({top: 0, left: 0, width: this.height, height: this.width});
	}
});

/* 
Class: Fx.Cycle.diagonalUp
*/
Fx.Cycle.diagonalUp = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeIn: {
			top: 0, left: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({top: -this.parentHeight, left: -this.parentWidth});
	}
});

/* 
Class: Fx.Cycle.diagonalDown
*/
Fx.Cycle.diagonalDown = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeIn: {
			top: 0, left: 0
		},
		overflow: 'hidden'
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
		this.animeOut({top: this.parentHeight, left: this.parentWidth});
	}
});

/* 
Class: Fx.Cycle.linear 
*/
Fx.Cycle.linear = new Class({

	Extends: Fx.Cycle,
	
	options: {
		animeOut: {
			display: 'none'
		},
		cssBefore: {
			display: 'block'
		}
	},
	
	initialize: function(element, options) {
		this.parent(element, options);
	}
});

/*
	Class: Element
	
	[Description] 
		Contains the cycle method which returns a determinate Fx.Cycle instance
	[/Description]
	
	Extends: Class Element
	
	[Methods]
		cycle -- returns an Fx.Cycle instance of the given type
	[/Methods]
*/	
Element.implement({
	
	/*
	Method: cycle
	Description:  returns an Fx.Cycle instance of the given type
	[Arguments]
		type :: the Fx.Cycle transition
		options :: the Fx.Cycle options
	[/Arguments]
	[Example]  
		> // slideUp instance
		> var slideUp = $('myElement').cycle('slideUp');
		> // diagonalUp instance
		> var diagonalUp = $('myElement').cycle('diagonalUp', {duration: 4000, steps: 4000});
	[/Example]
	*/
	cycle: function(type, options) {
		return new Fx.Cycle[type](this, options);
	}				  

});

/*
	Filename: effects_cycles.js
	
	[Description] 
		Contains the Fx.Cycles Class and the Fx.Cycles extensions to create powerful cycle slideshows which alter 
		two slides at once
	[/Description]
	
	Contains: Class Fx.Cycles and its extensions, Class Element
	
	[Summary]
		Fx.Cycles ::: A wrapper which allows you to create powerful cycle effects
		Element ::: Contains the cycles method which returns a determinate Fx.Cycles instance
	[/Summary]
*/
/*
	Class: Fx.Cycles
	
	[Description]  
		The Fx.Cycles Class provides a similar functionality to the Fx.Cycle Class. With the Fx.Cycles Class however,
		you can "cycle" two slides at once, to create more complex transitions. There are 13 transitions created by default,
		but you can create your own as with the Fx.Cycle Class.
	[/Description]
	
	Extends: Fx.Elements
	
	Constructor: new Fx.Cycles.cycleType (element, options)
	
	[Properties] 
		element - the wrapper which contains your slides
		options - optional. The Fx options
	[/Properties]
	
	[Options]
		animeOut : an object whose properties are the styles to alter when the slide gets out.
		animeIn : an object whose properties are the styles to alter when the slide comes in.
		cssBefore : an object whose properties are the styles to alter immediately before the slide comes in.
		cssAfter : an object whose properties are the styles to alter immediately after the slide has come in.
		reset : an object whose properties are the styles to reset to the next slide.
		overflow : the overflow of the wrapper. Depends on the type of cycle effect.
		steps : the timer used by autostart to change periodically the slides. Default is 2000 ms
		handles : an object which attaches events to elements passed in as values. The keywords represent the Fx.Cycles's methods
		autostart : if true the slides will be changed automatically. Deafult is true
		enable : an object containing some keywords to enable extra features. See below.
	[/Options]
	
	>> enable:
	[List]
		[li] keyboard: if true you can navigate with the keyboard too. In addition to the arrows, you can use the following keys. 'a' for autostart, 's' for stop, 'f' to go to the first slide and 'l' to go to the last slide. 
	[/List]
	
	[Events]
		onAnimeIn : function fired immediately before the element is animed in. The current and the next slide will be passed in
		onAnimeOut : function fired immediately before the element is animed out. The current and the next slide will be passed in
	[/Events]
	
	[Methods]
		next -- switches to the next slide
		prev -- switches to the previous slide
		goTo -- swicthes to the given slide
		toFirst -- switches to the first slide
		toLast -- switches to the last slide
		autostart -- enables the cycle slideshow
		stop -- stops the slideshow either if start method has been called or autostart option has been enabled
		animeIn -- sets the animeIn properties
		animeOut -- sets the animeOut properties
		cssBefore -- sets the cssBefore properties
		cssAfter -- sets the cssAfter properties
		reset -- sets the reset properties
	[/Methods]
	
	[Note]
		You can use the keywords 'this.height' and 'this.width' into the animeIn, animeOut, cssBefore, cssAfter and reset methods,
		to refer respectively to the images' height and width. Using the keyword 'this.parentHeight' and 'this.parentWidth'
		you can refer to the parent element dimensions.
		In addiction, you can use the keywords 'this.currSlide' and 'this.nextSlide' to refer respectively to the current and
		the next slide.
	[/Note]
	
	Method: next
	Description:  switches to the next slide
	[Example]  
		> fx.next();
	[/Example]
	
	Method: prev
	Description:  switches to the previous slide
	[Example]  
		> fx.prev();
	[/Example]
	
	Method: goTo
	Description:  swicthes to the given slide
	[Arguments]
		num :: the position of the needed slide
	[/Arguments]
	[Example]  
		> fx.goTo(2);
	[/Example]
	
	Method: toFirst
	Description:  switches to the first slide
	[Example]  
		> fx.toFirst();
	[/Example]
	
	Method: toLast
	Description:  switches to the last slide
	[Example]  
		> fx.toLast();
	[/Example]
	
	Method: autostart
	Description:  enables the cycle slideshow
	[Example]  
		> fx.autostart();
	[/Example]
	
	Method: stop
	Description:  stops the slideshow either if start method has been called or autostart option has been enabled
	[Example]  
		> fx.stop();
	[/Example]
	
	Method: animeIn
	Description:  sets the animeIn properties
	[Arguments]
		styles :: an object which contains the animeIn css styles
	[/Arguments]
	[Example]  
		> fx.animeIn({top: 200, left: 200});
	[/Example]
	
	Method: animeOut
	Description:  sets the animeOut properties
	[Arguments]
		styles :: an object which contains the animeOut css styles
	[/Arguments]
	[Example]  
		> fx.animeOut({top: -200, opacity: 0});
	[/Example]
	
	Method: cssBefore
	Description:  sets the cssBefore properties
	[Arguments]
		styles :: an object which contains the cssBefore css styles
	[/Arguments]
	[Example]  
		> fx.cssBefore({left: 200, opacity: 1, height: 0, width: 0});
	[/Example]
	
	Method: cssAfter
	Description:  sets the cssAfter properties
	[Arguments]
		styles :: an object which contains the cssAfter css styles
	[/Arguments]
	[Example]  
		> fx.cssAfter({left: 0, opacity: 0, height: 200});
	[/Example]
	
	Method: reset
	Description:  sets the reset properties
	[Arguments]
		styles :: an object which contains the reset css styles
	[/Arguments]
	[Example]  
		> fx.reset({top: 200, opacity: 1, width: 0});
	[/Example]
*/
Fx.Cycles = new Class({
	
	Extends: Fx.Elements,
	
	options: {
		animeOut: {},
		animeIn: {},
		cssBefore: {},
		cssAfter: {},
		reset: {},
		overflow: 'visible',
		autostart: true,
		steps: 2000,
		duration: 3000,
		handles: {
			next: false,
			prev: false,
			toFirst: false,
			toLast: false,
			autostart: false,
			stop: false
		},
		enable: {
			keyboard: false	
		},
		onAnimeIn: $empty,
		onAnimeOut: $empty
	},
	
	initialize: function(element, options) {
		this.element = $(element);
		this.elements = this.element.getChildren();
		this.parent($$(this.elements), options);
		this.imgs = this.element.getChildren();
		this.uimgs = this.element.getChildren().reverse();
		this.element.setStyles({'position': 'relative', 'overflow': this.options.overflow});
		this.first = this.element.getFirst();
		
		this.height = this.first.getStyle('height').toInt();
		this.width = this.first.getStyle('width').toInt();
		this.parentHeight = this.element.getStyle('height').toInt();
		this.parentWidth = this.element.getStyle('width').toInt();
		
		this.uimgs.each(function(img, i) {
			img.setStyles({'position': 'absolute', 'top': '0px', 'left': '0px', 'z-index': i});
		}, this);
		this.count = 0;
		this.where = -1;
		this.length = this.imgs.length-1;
		this.fullLength = this.imgs.length;
		if(this.options.autostart) this._autostart = this.next.periodical(this.options.steps, this);
		this.attachHandles();
		if(!this.options.enable.keyboard) this.attachKeys.bindWithEvent(this)();
	},
	
	next: function() {
		if(!this.timer) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			(this.count != this.length) ? this.count++ : this.count = 0;
			(this.where == -1) ? this.where = 0 : (this.count == 0) ? this.where = this.length : this.where = this.count-1;
			this.main();
		}
	},
	
	prev: function() {
		if(!this.timer) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			(this.count == 0) ? this.count = this.length : this.count--;
			(this.where == -1) ? this.where = 0 : (this.count == this.length) ? this.where = 0 : this.where = this.count+1;
			this.main();
		}
	},
	
	goTo: function(to) {
		if(!this.timer && to != this.count) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			this.where = this.count;
			this.count = to;
			this.main();
		}
	},
	
	toFirst: function() {
		if(!this.timer && this.count != 0) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			this.where = this.count;
			this.count = 0;
			this.main();
		}
	},
	
	toLast: function() {
		if(!this.timer && this.count != this.length) {
			this.checkAutostart();
			this.element = this.imgs[this.count];
			this.where = this.count;
			this.count = this.length;
			this.main();
		}
	},
	
	autostart: function() {
		this._autostart = this.next.periodical(this.options.steps, this);
	},
	
	stop: function() {
		this._autostart = $clear(this._autostart);	
	},
	
	checkAutostart: function() {
		if(this._autostart) {
			this._autostart = $clear(this._autostart);
			this._autostart = this.next.periodical(this.options.steps, this);
		}
	},
	
	attachHandles: function() {
		for(var mtd in this.options.handles) {
			var method = mtd.toString();
			if(this.options.handles[mtd] && $function(this[method])) {
				$(this.options.handles[mtd]).addEvent('click', function(event, method) {
					event.preventDefault();	
					this[method]();
				}.bindWithEvent(this, method));	
			}
		}
	},
	
	attachKeys: function(event) {
		$(document).addEvent('keydown', function(event) {
			switch(event.key) {
				case 'left': this.prev();
					break;
				case 'right': this.next();
					break;
				case 'a': this.autostart();
					break;
				case 's': this.stop();
					break;
				case 'f': this.toFirst();
					break;
				case 'l': this.toLast();
					break;
			}
		}.bind(this));
	},
	
	main: function() {
		this.element.setStyle('z-index', this.fullLength);
		this.imgs[this.count].setStyle('z-index', 1).setStyles(this.options.current);
		
		this.imgs.each(function(img, i) {
				if(i!=this.where)
					img.setStyles(this.options.cssBefore);
		}, this);
		
		var o = {};

		var curr = this.where;
		var next = this.count;
		
		this.currSlide = this.imgs[curr];
		this.nextSlide = this.imgs[next];
			
		o[curr] = this.options.animeOut;
		o[next] = this.options.animeIn;
		
		this.fireEvent('onAnimeOut', [this.currSlide, this.nextSlide]);
		this.imgs[next].setStyles(this.options.reset);
		this.start(o).chain(function() {
			this.imgs[curr].setStyles(this.options.cssAfter); 
			this.fireEvent('onAnimeIn', [this.currSlide, this.nextSlide]);	
		});
	}
					 
});

(function() {
var methods = {};

['animeOut', 'animeIn', 'cssBefore', 'cssAfter', 'reset'].each(function(method) {
	methods[method] = function(styles) {
		for(var style in styles)
			if($defined(styles[style])) this.options[method][style] = styles[style]; 
	}					
});

Fx.Cycles.implement(methods);
})();

/* 
Class: Fx.Cycles.scrollUp 
*/
Fx.Cycles.scrollUp = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({top: [0, -this.parentHeight]});
		this.animeIn({top: [this.parentHeight, 0]});
	}
});

/* 
Class: Fx.Cycles.scrollDown 
*/
Fx.Cycles.scrollDown = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({top: [0, this.parentHeight]});
		this.animeIn({top: [-this.parentHeight, 0]});
	}
});

/* 
Class: Fx.Cycles.scrollLeft
*/
Fx.Cycles.scrollLeft = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({left: [0, -this.parentWidth]});
		this.animeIn({left: [this.parentWidth, 0]});
	}
});

/* 
Class: Fx.Cycles.scrollRight
*/
Fx.Cycles.scrollRight = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({left: [0, this.parentWidth]});
		this.animeIn({left: [-this.parentWidth, 0]});
	}
});

/* 
Class: Fx.Cycles.fadeZoom
*/
Fx.Cycles.fadeZoom = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({opacity: [1, 0], display: 'block'});
		this.animeIn({left: [this.width/2, 0], top: [this.height/2, 0], width: [0, this.width], height: [0, this.height], display: 'block'});
		this.cssBefore({height: 0, width: 0, display: 'none'});
		this.reset({height: this.height, width: this.width, opacity: 1, top: this.height/2, left: this.width/2, display: 'none'});
	}
});

/* 
Class: Fx.Cycles.turnDown
*/
Fx.Cycles.turnDown = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({height: [this.height, 0], top: [0, this.height]});
		this.animeIn({height: [0, this.height]});
		this.reset({display: 'block', height: this.height, width: this.width, top: 0, left: 0});
		this.cssAfter({display: 'none', width: 0});
	}
});

/* 
Class: Fx.Cycles.turnUp
*/
Fx.Cycles.turnUp = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({height: [this.height, 0], top: 0});
		this.animeIn({height: [0, this.height], top: 0});
		this.reset({display: 'block', top: this.height, width: this.width});
		this.cssAfter({display: 'none', width: 0});
	}
});

/* 
Class: Fx.Cycles.turnLeft
*/
Fx.Cycles.turnLeft = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({width: [this.width, 0], left: 0});
		this.animeIn({width: [0, this.width], left: [this.width, 0]});
		this.reset({display: 'block', left: this.width, width: this.width});
		this.cssAfter({display: 'none', width: 0});
	}
});

/* 
Class: Fx.Cycles.turnRight
*/
Fx.Cycles.turnRight = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({width: [this.width, 0], left: [0, this.width]});
		this.animeIn({width: [0, this.width], left: 0});
		this.reset({display: 'block', left: 0, width: this.width});
		this.cssAfter({display: 'none', width: 0});
	}
});

/* 
Class: Fx.Cycles.inOutLeft
*/
Fx.Cycles.inOutLeft = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({top: this.parentHeight, left: this.parentWidth});
		this.animeIn({top:0, left: 0});
		this.cssBefore({display: 'none'});
		this.reset({top: -this.parentHeight, left: this.parentWidth, display: 'block'});
	}
});

/* 
Class: Fx.Cycles.inOutRight
*/
Fx.Cycles.inOutRight = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({top: -this.parentHeight, left: -this.parentWidth});
		this.animeIn({top:0, left: 0});
		this.cssBefore({display: 'none'});
		this.reset({top: this.parentHeight, left: -this.parentWidth, display: 'block'});
	}
});

/* 
Class: Fx.Cycles.inOutUp
*/
Fx.Cycles.inOutUp = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({top: -this.parentHeight});
		this.animeIn({left: 0});
		this.cssBefore({display: 'none'});
		this.reset({top: 0, left: this.parentWidth, display: 'block'});
	}
});

/* 
Class: Fx.Cycles.inOutDown
*/
Fx.Cycles.inOutDown = new Class({

	Extends: Fx.Cycles,
	
	options: {
		overflow: 'hidden'
	},
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.animeOut({top: this.parentHeight});
		this.animeIn({left: 0});
		this.cssBefore({display: 'none'});
		this.reset({top: 0, left: this.parentWidth, display: 'block'});
	}
});

/*
	Class: Element
	
	[Description] 
		Contains the cycles method which returns a determinate Fx.Cycles instance
	[/Description]
	
	Extends: Class Element
	
	[Methods]
		cycles -- returns an Fx.Cycles instance of the given type
	[/Methods]
*/	
Element.implement({
	
	/*
	Method: cycles
	Description:  returns an Fx.Cycles instance of the given type
	[Arguments]
		type :: the Fx.Cycles transition
		options :: the Fx.Cycles options
	[/Arguments]
	[Example]  
		> // scrollUp instance
		> var scrollUp = $('myElement').cycles('scrollUp');
		> // turnUp instance
		> var turnUp = $('myElement').cycles('turnUp', {duration: 2000, steps: 4000});
	[/Example]
	*/
	cycles: function(type, options) {
		return new Fx.Cycles[type](this, options);
	}				  

});