// mootools 的 Object.toQueryString 的别名
var $string = Object.toQueryString;

/**
 * iAjax 将 mootools 的 Ajax 对象放入队列中，依次调用执行，
 * 同时将获取到的 JSON 对象解析成指令进行执行。此外，还设置了默
 * 认的事件触发回调函数：onRequest、onComplete 和 onFailure，
 * 在加载的时候自动显示加载信息，请求成功后指向指令，如有错误则显
 * 示错误信息。
 *
 * 应用示例：
 * 	iAjax.add('/ajaxtest.php', {message: 'Hello!'});
 *
 * @author Nio Xiao
 */
var iAjax = {
	id_status: 'ajax_status', //用于显示 AJAX 状态的 DOM 元素 id
	
	queue: $A(), //AJAX 队列
	
	errors: $A(), //错误数组
	
	ff_console: true, //是否在 Firefox 的 Firebug 的控制终端中显示错误信息

	add: function(url, params, options){
		// AJAX 默认选项
		var defaultOptions = {
			onRequest : this.onRequest.bind(this),
			onComplete: this.onComplete.bind(this),
			onFailure : this.onFailure.bind(this)
		};
		// 覆盖默认的 AJAX 选项
		options = $merge(options || {}, defaultOptions);
		// 放入队列
		this.queue.push({'url': url, 'params': params, 'options': options});
		if (this.queue.length == 1) {
			// 如果当前只有一个 AJAX 请求，则开始运行，多于 1 个则在队列中等待
			this.request();
		}
	},
	
	request: function(){
		this.errors = $A();
		if (this.queue.length <= 0) return;
		var item = this.queue[0];
		this.queue.shift(); //移除第一个，因为已经执行过了
		var ajax = new Ajax(item.url, item.options).request(item.params);
	},
	
	requestNext: function(){
		//this.queue.shift(); //移除第一个，因为已经执行过了
		if (this.queue.length > 0) this.request(); //执行下一个
	},
	
	onRequest: function(){
		var el = null;
		
		if (!(el = $(this.id_status))) { //AJAX 状态元素不存在，创建之！
			var el = new Element('div', {'id': this.id_status});
			el.hide();
			el.injectInside($E('body'));
		}
		el.setHTML('<span>正在加载，请稍候....</span>'); //加入 AJAX 加载时显示的信息	
		//var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
		el.setStyles({
			//'top': (scrollTop + 100) +'0px', 
			'display': ''
		});
	},
	
	onComplete: function(response_text, response_xml){
		$(this.id_status).hide(); //隐藏加载状态
		this.handle(response_text, response_xml);
		this.doFinal();
	},
	
	onFailure: function(transport){
		$(this.id_status).hide(); //隐藏加载状态
		this.errors.push({message: 'AJAX 调用失败，服务器未响应，请确定网络连接是否正常。', object: transport});
		this.doFinal();
	},
	
	doFinal: function(){
		for (var i = 0; i < this.errors.length; i++) { //如果 AJAX 调用有错，则显示错误
			var error = this.errors[i];
			var msg = error.message;
			if (!$defined(msg)) continue; //用于修复页面中有 iframe 的情况
			var obj = error.object || null;
			var ex  = error.exception || null;
			if (window.ie) { //IE 则直接弹出错误对话框
				alert(msg + "\n" + $string(obj) + "\n" + $string(ex));
			} else { //在 Firefox 的 Firebug 中显示错误
				if ($defined(console.group)) {
					console.error(msg);
					if (obj || ex) {
						console.group('关联异常/对象/值');
						if (obj) console.log(obj);
						if (ex) console.log(ex);
						console.groupEnd();
					}
				} else {
					console.error(msg + "\n" + $string(obj) + "\n" + $string(ex));
				}
			}
		}
		this.requestNext(); //下一个	
	},
	
	handle: function(response_text, response_xml){
		try {
			var result = Json.evaluate(response_text);
			if ($defined(result['actions'])) {
				this.process(result['actions']);
			} else {
				this.errors.push({message: "从服务器接收到的 JSON 对象格式不正确。", object: response_text});
			}
		} catch(e) {
			this.errors.push({message: "从服务器接收到错误数据：不是一个 JSON 对象。", object: response_text, exception: e});
		}
	},
	
	process: function(actions){		
		var action = actions.shift();
		if (!action) return;
	
		if (!$defined(action.type)) {
			this.errors.push({message: 'Action 必须包含 type 属性。', object: action});
		} else if (!$defined(iAction[action.type])) {
			this.errors.push({message: '目前不支持动作 “' + action.type + '”。', object: action});
			this.process(actions);
			return;		
		} else {
			try {
				iAction[action.type](action);
			} catch (e) {
				this.errors.push({message: '解析执行 action “' + action.type + '” 失败。', object: action, exception: e});
			}
		}

		// 执行下一个动作
		this.process(actions);
	}
}
