

String.prototype.decodeNucleuParams = function (_params) {
	var value = this;
	for(var param in _params) {
		value = value.replace(new RegExp("\\$" + param, "g"), _params[param]);
	}
	return value;
}

var redirectToUrl = function(url) {
	location.href=url;
}

var Redirector = Class.create();

Object.extend(Redirector.prototype, {
	initialize: function(fieldId, url) {
		this.field = $(fieldId);
		this.url = url;
		this.field.observe('click', this.redirect.bindAsEventListener(this));
	},
	
	redirect: function() {
		redirectToUrl(this.url);//location.href=this.url;
	}
});

/*
 * Support functions to bidirectional select 
 */
 
var BidirectionalSelect = Class.create();
 
 
Object.extend(BidirectionalSelect.prototype, {
    
    options: {
    	rightToLeftURL: null,
    	leftToRightURL: null,
    	leftSearchInput: null,
    	rightSearchInput: null,
    	generic_ajax_params: {}
    },
    
    initialize: function(leftSelect, rightSelect, options){
        this.leftSelect = $(leftSelect);
        this.rightSelect = $(rightSelect);
        this.selectedItemsToMove = new Array();
        this.originalBox = null;
        this.destinyBox = null;
        Object.extend(this.options, options || {});
        this.pendingRequests = {};
    },
    
    setToLeftButton: function(button) {
    	this.toLeftButton = $(button);
    	this.toLeftButton.observe("click", this.rightToLeft.bindAsEventListener(this, -1));
    },
    
    setToRightButton: function(button) {
    	this.toRightButton = $(button);
    	this.toRightButton.observe("click", this.leftToRight.bindAsEventListener(this, -1));
    },
    
    setLeftSearchInput: function(input) {
    	this.leftSearchInput = $(input);
    	this.leftSearchInput.observe("keyup", this.searchLeft.bindAsEventListener(this, -1));
    },
    
    setRightSearchInput: function(input) {
    	this.rightSearchInput = $(input);
    	this.rightSearchInput.observe("keyup", this.searchRight.bindAsEventListener(this, -1));
    },
    
    searchLeft: function() {
    	
    },
    
    searchRight: function() {
    	var pattern = this.rightSearchInput.getValue().toLowerCase();
    	$A(this.rightSelect.options).each(
    		function(element) {
    			if (pattern == "" || element.text.toLowerCase().include(pattern)) {
    				element.show();
    			}
    			else {
    				element.hide();
    			}
    		}
    	);
    	
    },
    
    rightToLeft: function(event) {
    	var element = Event.element(event);
    	var selectedValues = this.rightSelect.getValue();//$F(this.rightSelect);
    	if(selectedValues && selectedValues.length > 0) {
	    	var selectedOptions = $A(this.rightSelect.options).findAll (
	    		function(option) {
	    			return option.selected;
	    		}
	    	);
	    	var strHash = randomStr();
	    	this.pendingRequests[strHash] = selectedOptions;
	    	
	        var ajax_options = Object.clone(this.options.generic_ajax_params);
	        ajax_options[this.rightSelect.name] = selectedValues;
	    	new Ajax.Request(this.options.rightToLeftURL, {
	    		method: 'get',
				parameters: ajax_options,
			  	onSuccess: function(transport) {
			  		if (transport.responseJSON.addOper == 'success')
			  			this.moveItems(this.leftSelect, strHash);
			  	}.bindAsEventListener(this, -1)
			});
    	}
	    Event.stop(event);
    },
    
    leftToRight: function(event) {
    	var element = Event.element(event);
    	var selectedValues = this.leftSelect.getValue();//$F(this.leftSelect);
    	if(selectedValues && selectedValues.length > 0) {
	    	var selectedOptions = $A(this.leftSelect.options).findAll (
	    		function(option) {
	    			return option.selected;
	    		}
	    	);
	    	var strHash = randomStr();
	    	this.pendingRequests[strHash] = selectedOptions;
	        var ajax_options = Object.clone(this.options.generic_ajax_params);
	        ajax_options[this.leftSelect.name] = selectedValues;
	    	new Ajax.Request(this.options.leftToRightURL, {
	    		method: 'get',
				parameters: ajax_options,
			  	onSuccess: function(transport) {
			  		if (transport.responseJSON.removeOper == 'success')
			  			this.moveItems(this.rightSelect, strHash);
			  	}.bindAsEventListener(this, -1),
			  	onFailure: function(transport) {
			  		this.pendingRequests[strHash] = null;
			  	}
			});
    	}
	    Event.stop(event);
    },
    
    moveItems: function(destBox, strHash) {
    	var elements = this.pendingRequests[strHash];
    	for (var i = 0; i < elements.length; i++) {
    		destBox.insert(elements[i].show());
    	}
		this.pendingRequests[strHash] = null;
    }
});

var SortableList = Class.create();

Object.extend(SortableList.prototype, {
    options: {
    },
    
    initialize: function(elementID, url, options) {
        Object.extend(this.options, options || {});
        this.elementID = elementID;
    	this.options.onUpdate = this.sortableUpdate.bindAsEventListener(this);
    	Sortable.create(elementID, this.options);
    },
    
    sortableUpdate: function(container) {
    	//alert('contentor');
    	container.select('.draggable').each(function(element) {
    		if(element.up() == container)
    			alert(element.id);
    	})
    	alert(Sortable.serialize(this.elementID));
    }
});

var Droppable = Class.create();

Object.extend(Droppable.prototype, {
    options: {
    	hoverclass: 'alerta'
    },
    
    initialize: function(elementID, url, options) {
    	this.elementID = elementID;
        Object.extend(this.options, options || {});
    	this.options.onDrop = this.onDrop.bindAsEventListener(this);
    	this.options.accept = ['draggable'];
    	Droppables.add(elementID, this.options);
    },
    
    onDrop: function(draggable, droppable) {
    	alert('contentor');
    	$(this.elementID).insert(draggable);
    	/*container.select('.draggable').each(function(element) {
    		if(element.up() == container)
    			alert(element.id);
    	})*/
    	//alert(container);
    }
});

/*
String.prototype.namespace = function(separator){
  this.split(separator || '.').inject(window, function(parent, child) {
    var o = parent[child] = { }; return o;
  })
}

'Asi.Window'.namespace();
*/
var Asi = {
	Nucleu: new Object(),
	External: new Object()
};


/*Asi.prototype.Nucleu = function() {
	return {};
}();*/

Asi.Nucleu.Window = Class.create();

Asi.Nucleu.Window.currentWindows = [];

