/*
	Filename: moo.rd - A lightweight Mootools extension
	
	Author: Riccardo Degni, <http://www.riccardodegni.it/> and Luciano Amodio, <http://www.lucianoamodio.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.3.1',
	author: 'Riccardo Degni',
	members: [
		'Luciano Amodio',
		'Cristiano Fino'
	]
};


/*
	Filename: constructors.js
	
	Contains: Class Custom, Class Table, Class Make, Class Fx
	
	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 = new Class({
					   
	/*
	Method: setText
	Description:  set the text of the custom alert/confirm
	[Example]  
		> // change the previous text
		> box.setText('Custom Alert/Confirm with some new text');
	[/Example]
	*/
	setText: function(text) {
		this.text = text;
		this.content.set(this.options.content, this.text);
		return this;
	},
	
	/*
	Method: setTitle
	Description:  set the title of the custom alert/confirm
	[Example]  
		> // change the previous title
		> box.setTitle('A new Custom Alert/Confirm');
	[/Example]
	*/
	setTitle: function(title) {
		this.title = title;	
		this.head.set(this.options.content, this.title);
		return this;
	}
});

/*
	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
	Description: Extension to create the moo.rd effects repository.  
*/
Fx.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: overlay.js
	
	Contains: Class Overlay
	
	Filedescription: Contains the Overlay Utility Class, that can be implemented with Implements property into any Class
	
	[Summary]
		Overlay ::: Utility Class for creating customized and advanced overlays
	[/Summary]
*/

/*
	Class: Overlay
	
	Description:  Utility Class for creating customized and advanced overlays. Adds the Overlay properties to the Classes
	
	Extends: nothing
	
	Constructor: new Overlay()
	
	[Methods]
		createOverlay -- creates the overlay property which represents the overlay
		createFullPage -- creates the full page overlay which represents the upper level
		setLight -- sets the light of the overlay. Can be 'draken', 'lighten', false or a color
	[/Methods]
*/
var Overlay = new Class({
						
	/*
	Method: createOverlay
	Description:  creates the overlay property which represents the overlay
	[Arguments]
		id :: the overlay id
		light :: the overlay light. It can be 'darken' 'lighten', false or a color
	[/Arguments]
	*/
	createOverlay: function(id, light) {
		this.overlay = new Element('div', {
			'id': id || 'overlay',
			'styles': {
				'position': (Browser.Engine.trident4) ? 'absolute' : 'fixed',
				'top': '0px',
				'left': '0px',
				'width': (Browser.Engine.trident4) ? window.getSize().x : '100%',
				'height': (Browser.Engine.trident4) ? window.getSize().y : '100%',
				'background-image':'url(g.gif)',
				'z-index': 800
			}
		});
		
		this.setLight(light);
		
		return this;
	},
	
	/*
	Method: createFullPage
	Description:  creates the full page overlay which represents the upper level
	[Arguments]
		id :: the fullpage id
	[/Arguments]
	*/
	createFullPage: function(id) {
		this.fullpage = new Element('div', {
			'id': id || 'overlay',
			'styles': {
				'position': (Browser.Engine.trident4) ? 'absolute' : 'fixed',
				'top': '0px',
				'left': '0px',
				'width': (Browser.Engine.trident4) ? window.getSize().x : '100%',
				'height': (Browser.Engine.trident4) ? window.getSize().y : '100%',
				'background-image':'url(g.gif)',
				'z-index': 900
			}
		});
		
		return this;
	},
	
	/*
	Method: setLight
	Description:  sets the light of the overlay. Can be 'draken', 'lighten', false or a color
	[Arguments]
		light :: the light of the overlay 
	[/Arguments]
	*/
	setLight: function(light) {
		switch(light) {
			case 'darken': 
				var color = '#333333';
				break;
			case 'lighten':
				var color = '#FFFFFF';
				break;
			case false:
				var color = 'transparent';
				break;
			default: 
				var color = light;
				break;
		};
		this.overlay.setStyles({
			'background-color': color,
			'opacity': '0.8'			   
		});
		
		return this;
	}
});



