/*
	Filename: moo.rd - A lightweight Mootools extension
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	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.2',
	author: 'Riccardo Degni'
};


/*
	Filename: constructors.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Custom, Class Table, Class Make, Class Fx.Base
	
	Filedescription: Contains some of the moo.rd native Constructors based on the MooTools Class. It permits a major modularity.
*/

/*
	Class: Custom
	Description: Wrapper to create standard customization 
*/
var Custom = {};

/*
	Class: Table
	Description: Allows you to customize tables, tables rows, cells and columns 
*/
var Table = new Class({	
	initialize: function(element) {
		this.element = $(element);
	}
});

/*
	Class: Make
	Description: Wrapper to create Classes that makes dinamically Elements.  
*/
var Make = {};


/*
	Class: Fx.Base
	Description: Extension to create the moo.rd effects repository.  
*/
Fx.Base.implement({
	initStyles: function() {
		this.init = {};
		$A(arguments).each(function(a) {
			(this.element.getStyle(a).test('px')) ? this.init[a] = this.element.getStyle(a).toInt() : this.init[a] = this.element.getStyle(a);
		}, this);	
	},
	
	removeAuto: function() {
		if(!this.init) this.init = {};
		$A(arguments).each(function(a) {
			(this.element.getStyle(a).test('auto')) ? this.element.setStyle(a, '0px') : this.element.getStyle(a);
			(this.init[a] != 'auto') ? this.init[a] : this.init[a] = 0;
		}, this);
	}
});


/*
	Filename: php_string.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class String (extension)
	
	Filedescription:  This file extends the native String object with many methods that works like PHP string methods. These are indispensable in server-side applications, but their functionally can be very useful in client-side applications. /n For this reason i have created this String extension, that allows you to use PHP string methods with Javascript.
	
	[Summary]
		String ::: Contains prototypes to apply some php string methods to String constructor
	[/Summary]
*/

/*
	Class: String
	Description:  Contains prototypes to apply some php string methods to String constructor
	
	Extends: Class String
	
	Constructor: new String (string)
	
	[Properties] 
		string - simply the string
	[/Properties]
	
	[Methods]
		stripTags -- strips all HTML tags from the string
		addslashes -- adds slashes before all ' or " characters
		nl2br -- replace all newline characters with the XHTML 'br' tag
		stripslashes -- strips slashes before all ' or " characters
		htmlEntities -- converts all possible characters in HTML entities
		trim -- trims a string
		ltrim -- delete all spaces at beginning of the string
		rtrim -- delete all spaces at the end of the string
	[/Methods]
*/

String.extend({
	
	/*
	Method: stripTags
	Description: strips all HTML tags from the string
	[Example]  
		> var s = '&lt;table&gt;&lt;tr&gt;&lt;td&gt;some data&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;';
		>  s.stripTags(); // returns 'some data'
	[/Example]
	*/
	stripTags: function () {
		return this.replace(/<([^>]+)>/g,'');
	},

	/*
	Method: addslashes
	Description: adds slashes before all ' or " characters
	[Example]  
		> var s = 'som'e da'ta'
		> s.addslashes(); 
		> // s is now 'som\'e da\'ta'
	[/Example]
	*/
	addslashes: function() {
		return this.replace(/['"]/g, function(match){
			return ('\\' + match.charAt(0) + match.charAt(1));
		});
	},
	
	/*
	Method: nl2br
	Description: replace all newline characters with the XHTML 'br' tag
	[Example]  
		> var s = 'this is \n some data \n'; 
		> s.nl2br(); 
		> // s is now:
		> 'this is &lt;br /&gt; some data &lt;br /&gt;'
	[/Example]
	*/
	nl2br: function() {
		return this.replace(/\\n/g, '<br />');
	},
	
	/*
	Method: stripslashes
	Description: strips slashes before all ' or " characters
	[Example]  
		> s = 'som\'e dat\'a';
		> s.stripslashes();
		> //s is now 'som'e dat'a'
	[/Example]
	*/
	stripslashes: function() {
		return this.replace(/\\['"]{1,}/g, function(match){
			return (match.charAt(1));
		});
	},
	
	/*
	Method: htmlEntities
	Description: converts all possible characters in HTML entities
	[Example]  
		> var s = '&lt;html&gt;&lt;head&gt;&lt;/head&gt;';
		> s.htmlEntities();
		> // returns '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;';
	[/Example]
	*/
	htmlEntities: function () {
		return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
	},
	
	/*
	Method: trim
	Description: trims a string
	[Example]  
		> var s = '&emsp;&emsp;&emsp;&emsp;some data&emsp;&emsp;&emsp;&emsp;';
		> // returns 'some data'
		> s.trim();
	[/Example]
	*/
	trim: function() {
		return this.replace(/^\s+|\s+$/g,'');
	},
	
	/*
	Method: ltrim
	Description: delete all spaces at beginning of the string
	[Example]  
		> var s = '&emsp;&emsp;&emsp;&emsp;some data';
		> // returns 'some data'
		> s.trim();
	[/Example]
	*/
	ltrim: function() {
		return this.replace(/^\s+/g,'');
	},
	
	/*
	Method: rtrim
	Description: delete all spaces at the end of the string
	[Example]  
		> var s = 'some data&emsp;&emsp;&emsp;&emsp;';
		> // returns 'some data'
		> s.trim();
	[/Example]
	*/
	rtrim: function() {
		return this.replace(/\s+$/g,'');
	}		
});


/*
	Filename: utility_string.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class String (extension)
	
	Filedescription:   This file extends the native String object with many methods which are very useful but they aren't contained in the core Javascript language. /n Others are shortcuts to Javascript String native methods. 
	
	[Summary]
		String ::: Contains prototypes which extend String constructor
	[/Summary]
*/

/*
	Class: String
	Description:  Contains prototypes which extend String constructor
	
	Extends: Class String
	
	Constructor: new String (string)
	
	[Properties] 
		string - simply the string
	[/Properties]
	
	[Methods]
		upper -- converts the string to upper case
		lower -- converts the string to lower case
		firstChar -- tests if the passed in character is the first of the string
		hasChar -- tests if the string contains the passed in character
		lastChar -- tests if the passed in character is the last of the string
		stripPhp -- strips all php tags from the string
		stripScripts -- strips all script tags from the string
		globalReplace -- replaces all occurrences with a regular expression
		contains -- tests if a string contains the passed in substring
		poOf -- returns an array represents the position of all occurences in the string
		getFirst -- returns the first character of the string
		getLast -- returns the last character of the string
		camelize -- returns a string camelized
		upperFirst -- converts the first char of the string to upper case
	[/Methods]
*/

String.extend({
	
	/*
	Method: upper
	Description: converts the string to upper case
	[Example]  
		> var s = 'a string';
		> // returns 'A STRING'
		> s.upper(); 
	[/Example]
	*/
	upper: function() {
 		return this.toUpperCase();
 	},
	
	/*
	Method: lower
	Description: converts the string to lower case
	[Example]  
		> var s = 'A STRING';
		> // returns 'a string'
		> s.lower(); 
	[/Example]
	*/
 	lower: function() {
 		return this.toLowerCase();
 	},
	
	/*
	Method: firstChar
	Description: tests if the passed in character is the first of the string
	[Arguments]
		char :: the character
	[/Arguments]
	[Example]  
		> var s = 'a string';
		> // returns true
		> s.firstChar('a');
		> // returns false
		> s.firstChar('f');
	[/Example]
	*/
	firstChar: function (n) {	
		return (this.charAt(0)==n) ? true : false;
	},
	
	/*
	Method: hasChar
	Description: tests if the string contains the passed in character
	[Arguments]
		char :: the character
	[/Arguments]
	[Example]  
		> var s = 'a string';
		> // returns true
		> s.hasChar('a');
		> // returns false
		> s.hasChar('f');  
	[/Example]
	*/
	hasChar: function (n) {
		for(var i=0; i<=this.length; i++)
			if(this.charAt(i)==n) return true;
		return false;
	},
	
	/*
	Method: lastChar
	Description: tests if the passed in character is the last of the string
	[Arguments]
		char :: the character
	[/Arguments]
	[Example]  
	 	> var s = 'a string';
		> // returns true
		> s.lastChar('g');
		> // returns false
		> s.lastChar('f');
	[/Example]
	*/
	lastChar: function (n) {	
		return (this.charAt(this.length-1)==n) ? true : false;
	},
	
	/*
	Method: stripPhp
	Description: strips all php tags from the string
	[Example]  
		> var s = '&lt;?php a string ?&gt;';
		> //returns 'a string'
		> s.stripPhp();
	[/Example]
	*/
	stripPhp: function() {
		return this.replace(/<\?php|\?>/gi, '');
	},
	
	/*
	Method: stripScripts
	Description: strips all script tags from the string
	[Example]  
		> var s = '&lt;script type='text/javascript'&gt; &lt;i&gt; a string &lt;/i&gt; &lt;/script&gt;';
		> // returns '&lt;i&gt; a string &lt;/i&gt;'
		> s.stripScripts();
	[/Example]
	*/
	stripScripts: function() {
		return this.replace(/<script[^>]{0,}>|<\/script>/gi, '');
	},
	
	/*
	Method: globalReplace
	Description: replaces all occurrences with a regular expression
	[Arguments]
		value :: it can be a regular expression, that specifies the pattern to be replaced, or a string. If it's a string it is not first converted to a RegExp object.
		replacement :: a string that specifies the replacement text or a function that is invoked to generate the replacement text
		options :: a string that specifies the regula expression attributes
	[/Arguments]
	[Example]  
		> var s = 'some data some';
		> // returns 'many data many'
		> s.globalReplace('some', 'many');
	[/Example]
	*/
	globalReplace: function(val, repl, regexAttr) {
		return this.replace(new RegExp(val, regexAttr || 'gi'), repl);
	},
	
	/*
	Method: contains
	Description: tests if a string contains the passed in substring
	[Arguments]
		substring :: the substring to search
	[/Arguments]
	[Example]  
		> var s = 'some data';
		> // returns true
		> s.contains('some');
	[/Example]
	*/
	contains: function (phrase) {
		return (this.indexOf(phrase) != -1) ? true : false;
	},
	
	/*
	Method: posOf
	Description: returns an array represents the position of all occurences in the string
	[Arguments]
		char :: the character to search
	[/Arguments]
	[Example]  
		> var s = 'insert a string';
		> // returns [2,9]
		> s.posOf('s');
	[/Example]
	*/
	posOf: function (n) {
		var positions = new Array();
			for (var i=0; i<this.length; i++)
				if(this.charAt(i)==n)
					positions.push(i);
			if(positions.length==0)
				return false;
			else
				return positions;
	},
	
	/*
	Method: getFirst
	Description: returns the first character of the string
	[Example]  
		> var s = 'some data';
		> // returns 's'
		> s.getFirst();
	[/Example]
	*/
	getFirst: function() {
		return this.charAt(0);
	},
	
	/*
	Method: getLast
	Description: returns the last character of the string
	[Example]  
	 	> var s = 'insert a string';
		> // returns 'g'
		> s.getLast();
	[/Example]
	*/
	getLast: function() {
		return this.charAt(this.length-1);
	},
	
	/*
	Method: camelize
	Description: returns a string camelized
	[Example]  
		> var s = 'a string';
		> // returns 'A StRiNg'
		> s = s.camelize();
	[/Example]
	*/
	camelize: function() {
		var s = '';
		for(var i=0; i<this.length; i++) {
			if(i%2 == 0) s+= this.charAt(i).upper();
			else s+= this.charAt(i).lower();
		}
		
		return s;
	},
	
	/*
	Method: upperFirst
	Description: converts the first char of the string to upper case
	[Example]  
	 	> var s = 'england';
		> // returns 'England'
		> s.upperFirst('s');
	[/Example]
	*/
	upperFirst: function() {
		return this.replace(this.charAt(0), this.charAt(0).upper());	
	}
			  
});


/*
	Filename: utility_array.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Array (extension), Function print_r
	
	Filedescription: This file extends the native Array object with many methods that aren't contained in the core Javascript language and allows you to execute many useful functionalities with the target array or with its items. /n It also contains a function, called print_r, that works as the PHP print_r function.  
	
	[Summary]
		Array ::: Contains prototypes which extend Array constructor
	[/Summary]
	[Functions]
		print_r --- print all array elements like the PHP print_r function
	[/Functions]
*/

/*
	Class: Array
	Description:  Contains prototypes which extend Array constructor
	
	Extends: Class Array
	
	Constructor: new Array ()
	
	[Methods]
		print_r -- print all array elements like the PHP print_r function
		numSort -- orders the array elements (asc)
		rNumSort -- orders the array elements (desc)
		getFirst -- returns the first item of the array
		getLast -- returns the last item of the array
		asItem -- tests if the array contains the passed in item
		asItems -- tests if the array contains the passed in items
		stripItem -- remove the passed in item from the array
		stripItems -- remove the passed in items from the array
		poOf -- returns an array represents the position of all occurences in the array
	[/Methods]
*/