Object.extend(Asi.Nucleu.Window.prototype, {
	/*
	 ! Attention! we shall not place options as an attribute of the class, as it will behave as a static method...
	 */
    /*
     * Also, it should be possible to send an URL and parameters, so the contents could
     * come from an AJAX request
     * It would be nice to make some descendant objects: Assisted Filling, Calendar...
     * Size of the window
     * Initial position: centered or other... Calendar is an example of "other"
     * ESC key should close the window...
     */
    __beforeInit: function() {
    },
    
    __afterInit: function() {
    	if(this.options.showAtStart)
    		this.show();
    	else if(this.options.windowID)
    		$(this.options.windowID).hide();
    },
    
    //currentWindows: [],
     
    initialize: function(element, options) {
    	this.__beforeInit();
    	if(element)
    		this.callerElement = $(element);
    	this.callerElement = this.callerElement?this.callerElement:null;
        this.options = Object.extend({
            title: null,
            windowID: null,
            cssClass: '',
            parameters: {},
            draggable: false,
            overlay: true,
            overlayOpacity: 0.7,
            onBeforeShow: function() {},
            onAfterShow: function() {},
            onBeforeHide: function() {},
            onAfterHide: function() {},
            loadAjaxRequest: null,
            onLoadFunction: function() {},
            closeWindowClasses: '.close-window',
            closeKeys: [Event.KEY_ESC],
            showAtStart: true,
            loadOnShow: true,
            windowLocation: null // {top: 'bottom + 1', left: 'right - 5', right: '10', bottom: 'bottom', baseElement: element, unit: 'px'}
        }, options || {});
        if(this.options.windowLocation && this.options.windowLocation.baseElement)
        	this.options.windowLocation.baseElement = $(this.options.windowLocation.baseElement);
        /*if(this.options.overlayOpacity == null)
        	this.options.overlayOpacity = 0.7;*/
        this.__afterInit();
        this.loaded = false;
    },
    
    create: function() {
    	
    },
    
    keyPressed: function(event) {
    	var currWindow = Asi.Nucleu.Window.currentWindows[Asi.Nucleu.Window.currentWindows.length - 1];
    	var closeKeysLen = currWindow.options.closeKeys.length;
    	// Must check if the pressed key is on the current window key-list
		for (var idx = 0; idx < closeKeysLen; idx++)
			if(event.keyCode == currWindow.options.closeKeys[idx]) { currWindow.destroy(); event.stop();/*alert(this.callerElement); */event.stop(); break; };
		
    	/*
    	// Must do this, so that we can stop observing this event
    	var closeKeysLen = this.options.closeKeys.length;
    	//var currWindow = Asi.Nucleu.Window.currentWindows.length[Asi.Nucleu.Window.currentWindows.length - 1];
    	var currWindow = this.currentWindows[this.currentWindows.length - 1];
    	adrtxWindows = this.currentWindows;
    	if(this != currWindow)
    		return;
    	alert(event);
    	event.stop();
		for (var idx = 0; idx < closeKeysLen; idx++)
			if(event.keyCode == this.options.closeKeys[idx]) { this.destroy(); alert(this.callerElement); event.stop(); break; };
		*/
    },
    
    show: function() {
    	// First let's take focus away from the element
    	if(this.callerElement)
    		this.callerElement.blur();
    	this.options.onBeforeShow(this);
    	//this.element.show();
    	if(this.options.overlay) {
			this.overlay = new Element("div", { 'class': "back_overlay" /*, opacity: 0.5*/ });
			this.overlay.observe("click", this.destroy.bindAsEventListener(this), false);
			this.overlay.hide();
	        $$('body')[0].insert(this.overlay);
			this.overlay.setOpacity(this.options.overlayOpacity).show();
			// This has to have the scriptaculous effects lib!
			this.overlay.forceRerendering();
    	}
    	
    	if(Asi.Nucleu.Window.currentWindows.length == 0) {
			Event.observe(document, 'keydown', this.keyPressed);
    	}
    	
    	/*
    	if(this.options.closeKeys) {
    		this.keyPressedFunc = this.keyPressed.bindAsEventListener(this);
    		Event.observe(document, 'keydown', this.keyPressedFunc);
    	}
    	*/
    	
    	this.removeWindow = false;
    	
		// The window element...
    	if(!this.options.windowID) {
			this.windowElement = new Element("div", { 'class': 'window ' + this.options.cssClass});
			this.windowElement.windowObj = this;
			var leftLoc = null, topLoc = null, rightLoc = null, bottomLoc = null, unit = 'px';
			var topLoc = (this.windowElement.cumulativeOffset().top - this.windowElement.getHeight() / 2) + "px";
	        $$('body')[0].insert(this.windowElement);
	        this.removeWindow = true;
    	}
    	else {
    		this.windowElement = $(this.options.windowID);
    		this.windowElement.show();
    	}
        if (this.options.windowLocation && !this.options.windowID) {
			var baseLocTop = this.options.windowLocation.top, baseLocBottom = this.options.windowLocation.bottom;
			var baseLocLeft = this.options.windowLocation.left, baseLocRight = this.options.windowLocation.right;
			var refOffset = null, refHeight = null, refWidth = null;
			if (this.options.windowLocation.baseElement) {
				refOffset = this.options.windowLocation.baseElement.cumulativeOffset();
				refHeight = this.options.windowLocation.baseElement.getHeight();
				refWidth = this.options.windowLocation.baseElement.getWidth();
				baseLocTop = baseLocTop?(baseLocTop.replace(/top/g, refOffset.top).replace(/left/g, refOffset.left).replace(/bottom/g, (refOffset.top + refHeight)).replace(/right/g, (refOffset.left + refWidth))):null;
				baseLocLeft = baseLocLeft?(baseLocLeft.replace(/top/g, refOffset.top).replace(/left/g, refOffset.left).replace(/bottom/g, (refOffset.top + refHeight)).replace(/right/g, (refOffset.left + refWidth))):null;
				baseLocBottom = baseLocBottom?(baseLocBottom.replace(/top/g, refOffset.top).replace(/left/g, refOffset.left).replace(/bottom/g, (refOffset.top + refHeight)).replace(/right/g, (refOffset.left + refWidth))):null;
				baseLocRight = baseLocRight?(baseLocRight.replace(/top/g, refOffset.top).replace(/left/g, refOffset.left).replace(/bottom/g, (refOffset.top + refHeight)).replace(/right/g, (refOffset.left + refWidth))):null;
			}
			if (this.options.windowLocation.unit)
				unit = this.options.windowLocation.unit;
			topLoc = baseLocTop?(eval(baseLocTop) + unit):null;
			leftLoc = baseLocLeft?(eval(baseLocLeft) + unit):null;
			bottomLoc = baseLocBottom?(eval(baseLocBottom) + unit):null;
			rightLoc = baseLocRight?(eval(baseLocRight) + unit):null;
		}
		if(!this.options.windowID && (!this.options.windowLocation || (!leftLoc && !rightLoc))) {
			leftLoc = (this.windowElement.cumulativeOffset().left - this.windowElement.getWidth() / 2) + unit;
		}
		if(!this.options.windowID && (!this.options.windowLocation || (!topLoc && !bottomLoc))) {
			topLoc = (this.windowElement.cumulativeOffset().top - this.windowElement.getHeight() / 2) + unit;
		}
		if(!this.options.windowID) {
			if (leftLoc)
				this.windowElement.setStyle({
		        	left: leftLoc
		        });
			if (topLoc)
				this.windowElement.setStyle({
		        	top: topLoc
		        });
			if (rightLoc)
				this.windowElement.setStyle({
		        	right: rightLoc
		        });
			if (bottomLoc)
				this.windowElement.setStyle({
		        	bottom: bottomLoc
		        });
		        
	        // Let's position the window inside the screen... 
	        if (parseInt(this.windowElement.getStyle('left')) < 0)
	        	this.windowElement.setStyle({left: '10px'});
	        if (parseInt(this.windowElement.getStyle('top')) < 0)
	        	this.windowElement.setStyle({top: '10px'});
	        if(this.options.draggable)
	        	new Draggable(this.windowElement);
		}
		this.opened = true;
        if(this.options.loadAjaxRequest) {
        	if(this.options.loadOnShow || !this.loaded)
	        	new Ajax.Request(this.options.loadAjaxRequest.uri, {
	        		parameters: (this.options.loadAjaxRequest.parameters || {}),
	        		onSuccess: this.ajaxLoadSuccess.bindAsEventListener(this),
	        		onFailure: this.ajaxLoadFailure.bindAsEventListener(this)
	        	});
        }
        else {
            this.loaded = true;
        	if(this.options.loadOnShow || !this.loaded)
        		this.options.onLoadFunction(this);
    		this.options.onAfterShow(this);
        }
        if (!this.windowElement.windowObj)
        	this.windowElement.windowObj = this;
        Asi.Nucleu.Window.currentWindows.remove(this);
        Asi.Nucleu.Window.currentWindows.append(this);
    	return this;
    	/*Asi.Nucleu.Window.currentWindows.remove(this);
    	Asi.Nucleu.Window.currentWindows.append(this);*/
    },
    
    ajaxLoadSuccess: function(transport) {
        this.loaded = true;
    	this.windowElement.update(transport.responseText.stripScripts());
    	if(this.options.loadAjaxRequest.evalJS) {
    		var scripts = transport.responseText.extractScripts();
    		for(var i = 0; i < scripts.length; i++) {
    			eval(scripts[i]);
    		}
    	}
    		//transport.responseText.evalScripts();
    	this.options.onAfterShow(this);
    	var closeWindowElements = this.windowElement.select(this.options.closeWindowClasses);
    	for (var i = 0; i < closeWindowElements.length; i++) {
    		closeWindowElements[i].observe('click', this.hide.bindAsEventListener(this));
    	}
		//alert('end2');
    },
    
    ajaxLoadFailure: function() {
    	this.options.onAfterShow(this);
    },
    
    hide: function() {
    	this.options.onBeforeHide(this);
    	this.windowElement.hide();
    	if(this.options.overlay) {
    		this.overlay.hide();
    	}

    	
    	/*if(this.options.closeKeys)
    		Event.stopObserving(document, 'keydown', this.keyPressedFunc);*/
		this.opened = false;
    	this.options.onAfterHide(this);
    	// Let's give focus back to the caller element.
    	if(this.callerElement)
    		this.callerElement.focus();
    	Asi.Nucleu.Window.currentWindows.remove(this);
    	if(Asi.Nucleu.Window.currentWindows.length == 0) {
			Event.stopObserving(document, 'keydown', this.keyPressed);
    	}
    	
    	return this;
    	//Asi.Nucleu.Window.currentWindows.remove(this);
    },
    
    toggle: function(event) {
    	this.opened?this.hide():this.show();
    	return this;
    },
    
    destroy: function() {
    	this.hide();
    	/*this.windowElement.hide();
    	this.overlay.hide();*/
    	if(this.removeWindow) {
    		this.windowElement.remove();
    	}
    	if(this.options.overlay) {
    		this.overlay.remove();
    	}
    	//delete this.windowElement;
    	//delete this.overlay;
    	if(this.callerElement)
    		this.callerElement.focus();
    }
});