/*
	Filename: custom_alert.js
	
	Contains: Class Custom.Alert
	
	Requires: constructors.js, overlay.js
	
	Filedescription:  It allows you to create custom alert boxes, without overriding the standard window.alert method. /n The boxes created with Custom.Alert Class are MODAL and FIXED, like the standard alert boxes, and can be DRAGGABLE.
	
	[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 four main zones descripted below, and you can set the styles of them all, passing a class name for each one.
	 
	 >> You may set an opacity transition when alert box appears and disappears and choose an overlay type. (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 which permits to customize the alert
	[/Properties]
	
	[Options]
		zones : an object which contains the alert zones
		buttons : an object which contains the buttons css classes
		text : an object which contains the buttons contents
		height : the alert height. Default is 'auto'
		width : the alert width. Default is '300px'
		opacify : if true the alert appears and disappears with an opacity transition. Default is true
		content : 'text' or 'html', the content types of the alert title, the alert box and the alert buttons. Default is 'text'
		draggable : if true the alert will be draggable. Default is true
		overlay : the type of the overlay. 'lighten', 'darken' or false (default)
	[/Options]
	
	>> Zones:
		[List]
			[li] alertbox: is the box that contains the other zones
			[li] alerthead: is the header of the alert box. (contains the title)
			[li] alertbody: is the main content of the alert box
	 		[li] buttonBox: (id: 'customAlertButtonBox') the zone which contains the confirm button
		[/List]
	
	>> Buttons:
		[List]
			[li] confirmButton: the confirm button class name
			[li] closeButton: the cancel button class name
		[/List]
		
	>> Text:
		[List]
			[li] buttonText: the text of the confirm button. Defaults to 'OK'
			[li] closeButtonText: the text of the cancel button. Defaults to 'X'
		[/List]
	
	[Methods]
		create -- creates the custom alert box
		setText -- sets the text of the custom alert
		setTitle -- sets the title of the custom alert
	[/Methods]
*/