Array.extend({
	
	/*
	Method: print_r
	Description: print all array elements like the PHP print_r function
	[Example]  
		> var a = ['a', 'b', 'c'];
		> a.print_r('box');
		> // returns
		> Array (
		> [0] => a
		> [1] => b
		> [2] => c
		> )
	[/Example]
	*/
	print_r: function(results) {
		var r = 'Array ( ' + '<br />';
		this.each(function(el, index) {
			r += '[' + index + ']' + ' => ' + el + '<br />';
		});
		r += ')';
		$(results).setHTML(r);
	},
	
	/*
	Method: numSort
	Description: orders the array elements (asc)
	[Example]  
		> var a = [44, 68, 32];
		> // returns
		> [32, 44, 68]
	[/Example]
	*/
	numSort: function() {
		return this.sort(function(a, b) {return a-b;});
	},
	
	/*
	Method: rNumSort
	Description: orders the array elements (des)
	[Example]  
		> var a = [44, 68, 32];
		> // returns
		> [68, 44, 32]
	[/Example]
	*/
	rNumSort: function() {
		return this.sort(function(a, b) {return b-a;});
	},
	
	/*
	Method: getFirst
	Description: returns the first item of the array
	[Example]  
		>  var a = [44, 68, 32];
		> // returns 44
		> a.getFirst();
	[/Example]
	*/
	getFirst: function() {
		return this[0];
	},
			
	/*
	Method: getLast
	Description: returns the last item of the array
	[Example]  
		>  var a = [44, 68, 32];
		> // returns 32
		> a.getLast();
	[/Example]
	*/
	getLast: function() {
		return this[this.length-1];
	},
	
	/*
	Method: asItem
	Description: tests if the array contains the passed in item
	[Arguments]
		item :: the item to search
	[/Arguments]
	[Example]  
 		> var a = [44, 68, 32];
		> // returns true
		> a.asItem(44);
	[/Example]
	*/
	asItem: function(item) {
		var a = new Array();
		for(var z=0; z<this.length; z++)
			if(this[z] == item) return true;
		return false;
	},
	
	/*
	Method: asItems
	Description: tests if the array contains the passed in items
	[Arguments]
		items :: the items to search
	[/Arguments]
	[Example]  
		> var a = [44, 68, 32];
		> // returns true
		> a.asItems(44, 32);
	[/Example]
	*/
	asItems: function() {
		var a = new Array();
				
		for(var i=0; i<arguments.length; i++)
			if(this.asItem(arguments[i]))
				a.push(arguments[i]);
				
		return (a.length >= arguments.length);
	},
	
	/*
	Method: stripItem
	Description: remove the passed in item from the array
	[Arguments]
		item :: the item to remove
	[/Arguments]
	[Example]  
		> var a = [44, 68, 32];
		> // returns [68, 32]
		> a.stripItem(44);
	[/Example]
	*/
	stripItem: function() {
		var a = new Array();
		for(var z=0; z<this.length; z++)
			for(var i=0; i<arguments.length; i++)
				if(this[z] != arguments[i])
					a.push(this[z]);
		return a;	
	},
	
	/*
	Method: stripItems
	Description: remove the passed in item from the array
	[Arguments]
		items :: the items to remove
	[/Arguments]
	[Example]  
		> var a = [44, 68, 32];
		> // returns [32]
		> a.stripItems(44, 68);
	[/Example]
	*/
	stripItems: function() {
		var a = new Array();
		for(var w=0; w<this.length; w++) a.push(this[w]);
				
		for(var z=0; z<this.length; z++) {
			for(var i=0; i<arguments.length; i++)
				if(this[z] == arguments[i])
					a = a.stripItem(arguments[i]);
		}	
		return a;	
	},
	
	/*
	Method: posOf
	Description: returns an array represents the position of all occurences in the array
	[Arguments]
		item :: the item to search
	[/Arguments]
	[Example]  
		> var a = [44, 68, 32, 44];
		> // returns 0, 3
		> a.posOf(44);
	[/Example]
	*/
	posOf: function(item) {
		var a = new Array();
				
		for(var z=0; z<this.length; z++)
			if(this[z] == item)
				a.push(z);
		return a;
	}
});

/*
	Function: print_r
	Description: print all array elements like the PHP print_r function
	[Arguments]
		array :: the array to print
		element :: the element where the array will be print
	[/Arguments]
	[Example]  
		> var a = ['a', 'b', 'c'];
		> print_r(a, 'box');
		> // returns
		> Array (
		>	[0] => a
		>	[1] => b
		>	[2] => c
		> )
	[/Example]
*/
function print_r(v, results) {
	if($type(v) == 'array') v.print_r(results);
}


/*
	Filename: element_get_shortcut.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Element (extension)
	
	Filedescription: Contains an extension of  the Element Class with many shortcuts to write a bit less code while getting property values
	
	[Summary]
		Element ::: Contains many Element shortcuts
	[/Summary]
*/

/*
	Class: Element
	Description:  Contains many Element shortcuts
	Extends: Class Element
	Constructor: new Element (element)
	
	[Properties] 
		element - the element
	[/Properties]
	
	[Methods]
		getId -- returns the element's id
		getClassName -- returns the element's className (or class names if more than one)
		getWidth -- returns the element's width (string or integer)
		getHeight -- returns the element's height (string or integer)
		getOpacity -- returns the element's opacity (string or integer)
		getColor -- returns the element's color
		getBg -- returns the element's background-color
		getBorder -- returns the element's border property or a specified section of the border
		getMargin -- returns the element's margin property or a specified section of the margin
		getPadding -- returns the element's padding property or a specified section of the padding
	[/Methods]
*/

Element.extend({
	
	/*
	Method: getId
	Description: returns the element's id
	[Example]  
		> var myId = $('box').getId(); // 'box'
		> // rather than:
		> var myId = $('box').getProperty('id');
	[/Example]
	*/
	getId: function() {
		return this.getProperty('id');
	},
	
	/*
	Method: getClassName
	Description: returns the element's className (or class names if more than one)
	[Example]  
		> var myClass = $('box').getClassName(); // 'box main'
	[/Example]
	*/
	getClassName: function() {
		return this.className;
	},
	
	/*
	Method: getWidth
	Description: returns the element's width (string or integer)
	[Arguments]
		int :: boolean. If true return the property value converted to integer 
	[/Arguments]
	[Example]  
		> var myWidth = $('box').getWidth(); // '200px'
		> var myIntWidth = $('box').getWidth(true); // 200
		> // rather than:
		> > var myWidth = $('box').getStyle('width).toInt();
	[/Example]
	*/
	getWidth: function() {
		return (!int) ? this.getStyle('width') : this.getStyle('width').toInt();
	},
	
	/*
	Method: getHeight
	Description: returns the element's height (string or integer)
	[Arguments]
		int :: boolean. If true return the property value converted to integer 
	[/Arguments]
	[Example]  
		> var myHeight = $('box').getHeight(); // '200px'
		> var myIntHeight = $('box').getHeight(true); // 200
		> // rather than:
		> > var myHeight = $('box').getStyle('height).toInt();
	[/Example]
	*/
	getHeight: function() {
		return this.getStyle('height');
	},
	
	/*
	Method: getOpacity
	Description: returns the element's opacity (string or integer)
	[Arguments]
		int :: boolean. If true return the property value converted to integer 
	[/Arguments]
	[Example]  
		> var myOpacity = $('box').getOpacity(); // 1
	[/Example]
	*/
	getOpacity: function() {
		return (!int) ? this.getStyle('opacity') : this.getStyle('opacity').toInt();
	},
	
	/*
	Method: getColor
	Description: returns the element's color
	[Example]  
		> var myColor = $('box').getColor(); // '#FFFFFF'
	[/Example]
	*/
	getColor: function() {
		return this.getStyle('color');
	},
	
	/*
	Method: getBg
	Description: returns the element's background-color
	[Example]  
		> var myColor = $('box').getBg(); // '#FFFFFF'
	[/Example]
	*/
	getBg: function() {
		return this.getStyle('background-color');
	},
	
	/*
	Method: getBorder
	Description: returns the element's border property or a specified section of the border
	[Arguments]
		where :: boolean. The specified section
	[/Arguments]
	[Example]
		> var myBorder = $('box').getBorder(); // '1px solid #000000'
		> var myBorder = $('box').getBorder('left'); // '2px solid #0033FF'
	[/Example]
	*/
	getBorder: function(where) {
		return (where) ? this.getStyle('border-' + where) : this.getStyle('border');
	},
	
	/*
	Method: getMargin
	Description: returns the element's margin property or a specified section of the Margin
	[Arguments]
		where :: boolean. The specified section
	[/Arguments]
	[Example]
		> var myMargin = $('box').getMargin(); // '1px 2px 2px 4px'
		> var myMargin = $('box').getMargin('left'); // '4px'
	[/Example]
	*/
	getMargin: function(where) {
		return (where) ? this.getStyle('margin-' + where) : this.getStyle('margin');
	},
	
	/*
	Method: getPadding
	Description: returns the element's padding property or a specified section of the Padding
	[Arguments]
		where :: boolean. The specified section
	[/Arguments]
	[Example]
		> var myPadding = $('box').getPadding(); // '1px 2px 2px 4px'
		> var myPadding = $('box').getPadding('left'); // '4px'
	[/Example]
	*/
	getPadding: function(where) {
		return (where) ? this.getStyle('padding-' + where) : this.getStyle('padding');
	}
		
});


/*
	Filename: table_rows.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Table
	
	Requires: constructors.js
	
	Filedescription: Contains methods that allows you to customize table rows. It's useful if you have tables with many rows and you want an easy way in order to set a style to them all. You also can set the mouseover and the click styles for the table rows: the table data will result more accessible.
	
	[Summary]
		Table ::: Custom Class to customize tables
	[/Summary]
*/

/*
	Class: Table
	Description:  Custom Class to customize tables. /n NOTE: The strings represent the colors you pass to each Table method MUST BE UPPERCASED.
	
	Extends: Class Table
	
	Constructor: new Table (element)
	
	[Properties] 
		element - the element. Must be a table element
	[/Properties]
	
	[Methods]
		zebra -- sets two alternate colors to the table rows
		overClickRows -- changes the bakcground-color of the table rows at mouseover and click events
		overRows -- changes the bakcground-color of the table rows at mouseover event
		clickRows -- changes the bakcground-color of the table rows at click event
	[/Methods]
*/
	
Table.implement({

	/*
	Method: zebra
	Description: sets two alternate colors to the table rows
	[Arguments]
		color1 :: one of the two color of the zebra
		color2 :: one of the two color of the zebra
		firstLine :: optional. an object represents the style of the first line
	[/Arguments]
	[Example]  
		>  tb = new Table('tb');
		>  tb.zebra('#CCCCCC','#666666');
		>  //or tb.zebra('#CCCCCC','#666666', {'background-color':'#FFFF00'});
	[/Example]
	*/
	zebra: function(color1, color2, firstLine) {
		if(this.element.getTag() != 'table')  return false;
		
		this.cells = this.element.getElements('tr').getElements('td');
		this.cells.each(function(cell, index) {
			if(index%2 == 0)
				(firstLine && index == 0) ? cell.setStyles(firstLine) : cell.setStyle('background-color', color1);
			else
				cell.setStyle('background-color', color2);
		});
			
	},
	
	/*
	Method: overClickRows
	Description: changes the bakcground-color of the table rows at mouseover and click events
	[Arguments]
		overcolor :: the color that the rows take at mouseover event
		clickcolor :: the color that the rows take at click event
	[/Arguments]
	[Example]  
		>  tb.overClickRows('blue', 'green');
	[/Example]
	*/
	overClickRows: function(color, clickcolor) {
		this.rows = this.element.getElements('tr');
		
		this.rows.each(function(row, index) {
			row.addEvent('mouseover', function() {
				if(!this.init) this.init = row.getElement('td').getStyle('background-color');
				if(this.getElement('td').getStyle('background-color').toUpperCase() != clickcolor)
					row.getElements('td').setStyle('background-color', color);
			});
			
			row.addEvent('mouseout', function() {
				if(this.getElement('td').getStyle('background-color').toUpperCase() != clickcolor)
					row.getElements('td').setStyle('background-color', this.init);
			});
			
			row.addEvent('click', function() {
				if(this.getElement('td').getStyle('background-color').toUpperCase() != clickcolor)
					this.getElements('td').setStyle('background-color', clickcolor);
				else
					this.getElements('td').setStyle('background-color', this.init);
			});
		});
	},
	
	/*
	Method: overRows
	Description:  changes the bakcground-color of the table rows at mouseover event
	[Arguments]
		overcolor :: the color that the rows take at mouseover event
	[/Arguments]
	[Example]  
		>  tb.overRows('#0066FF');
	[/Example]
	*/
	overRows: function(color) {
		this.rows = this.element.getElements('tr');
		
		this.rows.each(function(row, index) {
			row.addEvent('mouseover', function() {
				this.init = row.getElement('td').getStyle('background-color');
				row.getElements('td').setStyle('background-color', color);
			});
			
			row.addEvent('mouseout', function() {
				row.getElements('td').setStyle('background-color', this.init);
			});
		});
	},
	
	/*
	Method: clickRows
	Description: changes the bakcground-color of the table rows at click event
	[Arguments]
		clickcolor :: the color that the rows take at click event
	[/Arguments]
	[Example]  
		>  tb.clickRows('#0066FF');
	[/Example]
	*/
	clickRows: function(color) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, index) {
		
			row.addEvent('click', function() {
				if(!this.initBc) this.initBc = row.getElement('td').getStyle('background-color').toUpperCase();
				if(row.getElement('td').getStyle('background-color').toUpperCase() != this.initBc)
					row.getElements('td').setStyle('background-color', this.initBc);
				else
					row.getElements('td').setStyle('background-color', color);	
			});
		});
	}
});


/*
	Filename: table_cells.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Table
	
	Requires: constructors.js
	
	Filedescription: Contains methods that allows you to customize tables cells. It's useful if you have tables with many datas and you want an easy way in order to set a style to them all. You also can set the mouseover and the click styles for the table cells: the table data will result more accessible and elegant, easier to analyze.
	
	[Summary]
		Table ::: Custom Class to customize tables
	[/Summary]
*/