Asi.Nucleu.newWindow = function(event, options) {
	var element = Event.element(event);
	return new Asi.Nucleu.Window(element, options);
};

Asi.Nucleu.errorWindow = function(element, message, options) {
	new Asi.Nucleu.Window(element, {
		cssClass: 'window error',
		onLoadFunction: function(obj) {
			var windowContent = '';
			windowContent = '<p>Atenção</p>';
			windowContent += '<div>' + message;
			windowContent += '</div>';
			obj.windowElement.innerHTML = windowContent;
		}.bindAsEventListener(this)
	});
}

Asi.Nucleu.getParentWindowObject = function(obj) {
	return obj.up('div.window').windowObj;
};

Asi.Nucleu.Element = new Object();

Asi.Nucleu.Element.Methods = {
	getMyWindow: function(obj) {
		var element = $(this);
		while(element!=document && !element.windowObj)
			element = element.up();
		if (element == document)
			return null; // No window found... Nothing to return
		else
			return element;
	}
}

Object.extend(Element.prototype, Asi.Nucleu.Element.Methods);


Asi.Nucleu.Sortable = Class.create();


Object.extend(Asi.Nucleu.Sortable.prototype, {
	initialize: function(listId, options) {
		if(!options.onChange)
			options.onChange = this.onChangeDefault;
		options.onChange = options.onChange.bind(this);
		if(!options.onUpdate && options.submitUrl)
			options.onUpdate = this.onUpdateDefault;
		if(options.onUpdate)
			options.onUpdate = options.onUpdate.bind(this);
		try {
			//alert(options.scroll);
			if(options.scroll && typeof options.scroll == 'function')
				options.scroll = options.scroll().identify();
			//alert(options.scroll);
			}
		catch(e) {alert(e);};
		this.element = $(listId);
		this.options = options;
		Sortable.create(listId,options);
		
		this.initialOrder = Element.findChildren($(listId), options.only, options.tree ? true : false, options.tag || 'li');
		//alert(this.initialOrder);
	},
	
	destroy: function(listId) {
		if (listId)
			Sortable.destroy(listId);
		else
			Sortable.destroy(this.listId);
	},
	
	onChangeDefault: function(affectedElement) {
		this.affectedElement = affectedElement;
	},
	
	onUpdateDefault: function(element) {
		//Asi.Nucleu.Logger.add("Ordem inicial = " + this.initialOrder);
		this.actualOrder = Element.findChildren(this.element, this.options.only, this.options.tree ? true : false, this.options.tag || 'li');
		//Asi.Nucleu.Logger.add("Ordem actual = " + this.actualOrder);
		var originalPos = this.initialOrder.indexOf(this.affectedElement);
		var newPos = this.actualOrder.indexOf(this.affectedElement);
		var currentOrder = []
		for(var i = 0; i < this.actualOrder.length; i++)
			currentOrder[i] = this.actualOrder[i].getAttribute('menu_option_id');
		new Ajax.Request(this.options.submitUrl, {
			method: 'get',
			parameters: {'ordered_options': currentOrder, 'menu_option': this.affectedElement.getAttribute('menu_option_id')},
			onSuccess: function() {
				null;
				// If we disabled the ability to move the menu options during the request, we could re-enable it here 
			},
			onFailure: function() {
				if (originalPos == 0)
					this.initialOrder[1].insert({'before':this.affectedElement});
				else
					this.initialOrder[originalPos - 1].insert({'after': this.affectedElement});
			}.bind(this)
		});
		//Asi.Nucleu.Logger.add("newPos = " + newPos);
	}
});

