var commands = [];
commands['as'] = function(args) {
	property = args[1];
	data = args[2];
	if('string' == typeof(args[0]))
		element = $(args[0]);
	else
		element = args[0];
		
	switch (property) {
		case 'innerHTML':
			element.innerHTML = data;
			break;
		default:
			if(willChange(element, property, data))
				eval('element.' + property + '= data');
			break;
	}
}
commands['fn'] = function(args) {
	eval(args[0] + '(\'' + args[1].join("', '").toString() + '\')')
}
commands['il'] = function(args) {
	$(args[0]).innerHTML = '<div class="ajaxdiv"><p class=\"ajax_text\">Loading...</p></div>';
}

willChange = function(element, property, data) {
	if("string" == typeof element)
		element = $(element);

	if(element) {
		var oldData;
		eval("oldData=element." + attribute);
		return (newData != oldData);
	}
	
	return false;
}
var synAsyncObject = function(element, optionsObj) {
	this.initialize(element, optionsObj);
}

synAsyncObject.TEXTAREA = 1;
synAsyncObject.TEXT = 2;
synAsyncObject.PASSWORD = 3;
synAsyncObject.CHECKBOX = 4;
synAsyncObject.SELECT = 5;
synAsyncObject.FILE = 6;
synAsyncObject.RADIO = 7;
synAsyncObject.OTHER = 8;

synAsyncObject.prototype = {
	initialize: function(element, optionsObj) {
		if(element != null) {
			this.element = $(element);
			this.elementType = this.getElementType();
			this.AsyncRequests = [];
			this.Options = Object.extend({}, optionsObj || {});
			Object.extend(this, this.Options);
			switch(this.elementType) {
				case synAsyncObject.RADIO:
				case synAsyncObject.CHECKBOX:
					this.boundClick = this.doAsyncProcess.bindAsEventListener(this);
					Event.observe(this.element, 'click', this.boundClick);
				case synAsyncObject.SELECT:
				case synAsyncObject.FILE:
					this.boundChange = this.doAsyncProcess.bindAsEventListener(this);
					Event.observe(this.element, 'change', this.boundChange);
					break;
				case synAsyncObject.PASSWORD:
				case synAsyncObject.TEXT:
				case synAsyncObject.TEXTAREA:
					this.boundKeyUp = this.doAsyncProcess.bindAsEventListener(this);
					Event.observe(this.element, 'keyup', this.boundKeyUp);
					break;
				default:
					this.boundClick = this.doAsyncProcess.bindAsEventListener(this);
					Event.observe(this.element, 'click', this.boundClick);
			}
		}
	},
	doAsyncProcess:function() {
		for(var iLoop=0, iMax=this.AsyncRequests.length; iLoop < iMax; iLoop++) {
			this.execProcess(this.AsyncRequests[iLoop]);
		}
	},
	execProcess: function(aP) {
		if(aP.options.output != '') {
			showLoader(aP.options.output);
		}
		try {
			if(aP.options.beforeProcess.length > 0) {
				for(var iBProc=0, iMaxBProc=aP.options.beforeProcess.length; iBProc < iMaxBProc; iBProc++) {
					this.executeCommand(aP.options.beforeProcess[iBProc]);
					/*try {
						//eval(aP.options.beforeProcess[iBProc][0] + '(\'' + aP.options.beforeProcess[iBProc][1].join("', '").toString() + '\')');
					} catch (error) {}*/
				}
			}
		} catch (error) {alert(error);}
		try {
			eval(aP.request + '(' + aP.args + ')');
		} catch (error) {alert(error)}
		try {
			if(aP.options.afterProcess.length > 0) {
				for(var iAProc=0, iMaxAProc=aP.options.afterProcess.length; iAProc < iMaxAProc; iAProc++) {
					try {
						eval(aP.options.afterProcess[iAProc][0] + '(\'' + aP.options.afterProcess[iAProc][1].join("', '").toString() + '\')');
					} catch (error) {}
				}
			}
		} catch (error) {}
	},
	destroy:function() {
		Event.stopObeserving(this.element, 'click', this.boundClick);
	},
	getElementType: function(){
		switch(true){
		case (this.element.nodeName.toUpperCase() == 'TEXTAREA'):
			return synAsyncObject.TEXTAREA;
		case (this.element.nodeName.toUpperCase() == 'INPUT' && this.element.type.toUpperCase() == 'TEXT'):
			return synAsyncObject.TEXT;
		case (this.element.nodeName.toUpperCase() == 'INPUT' && this.element.type.toUpperCase() == 'PASSWORD'):
			return synAsyncObject.PASSWORD;
		case (this.element.nodeName.toUpperCase() == 'INPUT' && this.element.type.toUpperCase() == 'CHECKBOX'):
			return synAsyncObject.CHECKBOX;
		case (this.element.nodeName.toUpperCase() == 'INPUT' && this.element.type.toUpperCase() == 'FILE'):
			return synAsyncObject.FILE;
		case (this.element.nodeName.toUpperCase() == 'INPUT' && this.element.type.toUpperCase() == 'RADIO'):
			return synAsyncObject.RADIO;
		case (this.element.nodeName.toUpperCase() == 'SELECT'):
			return synAsyncObject.SELECT;
		default:
			return synAsyncObject.OTHER;
		}
	},
	addAsync: function(async_request, args, options) {
		this.AsyncRequests.push( {
									request: async_request, 
									args: args, 
									options: Object.extend({
										output:'',
										beforeProcess:[],
										afterProcess:[]}, options || {})
								} );
		return this;
	},
	executeAsync: function(async_request, args, options) {
		this.standAloneAsyncProc = {
									request: async_request,
									args: args,
									options: Object.extend({
										output:'',
										beforeProcess:[],
										afterProcess:[]}, options || {})
								};
		this.execProcess(this.standAloneAsyncProc);
		return this;
	},
	showLoader: function(elem) {
		$(elem).replace('<div class="ajaxdiv"><p class=\"ajax_text\">Loading...</p></div>');
	},
	parseCommand: function(cmd) {
		var command = '';
		switch(cmd.name.toLowerCase()) {
			case 'assign':
				command = 'as';
				break;
			case 'function':
				command = 'fn';
				break;
			case 'il':
				command = 'il';
				break;
		}
		
		return command;
	},
	executeCommand: function(cmd) {
		var command = this.parseCommand(cmd);
		if(command) {
			if(commands[command]) {
				commands[command](cmd.args);
			}
		}
	}
}