/*
	Class: Table
	Description:  Custom Class to customize tables. /n NOTE: The strings represent the colors you pass to each Table method MUST BE UPPERCASED.
	
	Extends: Class Table
	
	Constructor: new Table (element)
	
	[Properties] 
		element - the element. Must be a table element
	[/Properties]
	
	[Methods]
		overClickCells -- changes the bakcground-color of the table cells at mouseover and click events
		overCells -- changes the bakcground-color of the table cells at mouseover event
		clickCells -- changes the bakcground-color of the table cells at click event
	[/Methods]
*/

Table.implement({
	
	/*
	Method: overClickCells
	Description: changes the bakcground-color of the table cells at mouseover and click events
	[Arguments]
		overcolor :: the color that the cells take at mouseover event
		clickcolor :: the color that the cells take at click event
	[/Arguments]
	[Example]  
		>  tb.overClickCells('blue', 'green');
	[/Example]
	*/
	overClickCells: function(color, clickcolor) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, index) {
			row.getElements('td').each(function(td,index) {
				td.addEvent('mouseover', function() {
					if(!this.init) this.init = td.getStyle('background-color');
					if(this.getStyle('background-color').toUpperCase() != clickcolor)
						td.setStyle('background-color', color);
				});
				
				td.addEvent('mouseout', function() {
					if(this.getStyle('background-color').toUpperCase() != clickcolor)
						td.setStyle('background-color', this.init);
				});
				
				td.addEvent('click', function() {
					if(this.getStyle('background-color').toUpperCase() != clickcolor)
						this.setStyle('background-color', clickcolor);
					else
						this.setStyle('background-color', this.init);
				});
			});
		});
	},
	
	/*
	Method: overCells
	Description:  changes the bakcground-color of the table cells at mouseover event
	[Arguments]
		overcolor :: the color that the cells take at mouseover event
	[/Arguments]
	[Example]  
		>  tb.overCells('#0066FF');
	[/Example]
	*/
	overCells: function(color) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, index) {
			row.getElements('td').each(function(td,index) {
				td.addEvent('mouseover', function() {
					this.init = td.getStyle('background-color');
					td.setStyle('background-color', color);
				});
				
				td.addEvent('mouseout', function() {
					td.setStyle('background-color', this.init);
				});
			});
		});
	},
	
	/*
	Method: clickCells
	Description: changes the bakcground-color of the table cells at click event
	[Arguments]
		clickcolor :: the color that the cells take at click event
	[/Arguments]
	[Example]  
		>  tb.clickCells('#0066FF');
	[/Example]
	*/
	clickCells: function(color) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, index) {
			row.getElements('td').each(function(td,index) {
				td.addEvent('click', function() {
					if(!this.initC) this.initC = row.getElement('td').getStyle('background-color').toUpperCase();
					if(td.getStyle('background-color').toUpperCase() != this.initC)
						td.setStyle('background-color', this.initC);
					else
						td.setStyle('background-color', color);
				});
			});
		});
	}
});


/*
	Filename: table_cols.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Table
	
	Requires: constructors.js
	
	Filedescription: Contains methods that allows you to customize tables columns. It's useful if you have tables with many datas and you want an easy way in order to set a style to them all. You also can set the mouseover and the click styles for the table columns: the table data will result more accessible and elegant, easier to analyze.
	
	[Summary]
		Table ::: Custom Class to customize tables
	[/Summary]
*/

/*
	Class: Table
	Description: Custom Class to customize tables. /n NOTE: The strings represent the colors you pass to each Table method MUST BE UPPERCASED.
	
	Extends: Class Table
	
	Constructor: new Table (element)
	
	[Properties] 
		element - the element. Must be a table element
	[/Properties]
	
	[Methods]
		overClickCols -- changes the bakcground-color of the table columns at mouseover and click events
		overCols -- changes the bakcground-color of the table columns at mouseover event
		clickCols -- changes the bakcground-color of the table columns at click event
	[/Methods]
*/

Table.implement({	
				
	/*
	Method: overClickCols
	Description: changes the bakcground-color of the table columns at mouseover and click events
	[Arguments]
		overcolor :: the color that the columns take at mouseover event
		clickcolor :: the color that the columns take at click event
		firstLine :: boolean. If true the first line of the table doesn't change its styles
	[/Arguments]
	[Example]  
		>  tb.overClickCols('blue', 'green', true);
	[/Example]
	*/
	overClickCols: function(color, clickcolor, firstLine) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, indexRow) {
			
		  row.getElements('td').each(function(td,indexTd) {
			 
			var i = indexTd;
			var tdcolor = td.getStyle('background-color').toUpperCase();
			
			td.addEvent('mouseover', function() {
				this.getParent().getParent().getElements('tr').each(function(r, indexR) {
					r.getElements('td').each(function(c, indexC) {
						if(indexC == i)
							if((firstLine) && (indexR==0))
								c.setStyle('background-color', tdcolor);
							else if(c.getStyle('background-color').toUpperCase() != clickcolor)
								c.setStyle('background-color', color);
							else
								c.setStyle('background-color', clickcolor);
					});
				});
			});
			
			td.addEvent('mouseout', function() {
				this.getParent().getParent().getElements('tr').each(function(r, indexR) {
					r.getElements('td').each(function(c, indexC) {
						if(indexC == i)
							if(c.getStyle('background-color').toUpperCase() == color)
								c.setStyle('background-color', tdcolor);
					});
				});
			});
				
			td.addEvent('click', function() {
				this.getParent().getParent().getElements('tr').each(function(r, indexR) {
					r.getElements('td').each(function(c, indexC) {
						if(indexC == i)
							if((firstLine) && (indexR!=0))
							  if(c.getStyle('background-color').toUpperCase() != clickcolor)
								  c.setStyle('background-color', clickcolor);
							  else
								  c.setStyle('background-color', tdcolor);
							else if((!firstLine))
								 if(c.getStyle('background-color').toUpperCase() != clickcolor)
								  c.setStyle('background-color', clickcolor);
							  else
								  c.setStyle('background-color', tdcolor);
					});
				});
			});
				
			  
		  });		
		});
	},
	
	/*
	Method: overCols
	Description:  changes the bakcground-color of the table columns at mouseover event
	[Arguments]
		overcolor :: the color that the columns take at mouseover event
		firstLine :: boolean. If true the first line of the table doesn't change its styles
	[/Arguments]
	[Example]  
		>  tb.overCols('#0066FF', true);
	[/Example]
	*/
	overCols: function(color, firstLine) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, indexRow) {
			
			  row.getElements('td').each(function(td,indexTd) {
				 
				var i = indexTd;
				var tdcolor = td.getStyle('background-color').toUpperCase();
				
				td.addEvent('mouseover', function() {
					this.getParent().getParent().getElements('tr').each(function(r, indexR) {
						r.getElements('td').each(function(c, indexC) {
							if(indexC == i)
								if((firstLine) && (indexR==0))
									c.setStyle('background-color', tdcolor);
								else if(c.getStyle('background-color').toUpperCase() != color)
									c.setStyle('background-color', color);
								else
									c.setStyle('background-color', tdcolor);
						});
					});
				});
				
				td.addEvent('mouseout', function() {
					this.getParent().getParent().getElements('tr').each(function(r, indexR) {
						r.getElements('td').each(function(c, indexC) {
							if(indexC == i)
								if(c.getStyle('background-color').toUpperCase() == color)
									c.setStyle('background-color', tdcolor);
						});
					});
				});
			  
			});		
		});
	},
	
	/*
	Method: clickCols
	Description:  changes the bakcground-color of the table columns at click event
	[Arguments]
		clickcolor :: the color that the columns take at click event
		firstLine :: boolean. If true the first line of the table doesn't change its styles
	[/Arguments]
	[Example]  
		>  tb.clickCols('#0066FF', true);
	[/Example]
	*/
	clickCols: function(color, firstLine) {
		this.rows = this.element.getElements('tr');
		this.rows.each(function(row, indexRow) {
			
		  row.getElements('td').each(function(td,indexTd) {
			 
			var i = indexTd;
			var tdcolor = td.getStyle('background-color').toUpperCase();
			
			td.addEvent('click', function() {
				this.getParent().getParent().getElements('tr').each(function(r, indexR) {
					r.getElements('td').each(function(c, indexC) {
						if(indexC == i)
							if((firstLine) && (indexR==0))
								c.setStyle('background-color', tdcolor);
							else if(c.getStyle('background-color').toUpperCase() != color)
								c.setStyle('background-color', color);
							else
								c.setStyle('background-color', tdcolor);
					});
				});
			});
		  
		  });		
		});
	}
});


/*
	Filename: make_table.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Make.Table, Array.makeTable, Function make_table
	
	Requires: constructors.js
	
	Filedescription:  Allows you to create easily tables from array of array using the Make.Table Class. /n It also contains a function, called make_table and the Array.makeTable method, that extends the native Array object. /n They provide the same work of Make.Table.make method.
	
	[Summary]
		Make.Table ::: Custom Class to create tables
		Array ::: Contains prototypes which extend Array constructor
	[/Summary]
	
	[Functions]
		make_table --- creates tables like Make.Table Class but as a function
	[/Functions]
*/

/*
	Class: Make.Table
	Description:  Custom Class to create tables
	>> NOTE:
	>> Each item of the external array is a row of the table.
	>> Each item of inner arrays is a cell of the table.
	
	Extends: Class Make
	
	Constructor: new Make.Table (id, rows)
	
	[Properties] 
		id - the table id
		rows - the array that contains table elements. The last item can be an object represents the styles of row
	[/Properties]
	
	[Methods]
		make -- makes a table from an array of elements. Returns the table
	[/Methods]
*/

Make.Table = new Class({
			
	initialize: function(id, rows) {
		this.idKey = id;
		this.rows = rows;
	},
	
	/*
	Method: make
	Description: makes a table from an array of elements. Returns the table
	[Example]  
		> // create the rows
		> var items = [
		> ['a', 'b', 'c'],
		> ['d', 'e', 'f'],
		> ];
		
		> // returns the table
		> var makedtable = new Make.Table('makedtable', items).make();
		
		> // inject the table in the page makedtable.injectInside($('box'));
		
		> // this is the table created by Make.Table
		> &lt;table id='makedtable'&gt;
		> &lt;tr&gt;
		> &lt;td&gt; a &lt;/td&gt;
		> &lt;td&gt; b &lt;/td&gt;
		> &lt;td&gt; c &lt;/td&gt;
		> &lt;/tr&gt;
		> &lt;tr&gt;
		> &lt;td&gt; d &lt;/td&gt;
		> &lt;td&gt; e &lt;/td&gt;
		> &lt;td&gt; f &lt;/td&gt;
		> &lt;/tr&gt;
		> &lt;/table&gt; 
	[/Example]
	*/
	make: function() {
		if(!$(this.idKey)) {
		
		this.table = new Element('table', {
			'id': this.idKey
		});
		
		var table = this.table;
		var tbody = new Element('tbody').injectInside(table);
		var first = this.first;
		var l = this.rows.length-1;
		
		this.rows.each(function(row, index) {

			var tr = new Element('tr').injectInside(tbody);

			row.each(function(cell) {
				($type(cell) == 'object') ? tr.setStyles(cell) : new Element('td').appendText(cell).injectInside(tr);	
			});
		});
		
		return this.table;
		}
		else return;
	}
		
});

/*
	Class: Array
	Description:  Contains prototypes which extend Array constructor
	
	Extends: Class Array
	
	Constructor: new Array ()
	
	[Methods]
		makeTable -- Array method to make table from an array of elements. Returns the table
	[/Methods]
*/
Array.extend({
	/*
	Method: makeTable
	Description: Array method to make table from an array of elements. Returns the table
	[Properties] 
		id - the table id
	[/Properties]
	[Example]  
		> // create the rows
		> var items = [
		> ['a', 'b', 'c'],
		> ['d', 'e', 'f'],
		> ];
		
		> // returns the table
		> var makedtable = items.makeTable('makedtable'); 
	[/Example]
	*/
	makeTable: function(id) {
		return new Make.Table(id, this).make();
	}
});

/*
	Function: make_table
	Description: creates tables like Make.Table Class but as a function
	[Arguments]
		id - the table id
		rows - the array that contains table elements. The last item can be an object represents the styles of row
	[/Arguments]
	[Example]  
		> // create the rows
		> var items = [
		> ['a', 'b', 'c'],
		> ['d', 'e', 'f'],
		> ];
		
		> // returns the table
		> var makedtable =  make_table('makedtable', items); 
	[/Example]
*/
function make_table(id, rows) {
	return new Make.Table(id, rows).make();
}


/*
	Filename: make_list.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Make.List, Array.makeList, Function make_list
	
	Requires: constructors.js
	
	Filedescription: Allows you to create easily unordered and oreder lists from array using the Make.List Class. /n You can also create lists of lists and list of links. /n  It also contains a function, called make_list and the Array.makeList method, that extends the native Array object. They provide the same work of Make.List.make method.
	
	[Summary]
		Make.List ::: Custom Class to create lists
		Array ::: Contains prototypes which extend Array constructor
	[/Summary]
	[Functions]
		make_list --- creates lists like Make.List Class but as a function
	[/Functions]
*/