Asi.Nucleu.newSortable = function(listId, options) {
	new Sortable(listId, options);
}

Asi.Nucleu.executeFunction = function() {
	var args = $A(arguments).slice(0);
	var event = args.shift();
	var functAndArgs = args.shift().slice(0);
	var functionName = functAndArgs.shift();
	return functionName.apply(this, [event].concat(functAndArgs));
}

Asi.Nucleu.registerBindedEvent = function() {
	var args = $A(arguments);
	var element = args.shift();
	var event = args.shift();
	var thisObj = args.shift();
	$(element).observe(event, Asi.Nucleu.executeFunction.bindAsEventListener(thisObj, args));
}

Asi.Nucleu.bindedFunction = function() {
	//return;
	var args = $A(arguments);
	var funct = args.shift();
	return function() {
		var local_args = $A(arguments);
		return funct.apply(this, args.concat(local_args));
	}
	return funct.bind(this, args);
}

Asi.Nucleu.bindedFunctionToObject = function() {
	//return;
	var args = $A(arguments);
	var funct = args.shift();
	var thisObj = args.shift();
	return function() {
		var local_args = $A(arguments);
		return funct.apply(thisObj, args.concat(local_args));
	}
	return funct.bind(this, args);
}

Asi.Nucleu.cssClassSwitcher = function(event, obj, class1, class2) {
	var object = $(obj);
	var classToAdd = object.hasClassName(class1)?(class2?class2:null):class1;
	var classToRemove = object.hasClassName(class1)?class1:(class2?class2:null);
	if (classToAdd)
		object.addClassName(classToAdd);
	if (classToRemove)
		object.removeClassName(classToRemove);
};

Asi.External.setRichTextEditor = function(element, imageDir, options) {
	var ifrm = new Element('iframe');
	ifrm.id = 'hidden_iframe';
	ifrm.name = 'hidden_iframe';
	ifrm.hide();
	document.body.insert(ifrm);
	new Control.RTE(element, imageDir, options);
}

Asi.External.richTextServerImage = function(directory, callback) {
	new Ajax.Request(SITE.baseUrl + '/documentu/documents/get_files', {
			parameters: 'a=listdir&d=' + (directory || ''),
			onComplete: function(transport) {
				try {
					callback(eval('(' + transport.responseText + ')'));
				} catch(e) {
					callback({status:'error'});
				}
			}
		});
}

Asi.Nucleu.ElementExists = Class.create();

Asi.Nucleu.UserExistanceChecker = Class.create();

Object.extend(Asi.Nucleu.UserExistanceChecker.prototype, {		
    options: {
		validationElementID: null,
		requestUri: '../../nucleu/users/check_available',
		requestParams: {},
		defaultExpression: 'Validar',
		validExpression: '',
		invalidExpression: '',
		checkUsernameAjaxRequest: {uri: '', parameters: {}}
    },
    
    initialize: function(element, options) {
		this.element = element;
        Object.extend(this.options, options || {});
        if (!this.options.validationElementID)
        	this.options.validationElementID = this.element.identify() +  "_valid";
        this.element.stopObserving('focus', Asi.Nucleu.validateUserNotExists);
        this.element.observe('keyup', this.usernameChanged.bindAsEventListener(this));
    	this.validationElement = $(this.options.validationElementID);
    	if(this.validationElement)
    		throw new Asi.Nucleu.ElementExists();
    	this.validationElement = new Element("span", { 'class': "", 'id': this.options.validationElementID});
		this.validationElement.hide();
        element.up().insert(this.validationElement);
    },
    
    loadValidateMessage: function() {
    	this.validationElement.innerHTML = '<a href="' + this.options.url + '">' + this.options.defaultExpression + '</a>';
    	this.validationElement.select('a')[0].observe('click', this.checkValidUsername.bindAsEventListener(this));
    },
    
    usernameChanged: function(event) {
    	if(this.element.value) {
    		this.loadValidateMessage();
			this.validationElement.show();
		}
		else {
			this.validationElement.hide();
		}
    	event.stop();
    },
    
    checkValidUsername: function(event) {
    	var requestParams = {'username': this.element.value};
        Object.extend(requestParams, this.options.requestParams || {});
    	new Ajax.Request(this.options.requestUri, {
    		parameters: requestParams,
    		onSuccess: this.checkUsernameSuccess.bindAsEventListener(this),
    		onFailure: this.checkUsernameFailure.bindAsEventListener(this)
    	});
    	event.stop();
    },
    
    checkUsernameSuccess: function(transport) {
    	response = transport.responseJSON;
    	if (response.available)
    		this.validationElement.innerHTML = 'Utilizador válido';
    	else
    		this.validationElement.innerHTML = 'Utilizador inválido';
    },
    
    checkUsernameFailure: function(transport) {
    	// TODO: Create an error event in something like a window. And allow the user to validate again!!
    	this.validationElement.innerHTML = 'Erro no processamento do pedido!';
    }
});

Asi.Nucleu.validateUserNotExists = function(event, _options) {
	var element = Event.element(event);
	new Asi.Nucleu.UserExistanceChecker(element, _options);
}

Asi.Nucleu.Access_Group = {
	View: new Object()
}

Asi.Nucleu.Access_Group.View.changeUserState = function(event, url, options) {
	var stateBar = $(options.stateBar);
	var accepted = stateBar.hasClassName(options.acceptedClassName)?0:1;
	new Ajax.Request(url + '?access_group_id=' + options.accessGroupID + '&user_id=' + options.userID + '&accepted='+accepted, {
		onSuccess: function(transport) {
			var response = transport.responseJSON;
			var classToRemove = response.className==options.acceptedClassName?options.rejectedClassName:options.acceptedClassName;
			stateBar.removeClassName(classToRemove);
			stateBar.addClassName(response.className);
		}
	});
}

Asi.Nucleu.Access_Group.View.assocUserToGroup = function(_cells, _options, _assistedFillObj) {
	var options = {
		url: null
	};
	Object.extend(options, _options || {});
	var params = {
		'userId': _assistedFillObj.getField(_cells, 'userId')
	};
	options.url = options.url.decodeNucleuParams(params);
	
	new Ajax.Request(options.url, {
		onSuccess: function(transport) {
			var ulUserList = $$('ul.access_grp_user_lst')[0];
			var html_tmp_box = new Element('div');
			html_tmp_box.innerHTML = transport.responseText.stripScripts();
			ulUserList.insert(html_tmp_box.childElements()[0]);
			transport.responseText.evalScripts();
			html_tmp_box = null;
		}
	});
}

Asi.Nucleu.Access_Group.View.deassocUserToGroup = function(event, _options) {
	var options = {
		url: null
	};
	Object.extend(options, _options || {});
	var element = Event.element(event);
	var liEleme = element.up('li');
	
	new Ajax.Request(options.url, {
		onSuccess: function(transport) {
			liEleme.remove();
		}
	});
}

Asi.Nucleu.Table = Class.create();