Custom.Alert = new Class({
						 
	Extends: Custom,
						 
	Implements: [Options, Overlay],
		
	options: {
		height: 'auto',
		width: '300px',
		overlay: false,
		opacify: true,
		draggable: true,
		content: 'text',
		text: {
			buttonText: 'OK',
			closeButtonText: 'X'
		},
		zones: {
			alertbox: null,
			alerthead: null,
			alertbody: null,
			buttonBox: ''
		},
		buttons: {
			closeButton: '',
			confirmButton: ''
		}
	},

	initialize: function(title, text, options) {
		this.title = title;
		this.text = text;
		this.setOptions(options);
		this.alertbox = new Element('div', {
			'id': 'customAlert',
			'styles': {
				'position': (!Browser.Engine.trident4) ? 'fixed' : 'absolute',
				'top': '50%',
				'left': '50%',
				'z-index': 1000,
				'height': this.options.height,
				'width': this.options.width
			}
		});
		this.createOverlay('customAlertOverlay', this.options.overlay);
		this.createFullPage('customAlertfullpage');
		this.mechanize();
		this.fx = new Fx.Tween(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.zones['alertbox']) this.alertbox.addClass(this.options.zones['alertbox']);
		
		this.head = new Element('div').injectInside(this.alertbox);
		if(this.options.zones.alerthead) this.head.addClass(this.options.zones['alerthead']);
		this.head.set(this.options.content, this.title);
		
		this.closebutton = new Element('a', {'id': 'customAlertCloseButton', 'class': this.options.buttons.closeButton}).injectInside(this.head);
		this.closebutton.setProperty('href', '#');
		this.closebutton.set(this.options.content, this.options.text.closeButtonText);
		this.closebutton.addEvent('click', function(event) {
			event.preventDefault();
		});
		if(this.options.opacify)  this.closebutton.addEvent('click', this.opacify.bind(this));
		else this.closebutton.addEvent('click', this.remove.bind(this));
		
		this.content = new Element('div').injectInside(this.alertbox);
		if(this.options.zones.alertbody) this.content.addClass(this.options.zones['alertbody']);
		this.content.set(this.options.content, this.text);
	
		this.closebox = new Element('div', {'id': 'customAlertButtonBox', 'class': this.options.zones.buttonBox}).injectInside(this.alertbox);
	
		this.button = new Element('a', {'id': 'customAlertButton', 'class': this.options.buttons.confirmButton}).injectInside(this.closebox);
		this.button.setProperty('href', '#');
		this.button.set(this.options.content, this.options.text.buttonText);
		this.button.addEvent('click', function(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;
		
		if(this.options.opacify)	this.alertbox.set('opacity', 0);
		
		this.alertbox.injectInside(this.fullpage);
		this.fullpage.injectInside($E('body'));
		this.overlay.injectInside($E('body'));
		
		var dimensions = this.dimensions = { 
			top: this.alertbox.getSize().y/2,
			left: this.alertbox.getSize().x/2
		};
		
		this.alertbox.setStyles({
			'margin-left': -dimensions.left,
			'margin-top': -dimensions.top,
			'top': '50%',
			'left': '50%'
		});
		
		if(this.options.opacify)	this.fx.start(1);
		
		if(this.options.draggable) new Drag.Move(this.alertbox, { container: this.fullpage });
	},
	
	opacify: function() {
		this.fx.start(0).chain(function() {
			this.remove();
		}.bind(this));
	},
	
	remove: function() {
		this.alertbox.remove();
		this.fullpage.remove();
		this.overlay.remove();
	}
	
	/*
	Method: setText
	Description:  sets the text of the custom alert
	[Example]  
		> // changes the previous text
		> ca.setText('Custom Alert with some new text');
	[/Example]
	*/
	
	/*
	Method: setTitle
	Description:  sets the title of the custom alert
	[Example]  
		> // changes the previous title
		> ca.setTitle('A new Custom Alert');
	[/Example]
	*/
});



/*
	Filename: custom_confirm.js
	
	Contains: Class Custom.Confirm
	
	Requires: constructors.js, overlay.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, and can be DRAGGABLE.
	
	[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 four main zones descripted below, and you can set the styles of them all, passing a class name for each one.
	 
	 >> You may set an opacity transition when confirm box appears and disappears and choose an overlay type. (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 which permits to customize the confirm
	[/Properties]
	
	[Options]
		zones : an object which contains the confirm zones
		buttons : an object which contains the buttons css classes
		text : an object which contains the buttons contents
		height : the confirm height. Default is 'auto'
		width : the confirm width. Default is '300px'
		opacify : if true the confirm appears and disappears with an opacity transition. Default is true
		content : 'text' or 'html', the content types of the confirm title, the confirm box and the confirm buttons. Default is 'text'
		draggable : if true the confirm will be draggable. Default is true
		overlay : the type of the overlay. 'lighten', 'darken' or false (default)
		onConfirm : function fired when users confirm
		onCancel : function fired when users cancel
	[/Options]
	
	>> Zones:
		[List]
			[li] confirmbox: is the box that contains the other zones
			[li] confirmhead: is the header of the confirm box. (contains the title)
			[li] confirmbody: is the main content of the confirm box
	 		[li] buttonBox: (id: 'customConfirmButtonBox') the zone which contains the confirm button
		[/List]
	
	>> Buttons:
		[List]
			[li] confirmButton: the confirm button class name
			[li] closeButton: the close button class name
			[li] cancelButton: the cancel button class name
		[/List]
		
	>> Text:
		[List]
			[li] buttonText: the text of the confirm button. Defaults to 'OK'
			[li] closeButtonText: the text of the close button. Defaults to 'X'
			[li] cancelButtonText: the text of the cancel button. Defaults to 'Cancel'
		[/List]
	
	[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({
						   
	Extends: Custom,
		
	Implements: [Options, Events, Overlay],
		
	options: {
		height: 'auto',
		width: '300px',
		overlay: false,
		opacify: true,
		draggable: true,
		content: 'text',
		text: {
			buttonText: 'OK',
			closeButtonText: 'X',
			cancelButtonText: 'Cancel'
		},
		zones: {
			confirmbox: null,
			confirmhead: null,
			confirmbody: null,
			buttonBox: ''
		},
		buttons: {
			closeButton: '',
			confirmButton: '',
			cancelButton: ''
		},
		onConfirm: $empty,
		onCancel: $empty
	},
	
	initialize: function(title, text, options) {
		this.title = title;
		this.text = text;
		this.setOptions(options);
		this.confirmbox = new Element('div', {
			'id': 'customConfirm',
			'styles': {
				'position': (!Browser.Engine.trident4) ? 'fixed' : 'absolute',
				'top': '50%',
				'left': '50%',
				'z-index': 1000,
				'height': this.options.height,
				'width': this.options.width
			}
		});
		this.createOverlay('customConfirmOverlay', this.options.overlay);
		this.createFullPage('customConfirmfullpage');
		this.mechanize();
		this.fx = new Fx.Tween(this.confirmbox, 'opacity', {duration:1000});
		if(this.options.initialize) this.options.initialize.call(this);
	},
	
	/*
	Method: create
	Description:  creates the custom confirm 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.zones['confirmbox']) this.confirmbox.addClass(this.options.zones['confirmbox']);
		
		this.head = new Element('div').injectInside(this.confirmbox);
		if(this.options.zones.confirmhead) this.head.addClass(this.options.zones['confirmhead']);
		this.head.set(this.options.content, this.title);
		
		this.closebutton = new Element('a', {'id': 'customConfirmCloseButton', 'class': this.options.buttons.closeButton}).injectInside(this.head);
		this.closebutton.setProperty('href', '#');
		this.closebutton.set(this.options.content, this.options.text.closeButtonText);
		this.closebutton.addEvent('click', function(event) {
			event.preventDefault();
		});
		this.closebutton.addEvent('click', this.cancelRemove.bind(this));
		
		this.content = new Element('div').injectInside(this.confirmbox);
		if(this.options.zones.confirmbody) this.content.addClass(this.options.zones['confirmbody']);
		this.content.set(this.options.content, this.text);
	
		this.closebox = new Element('div', {'id': 'customConfirmButtonBox', 'class': this.options.zones.buttonBox}).injectInside(this.confirmbox);
	
		this.button = new Element('a', {'id': 'customConfirmButton', 'class': this.options.buttons.confirmButton}).injectInside(this.closebox);
		this.button.setProperty('href', '#');
		this.button.set(this.options.content, this.options.text.buttonText);
		this.button.addEvent('click', function(event) {
			event.preventDefault();
		});
		
		this.button.addEvent('click', this.confirmRemove.bind(this));
		
		this.cancelButton = new Element('a', {'id': 'customConfirmCancelButton', 'class': this.options.buttons.cancelButton}).injectInside(this.closebox);
		this.cancelButton.setProperty('href', '#');
		this.button.set(this.options.content, this.options.text.cancelButtonText);
		this.cancelButton.addEvent('click', function(event) {
			event.preventDefault();
		});
		
		this.cancelButton.addEvent('click', this.cancelRemove.bind(this));
	},
	
	customize: function() {
		if($('customConfrim'))  return;
		
		if(this.options.opacify)	this.confirmbox.set('opacity', 0);
		
		this.confirmbox.injectInside(this.fullpage);
		this.fullpage.injectInside($E('body'));
		this.overlay.injectInside($E('body'));
		
		var dimensions = this.dimensions = { 
			top: this.confirmbox.getSize().y/2,
			left: this.confirmbox.getSize().x/2
		};
		
		this.confirmbox.setStyles({
			'margin-left': -dimensions.left,
			'margin-top': -dimensions.top,
			'top': '50%',
			'left': '50%'
		});
		
		if(this.options.opacify)	this.fx.start(1);
		
		if(this.options.draggable) new Drag.Move(this.confirmbox, { container: this.fullpage });
	},
	
	remove: function() {
		this.confirmbox.remove();
		this.fullpage.remove();
		this.overlay.remove();
	},
	
	checkremove: function() {
		if(this.options.opacify) {
			this.fx.start(0).chain(function() {
				this.remove();
			}.bind(this));
		}
		else {
			this.remove();
		}
	},
	
	confirmRemove: function() {
		this.fireEvent('onConfirm');
		this.checkremove();
	},
	
	cancelRemove: function() {
		this.fireEvent('onCancel');
		this.checkremove();
	}
	
	/*
	Method: setText
	Description:  set the text of the custom confirm
	[Example]  
		> // change the previous text
		> cc.setText('Custom Confirm with some new text');
	[/Example]
	*/
	
	/*
	Method: setTitle
	Description:  set the title of the custom confirm
	[Example]  
		> // change the previous title
		> cc.setTitle('A new Custom Confirm');
	[/Example]
	*/
});