/*
	Class: Make.List
	Description:  Custom Class to create lists
	>> NOTE:
	>> If the current element of the main array is a string, it will be added at the main list as a nornal list item.
	>> If it is an array of strings, it will be added as a sub-list.
	>> If it is an object, you have to pass two property: 'text' (the text of the link) and 'href'. In this way you can create a link item in the list.
	
	Extends: Class Make
	
	Constructor: new Make.List (id, items, options)
	
	[Properties] 
		id - the list id
		items - the array that contains the list elements
		options - an object. See below
	[/Properties]
	
	[Options]
		type : the type of the list. Can be 'ul' (default) or 'ol'
		className : the class name of list which permits you to give it a style
	[/Options]
	
	[Methods]
		make -- makes a list from an array of elements. Returns the list
	[/Methods]
*/

Make.List = new Class({
					  
	options: {
		type: 'ul',
		className: ''
	},
	
	initialize: function(id, items, options) {
		this.idKey = id;
		this.items = items;
		this.setOptions(options);
	},
	
	/*
	Method: make
	Description: makes a list from an array of elements. Returns the list
	[Example]  
		> see the Make.List example in the examples section for code and demos
	[/Example]
	*/
	make: function() {
		if(!$(this.idKey)) {
			
			this.ul = new Element(this.options.type, {
				'id': this.idKey,
				'class': this.options.className
			});
			

			this.items.each(function(li) {
				if($type(li) == 'array') {
					li.each(function(item, i) {
						var mul = new Element('ul');
						if($type(item) == 'object') {
							var a = new Element('a', {
								'href': item.href
							}).appendText(item.text);
							var lis = new Element('li');
							a.injectInside(lis);
							lis.injectInside(mul);
							mul.injectInside(this.ul);
						}			 
						else {
							var mli = new Element('li').appendText(item).injectInside(mul);
							mul.injectInside(this.ul);
						}
					}, this);
				}
				else if($type(li) == 'object') {
					var a = new Element('a', {
						'href': li.href
					}).appendText(li.text);
					var li = new Element('li');
					a.injectInside(li);
					li.injectInside(this.ul);
				}
				else {
					var li = new Element('li').appendText(li);
					li.injectInside(this.ul);
				}
			}, this);
			
			return this.ul;
		
		}
		else return;
	}

});

Make.List.implement(new Options);

/*
	Class: Array
	Description:  Contains prototypes which extend Array constructor
	
	Extends: Class Array
	
	Constructor: new Array ()
	
	[Methods]
		makeList -- Array method to make lists from an array of elements. Returns the list
	[/Methods]
	[Arguments]
		id - the list id
		options - an object. See above Make.List options
	[/Arguments]
	[Example]  
		> see the Make.List example in the examples section for code and demos
	[/Example]
*/
Array.extend({
		makeList: function(id, options) {
			return new Make.List(id, this, options).make();
		}
});

/*
	Function: make_list
	Description: creates lists like Make.List Class but as a function
	[Arguments]
		id - the list id
		items - the array that contains the list elements
		options - an object. See below
	[/Arguments]
	[Example]  
		> see the Make.List example in the examples section for code and demos
	[/Example]
*/
function make_list(id, items, options) {
		return new Make.List(id, items, options).make();
}


/*
	Filename: make_select.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Make.Select, Array.makeSelect, Function make_select
	
	Requires: constructors.js
	
	Filedescription:  Allows you to create easily  lists of Option Elements nested in a main Select Element using the Make.Select Class. /n It also contains a function, called make_select and the Array.makeSelect method, that extends the native Array object. /n They provide the same work of Make.Select.make method.
	
	[Summary]
		Make.Select ::: Custom Class to create lists of Option Elements nested in a main Select Element
		Array ::: Contains prototypes which extend Array constructor
	[/Summary]
	[Functions]
		make_select --- creates Select elements like Make.Select Class but as a function
	[/Functions]
*/

/*
	Class: Make.Select
	Description:  Custom Class to create lists of Option Elements nested in a main Select Element
	
	Extends: Class Make
	
	Constructor: new Make.Select (id, items, properties)
	
	[Properties] 
		id - the table id
		items - the array that contains the option elements. If an item is an array of strings, the first item will become an Optgroup element, and the others will become normal Option element nested into this Optgroup.
		properties - the Select properties
	[/Properties]
	
	[Methods]
		make -- makes a Select element from an array of strings. Returns the Select
	[/Methods]
*/

Make.Select = new Class({
			
	initialize: function(id, items, properties) {
		this.idKey = id;
		this.items = items;
		this.props = properties || {};
	},
	
	/*
	Method: make
	Description: makes a Select element from an array of strings. Returns the Select
	[Example]  
		> see the Make.Select example in the examples section for code and demos
	[/Example]
	*/
	make: function() {
		if(!$(this.idKey)) {
			this.select = new Element('select', $extend({'id': this.idKey}, this.props));
			
			this.items.each(function(item) {
				if($type(item) == 'array') {
					item.each(function(i, index) {
						if(index == 0) {
							this.group = new Element('optgroup', { 'label': i });
							this.select.adopt(this.group);
						}
						else {
							var opt = new Element('option', {
								'label': i,
								'value': i
							}).appendText(i);
							opt.injectInside(this.group);	
						}
					}, this);	
				}					 
				else {
					var option = new Element('option', {
						'label': item,
						'value': item
					}).appendText(item);
					option.injectInside(this.select);
				}
			}, this);
			
			return this.select;
		
		}
		else return;
	}

});

/*
	Class: Array
	Description:  Contains prototypes which extend Array constructor
	
	Extends: Class Array
	
	Constructor: new Array ()
	
	[Methods]
		makeSelect -- Array method to make Select elements from an array of strings. Returns the Select
	[/Methods]
*/
Array.extend({
	/*
	Method: makeSelect
	Description: Array method to make Select elements from an array of strings. Returns the Select
	[Arguments] 
		id - the table id
		properties - the Select properties
	[/Arguments]
	[Example]  
		> see the Make.Select example in the examples section for code and demos
	[/Example]
	*/
	makeSelect: function(id, properties) {
		return new Make.Select(id, this, properties).make();
	}
});

/*
	Function: make_select
	Description: creates Select elements like Make.Select Class but as a function
	[Arguments]
		id :: the table id
		items :: the array that contains the option elements. If an item is an array of strings, the first item will become an Optgroup element, and the others will become normal Option element nested into this Optgroup.
		properties :: the Select properties
	[/Arguments]
	[Example]  
		> see the Make.Select example in the examples section for code and demos
	[/Example]
*/
function make_select(id, items, properties) {
	return new Make.Select(id, items, properties).make();
}


/*
	Filename: custom_alert.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Custom.Alert
	
	Requires: constructors.js
	
	Filedescription:  It allows you to create custom alert boxes, without overwriting the standard window.alert method. /n The boxes created with Custom.Alert Class are MODAL and FIXED, like the standard alert boxes.
	
	[Summary]
		Custom.Alert ::: Custom Class to create customized alert
	[/Summary]
*/

/*
	Class: Custom.Alert
	Description:  Custom Class to create customized alert. /n  The styles of your custom alert boxes can be different, and you may have many different custom alert boxes in the same page. The custom alert box consist of three zones: 
	[List]
	 [li] the alertbox, is the box that contains the other zones
	 [li] the alerthead, is the header of the alert box. (contains the title)
	 [li] the alertbody, is the content of the alert box (contains the 'OK' button)
	[/List]
	 
	 >> You can alter the normal style of the custom alert creating a css style for this three objects, and you may set an opacity transition when alert box appears and disappears. (unlike the standard)
	
	Extends: Class Custom
	
	Constructor: new Custom.Alert (title, text, options)
	
	[Properties] 
		title - a string represents the title of the alert
		text - a string represents the content text of the alert
		options - optional. an object that contains the class names of the alert box's zones. Allows you to set some general options like button text
	[/Properties]
	
	[Options]
		opacify : if true the alert appears and disappears with an opacity transition
		alertbox : see above
		alerthead : see above
		alertbody : see above
		height : the alert height. Default '100px'
		width : the alert width. Default '300px'
		buttonText : the text of the alert confirm button. Defaults to 'OK'
	[/Options]
	
	[Methods]
		create -- creates the custom alert box
		setText -- set the text of the custom alert
		setTitle -- set the title of the custom alert
	[/Methods]
*/

Custom.Alert = new Class({
		
	options: {
		height: '100px',
		width: '300px',
		buttonText: 'OK',
		opacify: true,
		alertbox: null,
		alerthead: null,
		alertbody: null
	},

	initialize: function(title, text, options) {
		this.title = title;
		this.text = text;
		this.setOptions(options);
		this.alertbox = new Element('div', {
			'id': 'customAlert',
			'styles': {
				'position': 'fixed',
				'top': '50%',
				'left': '50%',
				'z-index': 1000,
				'height': this.options.height,
				'width': this.options.width
			}
		});
		this.overlay = new Element('div', {
			'id': 'customAlertOverlay',
			'styles': {
				'position': 'absolute',
				'top': '0px',
				'left': '0px',
				'width': '100%',
				'height': window.getScrollHeight(),
				'background-image':'url(g.gif)',
				'z-index': 900
			}
		});
		this.mechanize();
		this.fx = new Fx.Style(this.alertbox, 'opacity', {duration:1000});
		if(this.options.initialize) this.options.initialize.call(this);
	},
	
	/*
	Method: create
	Description:  creates the custom alert box
	[Example]  
		> var ca = new Custom.Alert('custom alert', 'You cannot access at this page', 
		> {alertbox:'cabox', alerthead: 'cahead', alertbody: 'cabody'});
		> 
		> ca.create();
	[/Example]
	*/
	create: function() {
		this.customize();
	},
	
	mechanize: function() {
		if(this.options['alertbox']) this.alertbox.addClass(this.options['alertbox']);

		this.alertbox.setStyles({
			'margin-left': - this.alertbox.getStyle('width').toInt()/2,
			'margin-top': - this.alertbox.getStyle('height').toInt()/2
		});
		
		this.head = new Element('div').injectInside(this.alertbox);
		if(this.options.alerthead) this.head.addClass(this.options['alerthead']);
		this.head.appendText(this.title);
		
		this.content = new Element('div').injectInside(this.alertbox);
		if(this.options.alerthead) this.content.addClass(this.options['alertbody']);
		this.content.appendText(this.text);
	
		this.closebox = new Element('div').injectInside(this.alertbox);
		this.closebox.setProperty('align', 'center');
	
		this.button = new Element('a').injectInside(this.closebox);
		this.button.setProperty('href', '#');
		this.button.appendText(this.options.buttonText);
		this.button.addEvent('click', function(event) {
			var event = new Event(event).preventDefault();
		});
		if(this.options.opacify)  this.button.addEvent('click', this.opacify.bind(this));
		else this.button.addEvent('click', this.remove.bind(this));
	},
	
	customize: function() {
		if($('customAlert'))  return;
		
		this.alertbox.injectInside(this.overlay);
		this.overlay.injectInside($E('body'));
		
		if(this.options.opacify) this.alertbox.setStyle('opacity', 0);
		this.fx.start(1);
	},
	
	opacify: function() {
		this.fx.start(0).chain(function() {
			this.alertbox.remove();
			this.overlay.remove();
		}.bind(this));
	},
	
	remove: function() {
		this.alertbox.remove();
		this.overlay.remove();
	},
	
	/*
	Method: setText
	Description:  set the text of the custom alert
	[Example]  
		> // change the previous text
		> ca.setText('Custom Alert with some new text');
	[/Example]
	*/
	setText: function(text) {
		this.content.setHTML(text);
		return this;
	},
	
	/*
	Method: setTitle
	Description:  set the title of the custom alert
	[Example]  
		> // change the previous title
		> ca.setTitle('A new Custom Alert');
	[/Example]
	*/
	setTitle: function(title) {
		this.title = title;	
		return this;
	}
});

Custom.Alert.implement(new Options);


/*
	Filename: custom_confirm.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Custom.Confirm
	
	Requires: constructors.js
	
	Filedescription:  It allows you to create custom confirm boxes, without overwriting the standard window.confirm method. /n The boxes created with Custom.Confirm Class are MODAL and FIXED, like the standard confirm boxes.
	
	[Summary]
		Custom.Confirm ::: Custom Class to create customize confirm
	[/Summary]
*/

/*
	Class: Custom.Confirm
	Description:  Custom Class to create customized confirm. /n  The styles of your custom confirm boxes can be different, and you may have many different custom confirm boxes in the same page. The custom confirm box consist of three zones: 
	[List]
	 [li] the confirmbox, is the box that contains the other zones
	 [li] the confirmhead, is the header of the confirm box. (contains the title)
	 [li] the confirmbody, is the content of the confirm box (contains the 'OK' button)
	[/List]
	 
	 >> You can alter the normal style of the custom confirm creating a css style for this three objects, and you may set an opacity transition when confirm box appears and disappears. (unlike the standard)
	 >> In addiction, you can also specify the actions that will be fired when user clicks the 'OK' or the 'Cancel' button, with the onConfirm and onCancel options. 
	
	Extends: Class Custom
	
	Constructor: new Custom.Confirm (title, text, options)
	
	[Properties] 
		title - a string represents the title of the confirm
		text - a string represents the content text of the confirm
		options - optional. an object that contains the class names of the confirm box's zones. Allows you to set some general options like button text
	[/Properties]
	
	[Options]
		opacify : if true the confirm appears and disappears with an opacity transition
		confirmbox : see above
		confirmhead : see above
		confirmbody : see above
		height : the confirm height. Default '100px'
		width : the confirm width. Default '300px'
		confirmText : the text of the confirm button. Defaults to 'OK'
		cancelText : the text of the cancel button. Defaults to 'Cancel'
		onConfirm : a function executed when the user clicks confirm
		onCancel : a function executed when the user clicks cancel
	[/Options]
	
	[Methods]
		create -- creates the custom confirm box
		setText -- set the text of the custom confirm
		setTitle -- set the title of the custom confirm
	[/Methods]
*/

