/**
AJAS 2.0 - 2008 Tecnologias Avanzadas.

Changelog:
	2.0   - Rewrote for Mootools 1.2.1
	1.2b2 - Corrected a bug regarding ajasform and multiple forms
	1.2b3 - Removed the d=d parameter for POST requests
	1.2b4 - Added breadcrumb support
	1.2b5 - Changed history support, removed target div
	1.2b6 - Fixed div update bug, added abort method
**/

var ajas2 = new Class({
	Implements: [Chain, Events, Options],
	version: '2.0',
	options: {
		'crumbMan': $empty,
		'usecrumbs': false,
		'defaultdiv': "contentDiv",
		'url': $empty,
		'animate': true,
		'method': "GET",
		'forget': false,
		'loadingDiv': 'loading',
		'loadingtxt': 'Cargando',
		'loading': true,
		'history': false,
		'onComplete': $empty,
		'onStateChange': $empty,
		'update': $empty,
		'headers': {
			'X-Requested-With': 'XMLHttpRequest',
			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
		},
		'devmode': true,
		'lock': true
	},
	initialize: function(options)
	{
		if(options == null)
		{
			options = {};
		}
		this.setOptions(options);	
		if($type(options.crumbMan) != false)
		{
			this.usecrumbs = true;
		}
		this.options.update = this.options.defaultdiv;
		this.defaultOptions = this.options;
		this.xhr = new Browser.Request();
		this.busy = false;
		this.loadingEl = $(this.options.loadingDiv);
		this.headers = new Hash(this.options.headers);
	},
	updateOptions: function(options)
	{
		this.removeEvents();
		this.options = this.defaultOptions;
		if(options != null)
		{
			this.setOptions(options);	
		}
	},
	request: function(url, options)
	{
		//Update options
		this.updateOptions(options);
		this.options.url = url;
		//Check busy flag
		if(this.busy == true && this.options.lock == true)
		{
			return;
		}
		this.busy = true;
		//Compatibility with 1.0
		if($type(this.options.mode) == 'string')
		{
			this.options.mode = options.mode.toUpperCase();
		}
		//Crumbs
		if($type(this.options['addCrumb']) != false && this.options.usecrumbs)
		{
			this.crumbMan.add(this.options['addCrumb'], url);
		}
		if($type(this.options['replaceCrumb']) != false && this.options.usecrumbs)
		{
			this.crumbMan.replace(this.options['replaceCrumb'], url, this.options['crumbsOptions']);		
		}
		//History
		if(this.options.history == true )
		{
			dhtmlHistory.add(this.options['uid'] ,url);
		}
		if(this.options.loading == true)
		{
			this.loadingEl.setStyle('display','block');
			this.loadingEl.setStyle('top',(window.getHeight()/2)-15);
			this.loadingEl.setStyle('left', (window.getWidth()/2)-40);
			this.loadingEl.effect('opacity',{
					wait:true, duration: 200, 
					transition: Fx.Transitions.linear
			}).start(0,0.8);
			
		}
		if(this.options.animate == true)
		{
			$(this.options.update).effect('opacity',{
					wait:true, duration: 500, 
					transition: Fx.Transitions.linear,
					onComplete: this.doRequest.bind(this)
			}).start(1,0);
		}
		else
		{
			this.doRequest();
		}
	},
	setDefault: function(ndefault)
	{
		this.options = this.defaultOptions;
		this.options.defaultdiv = ndefault;
		this.defaultOptions = this.options;
	},
	evalScripts: function(element)
	{
		if(element.childNodes.length > 0)
		{
			element.getChildren().each(function(el){
				if(el.get('tag') == 'script')
				{
					try {
						eval(el.innerHTML);	
						if(this.options.devmode==false)
						{
							el.dispose();
						}
					}
					catch(err)
					{
					}		
				}
				else
				{
					this.evalScripts(el);
				}
			});
		}
	},
	onStateChange: function()
	{
		if(this.xhr.readyState == 4) {
				//Parse response
				$(this.options.update).set('html',this.xhr.responseText);
				if(this.options.animate == true)
				{	
					$(this.options.update).effect('opacity',{wait: true,duration: 500,transition: Fx.Transitions.linear, onComplete: function() { 
						this.evalScripts($(this.options.update));
						}.bind(this)
					}).start(0,1);
				}
				else
				{
					this.evalScripts($(this.options.update));
				}
				if(this.options.loading == true)
				{
					this.loadingEl.effect('opacity',{
						wait:true, duration: 200, 
						transition: Fx.Transitions.linear
					}).start(0.8,0);
					this.loadingEl.setStyle('display','none');
				}
				this.busy = false;
				this.fireEvent('complete');
		}
		else
		{
			this.fireEvent('StateChange',this.xhr.readyState);
		}
	},
	abort: function()
	{
		this.busy = false;
		this.xhr.abort();
		this.xhr = Browser.Request();
	},
	doRequest: function()
	{
		if(this.options.forget == false)
		{
			this.ajasLastOpen = this.options.url;
		}
		if(this.options.method == "GET")
		{
			this.xhr.open("GET", this.options.url , true);
			this.setHeaders();
			this.xhr.onreadystatechange = this.onStateChange.bind(this);
			this.xhr.send(null);
		}
		if(this.options.method == "POST")
		{
			this.xhr.open("POST", this.options.url , true);
			this.setHeaders();
			this.xhr.onreadystatechange = this.onStateChange.bind(this);
			this.xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			this.xhr.send(this.options.postData);
		}
		
	},
	ajasForm: function(form, options)
	{
		form = $(form);
		if ($type(options) == false)
		{
			options = {};
		}
		furl = form.getAttribute('action');
		if($type(furl) == false)
		{
			return;
		}
		fmode = this.getAttribute('method').toUpperCase();
		if($type(fmode) == false)
		{
			fmode = "GET";
		}
		options['mode'] = fmode;
		form.store('options',options);		
		form.addEvent('submit',function(e){
			e = new Event(e);
			e.stop();
			document.ajaxer.sendForm(this, this.get("action"), this.retrieve('options'));
		});
	},
	sendForm: function(form, url, options)
	{
		form = $(form);
		var fmode = "GET";
		if($type(options['mode']) == "string")
		{
			fmode = options['mode'];
		}
		if(fmode == "POST")
		{
			var uri = "";
		}
		else
		{
			var uri = surl+"?";
		}
		uri+= form.toQueryString();
		if(fmode == "POST")
		{
			options['data'] = uri;
			this.request(surl, options);
		}
		else
		{
			this.request(uri, options);
		}
	},
	setHeaders: function()
	{
		this.headers.each(function(value, key){
			try {
				this.xhr.setRequestHeader(key, value);
			} catch (e){
			}
		}, this);
	}
});