Object.extend(Asi.Nucleu.Table.prototype, {
	GENERAL: 0,
	NUMBER: 1,
	DATE: 2,
	
    options: {
    	sortableClass: 'sortable-column',
    	filterableClass: 'filterable-column',
    	sortableRowsExpr: 'tbody tr',
    	colValueClass: 'col-value'
    },
    
    initialize: function(element, options) {
		this.element = $(element);
        Object.extend(this.options, options || {});
        var sortableElements = this.element.select('.' + this.options.sortableClass);
        var sortableElementsCount = sortableElements.length;
        for(var i = 0; i < sortableElementsCount; i++) {
        	this.setOrderColumn(sortableElements[i]);
        }
        
        var filterableElements = this.element.select('.' + this.options.filterableClass);
        var filterableElementsCount = filterableElements.length;
        this.colFilters = new Object();
        for(var i = 0; i < filterableElementsCount; i++) {
        	this.setFilterColumn(filterableElements[i]);
        }
    },
    
    setFilterColumn: function(element) {
    	var element = $(element);
    	if(!element.hasClassName(this.options.filterableClass))
    		element.addClassName(this.options.filterableClass);
    	var prevSib = element.up('th').previousSiblings();
    	element.colIndex = prevSib.length;
    	this.colFilters[element.colIndex] = new Object();
    	element.observe('click', this.showFilterWindow.bindAsEventListener(this));
    	
    },
    
    setOrderColumn: function(element, type, orderWay) {
    	var element = $(element);
    	if(!element.hasClassName(this.options.sortableClass))
    		element.addClassName(this.options.sortableClass);
    	var prevSib = element.previousSiblings();
    	element.colIndex = prevSib.length;
    	element.orderWay = orderWay?orderWay:1;
    	element.type = type?type:this.GENERAL;
    	element.observe('click', this.order.bindAsEventListener(this));
    },
    
    getCellValue: function(cell) {
    	var cellValue = cell.select('.' + this.options.colValueClass);
    	if(cellValue.length)
    		cellValue = cellValue[0].innerHTML;
    	else
    		cellValue = cell.innerHTML;
    	return cellValue.trim();
    },
    
    generalSort: function(colNum) {
    	return function(a, b) {
    		if(a.colValues[colNum] < b.colValues[colNum])
				return -1;
			else
				if(a.colValues[colNum] > b.colValues[colNum])
					return 1
				else
					return 0;
	    }
    },
    
    getSortedTableArray: function(column) {
    	var rows = this.element.select(this.options.sortableRowsExpr);
		var rowCount = rows.length;
	    var cols = rows[0].select('td');
	    var colCount = cols.length;
		
		var array = new Array(rowCount);
		for (var i=0; i < rowCount; i++) {
			array[i] = rows[i];
			if(!rows[i].colValues)
				rows[i].colValues = Array();
			if(!rows[i].colValues[column.colIndex]) {
				var cell = rows[i].select('td')[column.colIndex];
				rows[i].colValues[column.colIndex] = this.getCellValue(cell);
				/*
				var cellValue = cell.select('.' + this.options.colValueClass);
					//alert(cellValue);
				if(cellValue.length) {
					rows[i].colValues[element.colIndex] = cellValue[0].innerHTML;
				}
				else {
					rows[i].colValues[element.colIndex] = cell.innerHTML;
				}
				*/
			} 
		}
		
		// Invoke the correct sorting procedure...
		array.sort(eval('this.' + 'generalSort(' + column.colIndex + ')'));
		return array;
    },
    
    order: function(event) {

    	var element = Event.element(event);
    	var rows = this.element.select(this.options.sortableRowsExpr);
		var rowCount = rows.length;
    	/*
    	var rows = this.element.select(this.options.sortableRowsExpr);
		var rowCount = rows.length;
	    var cols = rows[0].select('td');
	    var colCount = cols.length;
		
		var array = new Array(rowCount);
		for (var i=0; i < rowCount; i++) {
			array[i] = rows[i];
			if(!rows[i].colValues)
				rows[i].colValues = Array();
			if(!rows[i].colValues[element.colIndex]) {
				var cell = rows[i].select('td')[element.colIndex];
				rows[i].colValues[element.colIndex] = this.getCellValue(cell);
				
			} 
		}
		
		// Invoke the correct sorting procedure...
		array.sort(eval('this.' + 'generalSort(' + element.colIndex + ')'));*/
		var array = this.getSortedTableArray(element);
		
		var body = this.element.select('tbody')[0];
		for (var i=element.orderWay?0:(rowCount - 1), count = 0; count < rowCount; count++, element.orderWay?i++:i--) {
			body.appendChild(array[i]);
		}
		// Revert the order of the column...
		element.orderWay = element.orderWay?0:1;
    },
    /*
    generalSortSimple: function(colNum) {
    	return function(a, b) {
	    	if(a[colNum] < b[colNum])
				return -1;
			else
				if(a[colNum] > b[colNum])
					return 1
				else
					return 0;
	    }
    },
    
    orderSimple: function(event) {
    	var element = Event.element(event);
    	var rows = this.element.select(this.options.sortableRowsExpr);
		var rowCount = rows.length;
	    var cols = rows[0].cells;
	    var colCount = cols.length;
		
		var array = new Array(rowCount);
		for (var i=0; i < rowCount; i++) {
			array[i] = new Array(colCount);
			var childElems = rows[i].cells;
			for (var j=0; j < colCount; j++) {
				array[i][j] = childElems[j].innerHTML;
			}
		}
		// Invoke the correct sorting procedure...
		array.sort(eval('this.' + 'generalSort'));
		//alert(element.orderWay);
		for (var i=element.orderWay?0:(rowCount - 1), count = 0; count < rowCount; count++, element.orderWay?i++:i--) {
			var childElems = rows[count].cells;
			for (var j=0; j < colCount; j++) {
				childElems[j] = array[i][j];
			}
		}
		// Revert the order of the column...
		element.orderWay = element.orderWay?0:1;
    }
    */
    executeFilter: function(element, filters) {
		var rows = this.element.select(this.options.sortableRowsExpr);
		var rowCount = rows.length;
	
		/* Lookup which rows must be hidden / shown */
		for (var i = 0; i < rowCount; i++) {
			if(!rows[i].colValues)
				rows[i].colValues = Array();
			if(!rows[i].colValues[element.colIndex]) {
				var cell = rows[i].select('td')[element.colIndex];
				rows[i].colValues[element.colIndex] = this.getCellValue(cell);
				
			}
			// If this particular filter is not set, define it as true
			if(this.colFilters[element.colIndex][rows[i].colValues[element.colIndex]] == null)
				this.colFilters[element.colIndex][rows[i].colValues[element.colIndex]] = true;
			if (!filters[rows[i].colValues[element.colIndex]]) {
				
				if (!rows[i].activeFiltersCount) {
					rows[i].activeFiltersCount = 0;
				}
				if(this.colFilters[element.colIndex][rows[i].colValues[element.colIndex]])
					rows[i].activeFiltersCount++;
				
				if(rows[i].activeFiltersCount == 1)
					rows[i].hide();
			}
			else {
				if(this.colFilters[element.colIndex][rows[i].colValues[element.colIndex]] == false)
					rows[i].activeFiltersCount--;
				else if (!rows[i].activeFiltersCount)
					rows[i].activeFiltersCount = 0;
				if (rows[i].activeFiltersCount == 0)
					rows[i].show();
			}
		}
		for(var filter in filters) {
			this.colFilters[element.colIndex][filter] = filters[filter];
		}
    },
    
    loadFilterLines: function(columnHeader) {
		var exists = false;
		var lastValue = '';
		var colNum = columnHeader.colIndex;
		
		for(var filter in this.colFilters[colNum]) {
			exists = true;
			break;
		}
		if (!exists) {
			var array = this.getSortedTableArray(columnHeader);
			var arrayLength = array.length;
			for(var i = 0; i < arrayLength; i++) {
				if (lastValue != array[i].colValues[colNum]) {
					this.colFilters[colNum][array[i].colValues[colNum]] = true;
					lastValue = array[i].colValues[colNum];
				}
			}
		}
		
	},
    
    showFilterWindow: function(event) {
    	event.stop();
    	var element = Event.element(event);
    	var columnHeader = element.up('th');
    	new Asi.Nucleu.Window(element, {
    		cssClass: 'window filter-window',
    		windowLocation: {top: 'bottom', left: 'left', unit: 'px', baseElement: columnHeader},
    		onLoadFunction: function(obj) {
				var windowContent = '';
				windowContent = '<ul>';
				this.loadFilterLines(columnHeader);
				for(var filter in this.colFilters[columnHeader.colIndex]) {
					windowContent += ('<li class="filter-value"><input type="checkbox" name="selector" value="' + filter/*array[i].colValues[columnHeader.colIndex]*/ + '"' + (this.colFilters[columnHeader.colIndex][filter]?' checked="checked"':'') /*(this.colFilters[element.colIndex][array[i].colValues[columnHeader.colIndex]]?' checked="checked"':'')*/ + ' class="selector" />' + filter/*array[i].colValues[columnHeader.colIndex]*/ + '</li>');
				}
				windowContent += '</ul><p class="filter-buttons">';
				windowContent += '<input name="apply" type="button" value="Aplicar" />';
				windowContent += '</p>';
				obj.windowElement.innerHTML = windowContent;
				obj.windowElement.select('input[name="apply"]')[0].observe('click', function(event) {
					var htmlFilters = obj.windowElement.select('li.filter-value > input');
					var filterCount = htmlFilters.length;
					var filters = {};
					for(var i = 0; i < filterCount; i++) {
						filters[htmlFilters[i].value] = (htmlFilters[i].checked);
					}
					this.executeFilter(columnHeader, filters);
					obj.destroy();
				}.bindAsEventListener(this));
    		}.bindAsEventListener(this)
    	});
    }
});
Asi.Nucleu.Droppable = Class.create();