Custom.Confirm = new Class({
		
	options: {
		height: '100px',
		width: '300px',
		confirmText: 'OK',
		cancelText: 'Cancel',
		opacify: true,
		confirmbox: null,
		confirmhead: null,
		confirmbody: null,
		onConfirm: function() {
			return true;	
		},
		onCancel: function() {
			return false;	
		}
	},
	
	initialize: function(title, text, options) {
		this.title = title;
		this.text = text;
		this.setOptions(options);
		this.confirmbox = new Element('div', {
			'id': 'customConfirm',
			'styles': {
			'position': 'fixed',
			'top': '50%',
			'left': '50%',
			'z-index': 1000,
			'height': this.options.height,
			'width': this.options.width	
			}
		});
		this.overlay = new Element('div', {
			'id': 'customConfirmOverlay',
			'styles': {
				'position': 'absolute',
				'top': '0px',
				'left': '0px',
				'width': '100%',
				'height': window.getScrollHeight(), //window.getHeight() + window.getScrollTop(),
				'background-image':'url(g.gif)',
				'z-index': 900
			}
		});
		this.mechanize();
		this.fx = new Fx.Style(this.confirmbox, 'opacity', {duration:1000});
		if(this.options.initialize) this.options.initialize.call(this);
	},
	
	/*
	Method: create
	Description:  creates the custom alert box
	[Example]  
		> var cc = new Custom.Confirm('custom confirm', 'Do you want to submit?', 
		> {confirmbox:'ccbox', confirmhead: 'cchead', confirmbody: 'ccbody'});
		> 
		> cc.create();
	[/Example]
	*/
	create: function() {
		this.customize();
	},
	
	mechanize: function() {
		if(this.options['confirmbox']) this.confirmbox.addClass(this.options['confirmbox']);
		this.confirmbox.setStyles({
			'margin-left': - this.confirmbox.getStyle('width').toInt()/2,
			'margin-top': - this.confirmbox.getStyle('height').toInt()/2
		});
		
		this.head = new Element('div').injectInside(this.confirmbox);
		if(this.options.confirmhead) this.head.addClass(this.options['confirmhead']);
		this.head.appendText(this.title);
		
		this.content = new Element('div').injectInside(this.confirmbox);
		if(this.options.confirmhead) this.content.addClass(this.options['confirmbody']);
		this.content.appendText(this.text);
	
		this.closebox = new Element('div').injectInside(this.confirmbox);
		this.closebox.setProperty('align', 'center');
	
		this.confirmButton = new Element('a').injectInside(this.closebox);
		this.confirmButton.setProperty('href', '#');
		this.confirmButton.appendText(this.options.confirmText);
		this.confirmButton.addEvent('click', function(event) {
			var event = new Event(event).preventDefault();
		});
		if(this.options.opacify)  this.confirmButton.addEvent('click', this.opacifyConfirm.bind(this));
		else this.confirmButton.addEvent('click', this.confirmRemove.bind(this));
		
		this.cancelButton = new Element('a').injectInside(this.closebox);
		this.cancelButton.setProperty('href', '#');
		this.cancelButton.appendText(this.options.cancelText);
		this.cancelButton.addEvent('click', function(event) {
			var event = new Event(event).preventDefault();
		});
		if(this.options.opacify)  this.cancelButton.addEvent('click', this.opacifyCancel.bind(this));
		else this.cancelButton.addEvent('click', this.cancelRemove.bind(this));
	},
	
	customize: function() {
		if($('customConfirm'))  return false;
		
		this.confirmbox.injectInside(this.overlay);
		this.overlay.injectInside($E('body'));
		
		if(this.options.opacify) this.confirmbox.setStyle('opacity', 0);
		this.fx.start(1);
		
	},
	
	opacifyConfirm: function() {
		this.fireEvent('onConfirm');
		this.fx.start(0).chain(function() {
			this.confirmbox.remove();
			this.overlay.remove();
		}.bind(this));
	},
	
	opacifyCancel: function() {
		this.fireEvent('onCancel');
		this.fx.start(0).chain(function() {
			this.confirmbox.remove();
			this.overlay.remove();
		}.bind(this));
	},
	
	confirmRemove: function() {
		this.fireEvent('onConfirm');
		this.confirmbox.remove();
		this.overlay.remove();
	},
	
	cancelRemove: function() {
		this.fireEvent('onCancel');
		this.confirmbox.remove();
		this.overlay.remove();
	},
	
	/*
	Method: setText
	Description:  set the text of the custom confirm
	[Example]  
		> // change the previous text
		> ca.setText('Custom Confirm with some new text');
	[/Example]
	*/
	setText: function(text) {
		this.content.setHTML(text);
		return this;
	},
	
	/*
	Method: setTitle
	Description:  set the title of the custom confirm
	[Example]  
		> // change the previous title
		> ca.setTitle('A new Custom Confirm');
	[/Example]
	*/
	setTitle: function(title) {
		this.title = title;
		return this;
	}
});

Custom.Confirm.implement(new Options, new Events);


/*
	Filename: smooth_scrolling.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Table
	
	Requires: nothing
	
	Filedescription: With this file you can alterate the automatic process that displays the transition of all anchors situated in a page. /n You can also specify the style options of transitions: this permits to make a lot of different animations!
*/

/*
	Class: SmoothScrolling
	Description: smooth scroll the anchor links
	
	Extends: nothing
	
	Constructor: new SmoothScrolling (options, links)
	
	[Properties] 
		options - the Fx.Scroll options
		links - optional. the links to apply the smooth scrolling to
	[/Properties]
	
	[Methods]
		create -- creates the smooth scrolling for all anchors of the page
	[/Methods]
*/

var SmoothScrolling = new Class ({
	   
	initialize: function(options, links) {
		(!links) ? this.links = $$('a') : this.links = links;
		this.setOptions(options);
		this.fxscroll = new Fx.Scroll(window, this.options);
		if(this.options.initialize) this.options.intialize.call(this);
	},
    
	/*
	Method: create
	Description:  creates the smooth scrolling for all anchors of the page
	[Example]  
		>  new SmoothScrolling({duration:1800, transition:Fx.Transitions.Bounce.easeOut}).create();
	[/Example]
	*/
    create: function() {
	 var targets = new Array();
	 var anchors = new Array();
	
	 $$('a').each(function(lnk, index) {
		if(lnk.name) targets.push(lnk);
	 });
				
	 this.links.each(function(lnk, index) {
	 	if(lnk.href.test(/#\w+/)) {
			anchors.push(lnk);
			for(var i=0; i<targets.length; i++) {
				if(lnk.href.split('#')[1] == targets[i].name)
					lnk.targetName = targets[i].name;
					lnk.addEvent('click', this.makeScroll.bind(this, lnk));
			}
		}
	  }, this);
	},
	
	makeScroll: function(lnk) {
		this.fxscroll.scrollTo(0,document.getElementsByName(lnk.targetName)[0].getTop());
	}
	
});

SmoothScrolling.implement(new Options);


/*
	Filename: effects.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Fx.Fold, Fx.Squish, Fx.Puff, Fx.Shrink, Fx.Grow
	>> Element.fold, Element.squish, Element.puff, Element.shrink, Element.grow
	
	Requires: constructors.js
	
	Filedescription: Contains Fx extensions which allow to create web2.0 effects
	
	[Summary]
		Fx.Fold ::: Will close an element like a folder
		Fx.Squish ::: Will resize an element with a squish transition
		Fx.Puff ::: Will fade an element with a puff transition
		Fx.Shrink ::: Will shrink an element
		Fx.Grow ::: Will grow an element
		Element ::: Extend the Element Class with Fx shortcuts
	[/Summary]
*/

/*
	Class: Fx.Fold
	Description: Will close an element like a folder
	Extends: Class Fx.Style
	Constructor: new Fx.Fold (element, options, options2)
	[Properties] 
		element - the element
		options - the height transition (first) Fx options
		options2 - the width transition (second) Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.Fold effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Fold effects
	[Example]  
		>  var fx = new Fx.Fold('box', {duration:2000}, {onComplete:function() { alert('Complete!');}});
		> fx.start();
	[/Example]
*/
Fx.Fold = Fx.Style.extend({	
	initialize: function(element, options, opt2) {
		this.parent(element, 'height', options);
		this.fx = new Fx.Style(element, 'width', opt2);
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.parent(0).chain(function() {
			this.fx.start(0); 
		});
	}		
});
	
/*
	Class: Fx.Squish
	Description: Will resize an element with a squish transition
	Extends: Class Fx.Styles
	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 = Fx.Styles.extend({		
	initialize: function(element, options) {
		this.parent(element, options);
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.parent({
			'height': [0],
			'width': [0],
			'opacity': [0]
		});
	}		
});
		
/*
	Class: Fx.Puff
	Description: Will fade an element with a puff transition
	Extends: Class Fx.Styles
	Constructor: new Fx.Squish (element, options)
	[Properties] 
		element - the element
		options - the Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.Puff effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Puff effect
	[Example]  
		>  var fx = new Fx.Puff('box', {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.Puff = Fx.Styles.extend({	
	initialize: function(element, options) {
		this.parent(element, options);
		this.initStyles('height', 'width', 'fontSize');
		this.element.setStyles({position: 'relative', overflow: 'hidden'});
	},
	
	start: function() {
		this.parent({
			'height': [this.init.height*1.3],
			'width': [this.init.width*1.3],
			'font-size': [this.init.fontSize*1.3],
			'opacity': [0]
		}).chain(function() { this.element.setStyle('display', 'none'); });
	}			
});
		
/*
	Class: Fx.Shrink
	Description: Will shrink an element
	Extends: Class Fx.Styles
	Constructor: new Fx.Squish (element, options, options2)
	[Properties] 
		element - the element
		options - the main Fx options
		options2 - the Fx options for the opacity
	[/Properties]
	[Methods]
		start -- starts the Fx.Shrink effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Shrink effect
	[Example]  
		>  var fx = new Fx.Shrink('box', {wait:true});
		> fx.start();
	[/Example]
*/	
Fx.Shrink = Fx.Styles.extend({		
	initialize: function(element, options, opt2) {
		this.parent(element, options);
		this.fx = new Fx.Style(this.element, 'opacity', opt2);
		this.initStyles('fontSize');
		this.element.setStyles({position: 'relative', overflow: 'hidden'});
	},
	
	start: function() {
		this.parent({
			'height': [0],
			'width': [0],
			'font-size': [this.init.fontSize, 0]
		}).chain(function() {
			this.fx.start(1,0);
		});
	}		
});
		
/*
	Class: Fx.Grow
	Description: Will grow an element
	Extends: Class Fx.Styles
	Constructor: new Fx.Grow (element, options, values)
	[Properties] 
		element - the element
		options - the Fx options
		values - an object represents the final values of height, width and fontsize. These properties can be passed in. 
	[/Properties]
	[Methods]
		start -- starts the Fx.Grow effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Grow effect
	[Example]  
		>  var fx = new Fx.Grow('box', {wait:true}, {height: 200, width: 200, fontsize: 16});
		> fx.start();
	[/Example]
*/	
Fx.Grow = Fx.Styles.extend({	
	initialize: function(element, options, values) {
		this.parent(element, options);
		this.values = values || {};
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.parent({
			'height': [0, this.values.height],
			'width': [0, this.values.width],
			'font-size': [0, this.values.fontsize]
		});
	}	
});

/*
	Class: Element
	Description: Extend the Element Class with Fx shortcuts. All these methods accept the same arguments of the relative Fx effect (obviously without the element)
	Extends: Class Element
	Constructor: new Element (element)
	[Properties] 
		element - the element
	[/Properties]
	[Methods]
		fold -- returns an Fx.Fold instance
		squish -- returns an Fx.Squish instance
		puff -- returns an Fx.Puff instance
		shirnk -- returns an Fx.Shrink instance
		grow -- return an Fx.Grow instance
	[/Methods]

*/	
Element.extend({
	/*
	Method: fold
	Description:  returns an Fx.Fold instance
	[Example]  
		>  var fx = $('box').fold({wait:true}, {duration:2000});
		> fx.start();
	[/Example]
	*/
	fold: function(options, opt2) {
		return new Fx.Fold(this, options, opt2);	
	},
	
	/*
	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);	
	},
	
	/*
	Method: shrink
	Description:  returns an Fx.Shrink instance
	*/
	shrink: function(options, opt2) {
		return new Fx.Shrink(this, options, opt2);	
	},
	
	/*
	Method: grow
	Description:  returns an Fx.Grow instance
	*/
	grow: function(options, values) {
		return new Fx.Grow(this, options, values);	
	}
});


/*
	Filename: effects2.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Fx.FadeOut, Fx.SwitchOffH, Fx.SwitchOffW, Fx.ShakeH, Fx.ShakeW
	>> Element.fadeOut, Element.switchOffH, Element.switchOffW, Element.shakeH, Element.shakeW
	
	Requires: constructors.js
	
	Filedescription: Contains Fx extensions which allow to create web2.0 effects
	
	[Summary]
		Fx.FadeOut ::: Will smoothly show the element
		Fx.SwitchOffH ::: Will close vertically the element with a 'switch off'
		Fx.SwitchOffW ::: Will close horizontally the element with a 'switch off'
		Fx.ShakeH ::: Will shake vertically the element
		Fx.ShakeW ::: Will shake horizontally the element
		Element ::: Extend the Element Class with Fx shortcuts
	[/Summary]
*/

/*
	Class: Fx.FadeOut
	Description: Will smoothly show the element
	Extends: Class Fx.Style
	Constructor: new Fx.FadeOut (element, options)
	[Properties] 
		element - the element
		options - the effect Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.FadeOut effect
	[/Methods]

	Method: start
	Description:  starts the Fx.FadeOut effect
	[Example]  
		>  var fx = new Fx.FadeOut('box', {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.FadeOut = Fx.Style.extend({
	initialize: function(element, options) {
		this.parent(element, 'opacity', options);
	},
	
	start: function() {
		this.parent(0);
	}
});

/*
	Class: Fx.SwitchOffH
	Description: Will close vertically the element with a 'switch off'
	Extends: Class Fx.Style
	Constructor: new Fx.SwitchOffH (element, options)
	[Properties] 
		element - the element
		options - the height transition Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.SwitchOffH effect
	[/Methods]

	Method: start
	Description:  starts the Fx.SwitchOffH effect
	[Example]  
		>  var fx = new Fx.SwitchOffH('box', {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.SwitchOffH = Fx.Style.extend({	
	initialize: function(element, options) {
		this.parent(element);
		this.fx = new Fx.Style(this.element, 'opacity', {duration:100});
		this.fx2 = new Fx.Style(this.element, 'height', options);
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.fx.start(0).chain(function() {
			this.fx.start(1);
		}.bind(this)).chain(function() {
			this.fx2.start(0);	
		}.bind(this));
	}
});

/*
	Class: Fx.SwitchOffW
	Description: Will close horizontally the element with a 'switch off'
	Extends: Class Fx.Style
	Constructor: new Fx.SwitchOffH (element, options)
	[Properties] 
		element - the element
		options - the width transition Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.SwitchOffW effect
	[/Methods]

	Method: start
	Description:  starts the Fx.SwitchOffW effect
	[Example]  
		>  var fx = new Fx.SwitchOffW('box', {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.SwitchOffW = Fx.Style.extend({
	initialize: function(element, options) {
		this.parent(element);
		this.fx = new Fx.Style(this.element, 'opacity', {duration:100});
		this.fx2 = new Fx.Style(this.element, 'width', options);
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.fx.start(0).chain(function() {
			this.fx.start(1);
		}.bind(this)).chain(function() {
			this.fx2.start(0);	
		}.bind(this));
	}
});

/*
	Class: Fx.ShakeH
	Description: Will shake vertically the element
	Extends: Class Fx.Style
	Constructor: new Fx.ShakeH (element, options)
	[Properties] 
		element - the element
		options - the shake transition Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.ShakeH effect
	[/Methods]

	Method: start
	Description:  starts the Fx.ShakeH effect
	[Example]  
		>  var fx = new Fx.ShakeH('box');
		> fx.start();
	[/Example]
*/
Fx.ShakeH = Fx.Style.extend({	
	initialize: function(element, options) {
		this.parent(element);
		this.fx = new Fx.Style(this.element, 'top', options || {duration:100});
		this.element.setStyles({'position': 'relative', 'overflow': 'hidden'});
	},
	
	start: function() {
		this.fx.start(-10).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(0);
		}.bind(this));
	}
});

