var Ajax = function(){
	var getRequestObject = function(url,options) {
		//初始化请求对象
		var req = false;
		if(window.XMLHttpRequest) {
			req = new window.XMLHttpRequest();
		}else if(window.ActiveXObject){
			req = new window.ActiveXObject('Microsoft.XMLHTTP');
		}
		if(!req){
			return false;
		}
		
		//定义默认的选项
		options = options || {};
		options.method = options.method || 'GET';
		options.send = options.send || null;
		
		//为请求的每个阶段定义不同的侦听器
		req.onreadystatechange = function(){
			switch (req.readyState) {
				case 1 :
					//载入中
					if(options.loadListener){
						options.loadListener.apply(req,arguments);
					}
				break;
				case 2 :
					//载入完成
					if(options.loadedListener){
						options.loadedListener.apply(req,arguments);
					}
				break;
				case 3 :
					//交互
					if(options.ineractiveListener){
						options.ineractiveListener.apply(req,arguments);
					}
				break;
				case 4 :
					//完成。如果失败则抛出错误
					try{
						if(req.status && req.status == 200){
							//针对 content-type 的特殊侦听器。由于content-type头部可能包含子集，如：Content-type : text/html;charset=ISO-8859-4
							//因此通过正则表达式提取所需的部分
							var contentType = req.getResponseHeader('Content-Type');
							var mimeType = contentType.match(/\s*([^;]+)\s*(;|$)/i)[1];
							
							switch(mimeType){
								case 'text/javascript' :
								case 'application/javascript':
									//响应的是javascript,因此以req.responseText作为回调的参数
									if(options.jsResponseListener) {
										options.jsResponseListener.call(req,req.responseText);
									}
								break;
								case 'application/json':
									//响应的是JSON,因此需要用匿名函数对req.responseText进行解析以返回作为回调参数的json对象
									if(options.jsonResponseListener) {
										try{
											var json = Ajax.parseJSON(req.responseText);
										}catch(e){
											var json = false;
										}
										options.jsonResponseListener.call(req,json);
										
									}
								break;
								case 'text/xml':
								case 'application/xml':
								case 'application.xhtml+xml':
									//响应是XML，因此以req.responseXML作为回调参数 此时是Document对象
									if(options.xmlResponseListener){
										options.xmlResponseListener.call(req,req.responseXML);
									}
								break;
								case 'text/html':
									//响应是HTML，因此以req.responseText作为回调参数
									if(options.htmlResponseListener){
										options.htmlResponseListener.call(req,req.responseText);
									}
								break;
							}
							//针对响应成功完成的侦听器
							if(options.completeListener){
								options.completeListener.apply(req,arguments);
							}
						}else{
							//响应完成但却存在错误
							if(options.errorListener){
								options.errorListener.apply(req,arguments);
							}
						}
						
					}catch (e) {
						//忽略错误
					}
					break;
			}
		}
		req.open(options.method,url,true);
		req.setRequestHeader('X-GTRI-Ajax-Request','AjaxRequest');
		req.setRequestHeader('Content-Type','application/x-www-form-urlencoded;');
		return req;
	}
	var  isValid = function (str) {
        if (typeof str != 'string') {
            return false;
        }
		var _INVALID = /^[\],:{}\s]*$/;
		var _ESCAPES = /\\["\\\/bfnrtu]/g;
		var _VALUES  = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
		var _BRACKETS = /(?:^|:|,)(?:\s*\[)+/g;
        return _INVALID.test(str.
                replace(_ESCAPES,'@').
                replace(_VALUES,']').
                replace(_BRACKETS,''));
    }
	return{
		  	ajax:function(url,options){
				var req = getRequestObject(url,options);
				return req.send(options.send);
		  	},
		  	parseJSON : function(s,filter){
				var j;
				function walk(k,v){
					var i;
					if(v && typeof v === 'object'){
						for(var i in v){
							if(v.haOwnProperty(i)){
								v[i] = walk(i,v[i]);
							}
						}
					}
					return filter(k,v);
				}
				//解析通过3个阶段执行。第一阶段。通过正则表达式检测json文本，查找非JSON字符
				//其中特别关注‘()’,‘new’，因为他们会引起语句的调用，还有‘=’，因为它会导致变量的值发生改变
				//不过，为安全起见这里会拒绝所有不希望出现的字符
				
				
				//if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(s)){
				if(isValid(s)){
					//第二阶段，使用eval函数将json文本编译javascript结构。其中的“{”操作符具有语法上的二义性：即
					//他可以定义一个语句块，也可以表示对象字面量。这里将JSON文本用括号括起来是为了消除这种二义性
					try{
						j = eval('('+ s + ')');
					}catch(e){
						throw new SyntaxError("parseJSON");
					}
				}else{
					throw new SyntaxError("parseJSON");
				}
				//第三阶段，代码递归地遍历了新生成的结构，而且将每个名/值对传递给一个过滤函数，以便进行可能的转换
				if(typeof filter === 'function'){
					j = walk('',j);
				}
				return j;
			}
		}
}();