Object.extend(Asi.Nucleu.Droppable.prototype, {		
    options: {
        accept: ['draggable'],
        accept: null,
        hoverclass : null,
        overlap: null,
        onHover: function() {},
        onDrop: null,
        url: null
   },
     
    initialize: function(element, options) {
		this.callerElement = $(element);
        Object.extend(this.options, options || {});
        if (!this.options.onHover)
			this.options.onHover = this.onHover.bind(this);
        	//this.options.onHover = this.options.onHover.bind(this);
        if (!this.options.onDrop)
        	this.options.onDrop = this.onDrop.bind(this);
    	Droppables.add(element, this.options);
    },
    
    onDrop: function() {
    	alert(this.options.url);
    },
    
    onHover: function() {
    	
    }
});

Asi.Nucleu.addCss = function(href) {
	var header = $$('head')[0];
	if($$('link[href="' + href + '"]').length == 0) {
		header.insert(new Element('link', {href: href, type: "text/css", rel: "stylesheet", media: "screen"}));
	}
};

Asi.Nucleu.loadedScripts = {};

Asi.Nucleu.addScript = function(src) {
	var header = $$('head')[0];
	if($$('script[src="' + src + '"]').length == 0 && !Asi.Nucleu.loadedScripts[src]) {
		new Ajax.Request(src, {
			  asynchronous: false,
			  method: 'get',
			  evalJS: false,
			  onSuccess: function(transp) {
				var script = new Element('script', {type: "text/javascript"});
				//alert('trasporte = ' + transp.responseText);
				script.update(transp.responseText);
				header.insert(script);
				Asi.Nucleu.loadedScripts[src] = true;
			  }
			});
	}
};

Asi.Nucleu.FormRequest = Class.create();

Object.extend(Asi.Nucleu.FormRequest.prototype, {
    initialize: function(formElement, event, options) {
		this.formElement = $(formElement);
		//try {
		this.options = Object.extend({
        	onSuccess: this.defaultSuccess,
        	onFailire: function() {},
        	onComplete: function() {},
        	substituteElement: null,
        	evalJS: true,
        	eventStop: true
        }, options || {});
        /*} catch(e) {
        	alert('Erro!');
    	}*/

        if(this.options.eventStop)
        	event.stop();

		////alert(this.options.onSuccess);
        //try {
    	this.formElement.request({
    		onSuccess: this.options.onSuccess?this.options.onSuccess.bindAsEventListener(this):null,
    		onFailure: this.options.onFailure?this.options.onFailure.bindAsEventListener(this):null,
    		onComplete: this.options.onComplete?this.options.onComplete.bindAsEventListener(this):null
    	});
        /*} catch(e) {
        	alert(e);
        	z = 'teste';
    	}*/
        //x = this.formElement.method.toLowerCase();
        //alert(3.5);
    },
    
    defaultSuccess: function(transport) {
		$(this.options.subsituteElement?this.options.subsituteElement:this.formElement.parentNode).update(transport.responseText.stripScripts());
	
    	if(this.options.evalJS) {
    		var scripts = transport.responseText.extractScripts();
    		for(var i = 0; i < scripts.length; i++) {
    			eval(scripts[i]);
    		}
    	}
    }
});

Asi.Nucleu.formRequest = function(event, options) {
	event.stop();
	var element = Event.element(event);
	new Asi.Nucleu.FormRequest(element, event, options);
}

Asi.Nucleu.AjaxUpdater = Class.create();

