/*
$Id: ajax.js 5008 2008-05-15 03:37:52Z xkxmud $
*/
//var 100 = 100; //初始的請求已經接受，客戶應當繼續發送請求的其余部分。
//var 101 = 101; //服務器將遵從客戶的請求轉換到另外一種協議。
//var 200 = 200; //一切正常，對get和post請求的應答文檔跟在後面。
//var 201 = 201; //服務器已經創建了文檔，location頭給出了它的url。
//var 202 = 202; //已經接受請求，但處理尚未完成。
//var 203 = 203; //文檔已經正常地返回，但一些應答頭可能不正確，因為使用的是文檔的拷貝。
//var 204 = 204; //沒有新文檔，瀏覽器應該繼續顯示原來的文檔。如果用戶定期地刷新頁面，而servlet可以確定用戶文檔足夠新，這個狀態代碼是很有用的。
/*
沒有全部定義完整，只定義了使用中的
*/
var XMLHTTP_READYSTATE_UNLOAD = 0; //未初始化
var XMLHTTP_READYSTATE_READING = 1; //
var XMLHTTP_READYSTATE_READED = 2; //
var XMLHTTP_READYSTATE_EXCHANING = 3; //
var XMLHTTP_READYSTATE_FINISHED = 4; //

var ajaxarr = new Array();//note 每個URL只允許生成一個AJAX對象，防止重復點擊。
var ajaxstackarr = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);//note ajax 對象時間占位堆棧。預置位10個，應該足夠用了。
var attackevasive = 1;//note 防止刷新是否打開
var ajsetarr = new Array();
var xctrlid;

