/*******************************************************************************

	options:
		call: (string) 'extension_key.ajax_method'
		data: (object) Data object or array,
		inject: (element) DOM-Object
		injectPosition: (string) 'top' || 'bottom' || 'after' || 'before' || 'fill'
		replace: (element) DOM-Object

********************************************************************************/

var MoojaxRequest = new Class({
	Implements: [Options, Events, Chain],
	options: {
		url: undefined,
		call: undefined,
		targetElement: undefined,
		targetPosition: 'fill',
		method: 'post',
		urlEncoded: true,
		onRequest: function(){},
		onCancel: function(){},
		onComplete: function(){},		
		onSuccess: function(){}
	},
	initialize: function(data, options){
		this.setOptions(options);
		this.data = data;
		// Replace submit action if data is a form element
		if ($type(data) == 'element' && data.tagName == "FORM") {
			data.addEvent('submit', function(e){
				var event = new Event(e);
				event.stop();
				this.send();
			}.bind(this));
			this.dataType = 'form';
		} else {
			this.dataType = 'data';			
		}
	}
});

MoojaxRequest.implement({
	
    send: function(call){
		// call
		if(call != undefined) this.options.call = call;
		if(this.options.call == undefined) this.fireEvent('cancel');
		// url
		if(this.options.url == undefined) this.options.url = moojaxRouter;
		if(this.options.url == undefined) this.fireEvent('cancel');
		// send
		switch(this.dataType){
			case 'form': return this.sendForm(); break;
			case 'data': return this.sendData(); break;
		}
    },

    sendData: function(){
		// Prepare data
		var data = this.data;
		var url = this.options.url;
		if (data && this.options.method == 'get'){
			switch ($type(data)){
				case 'element': data = $(data).toQueryString(); break;
				case 'object': case 'hash': data = Hash.toQueryString(data);
			}
			url = url + (url.contains('?') ? '&' : '?') + '_method=get&_call='+this.options.call + '&'+data;
			data = null;
		} else {
			data._call = this.options.call;
		}
		// Init JSON request
		this.JSONrequest = new Request.JSON({
			url: url,
			method: this.options.method,
			onRequest:  (function(){ this.fireEvent('request'); }).bindWithEvent(this),
			onCancel:   (function(){ this.fireEvent('cancel'); }).bindWithEvent(this),
			onComplete: (function(){ this.fireEvent('complete'); }).bindWithEvent(this),
			onSuccess:  this.processResponse.bindWithEvent(this),
			data: data
		});
		// Set encoding
		if (this.options.urlEncoded && this.options.method == 'post') {
			this.JSONrequest.headers.set('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
		}
		// Send the thing
		this.JSONrequest.send();
    },

	sendForm: function(){
		var url = this.options.url + (this.options.url.contains('?') ? '&' : '?') + '_method='+this.options.method+'&_call='+this.options.call;
		this.data.set("send", {
			url: url,
			method: this.options.method,
			onRequest:  (function(){ this.fireEvent('request'); }).bindWithEvent(this),
			onCancel:   (function(){ this.fireEvent('cancel'); }).bindWithEvent(this),
			onComplete: (function(){ this.fireEvent('complete'); }).bindWithEvent(this),
			onSuccess:  this.processResponse.bindWithEvent(this)
		}).send();
		return true;
	},

	processResponse: function(response){
		if(this.dataType == 'form'){
			response = JSON.decode(response);
		}
		this.response = response;
		if($chk(response.html)){
			var htmlElement = new Element('span').set('html',response.html);
			var targetElement = this.options.targetElement;
			var targetPosition = this.options.targetPosition;
			if(targetElement != undefined){
				if(targetPosition != undefined && targetPosition == 'fill'){
					//targetElement.set('html', response.html);
					htmlElement.inject(targetElement.empty());
				} else if(targetPosition != undefined && targetPosition == 'replace'){					
					htmlElement.replaces(targetElement);
				} else {
					htmlElement.inject(targetElement, targetPosition);
				}
			} else {			
			}
			response.html.stripScripts(true);
		}
		this.fireEvent('success', this.response.data);
		eval(response.js);
	}
	
});