/*
	Class: Fx.ShakeW
	Description: Will shake horizontally the element
	Extends: Class Fx.Style
	Constructor: new Fx.ShakeW (element, options)
	[Properties] 
		element - the element
		options - the shake transition Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.ShakeW effect
	[/Methods]

	Method: start
	Description:  starts the Fx.ShakeW effect
	[Example]  
		>  var fx = new Fx.ShakeW('box');
		> fx.start();
	[/Example]
*/
Fx.ShakeW = Fx.Style.extend({
	initialize: function(element, options) {
		this.parent(element);
		this.fx = new Fx.Style(this.element, 'left', options || {duration:100});
		this.element.setStyles({'position': 'relative', 'overflow': 'hidden'});
	},
	
	start: function() {
		this.fx.start(-10).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(10);
		}.bind(this)).chain(function() {
			this.fx.start(-10);
		}.bind(this)).chain(function() {
			this.fx.start(0);
		}.bind(this));
	}
});


/*
	Class: Element
	Description: Extend the Element Class with Fx shortcuts. All these methods accept the same arguments of the relative Fx effect (obviously without the element)
	Extends: Class Element
	Constructor: new Element (element)
	[Properties] 
		element - the element
	[/Properties]
	[Methods]
		fadeOut -- returns an Fx.FadeOut instance
		switchOffH -- returns an Fx.SwitchOffH instance
		switchOffW -- returns an Fx.SwitchOffW instance
		shakeH -- returns an Fx.ShakeH instance
		shakeW -- return an Fx.ShakeW instance
	[/Methods]

*/
Element.extend({
	/*
	Method: fadeOut
	Description:  returns an Fx.FadeOut instance
	[Example]  
		>  var fx = $('box').fadeOut();
		> fx.start();
	[/Example]
	*/
	fadeOut: function(options) {
		return new Fx.FadeOut(this, options);	
	},
	
	/*
	Method: switchOffH
	Description:  returns an Fx.SwitchOffH instance
	*/
	switchOffH: function(options) {
		return new Fx.switchOffH(this, options);	
	},
	
	/*
	Method: switchOffH
	Description:  returns an Fx.SwitchOffW instance
	*/
	switchOffW: function(options) {
		return new Fx.FixswitchOffH(this,options);	
	},
	
	/*
	Method: shakeH
	Description:  returns an Fx.ShakeH instance
	*/
	shakeH: function(options) {
		return new Fx.ShakeH(this, options);	
	},
	
	/*
	Method: shakeW
	Description:  returns an Fx.ShakeW instance
	*/
	shakeW: function(options) {
		return new Fx.ShakeW(this, options);	
	}
});


/*
	Filename: effects3.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Fx.Pulsate, Fx.Gradient, Fx.FixGradient, Fx.FadeIn, Fx.Rumble
	>> Element.pulsate, Element.gradient, Element.fixgradient, Element.fadeIn, Element.rumble
	
	Requires: constructors.js
	
	Filedescription: Contains Fx extensions which allow to create web2.0 effects
	
	[Summary]
		Fx.Pulsate ::: Will pulsate an element many times
		Fx.Gradient ::: Will smoothly change the background-color of the element two times
		Fx.FixGradient ::: Will smoothly change the background-color of the element
		Fx.FadeIn ::: Will smoothly fade the element
		Fx.Rumble ::: With this cool effect you can drag an element and release it like an elastic
		Element ::: Extend the Element Class with Fx shortcuts
	[/Summary]
*/

/*
	Class: Fx.Pulsate
	Description: Will pulsate an element many times
	Extends: Class Fx.Style
	Constructor: new Fx.Pulsate (element)
	[Properties] 
		element - the element
	[/Properties]
	[Methods]
		start -- starts the Fx.Pulsate effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Pulsate effects
	[Example]  
		>  var fx = new Fx.Pulsate('box');
		> fx.start();
	[/Example]
*/
Fx.Pulsate = Fx.Style.extend({	
	initialize: function(element) {
		this.parent(element, 'opacity');
		this.fx = new Fx.Style(this.element, this.property, {duration:100});
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.fx.start(0).chain(function() {
			this.fx.start(1);
		}.bind(this)).chain(function() {
			this.fx.start(0);
		}.bind(this)).chain(function() {
			this.fx.start(1);
		}.bind(this)).chain(function() {
			this.fx.start(0);
		}.bind(this)).chain(function() {
			this.fx.start(1);
		}.bind(this)).chain(function() {
			this.fx.start(0);
		}.bind(this)).chain(function() {
			this.fx.start(1);
		}.bind(this)).chain(function() {
			this.fx.start(0);
		}.bind(this)).chain(function() {
			this.fx.start(1);
		}.bind(this));
	}
});
		
/*
	Class: Fx.Gradient
	Description: Will smoothly change the background-color of the element two times
	Extends: Class Fx.Style
	Constructor: new Fx.Gradient (element, color, options, options2)
	[Properties] 
		element - the element
		color - the transition background-color
		options - the first effect Fx options
		options2 - the second effect Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.Gradient effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Gradient effect
	[Example]  
		>  var fx = new Fx.Gradient('box', '#F5C776', {duration:2000}, {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.Gradient = Fx.Style.extend({
	initialize: function(element, color, options, opt2) {
		this.parent(element,'background-color',  options);
		this.color = color;
		this.fx = new Fx.Style(this.element, 'background-color', opt2);
		this.initStyles('backgroundColor');
	},
	
	start: function() {
		this.parent(this.color).chain(function() {
			this.fx.start(this.init.backgroundColor);
		}.bind(this));
	}
});

/*
	Class: Fx.FixGradient
	Description: Will smoothly change the background-color of the element
	Extends: Class Fx.Style
	Constructor: new Fx.FixGradient (element, color, options)
	[Properties] 
		element - the element
		color - the transition background-color
		options - the effect Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.FixGradient effect
	[/Methods]

	Method: start
	Description:  starts the Fx.FixGradient effect
	[Example]  
		>  var fx = new Fx.FixGradient('box', '#F5C776', {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.FixGradient = Fx.Style.extend({
	initialize: function(element, color, options) {
		this.parent(element, 'background-color', options);
		this.color= color;
	},
	
	start: function() {
		this.parent(this.color);
	}
});

/*
	Class: Fx.FadeIn
	Description: Will smoothly fade the element
	Extends: Class Fx.Style
	Constructor: new Fx.FadeIn (element, options)
	[Properties] 
		element - the element
		options - the effect Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.fadeIn effect
	[/Methods]

	Method: start
	Description:  starts the Fx.FadeIn effect
	[Example]  
		>  var fx = new Fx.FadeIn('box', {duration:2000});
		> fx.start();
	[/Example]
*/
Fx.FadeIn = Fx.Style.extend({
	initialize: function(element, options) {
		this.parent(element, 'opacity', options);
	},
	
	start: function() {
		this.parent(1);
	}
});

/*
	Class: Fx.Rumble
	Description:  With this cool effect you can drag an element and release it like an elastic
	Extends: Class Fx.Styles
	Constructor: new Fx.Rumble (element, options)
	[Properties] 
		element - the element
		options - the effect Fx options
	[/Properties]
	[Methods]
		start -- starts the Fx.Rumble effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Rumble effect
	[Example]  
		>  var fx = new Fx.Rumble('box');
		> fx.start();
	[/Example]
*/
Fx.Rumble = Fx.Styles.extend({	
	initialize: function(element, options) {
		this.parent(element);
		this.element.setStyles({'position': 'relative', 'cursor': 'move'});
		this.initStyles('top', 'left');
		this.obj = {'top': [this.element.getStyle('top').toInt(), this.init.top], 
					'left': [this.element.getStyle('left').toInt(), this.init.left]
				   };
		this.fx = new Fx.Styles(this.element, options || {duration: 800, transition: Fx.Transitions.Elastic.easeOut});
	},

	start: function() {
		var top = this.init.top; var left = this.init.left;
		var coord = {'top': (top != 'auto' ? top : 0), 'left': (left != 'auto' ? left : 0)};
		var fx = function() { this.fx.start(coord); };
		new Drag.Move(this.element).addEvent('onComplete', fx.bind(this));		   
	}
			
});


/*
	Class: Element
	Description: Extend the Element Class with Fx shortcuts. All these methods accept the same arguments of the relative Fx effect (obviously without the element)
	Extends: Class Element
	Constructor: new Element (element)
	[Properties] 
		element - the element
	[/Properties]
	[Methods]
		pulsate -- returns an Fx.Pulsate instance
		gradient -- returns an Fx.Gradient instance
		fixgradient -- returns an Fx.FixGradient instance
		fadeIn -- returns an Fx.FadeIn instance
		rumble -- return an Fx.Rumble instance
	[/Methods]

*/
Element.extend({
	/*
	Method: pulsate
	Description:  returns an Fx.Pulsate instance
	[Example]  
		>  var fx = $('box').pulsate();
		> fx.start();
	[/Example]
	*/
	pulsate: function() {
		return new Fx.Pulsate(this);	
	},
	
	/*
	Method: gradient
	Description:  returns an Fx.Gradient instance
	*/
	gradient: function(color, options, opt2) {
		return new Fx.Gradient(this, color, options, opt2);	
	},
	
	/*
	Method: fixgradient
	Description:  returns an Fx.FixGradient instance
	*/
	fixgradient: function(color, options) {
		return new Fx.FixGradient(this, color, options);	
	},
	
	/*
	Method: fadeIn
	Description:  returns an Fx.FadeIn instance
	*/
	shrink: function(options) {
		return new Fx.FadeIn(this, options);	
	},
	
	/*
	Method: rumble
	Description:  returns an Fx.Rumble instance
	*/
	rumble: function(options) {
		return new Fx.Rumble(this, options);	
	}
});


/*
	Filename: effects4.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Fx.BubbleH, Fx.BubbleW, Fx.Morph, Fx.DropOut, Fx.Move
	>> Element.bubbleH, Element.bubbleW, Element.morph, Element.dropOut, Element.move
	
	Requires: constructors.js
	
	Filedescription: Contains Fx extensions which allow to create web2.0 effects
	
	[Summary]
		Fx.BubbleH ::: Will smoothly fade and close an element vertically
		Fx.BubbleW ::: Will smoothly fade and close an element horizontally
		Fx.Morph ::: Will change some CSS properties of an element from one class to another
		Fx.DropOut ::: Will drop an element out
		Fx.Move ::: Will move an element on a x/y scale
		Element ::: Extend the Element Class with Fx shortcuts
	[/Summary]
*/

