/*  Object ajaxa
/*  v 1.3
/*--------------------------------------------------------------------------*/
var ajaxa = {	
	handlers: [],
	
	elements: [],
	
	updaters: [],
	
	defaultEvent: "onclick",
	
	defaultEventForm: "onsubmit",
	
	defaultTarget: "__ajaxa_default_container",
	
	updater: Prototype.emptyFunction,
	
	execute: function (callback, time) {
		return new PeriodicalExecuter (callback, time);
	},
	
	add: function (element, name, handler, object) {
		var element = this.addElement(element);
		this.addArray(
			this.handlers,
			element
		).push({
			eventName: name,
			handlerName: handler,
			handlerObject: object
		});
	},
	
	addElement: function (element) {
		var length, index;		
		if (typeof element == "object") {
			for (var i = 0, length = element.length; i < length; i++) {
				if((index = this.getIndexElement(this.elements, element[i])) === false) {
					this.addId(element[i], (this.elements.push(element[i]) - 1));
					Object.extend(element[i], this.element);
				}
			}				
		}
		else if (typeof element == "string") {			
			if((index = this.getIndexElement(this.elements, $(element))) === false) {
				index = this.elements.push($(element)) - 1;
				this.addId($(element), index);
				Object.extend($(element), this.element);
				return index;
			}
			else {
				return index;
			}
		}
		else {			
			return element;
		}
	},
	
	addId: function (element, id) {
		element.setAttribute(
			"__this.element.id",
			element.readAttribute("__this.element.id") 
			? element.readAttribute("__this.element.id") 
			: id
		);		
	},
	
	$id: function (element) {
		return element.readAttribute("__this.element.id");
	},
	
	getIndexElement: function (elements, find) {
		var length;		
		for (var i = 0, length = elements.length; i < length; i++) {
			if (elements[i] == find) return i;
		}
		return false;
	},
	
	getElements: function () {
		return this.elements;
	},
	
	getHandleObject: function (handler) {
		var matches;		
		if (handler!=undefined && handler.length > 0) {
			if ((matches = handler.strip().match(/^(\w+)\./i))) {
				return eval(matches[1]);
			}
		}
		return this;
	},
	
	parseEvent: function (elements) {
		var matches, handle, _length, length, events, type;		
		for (var i = 0, length = elements.length; i < length; i++) {
			events = elements[i].readAttribute("event");			
			if (events != null && events.strip() != "") {
				for (var j = 0, _length = (type = events.split(";")).length; j < _length; j++) {					
					if ((matches = type[j].strip().match(/^([a-z]+)\s*(:\s*([\w\.]+)+\s*((\s*,?\s*[\w\.]+\s*)*))?$/i))) {						
						this.add(
							i, 
							matches[1], 
							eval(matches[3]!=undefined && matches[3].length > 0 
								? matches[3] 
								: this.getDefaultHandle(elements[i])),
							this.getHandleObject(matches[3])
						);						
						for (var h=0;
							matches[4]!=undefined 
							&& matches[4].length > 0 
							&& h < (handle = matches[4].strip().substr(1, matches[4].strip().length).split(",")).length;
							h++) {							
							this.add(
								i, 
								matches[1], 
								eval(handle[h]),
								this.getHandleObject(handle[h])
							);
						}
					}
				}
			}
			else {
				this.add(
					i, 
					this.getDefaultEvent(elements[i]), 
					this.getDefaultHandle(elements[i]),
					this
				);
			}
		}
	},
	
	getDefaultEvent: function (element) {
		return element.isForm()
	  		 ? this.defaultEventForm
			 : this.defaultEvent;
	},
	
	getDefaultHandle: function (element) {
		if (element.isForm() && this.form.isInputTypeFile(element)) {
			return this.form._updater;
		}
		return this._updater;
	},
	
	getTarget: function (element) {
		var target;		
		if((target = element.readAttribute("_target"))) {
			if (target == "_self") {
				if (!(target = element.readAttribute("id"))) {
					element.setAttribute(
						"id",
						(target = "__this.element.id" + this.$id(element))
					);
				}
			}			
			return target;
		}
		else {	
			return this.defaultTarget;
		}
	},
	
	setEventHandler: function (elements, handlers) {
		var handler = null, length, _length;		
		for (var i = 0, length = handlers.length; i < length; i++) {
			for (j = 0, _length = handlers[i].length; j < _length; j++) {				
				handler = handlers[i][j].handlerName.bindAsEventListener(
					handlers[i][j].handlerObject,
					elements[i]
				);
				this.stopEvent(
					elements[i],
					handlers[i][j].eventName,
					handler
				);
				this.startEvent(
					elements[i],
					handlers[i][j].eventName,
					handler
				);				
			}
		}
	},
	
	startEvent: function (element, event, handler) {
		Element.observe(
			$(element), 
			event.strip().substr(2, event.strip().length), 
			typeof handler != "function" 
			? Prototype.emptyFunction 
			: handler			
		)
	},
	
	stopEvent: function (element, event, handler) {
		Element.stopObserving(
			$(element), 
			event.strip().substr(2, event.strip().length), 
			typeof handler != "function" 
			? Prototype.emptyFunction 
			: handler
		)
	},
	
	establishEvent: function (parentElement) {
		this.addElement(this.getElementsByClassName('ajaxa', parentElement));		
		this.parseEvent(this.elements);
		this.setEventHandler(this.elements, this.handlers);
	},
	
	getElementsByClassName: function(className, parentElement) {
		var elements = [], child, length, _length;
		var children = ($(parentElement) || document.body).getElementsByTagName('*');		
		for (var i = 0, length = children.length; i < length; i++) {
			if (children[i].className == className) {				
		 		elements.push($(children[i]));				
				child = children[i].getElementsByTagName('*');
				for (var j = 0, _length = child.length; j < _length; j++) {
					$(child[j]);
				}
			}
		}
		return elements;
	},
	
	update: function(parentElement) {
		this.establishEvent(parentElement);
	},
	
	isIE: function () {
		return navigator.userAgent.indexOf("MSIE") != -1;
	},
	
	element: {
		isForm: function () {
			return 	this.tagName == "FORM";
		}
	},
	
	addArray: function (array, value) {		
		if (array[value] == undefined)
			array[value] = [];
		return array[value];
	},
		
	_updater: function (event, element) {		
		var options = {
			method: 	   element.readAttribute("method") 
						 ? element.readAttribute("method") 
						 : "post",
						 
			encoding:	   element.readAttribute("encoding") 
						 ? element.readAttribute("encoding") 
						 : "UTF-8",
						 
			contentType:   element.readAttribute("contentType") 
						 ? element.readAttribute("contentType") 
						 : "application/x-www-form-urlencoded",
						 
			parameters:    element.readAttribute("params") 
						 ? element.readAttribute("params") 
						 : ""
		};
		if (element.readAttribute("url") !== null) {
			var url = element.readAttribute("url");
		}
		else if (element.readAttribute("href") !== null) {
			var url = element.readAttribute("href");		
		}
		else if (element.readAttribute("action") !== null) {
			var url = element.readAttribute("action");		
		}
		/* EVAL SCRIPTS */
		options.evalScripts = true;
		
		/* FORM */
		if (element.isForm()) {
			options.parameters = options.parameters + Form.serialize(element, false);			
			if (element.isForm()) Form.disable(element);
		}				
		var updater = new Ajax.Updater(this.getTarget(element), url, options);
		
		this.updaters[this.$id(element)] = {obj:updater, onComplete:Prototype.emptyFunction};
		
		var obj = this;
		updater.options.onComplete = function (transport, param) {
			updater.updateContent();
			if (element.isForm()) Form.enable(element);			
			obj.updaters[obj.$id(element)].onComplete(transport, param);
		}
		this.updater(event, element, this.updaters[this.$id(element)]);
		Event.stop(event);
	},
	
	/* OBJ FORM */
	form: {
		frames: [],
		
		createFrame: function (id, form) {			
			if (!this.frames[id]) {
				var div = $(document.createElement('div')).hide();
				document.body.appendChild(div);
				div.update('<iframe width="0" height="0" name="__ifr_name' + id + '" id="__ifr_id' + id + '" src=""></iframe>');
				var frame = $("__ifr_id" + id).hide();
				Element.observe(frame, 'load', this.onComplete.bindAsEventListener(this, form, frame));
				this.frames[id] = frame;
			}
			return this.frames[id];
		},
		
		isInputTypeFile: function (element) {			
			return (Form.getInputs(element, "file", false)).length;
		},
		
		_updater: function (event, form) {
			var form_id = this.$id(form);
			
			this.form.createFrame(form_id, form);
			
			if (!form.readAttribute("action")) {
				form.setAttribute("action", form.readAttribute("url"));
			}
			
			form.setAttribute("target", "__ifr_name" + form_id);
			form.setAttribute("method", "post");
			
			this.form.disable(form);
			this.updaters[form_id] = {onComplete:Prototype.emptyFunction};
			this.updater(event, form, this.updaters[form_id]);
		},
		
		disable: function(form) {			
			setTimeout(function() { Form.disable(form); }, 10);
		},
		
		onComplete: function (event, form, frame) {
			var transport = {};
			var form_id = ajaxa.$id(form);

			if (frame.readAttribute("name") && window.frames && window.frames[frame.readAttribute("name")]) {
				transport.responseText = window.frames[frame.readAttribute("name")].document.body.innerHTML;
			}
			
			var target = $(ajaxa.getTarget(form));
			if (target) target.update(transport.responseText);
			
			Form.enable(form);
			ajaxa.updaters[form_id].onComplete(transport);
		}
	}
}
//end ajaxa