//構造AJAX類
function ajax_cls(recvtype) {

	for(var _stackindex = 0; _stackindex < ajaxstackarr.length && ajaxstackarr[_stackindex] != 0; _stackindex++);//note 查詢空閒的時間位
	ajaxstackarr[_stackindex] = 1;//note 表示該任務占位

	var aj = new Object();

	aj._recvtype = recvtype ? recvtype : 'XML';

	aj._resulthandle = null;
	aj._sendstring = '';
	aj.targeturl = '';
	aj._stackindex = 0;
	aj._stackindex = _stackindex;

	//note 默認為 XML 方式
	aj.setrecvtype = function(recvtype) {
		aj._recvtype = recvtype;
	}

	aj._create = function() {
		var request = false;
		if(window.XMLHttpRequest) {
			request = new XMLHttpRequest();
			if(request.overrideMimeType) {
				request.overrideMimeType('text/xml');
			}
		} else if(window.ActiveXObject) {
			var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
			for(var i=0; i<versions.length; i++) {
				try {
					request = new ActiveXObject(versions[i]);
					if(request) {
						return request;
					}
				} catch(e) {
					continue;
				}
			}
		}
		return request;
	}

	aj._xmlhttp_request = aj._create();


	//note private
	aj._processhandle = function() {
		var XMLHTTP_READYSTATE_FINISHED = 4;
		if(aj._xmlhttp_request.readyState == XMLHTTP_READYSTATE_FINISHED && aj._xmlhttp_request.status == 200) {
			if(ajaxarr.length > 0 ) {
				for(k in ajaxarr) {
					if(ajaxarr[k] == aj.targeturl) {
						ajaxarr[k] = null;
					}
				}
			}
			if(aj._recvtype == 'HTML') {
				aj._resulthandle(aj._xmlhttp_request.responseText, aj);
			} else if(aj._recvtype == 'XML') {
				if(aj._xmlhttp_request.responseXML.lastChild != null) {
					aj._resulthandle(aj._xmlhttp_request.responseXML.lastChild.firstChild.nodeValue, aj);
				}
			}
			ajaxstackarr[aj._stackindex] = 0;//note 清空標志位，使其它對象有時間段可以被申請
		}
	}

	//note public
	aj.get = function(targeturl, resulthandle) {
		if(in_array(targeturl, ajaxarr)) {
			return false;
		} else {
			ajaxarr.push(targeturl);
		}
		aj.targeturl = targeturl;
		aj._xmlhttp_request.onreadystatechange = aj._processhandle;
		aj._resulthandle = resulthandle;
		var delay = attackevasive & 1 ? (aj._stackindex + 1) * 1001 : 100;
		if(window.XMLHttpRequest) {
			setTimeout(function(){
			aj._xmlhttp_request.open('GET', aj.targeturl);
			aj._xmlhttp_request.send(null);}, delay);
		} else {
			setTimeout(function(){
			aj._xmlhttp_request.open("GET", aj.targeturl, true);
			aj._xmlhttp_request.send();}, delay);
		}

	}
	//note public
	aj.post = function(targeturl, sendstring, _resulthandle) {
		/*
		if(in_array(targeturl, ajaxarr)) {
			return false;
		} else {
			ajaxarr.push(targeturl);
		}
		*/
		aj.targeturl = targeturl + '&inajax=1';
		aj._sendstring = sendstring;
		aj._xmlhttp_request.onreadystatechange = aj._processhandle;
		aj._resulthandle = _resulthandle;
		aj._xmlhttp_request.open('POST', aj.targeturl);
		aj._xmlhttp_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		aj._xmlhttp_request.send(aj._sendstring);
	}
	return aj;
}
//執行JS腳本
var evalscripts = new Array();
function _evalscript(s) {
	if(s.indexOf('<script') == -1) return s;
	var p = /<script[^\>]*?src=\"([^\>]*?)\"[^\>]*?(reload=\"1\")?(?:charset=\"([\w\-]+?)\")?><\/script>/ig;
	var arr = new Array();
	while(arr = p.exec(s)) _appendscript(arr[1], '', arr[2], arr[3]);
	p = /<script (?!src)[^\>]*?( reload=\"1\")?>([^\x00]+?)<\/script>/ig;
	while(arr = p.exec(s)) _appendscript('', arr[2], arr[1]);
	return s;
}
// 綁定JS腳本
function _appendscript(src, text, reload, charset) {
	var id = hash(src + text);
	if(!reload && in_array(id, evalscripts)) return;
	if(reload && $(id)) {
		$(id).parentNode.removeChild($(id));
	}

	evalscripts.push(id);
	var scriptNode = document.createElement("script");
	scriptNode.type = "text/javascript";
	scriptNode.id = id;
	scriptNode.charset = charset;
	try {
		if(src) {
			scriptNode.src = src;
		} else if(text){
			scriptNode.text = text;
		}
		$('supevbox').appendChild(scriptNode);
	} catch(e) {}
}
//對JS進行過濾
function _stripscript(s) {
	s = unescape(s);
	return s.replace(/<script.*?>.*?<\/script>/ig, '');
}

/*	調用遠程接口，並返回UI套入到當前div的容器中。
 *@ url: 需求請求的 url
 *@ id : 顯示的 id
 *@ _waiting: 等待的 id，默認為顯示的 id，如果 _waiting 為空字符串，則不顯示 loading...， 如果為 null，則在 showid 區域顯示
 *@ linkid: 是哪個鏈接觸發的該 ajax 請求，該對象的屬性(如 ajaxdisplay)保存了一些 ajax 請求過程需要的數據。
 *@ recall:　回調函數
*/
function aj_load(url, oshowid, force, loading) {

	force = empty(force) ? false : force;
	if(force == false && in_array(url, ajsetarr)) {
		return false;
	} else {
		ajsetarr.push(url);
	}

	var x = new ajax_cls();
	var oshow = $(oshowid);
	var autogoto = 0;

	loading = empty(loading) ? 'loading...' : loading;
	oshow.innerHTML = '<p class="info"><img src="'+jsenv['THEME_PATH']+'res/loading.gif"> ' + loading + '</p>';

	x.oshow = oshow;

	if(url.substr(strlen(url) - 1) == '#') {
		url = url.substr(0, strlen(url) - 1);
		autogoto = 1;
	}

	var url = url + '&inajax=1&ajaxtarget=' + oshowid;

	x.get(url, function(s, x) {
		if(_ajaxshow(s)) {
			return;
		}
		_evalscript(s);
		s = _stripscript(s);
		_sinnerHTML(x.oshow, s);
		_ajaxupdateevents(x.oshow);
		if(autogoto) {
			scroll(0, x.oshow.offsetTop);
		}
	});
}
//僅調用遠程接口，不返回任何UI
function aj_send(url) {
	var x = new ajax_cls();
	var url = url + '&inajax=1';
	x.get(url, function(s, x){
		if(_ajaxshow(s)) {
			return;
		}
		_evalscript(s);
		s = _stripscript(s);
	});
}

var checkedtab = 'purple';
var uncheckedtab = 'sep';
/**
* 設置Tab.  調用遠程UI，並在當前窗口中切換
*/
function aj_settab(cur, tabs_label, e) {
	if(isset(e)) {
		doane(e);
	}

	ocur = $(cur);
	ocur_btn = $(cur+'_btn');

	eval('var tabs='+tabs_label);

	var l = tabs.length;

	for(i = 0;  i < l; i++) {
		$(tabs[i]+'_btn').className = uncheckedtab;
		$(tabs[i]).style.display = 'none';
	}

	ocur.style.display = '';
	ocur_btn.className = checkedtab;
	ocur_btn.blur();

	if(!empty(ocur_btn.href)) {
		aj_load(ocur_btn.href, cur);
	}
}

function aj_form(e, ctrlid, divclass, lefttime) {
	divclass = empty(divclass) ? 'ajax_form' : divclass;
	lefttime = empty(lefttime) ? 999999 : lefttime;
	xctrlid = ctrlid;
	aj_menu(e, ctrlid, divclass, lefttime);
}

function aj_menu(e, ctrlid, divclass, lefttime) {

	divclass = empty(divclass) ? 'ajax_msg' : divclass;
	lefttime = empty(lefttime) ? 2 : lefttime;

	var div = $(ctrlid + '_menu');

	if(empty(div)) {
		div = $c('div');
		div.id = ctrlid + '_menu';
		div.style.display = 'none';
		$('supevbox').appendChild(div);
	}

	div.className = divclass;
	var x = new ajax_cls();
	x.ctrlid = ctrlid;
	var href = isset($(x.ctrlid).href) ? $(x.ctrlid).href : $(x.ctrlid).attributes['href'].value;

	x.div = div;
	x.get(href + '&inajax=1&ajaxtarget='+x.ctrlid+'_menu',function(s, x) {
		_evalscript(s);
		s = _stripscript(s);
		if(x.div) {
			x.div.innerHTML = s;
		}
		showMenu(x.ctrlid, true, 0, lefttime);

	});
	doane(e);
}

// 將返回信息插入到容器
function _sinnerHTML(oshow, s) {
	if(oshow.tagName != 'TBODY') {
		oshow.innerHTML = s;
	} else {
		while(oshow.firstChild) {
			oshow.firstChild.parentNode.removeChild(oshow.firstChild);
		}
		var div1 = $c('DIV');
		div1.id = oshow.id+'_div';
		div1.innerHTML = '<table><tbody id="'+oshow.id+'_tbody">'+s+'</tbody></table>';
		$('supevbox').appendChild(div1);
		var trs = div1.getElementsByTagName('TR');
		var l = trs.length;
		for(var i=0; i<l; i++) {
			oshow.appendChild(trs[0]);
		}
		var inputs = div1.getElementsByTagName('INPUT');
		var l = inputs.length;
		for(var i=0; i<l; i++) {
			oshow.appendChild(inputs[0]);
		}
		div1.parentNode.removeChild(div1);
	}
}
//附加事件
function _ajaxupdateevents(obj, tagName) {
	tagName = tagName ? tagName : 'A';
	var objs = obj.getElementsByTagName(tagName);
	for(k in objs) {
		var o = objs[k];
		_ajaxupdateevent(o);
	}
}
//更新事件
function _ajaxupdateevent(o) {
	if(typeof o == 'object' && o.getAttribute) {
		if(o.getAttribute('ajaxtarget')) {
			if(!o.id) {
				o.id = ('id' + Math.random() * 10).replace(/\./i, '');	//note 該標簽唯一標識
			}
			var ajaxevent = o.getAttribute('ajaxevent') ? o.getAttribute('ajaxevent') : 'click';//note 默認為 click 事件
			var ajaxurl = o.getAttribute('ajaxurl') ? o.getAttribute('ajaxurl') : o.href;//note 默認為 click 事件
			_attachEvent(o, ajaxevent, newfunction('aj_load', ajaxurl, o.getAttribute('ajaxtarget'), o.getAttribute('ajaxwaitid'), o.getAttribute('ajaxloading'), o.getAttribute('ajaxdisplay')));
			if(o.getAttribute('ajaxfunc')) {
				o.getAttribute('ajaxfunc').match(/(\w+)\((.+?)\)/);
				_attachEvent(o, ajaxevent, newfunction(RegExp.$1, RegExp.$2));
			}
		}
	}
}
//彈出js信息
function _ajaxshow(s) {
	if(s.indexOf('ajaxshow()') != -1) {
		//ajaxshow();
		return true;
	}
	return false;
}


//展示列表，含翻頁等功能
function getform(formName) {
	returnString = "";
	formElements = $(formName).elements;

	var first = true;

	for (var i=0; i< formElements.length; i++) {

		var e = formElements[i];
		if(e.name == null || e.name==""){
			continue;
		}
		if(e.type == "radio"){
			if(e.checked){//判斷單選按鈕是否被選中
				if(first == true){
					first = false;
					returnString += escape(e.name) + "=" + escape(e.value);
				}else{
					returnString += "&" + escape(e.name) + "=" + escape(e.value);
				}
			}
		}else{
			if(first == true){
				first = false;
				returnString += escape(e.name) + "=" + escape(e.value);
			}else{
				returnString += "&" + escape(e.name) + "=" + escape(e.value);
			}
		}
	}
	return returnString;
}
//提交一個post請求，並把返回結果在當前容器中
function aj_submit(formid, outid, insert, except, loading) {
	var x = new ajax_cls();
	var param = getform(formid) + '&inajax=1';
	insert = empty(insert) ? 0 : insert;
	except = empty(except) ? '' : except;
	loading = empty(loading) ? false : true;
	loadingstr = '';
	x.outid = outid;
	if(loading == true) {
		loadingstr = "<p class='info'><img src='"+jsenv['THEME_PATH']+"res/loading.gif'>loading...</p>";
	}

	var tmpinnerHTML = $(x.outid).innerHTML;
	if(isset(except)) {
		if(tmpinnerHTML.indexOf(except) != -1) {
			tmpinnerHTML = '';
		}
	}
	if(loading == true) {
		if(insert != 0) {
			$(x.outid).innerHTML = loadingstr + tmpinnerHTML;
		} else {
			$(x.outid).innerHTML = loadingstr;
		}
	}
	x.post($(formid).action, param, function(s, x) {

			setMenuPosition($(x.outid).ctrlid, 0);
			setTimeout("hideMenu()", 3000);
			_evalscript(s);
			s = _stripscript(s);
			if(insert != 0) {
				$(x.outid).innerHTML = s + tmpinnerHTML;
			} else {
				$(x.outid).innerHTML = s;
			}
			_ajaxupdateevents($(x.outid));

	});

	return false;
}