/*
	Class: Fx.BubbleH
	Description: Will smoothly fade and close an element vertically
	Extends: Class Fx.Styles
	Constructor: new Fx.BubbleH (element, options)
	[Properties] 
		element - the element
		options - the Fx Options
	[/Properties]
	[Methods]
		start -- starts the Fx.BubbleH effect
	[/Methods]

	Method: start
	Description:  starts the Fx.BubbleH effects
	[Example]  
		>  var fx = new Fx.BubbleH('box');
		> fx.start();
	[/Example]
*/
Fx.BubbleH = Fx.Styles.extend({
	initialize: function(element, options) {
		this.parent(element, options || {duration:3000});
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.parent({
			'height': [0],
			'font-size': [0],
			'opacity': [0]
		});
	}
});


/*
	Class: Fx.BubbleW
	Description: Will smoothly fade and close an element horizontally
	Extends: Class Fx.Styles
	Constructor: new Fx.BubbleW (element, options)
	[Properties] 
		element - the element
		options - the Fx Options
	[/Properties]
	[Methods]
		start -- starts the Fx.BubbleW effect
	[/Methods]

	Method: start
	Description:  starts the Fx.BubbleW effects
	[Example]  
		>  var fx = new Fx.BubbleW('box');
		> fx.start();
	[/Example]
*/
Fx.BubbleW = Fx.Styles.extend({		
	initialize: function(element, options) {
		this.parent(element, options || {duration:3000});
		this.element.setStyle('overflow', 'hidden');
	},
	
	start: function() {
		this.parent({
			'width': [0],
			'font-size': [0],
			'opacity': [0]
		});
	}
});


/*
	Class: Fx.Morph
	Description: Will change some CSS properties of an element from one class to another. Inspired by that found in the MooTools examples
	Extends: Class Fx.Styles
	Constructor: new Fx.BubbleW (element, options)
	[Properties] 
		element - the element
	[/Properties]
	[Methods]
		start -- starts the Fx.Morph effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Morph effects
	[Arguments]
		className :: the new className contains the new CSS rules
	[/Arguments]
	[Example]  
		>  var fx = new Fx.Morph('box');
		> fx.start('box2');
	[/Example]
*/
Fx.Morph = Fx.Styles.extend({
	initialize: function(element) {
		this.parent(element);
	},
 
	start: function(className){

		var to = {};

		$each(document.styleSheets, function(style){
			var rules = style.rules || style.cssRules;
				$each(rules, function(rule) {
					if (!rule.selectorText.test('\.' + className + '$')) return;
					CSSProperties.each(function(style) {
						if (!rule.style || !rule.style[style]) return;
						var ruleStyle = rule.style[style];
						to[style] = (style.test(/color/i) && ruleStyle.test(/^rgb/)) ? ruleStyle.rgbToHex() : ruleStyle;
					});
				});
		});
		return this.parent(to);
	}

});
 
CSSProperties = ["backgroundColor", "backgroundPosition", "backgroundImage", "color", "width", "height", "left", "top", "bottom", "right", "fontSize", "letterSpacing", "lineHeight", "textIndent", "opacity"];
 
CSSProperties.extend(Element.Styles.padding);
CSSProperties.extend(Element.Styles.margin); 

Element.Styles.border.each(function(border){
	['Width', 'Color'].each(function(property){
		CSSProperties.push(border + property);
	});
});

/*
	Class: Fx.DropOut
	Description: Will drop an element out
	Extends: Class Fx.Styles
	Constructor: new Fx.DropOut (element, options)
	[Properties] 
		element - the element
		options - the Fx Options
	[/Properties]
	[Methods]
		start -- starts the Fx.DropOut effect
	[/Methods]

	Method: start
	Description:  starts the Fx.DropOut effects
	[Example]  
		>  var fx = new Fx.DropOut('box');
		> fx.start();
	[/Example]
*/
Fx.DropOut = Fx.Styles.extend({		
	initialize: function(element, options) {
		this.parent(element, options);
		this.element.setStyle('position', 'relative');
		this.initStyles('top');
		this.removeAuto('top');
	},
	
	start: function() {
		this.parent({
			'top': [this.init.top + 40],
			'opacity': [0]
		});
	}
});


/*
	Class: Fx.Move
	Description: Will move an element on a x/y scale
	Extends: Class Fx.Styles
	Constructor: new Fx.Move (element, options)
	[Properties] 
		element - the element
		options - the Fx Options
	[/Properties]
	[Methods]
		start -- starts the Fx.Move effect
	[/Methods]

	Method: start
	Description:  starts the Fx.Move effects
	[Arguments]
		top :: the new top value
		left :: the new left value
	[/Arguments]
	[Example]  
		>  var fx = new Fx.Move('box');
		> fx.start();
	[/Example]
*/
Fx.Move = Fx.Styles.extend({	
	initialize: function(element, options) {
		this.parent(element, options);
		this.element.setStyle('position', 'relative');
		this.initStyles('top', 'left');
		this.removeAuto('top', 'left');
	},
	
	start: function(top, left) {
		this.parent({
			'top': top,
			'left': left
		});
	}
});


/*
	Class: Element
	Description: Extend the Element Class with Fx shortcuts. All these methods accept the same arguments of the relative Fx effect (obviously without the element)
	Extends: Class Element
	Constructor: new Element (element)
	[Properties] 
		element - the element
	[/Properties]
	[Methods]
		bubbleH -- returns an Fx.BubbleH instance
		bubbleW -- returns an Fx.BubbleW instance
		morph -- returns an Fx.Morph instance
		dropOut -- returns an Fx.DropOut instance
		move -- return an Fx.Move instance
	[/Methods]

*/
Element.extend({
	/*
	Method: bubbleH
	Description:  returns an Fx.BubbleH instance
	[Example]  
		>  var fx = $('box').bubbleH();
		> fx.start();
	[/Example]
	*/
	bubbleH: function(options) {
		return new Fx.BubbleH(this, options);	
	},
	
	/*
	Method: bubbleW
	Description:  returns an Fx.BubbleW instance
	*/
	bubbleW: function(options) {
		return new Fx.BubbleW(this, options);	
	},
	
	/*
	Method: morph
	Description:  returns an Fx.Morph instance
	*/
	morph: function(color) {
		return new Fx.Morph(this);	
	},
	
	/*
	Method: dropOut
	Description:  returns an Fx.DropOut instance
	*/
	dropOut: function(options) {
		return new Fx.DropOut(this, options);	
	},
	
	/*
	Method: move
	Description:  returns an Fx.Move instance
	*/
	move: function(options) {
		return new Fx.Move(this, options);	
	}
});


/*
	Filename: toggle.js
	
	Author: Riccardo Degni , <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: class Fx.Toggle
	
	Requires: nothing
	
	Filedescription: Contains the Fx.Toggle Class and the Element::toggle method
	
	[Summary]
		Fx.Toggle ::: allows you to use many toggle methods
		Element ::: contains the Fx.Toggle method shortcut
	[/Summary]
*/

/*
	Class: Fx.Toggle
	Description:  This class allows you to use many toggle methods.  The "toggle" effect is an intermittent change of a property value. /n  The toggle methods are helpful to hide or to show an element with a transition. Unlike the mootools toggle methods, these can be implemented without a strict doctype.
	
	Extends: Class Fx (MooTools)
	
	Constructor: new Fx.Toggle (element, property, options)
	
	[Properties] 
		element - the $(element) to apply the toggle to
		property - the property to alter
		options - optional. the Fx.Base and Fx.Style options
	[/Properties]
	
	[Methods]
		toggleHeight -- toggles the height property
		toggleWidth -- toggles the width property
		toggleOpacity -- toggles the opacity property
		toggleProperty -- toggles a specified CSS property, string or integer, from one value to another
	[/Methods]
*/

Fx.Toggle = Fx.Style.extend({
	initialize: function(element, options) {
		this.parent(element, null, options);
		this.initHeight = this.element.getStyle('height').toInt();
		this.initWidth = this.element.getStyle('width').toInt();
		this.initOpacity = this.element.getStyle('opacity').toInt();
	},
	
	/*
	Method: toggleHeight
	Description: toggles the height property
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.toggleHeight();
	[/Example]
	*/
	toggleHeight: function() {
		this.property = 'height';
		(this.element.getStyle(this.property).toInt() > 0) ? this.start(0) : this.start(this.initHeight);
	},
	
	/*
	Method: toggleWidth
	Description: toggles the width property
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.toggleWidth();
	[/Example]
	*/
	toggleWidth: function() {
		this.property = 'width';
		(this.element.getStyle(this.property).toInt() > 0) ? this.start(0) : this.start(this.initWidth);
	},
	
	/*
	Method: toggleOpacity
	Description: toggles the opacity property
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.toggleOpacity();
	[/Example]
	*/
	toggleOpacity: function() {
		this.property = 'opacity';
		(this.element.getStyle(this.property).toInt() > 0) ? this.start(0) : this.start(this.initOpacity);
	},
	
	/*
	Method: toggleProperty
	Description: toggles a specified CSS property, string or integer, from one value to another
	[Arguments]
		property :: the property to toggle
		from :: the start value of the property. It can be different from it real start value
		to :: the final value of the property
		options :: an object with only a property: 'fx'. If it is true the property changes with a transition
	[/Arguments]
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.toggleProperty('color', 'blue', 'green');
		> box.toggleProperty('color', 'blue', 'green', {fx:true});
	[/Example]
	*/
	toggleProperty: function(property, from, to, options) {
		this.property = property;
		var options = options || {fx:false};
		if(($type(from) == 'string') && ($type(to) == 'string') && !options.fx)
			((this.element.getStyle(this.property)) == from.toLowerCase()) ? this.element.setStyle(this.property, to) : this.element.setStyle(this.property, from);
		else if(($type(from) == 'string') && ($type(to) == 'string') && options.fx)
			((this.element.getStyle(this.property)) == from.toLowerCase()) ? this.start(to) : this.start(from);
		else if(($type(from) == 'number') && ($type(to) == 'number'))
			((this.element.getStyle(this.property).toInt()) == from) ? this.start(to) : this.start(from);
	}
});
			
/*
	Class: Element
	Description: contains the Fx.Toggle method shortcut
	Extends: Class Element (MooTools)
	Requires: nothing
	
	[Methods]
		toggle -- apply each Fx.Toggle methods to this element
	[/Methods]
*/
Element.extend({
	/*
	Method: toggle
	Description: apply each Fx.Toggle methods to this element
	[Example]  
		> $('box').toggle({duration:2000}).toggleColor('#6666FF', '#000000', {fx:true});
	[/Example]
	*/
	toggle: function(options) {
		return new Fx.Toggle(this, options);
	}
});


/*
	Filename: toggle_extend.js
	
	Author: Riccardo Degni , <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: extension of class Fx.Toggle
	
	Requires: toggle.js
	
	Filedescription: Contains the Fx.Toggle Class extension
	
	[Summary]
		Fx.Toggle ::: extends the Fx.Toggle Class using the Fx.Toggle::toggleProperty method to create shortcuts
	[/Summary]
*/

/*
	Class: Fx.Toggle
	
	Description: extends the Fx.Toggle Class using the Fx.Toggle::toggleProperty method to create shortcuts
	
	Extends: Class Fx.Toggle
	
	Constructor: new Fx.Toggle (element, property, options)
	
	[Properties] 
		element - the $(element) to apply the toggle to
		property - the property to alter
		options - optional. the Fx.Base and Fx.Style options
	[/Properties]
	
	[Methods]
		toggleColor -- toggles the background-color property
		display -- creates a display-toggle transition. If the element's display is 'block' it becomes 'none' and vice-versa
		see -- creates a visibility-toggle transition. If the element is visibile it becomes hidden and vice-versa
	[/Methods]
*/

Fx.Toggle.implement({
	/*
	Method: toggleColor
	Description: toggles the color property
	[Arguments]
		from :: the start value of the background-color property. It can be different from it real start value
		to :: the final value of the background-color property
		options :: an object with only a property: 'fx'. If it is true the property changes with a transition
	[/Arguments]
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.toggleColor('#6666FF', '#000000', {fx:true});
	[/Example]
	*/
	toggleColor: function(from, to, options) {
		this.property = 'background-color';
		this.toggleProperty(this.property, from, to, options);
	},
	
	/*
	Method: display
	Description: creates a display-toggle transition. If the element's display is 'block' it becomes 'none' and vice-versa
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.display();
	[/Example]
	*/
	display: function() {
		this.property = 'display';
		this.toggleProperty(this.property, 'block', 'none');
	},
	
	/*
	Method: see
	Description: creates a visibility-toggle transition. If the element is visibile it becomes hidden and vice-versa
	[Example]  
		> box = new Fx.Toggle('box'); 
		> box.see();
	[/Example]
	*/
	see: function() {
		this.property = 'visibility';
		this.toggleProperty(this.property, 'visible', 'hidden');
	}
});
/*
	Filename: virtual_base.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Virtual.Base
	
	Filedescription:  Contains the Virtual.Base Class
	
	[Summary]
		Virtual.Base ::: Wrapper Class to create Virtual.Box and Virtual.Ajax
	[/Summary]
*/