/*
	Filename: smooth_scrolling.js
	
	Contains: Class SmoothScrolling
	
	Requires: nothing
	
	Filedescription: Allows you to 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: Class Fx.Scroll
	
	Constructor: new SmoothScrolling (options)
	
	[Properties] 
		options - the Fx.Scroll options plus some other options
	[/Properties]
	
	[Options]
		links : a string which specify the links to apply the effect to. Default is 'a' (all anchors)
		preventDefault : if true the default will be prevented on click events
		wheelStops : if false the wheel movement doesn't cause the scroll stop. Default is true
	[/Options]
	
	[Methods]
		create -- creates the smooth scrolling for either all anchors of the page or only specified anchors
	[/Methods]
*/

var SmoothScrolling = new Class ({
								 
	Extends: Fx.Scroll,
	
	options: {
		links: 'a',
		preventDefault: false
	},
	   
	initialize: function(options) {
		this.parent(window, options);
		if(this.options.initialize) this.options.intialize.call(this);
	},
    
	/*
	Method: create
	Description:  creates the smooth scrolling for either all anchors of the page or only specified anchors
	[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.options.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));
					if(this.options.preventDefault) lnk.addEvent('click', function(event) { event.preventDefault(); });
			}
		}
	  }, this);
	},
	
	makeScroll: function(lnk) {
		this.start(0, $(document.body).getElement('a[name=' + lnk.targetName + ']').getTop());
	}
	
});