Object.extend(Asi.Nucleu.AjaxUpdater.prototype, {
    initialize: function(element, event, options) {
		this.element = $(element);
		this.options = Object.extend({
        	ajaxRequest: {
        		url: null,
        		parameters: {},
        		method: 'get'
        	},
        	responseElements: null, // This can also be {success: 'element1', failure: 'element2'}
        	onSuccess: function() {},
        	onFailire: function() {},
        	onComplete: function() {},
        	evalJS: true,
        	eventStop: true,
        	replaceElement: false,
        	insertion: null // Can also be 'top', 'bottom', 'before' or 'after'
        }, options || {});
		if(!this.options.responseElements) {
			// There are no response elements, so the reference would be this element
			if (this.options.replaceElement) {
				// This element is to be replaced, so we'll add it before first...
				this.options.insertion = 'before';
				// ... and then remove this element
				if(this.options.onComplete)
					// If there is some function already defined, we'll include it's behavior in the new function, along with the removal of the element...
					this.options.onComplete = function(event) {
						this.element.remove();
						this.options.onComplete.bind(this, event);
					}
				else
					// ... otherwise, we'll just define a now function 
					this.options.onComplete = function(event) {
						//alert(this.element.innerHTML);
						this.element.remove();
					};
			}
			else
				this.options.responseElements = this.element;
		}
        if(this.eventStop && event)
        	event.stop();
        new Ajax.Updater(this.options.responseElements?this.options.responseElements:this.element, this.options.ajaxRequest.url, {
        	method: this.options.ajaxRequest.method,
        	parameters: this.options.ajaxRequest.parameters,
        	insertion: this.options.insertion,
        	evalScripts: this.options.evalJS,
        	onSuccess: this.options.onSuccess?this.options.onSuccess.bindAsEventListener(this):null,
    		onFailure: this.options.onFailure?this.options.onFailure.bindAsEventListener(this):null,
    		onComplete: this.options.onComplete?this.options.onComplete.bindAsEventListener(this):null
    	});
    }
});

Asi.Nucleu.ajaxUpdaterEvt = function(event, options) {
	var element = Event.element(event);
	new Asi.Nucleu.AjaxUpdater(element, event, options);
}

Asi.Nucleu.ajaxUpdater = function(element, options) {
	new Asi.Nucleu.AjaxUpdater(element, null, options);
}

Asi.Nucleu.ajaxRequest = function(event, url, options) {
	new Ajax.Request(url, options);
}

Asi.Nucleu.ajaxRequestToJson = function(event, url, options) {
	var _options = Object.clone(options);
	var optKeys = Object.keys(_options);
	var optKeysLen = optKeys.length;
	for(var i = 0; i < optKeysLen; i++) {
		if(Object.isFunction(_options[optKeys[i]])) {
			_options[optKeys[i]] = function(funct, transport) {
				funct(transport.responseJSON);
			}.bind(null,options[optKeys[i]]);
		}
	}
	new Ajax.Request(url, _options);
}

Asi.Nucleu.eventAbsorver = function(event) {
	event.stop();
}

Asi.Nucleu.AutoCompleter = Class.create();

Object.extend(Asi.Nucleu.AutoCompleter.prototype, {
    initialize: function(element, resultsElement, options) {
		this.element = $(element);
		this.resultsElement = $(resultsElement);
		this.options = Object.extend({
			url: null,
			resultsElementExtraClasses: '',
			paramName: element.name,
			tokens: [],
			frequency: 0.4,
			minChars: 1,
			setWidthResultBox: null,
			selectableClass: null,
			onValueChange: null,
			onUpdateElement: null,
			onAfterUpdateElement: null,
			onBeforeRequest: null,
			requestParameters: null
		}, options);
		this.options.select = this.options.selectableClass;
		this.options.afterUpdateElement = this.options.onAfterUpdateElement;
		this.options.callback = this.options.onBeforeRequest;
		this.options.updateElement = this.options.onUpdateElement;
		if(!this.resultsElement) {
			this.resultsElement = new Element('div', {
				className: "autocomplete"
			}).hide();
			this.element.insert({after: this.resultsElement});
		};
		if (this.options.resultsElementExtraClasses) {
			this.resultsElement.addClassName(resultsElementExtraClasses);
		}
		new Ajax.Autocompleter(this.element.identify(), this.resultsElement.identify(), this.options.url, this.options);
	}
});

Asi.Nucleu.autoComplFillFieldsFactory = function(elements) {
	return function(textElem, liElem) {
		//alert(elements);
		if (elements) {
			if(typeof(elements) != 'string') {
				var keys = Object.keys(elements);
				if(keys.length > 0) {
					var keysLength = keys.length;
					for(var i = 0; i < keysLength; i++) {
						$(keys[i]).writeAttribute("value", liElem.select('.' + elements[keys[i]])[0].innerHTML);
					}
				}
			}
			else
				$(elements).writeAttribute("value", liElem.readAttribute("id"));
		}
	};
}

Asi.Nucleu.autoComplResetFieldsFactory = function(elements) {
	return function(textElem, queryString) {
		if (elements) {
			if(typeof(elements) != 'string') {
				var keys = Object.keys(elements);
				if(keys.length > 0) {
					var keysLength = keys.length;
					for(var i = 0; i < keysLength; i++) {
						$(keys[i]).writeAttribute("value", elements[keys[i]]);
					}
				}
			}
			else
				$(elements).writeAttribute("value", "");
		}
		return queryString;
	};
}

/**
 * Receives an object with operations to be executed in some element.
 */
Asi.Nucleu.jsonOperationsExecuter = function(element, operations) {
	//alert('domNodeOperationExecuter');
	//alert(element);
	//alert(operations);
	//x = element;
	var operationsLength = operations.length;
	var operElement = $(element);
	for (var operIdx = 0; operIdx < operationsLength; operIdx++) {
		var currOper = operations[operIdx];
		
		if (currOper.addClasses)
			for (var i = 0; i < currOper.addClasses.length; i++)
				operElement.addClassName(currOper.addClasses[i]);
		else if (currOper.removeClasses)
			for (var i = 0; i < currOper.removeClasses.length; i++)
				operElement.removeClassName(currOper.removeClasses[i]);
		else if (currOper.remove)
			operElement.remove();
	}
	//alert(operations[0].addClass);
}

Asi.Nucleu.Manager = {
	View: new Object()
}

Asi.Nucleu.Manager.View.changeGlobalState = function() {
	
}

Asi.Nucleu.Logger = Class.create();

Object.extend(Asi.Nucleu.Logger.prototype, {
	element: $('js_logger'),
	initialize: function() {
		if(!element)
			var element = new Element('div');
			element.addClassName('nucleu_logger');
			document.body.insert(element);
	}
});

Asi.Nucleu.Logger.add = function(message) {
	if(!Asi.Nucleu.Logger.element) {
		new Asi.Nucleu.Logger();
		Asi.Nucleu.Logger.element = new Element('div');
		Asi.Nucleu.Logger.element.addClassName('nucleu_logger');
		document.body.insert(Asi.Nucleu.Logger.element);
	}
	Asi.Nucleu.Logger.element.innerHTML += message + '<br />';
}

Asi.Nucleu.Tools = new Object();

Asi.Nucleu.Tools.defaultAlert = window.alert;

Asi.Nucleu.Tools.alert = function(value) {
	new Asi.Nucleu.Window(null, {
		cssClass: 'window alert_window',
		onLoadFunction: function(obj) {
			var windowContent = '';
			windowContent = '<p>Atenção</p>';
			windowContent += '<div>' + value;
			windowContent += '</div>';
			obj.windowElement.innerHTML = windowContent;
			/*obj.windowElement.select('input[name="apply"]')[0].observe('click', function(event) {
				var htmlFilters = obj.windowElement.select('li.filter-value > input');
				var filterCount = htmlFilters.length;
				var filters = {};
				for(var i = 0; i < filterCount; i++) {
					filters[htmlFilters[i].value] = (htmlFilters[i].checked);
				}
				this.executeFilter(columnHeader, filters);
				obj.destroy();
			}.bindAsEventListener(this));*/
		}.bindAsEventListener(this)
	});
}
/*
window.alert = Asi.Nucleu.Tools.alert;
*/
Asi.Nucleu.Tools.setDefaultAlert = function() {
	window.alert = Asi.Nucleu.Tools.defaultAlert;
}