/*
	Class: Virtual.Base
	Description: Wrapper Class to create Virtual.Box and Virtual.Ajax
	
	Extends: Class Virtual
	
	[Options]
		className : the class name of the virtual box
		easing : the transition of the virtual box. You can choose one value from 'elastic' (default), 'bounce' and 'normal'
		duration : the duration in ms of start effect
		position : the position of the virtual box. You can choose one value from 'top', 'center' (default) or 'bottom'. If the mode is set to 'horizontal', these values are horizontal, if it's set to 'vertical' are vertical.
		mode : the mode how the virtual box appears. 'horizontal' (horizontally) or 'vertical' (vertically)
		opacify: 'darken' or 'lighten' opacify
	[/Options]
	
	[Example]
		> // Virtual.Box
		> var virtualbox = new Virtual.Box('Virtual Box', {
		>		className: 'box',
		>		mode: 'horizontal',
		>		position: 'top'
		> });
		> // Virtual.Ajax
		> var virtualajax = new Virtual.Ajax('page.php', {
		>		className: 'box',
		>		mode: 'vertical',
		>		closeClass : 'closeBox'
		> });
	[/Example]
*/

var Virtual = {};

Virtual.Base = new Class({
						 
	options: {
		className: '',
		easing: 'elastic',
		duration: 1600,
		position: 'center',
		mode: 'vertical',
		opacify: 'darken'
	},
	
	initialize: function(text, options) {
		this.text = text;
		this.setOptions(options);
		this.box = new Element('div', {
			'id': 'virtualBox2.0',
			'class': this.options.className,
			'styles': {
				'position': 'absolute',
				'z-index': 1000
			}				   
		});
		this.createOverlay();
		
		switch(this.options.easing) {
			case 'elastic': this.transition = Fx.Transitions.Elastic.easeOut; break;
			case 'bounce': this.transition = Fx.Transitions.Bounce.easeOut; break;
			case 'normal': this.transition = Fx.Transitions.Sine.easeInOut; break;
		};
		switch(this.options.position) {
			case 'top': this.pos = 20; break;
			case 'center': this.pos = 50; break;
			case 'bottom': (this.options.mode == 'vertical') ? this.pos = 75 : this.pos = 80; break;
		};
		this.settings = {duration: this.options.duration, transition: this.transition, wait:false, unit: '%'};
		this.fxTop = new Fx.Style(this.box, 'top', this.settings);
		this.fxLeft = new Fx.Style(this.box, 'left', this.settings);
		this.mechanize();
		if(this.options.initialize) this.options.initialize.call(this);
	},
	
	createOverlay: function() {
		this.overlay = new Element('div', {
			'id': 'overlay',
			'styles': {
				'position': 'absolute',
				'top': '0px',
				'left': '0px',
				'width': '100%',
				'height': window.getScrollHeight(),
				'background-color': (this.options.opacify == 'darken') ? '#333333' : '#FFFFFF',
				'opacity': '0.8',
				'z-index': 900
			}
		});
	},
	
	createPage: function() {
		this.page = new Element('div', {
			'id': 'virtualBox2.0page',
			'styles': {
				'position': 'absolute',
				'top': window.getScrollTop(),
				'left': '0px',
				'width': window.getWidth() + 'px',
				'height': window.getHeight() + 'px',
				'z-index': 900
			}
		});
	},
	
	mechanize: function() {
		this.box.addEvent('click', this.removeElements.bind(this));
		this.box.setHTML(this.text);
	},
	
	appendElements: function() {
		this.box.injectInside(this.page);
		this.page.injectTop($E('body'));
		this.overlay.injectTop($E('body'));
	},
	
	customize: function() {
		
		if($('virtualBox2.0')) return;
		
		switch(this.options.mode) {
			case 'vertical':
				this.box.setStyles({'top': '-20%', 'left': '50%'});
				break;
			case 'horizontal':
				this.box.setStyles({'top': '50%', 'left': '-20%'});
				break;
		}
		
		this.createPage();
		
		if(!window.gecko) this.appendElements();
 
		this.box.setStyles({
			'margin-left': - this.box.getStyle('width').toInt()/2,
			'margin-top': - this.box.getStyle('height').toInt()/2
		});
 
 		if(window.gecko) this.appendElements();
		
		this.marginY = this.box.getStyle('height').toInt()/2;
		this.marginX = this.box.getStyle('width').toInt()/2;
		
		this.fxTop.setOptions(this.settings);
		this.fxLeft.setOptions(this.settings);
		
		(this.options.mode == 'vertical') ? this.fxTop.start(-20, this.pos) : this.fxLeft.start(-20, this.pos);
	},
	
	removeElements: function() {
		var opt = {duration:800, transition:Fx.Transitions.linear};
		if(this.options.mode == 'vertical') {
			this.fxTop.setOptions(opt);
			this.fxTop.start(-this.marginY*4).chain(function() {
				this.page.remove();
				this.overlay.remove();															
			}.bind(this));
		}
		else if(this.options.mode == 'horizontal') {
			this.fxLeft.setOptions(opt);
			this.fxLeft.start(-this.marginX*4).chain(function() {
				this.page.remove();
				this.overlay.remove();															
			}.bind(this));
		}
	}
						 
});

Virtual.Base.implement(new Options);


/*
	Filename: virtual_box.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Virtual.Box
	
	Requires: virtual_base.js
	
	Filedescription:  Contains the Virtual.Box Class
	
	[Summary]
		Virtual.Box ::: Custom Class to create virtual boxes
	[/Summary]
*/

/*
	Class: Virtual.Box
	Description:  Custom Class to create virtual boxes. Allows you to create easily virtual boxes, that are special boxes appear on an overlay which cover the page. This means the virtual boxes can contain special or important information. /n You can remove the virtual box from the page by clicking on it. 
	
	Extends: Class Virtual.Base
	
	Constructor: new Virtual.Box (text, options)
	
	[Properties] 
		text - the text that virtual box shows
		options - optional. the virtual box options
	[/Properties]
	
	[Options]
		Virtual.Base options : all the Virtual.Base options
	[/Options]
	
	[Methods]
		start -- shows the virtual box
		setText -- sets the text of the virtual box
	[/Methods]
	
	Method: start
	Description: shows the virtual box
	[Example]  
		> var virtualbox = new Virtual.Box('Virtual Box', {
		>		className: 'box',
		>		mode: 'horizontal',
		>		position: 'top'
		> });
		> // shows the virtual box
		> virtualbox.start();
	[/Example]
	
	Method: setText
	Description: sets the text of the virtual box
	[Example]  
		> virtualbox.setText('The Virtual Box');
	[/Example]
*/

Virtual.Box = Virtual.Base.extend({
	
	initialize: function(text, options) {
		this.parent(text, options);
	},
	
	start: function() {
		this.customize();	
	},
	
	setText: function(text) {
		this.box.setHTML(text);
		return this;
	}
						   
});


/*
	Filename: virtual_ajax.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Virtual.Ajax
	
	Requires: virtual_base.js
	
	Filedescription:  Contains the Virtual.Ajax Class
	
	[Summary]
		Virtual.Ajax ::: Custom Class to create ajax virtual boxes
	[/Summary]
*/

/*
	Class: Virtual.Ajax
	Description:  Custom Class to create ajax virtual boxes. In addiction you can load a page from the server and show it on the virtual box. /n You can remove the virtual box from the page by clicking on 'close' button, situated in the upper left corner. The virtual box appear in the center of page, slightly inspired by the DezinerFolio (<http://www.dezinerfolio.com/>) theory.
	
	Extends: Class Virtual.Base
	
	Constructor: new Virtual.Ajax (server, options)
	
	[Properties] 
		server - the page to load
		options - optional. the virtual box options
	[/Properties]
	
	[Options]
		Virtual.Base options : all the Virtual.Base options
		closeText : the text of the close  button
		closeClass : the class name of the close button
	[/Options]
	
	[Methods]
		start -- shows the virtual box
		setXhrOptions -- sets the ajax options
		setServer -- sets the page to load
	[/Methods]
	
	Method: start
	Description: shows the virtual box
	[Example]  
		> var virtualajax = new Virtual.Ajax('page.php', {
		>		className: 'box',
		>		mode: 'vertical',
		>		closeStyles: 'closeBox'
		> });
		> // shows the ajax virtual box
		> virtualajax.start();
	[/Example]
	
	Method: setXhrOptions
	Description: sets the ajax options
	[Example]  
		> virtualajax.setXhrOptions({onComplete: function() { alert('Complete'); }});
	[/Example]
	
	Method: setServer
	Description: sets the page to load
	[Example]  
		> virtualajax.setServer('myPage.php');
	[/Example]
*/

Virtual.Ajax = Virtual.Base.extend({
						
	options: {
		closeClass: '',
		closeText: 'close'
	},
	
	initialize: function(server, options) {
		this.server = server;
		this.parent('', options);
		this.createClose();
	},
	
	createClose: function() {
		this.close = new Element('div', {
			'id': 'close_virtual_ajax',
			'class': this.options.closeClass,
			'styles': {
				'position': 'absolute',
				'top': (window.getScrollTop()>0) ? window.getScrollTop() : '10px',
				'left': '10px',
				'z-index': 900
			}
		});
	},
	
	mechanize: function() {
		this.parent();
		this.box.removeEvents('click');
	},
	
	appendElements: function() {
		this.parent();
		this.close.addEvent('click', this.removeElements.bind(this));
		this.close.setHTML(this.options.closeText);
		this.close.injectInside(this.page);
	},
	
	customize: function() {
		this.parent();
		this.ajaxOptions = $extend(this.xhr || {}, {
			update: 'virtualBox2.0'
		});
		new Ajax(this.server, this.ajaxOptions).request();
	},
	
	start: function() {
		this.customize();
	},
	
	setXhrOptions: function(xhr) {
		this.xhr = xhr;
		return this;
	},
	
	setServer: function(server) {
		this.server = server;
		return this;
	}
						   
});


/*
	Filename: kwick_menu.js
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/>
	
	License: GPL (General Public License)
	
	Contains: Class Kwick.Base, Kwick.Menu
	
	Filedescription:  It allows you to create customized kwick menu, horizontal or vertical.
	
	[Summary]
		Kwick.Base ::: Base Class, internal. A wrapper for the Kwick.Menu Class
		Kwick.Menu ::: Custom Class to create customized kwick menu, horizontal or vertical
	[/Summary]
*/

/*
	Class: Kwick.Base
	Description: Base Class, internal. A wrapper for the Kwick.Menu Class
	Extends: Fx.Elements
*/

/*
	Class: Kwick.Menu
	Description:  Custom Class to create customized kwick menu, horizontal or vertical
	
	Extends: Class Kwick.Base
	
	Constructor: new Kwick.Menu (elements, options)
	
	[Properties] 
		element - the $$(elements) to apply the kwick to
		options - optional. The Fx.Element options plus some other options
	[/Properties]
	
	[Options]
		large : int. the large sizes
		normal : int. the normal sizes
		small : int. the small sizes
		mode : 'vertical' (height transitions, vertical) or 'horizontal' (width transitions, horizontal, default)
	[/Options]
	
	[Example]
		> var kwick = new new Kwick.Menu($$("#kwick kwick"), {
		> 		mode: 'vertical'									
		> });
	[/Example]
*/

var Kwick = {};

Kwick.Base = Fx.Elements.extend({
	options: {
		large: 200,
		normal: 100,
		small: 50,
		mode: 'horizontal'
	},	
	
	initialize: function(element, options) {
		this.parent(element, options);
	},
	
	enterH: function(el, i) {
		var o = {};
		o[i] = {height: [el.getStyle('height').toInt(), this.options.large]};
		this.elements.each(function(other, j) {
			if(i != j) {
				var h = other.getStyle('height').toInt();
				if(h != this.options.small) o[j] = {height: [h, this.options.small]};
			}
		}, this);
		this.start(o);
	},
	
	outH: function(el, i) {
		var o = {};
		this.elements.each(function(el, i) {
			o[i] = {height: [el.getStyle('height').toInt(), this.options.normal]};			 
		}, this);
		this.start(o);
	},
	
	enterW: function(el, i) {
		var o = {};
		o[i] = {width: [el.getStyle('width').toInt(), this.options.large]};
		this.elements.each(function(other, j) {
			if(i != j) {
				var w = other.getStyle('width').toInt();
				if(w != this.options.small) o[j] = {width: [w, this.options.small]};
			}
		}, this);
		this.start(o);
	},
	
	outW: function() {
		var o = {};
		this.elements.each(function(el, i) {
			o[i] = {width: [el.getStyle('width').toInt(), this.options.normal]};			 
		}, this);
		this.start(o);
	}
});

Kwick.Menu = Kwick.Base.extend({
	
	initialize: function(elements, options) {
		this.parent(elements, options);
		this.ul = this.elements.getParent();
		switch(this.options.mode) {
			case 'vertical': this.elements.each(function(el, i) { this.buildH(el, i); }, this);
					  this.elements.each(function(el) { el.addEvent('mouseleave', this.outH.bind(this)); }, this);
					  break;
					  
			case 'horizontal': this.elements.each(function(el, i) { this.buildW(el, i); }, this);
					  this.elements.each(function(el) { el.addEvent('mouseleave', this.outW.bind(this)); }, this);
					  break;
		}; 
	},
	
	buildH: function(el, i) {
		var enter = this.enterH.bind(this);
		el.addEvent("mouseenter", enter.pass([el, i]));
	},
	
	buildW: function(el, i) {
		var enter = this.enterW.bind(this);
		el.addEvent("mouseenter", enter.pass([el, i]));
	}
});