Asi.Nucleu.Event = new Object();

Asi.Nucleu.Ajax = new Object();

Asi.Nucleu.JsonOperation = new Object();

Asi.Nucleu.JsonOperation.remove = function(jsonObject) {
	alert(this.options.element);
	alert(jsonObject);
}

Asi.Nucleu.Ajax.requestToJson = function(event, url, options) {
	var _options = Object.clone(options);
	var optKeys = Object.keys(_options);
	var optKeysLen = optKeys.length;
	for(var i = 0; i < optKeysLen; i++) {
		if(Object.isFunction(_options[optKeys[i]])) {
			_options[optKeys[i]] = function(funct, transport) {
				funct(transport.responseJSON);
			}.bind(null,options[optKeys[i]]);
		}
	}
	new Ajax.Request(url, _options);
}


Asi.Nucleu.Ajax.Requester = Class.create();

Object.extend(Asi.Nucleu.Ajax.Requester.prototype, {
    initialize: function(options) {
        new Ajax.Request(this.options.ajaxRequest.url, this.options);
    }
});

Asi.Nucleu.Ajax.requester = function(options) {
	new Asi.Nucleu.Ajax.Requester(options);
}

Asi.Nucleu.Ajax.removeObject = function(url, options) {
	var _options = Object.extend({
		confirmation: {
			ask: true,
			request: {
	    		url: null,
	    		parameters: {},
	    		method: 'get'
	    	},
	    	contents: null
		},
    	action: {
	    	request: {
	    		url: null,
	    		parameters: {},
	    		method: 'get'
	    	},
	    	options: {}
    	}
	}, options || {});
	if(_options.confirmation.ask) {
		if(_options.confirmation.contents) {
			new Asi.Nucleu.Window(null, {
	    		cssClass: 'window remove',
	    		onLoadFunction: function(obj) {
					var windowContent = '';
					windowContent = '<div class="content_alert question">Atenção</div>';
					windowContent += '<div class="message">' + _options.confirmation.contents;
					windowContent += '</div><p class="width: 0 auto 0 auto;"><input type="button" class="continue" value="Sim" /><input type="button" class="abort" value="Não" /></p>';
					obj.windowElement.innerHTML = windowContent;
					obj.windowElement.select('input.continue')[0].observe('click', function() {
						this.windowElement.update('');
						new Ajax.Request(_options.action.request.url, {
							onSuccess: function(transport) {
								alert(transport.responseJSON);
							},
							onFailure: function(transport) {
								this.destroy();
								Asi.Nucleu.errorWindow(null, 'Ocorreu um erro na eliminação do objecto.', {});
							}.bindAsEventListener(this)
						});
					}.bindAsEventListener(obj));
					obj.windowElement.select('input.abort')[0].observe('click', function() {this.destroy();}.bindAsEventListener(obj));
	    		}.bindAsEventListener(this)
	    	});
		}
		else {
			new Ajax.Request(_options.confirmation.request.url, {
	        	method: _options.confirmation.request.method,
	        	parameters: _options.confirmation.request.parameters,
	        	onSuccess: function(options, transport) {
					new Asi.Nucleu.Window(null, {
			    		cssClass: 'window remove',
			    		onLoadFunction: function(obj) {
							var windowContent = '';
							windowContent = '<div class="content_alert question">Atenção</div>';
							windowContent += '<div class="message">' + transport.responseText;
							windowContent += '</div><p><input type="button" class="continue" value="Sim" /><input type="button" class="abort" value="Não" /></p>';
							obj.windowElement.innerHTML = windowContent;
							obj.windowElement.select('input.continue')[0].observe('click', function() {alert(1);}.bindAsEventListener(this));
							obj.windowElement.select('input.abort')[0].observe('click', function() {alert(2);}.bindAsEventListener(this));
			    		}.bindAsEventListener(this)
			    	});
				}.bind(this, _options.deleteOptions),
				onFailure: function(transport) {
					Asi.Nucleu.errorWindow(null, 'Ocorreu um erro na eliminação do objecto.', {});
				}
			});
		}
	}
			
		/*loadAjaxRequest.uri, {
		parameters: (this.options.loadAjaxRequest.parameters
				
				
	if (_options.confirmation.request.url)
		new Ajax.Request(_options.confirmation.request.url, {
        	method: _options.confirmationRequest.method,
        	parameters: _options.confirmation.request.parameters,
        	onSuccess: function(options, transport) {
				new Asi.Nucleu.Window(null, {
		    		cssClass: 'window',
		    		onLoadFunction: function(obj) {
						var windowContent = '';
						windowContent = '<p>Atenção</p>';
						windowContent += '<div>' + transport.responseText;
						windowContent += '</div>';
						obj.windowElement.innerHTML = windowContent;
						
		    		}.bindAsEventListener(this)
		    	});
			}.bind(this, _options.deleteOptions),
			onFailure: function(transport) {
				Asi.Nucleu.errorWindow(null, 'Ocorreu um erro na eliminação do objecto.', {});
			}
		});*/
}

Asi.Nucleu.Event.executeHandler = function() {
	var args = $A(arguments).slice(0);
	var event = args.shift();
	var functAndArgs = args.shift().slice(0);
	var functionName = functAndArgs.shift();
	alert(functionName.length);
	return functionName.apply(this, [event].concat(functAndArgs));
}

Asi.Nucleu.Event.executeHandlerWithElement = function(event, functionRef, options) {
	var args = $A(arguments).slice(0);
	var element = args.shift().element();
	var functAndArgs = args.shift().slice(0);
	var functionName = functAndArgs.shift();
	alert(functionName.length);
	return functionName.apply(this, [element].concat(functAndArgs));
}

Asi.Nucleu.Event.executeHandlerNoEvent = function(event, functionRef, options) {
	var args = $A(arguments).slice(0);
	args.shift();
	var functAndArgs = args.shift().slice(0);
	var functionName = functAndArgs.shift();
	alert(functionName.length);
	return functionName.apply(this, functAndArgs);
}

Asi.Nucleu.Event.registerBindedEventHandler = function() {
	var args = $A(arguments);
	var element = args.shift();
	var event = args.shift();
	var funct = args.shift();
	var thisObj = args.shift();
	$(element).observe(event, funct.bindAsEventListener(thisObj, args));
}

Asi.Nucleu.Event.registerEventHandler = function () {
	var args = $A(arguments);
	var element = args.shift();
	var event = args.shift();
	var funct = args.shift();
	$(element).observe(event, funct.bindAsEventListener(this, args));
}

Asi.Nucleu.eventHandler = function(event, functionRef, options) {
	
}
