/**
 *
 * $Id: entry.js 125 2007-01-11 10:18:38Z atppp $
 */



/* general functions */
function isUndefined(a) {
	return typeof a == 'undefined';
}

function isObject(a) {
	return (a && typeof a == 'object');
}

function isArray(a) {
	return isObject(a) && a.constructor == Array;
}

function isString(a) {
	return typeof a == 'string';
}

function getObj(o) {
	return document.getElementById(o);
}
function hideObj(o) {
	getObj(o).style.display = "none";
}
function showObj(o) {
	getObj(o).style.display = "";
}
function changeStatus(s) {
	getObj("divStatus").innerHTML = s; // + "  <input onclick='abortDownload()' type='button' value='取消' />";
	showObj("divStatus");
}





/* event functions */

// Add an event to the obj given
// event_name refers to the event trigger, without the "on", like click or mouseover
// func_name refers to the function callback when event is triggered
function addEvent(obj,event_name,func_name){
	if (obj.attachEvent) {
		obj.attachEvent("on"+event_name, func_name);
	} else if(obj.addEventListener) {
		obj.addEventListener(event_name,func_name,true);
	} else {
		obj["on"+event_name] = func_name;
	}
}

// Removes an event from the object
function removeEvent(obj,event_name,func_name) {
	if (obj.detachEvent){
		obj.detachEvent("on"+event_name,func_name);
	} else if(obj.removeEventListener) {
		obj.removeEventListener(event_name,func_name,true);
	} else {
		obj["on"+event_name] = null;
	}
}

function AJAXEvent(evt) {
	evt = (evt) ? evt : ((window.event) ? event : null);
	this.e = evt;
	if (evt == null) return;
	this.keyCode = evt.keyCode ? evt.keyCode : evt.charCode;
	this.key = String.fromCharCode(this.keyCode).toLowerCase();
	this.ctrlKey = evt.ctrlKey;
	this.shiftKey = evt.modifiers? evt.modifiers&Event.SHIFT_MASK : (evt.shiftKey || false);
	this.target = evt.target || evt.srcElement || null;
	this.tagName = ("" + (this.target.tagName || this.target)).toLowerCase();
}
AJAXEvent.prototype.stopEvent = function() {
	if (!this.e.stopPropagation) {
		this.e.cancelBubble = true;
		this.e.returnValue = false;
	} else {
		this.e.preventDefault();
		this.e.stopPropagation();
	}
}




var Abstract = function() {};
Abstract.prototype.extend = function(object) {
	for (property in object) {
		this[property] = object[property];
	}
	return this;
}





var gCacheableRequestSet = null;
var gCurHTTPRequest = null;

var HTTPRequest = function() {};
HTTPRequest.prototype = (new Abstract()).extend({
	onReady : function(obj) {},
	callReady : function(txt) {
		this.onReady(txt.length == 0 ? null : txt);
	},
	init : function() {},
	send : function(url) {
		/* status === false: backgroundly download */

		this.cached = null;
		this.url = url;
		this.status = "下载中...";
		this.req = null;
		this.processed = false;
	
		abortDownload();
		gCurHTTPRequest = this;

		//check cache
		this.cached = gCacheableRequestSet.checkCache(this);
		if (this.cached === true) {
			return;
		}

		changeStatus(this.status);

		if (window.XMLHttpRequest) {
			this.req = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			this.req = new ActiveXObject("Microsoft.XMLHTTP");
		}
		if (this.req) {
			var self = this;
			this.req.onreadystatechange = function() {
				self.onStateChange.call(self);
			};
			this.req.open("GET", this.url, true);
			if (this.cached && this.cached.modifyStr) {
				this.req.setRequestHeader("If-Modified-Since", this.cached.modifyStr);
			}
			this.req.send(null);
		}
	},

	onStateChange : function() {
		if (this.req == null) return;
		if (this.req.readyState == 4 && !this.processed) {
			this.processed = true;
			var req = this.req;
			this.req == null;
			if (this.status !== false) {
				hideObj("divStatus");
			}
			if (req.status == 200) {
				this.cached = gCacheableRequestSet.tryAddCache(this);
				this.callReady(req.responseText);
			 } else if (req.status == 304 && this.cached) { // Not Modified
				this.cached.expire = new Date().getTime() + this.cached.ajaxCache * 1000;
				this.callReady(this.cached.content);
			 } else if (req.status == 0) {
				//aborted
			 } else {
				alert("下载数据出错：(" + req.status + ")\n" + req.statusText);
			 }
		} else if (this.req.readyState == 3) {
			var str = this.status;
			if (str !== false) {
				try {
					var contentLength = this.req.getResponseHeader("Content-Length");
					str += " " + Math.floor(this.req.responseText.length * 100 / contentLength) + "% 完成";
				} catch (e) {
				} 
				changeStatus(str);
			}
		}
	},

	abort : function() {
		if (this.req != null) {
			if (this.status !== false) {
				hideObj("divStatus");
			}
			var req = this.req;
			this.req = null;
			req.abort();
		}
	}
});





function abortDownload() {
	if (gCurHTTPRequest != null) gCurHTTPRequest.abort();
}





function CacheItem(modifyStr, ajaxCache, content) {
	this.modifyStr = modifyStr;
	this.modifyVal = Date.parse(modifyStr);
	this.ajaxCache = ajaxCache;
	this.expire = (new Date()).getTime() + ajaxCache * 1000;
	this.content = content;
}

function CacheableRequestSet() {
	this.allURLs = new Object();
}


/*
 * returns:
 * true        - HIT cache and cached content not expired. call onReady function here
 * null        - no cache found
 * a CacheItem - HIT cache but cached content expired. have to check with the server.
 */
CacheableRequestSet.prototype.checkCache = function(request) {
	var url = request.url;
	if (isUndefined(this.allURLs[url])) return null;
	var cacheItem = this.allURLs[url];
	if ((new Date()).getTime() > cacheItem.expire) return cacheItem;
	request.callReady(cacheItem.content);
	return true;
}
CacheableRequestSet.prototype.tryAddCache = function(request) {
	var ajaxCache, modifyStr;
	ajaxCache = 3600; // one hour
	try {
		modifyStr = request.req.getResponseHeader("Last-Modified");
	} catch(e) { }
	var ret = new CacheItem(modifyStr, ajaxCache, request.req.responseText);
	this.allURLs[request.url] = ret;
	return ret;
}


gCacheableRequestSet = new CacheableRequestSet();






var ArticleRequest = function() {};
ArticleRequest.prototype = (new HTTPRequest()).extend({
	init : function(url) {
		this.url = url;
		this.send(url);
	},
	
	onReady: function(txt) {
		var s = txt;
		s = s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
		s = s.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
		if (this.url.indexOf("kbsIntro.txt") != -1) {
			s = kbsIntroProcess(s);
		}
		s = s.replace(/\x20\x20/g, " &nbsp;");
		s = s.replace(/\n /g, "<br/>&nbsp;").replace(/\n/g, "<br/>");
		showArticle(s, this.url);
	}
});



function spaces(num) {
	var str = "          ";
	if (num < 10) return str.substr(0,num);
	else return str;
}
function kbsIntroProcess(s) {
	var toc = "", toc_id = 0;
	s = s.replace(/\n([0-9][^\n]+)/g, function(w,u) {
		toc_id++;
		var indent = u.match(/(\.[0-9]+)/g);
		if (indent) indent = indent.length; else indent = 0;
		toc += spaces(indent*2) + '<a class="toc" href="#a' + toc_id + '">' + u + '</a>\n';
		return '\n<a name="a' + toc_id + '"></a>' + u + '  [ <a class="toc" href="#">回目录</a> ]';
	});
	return toc + "\n\n" + s;
}

function jumpArticle(e) {
	var evt = new AJAXEvent(e);
	var ele = evt.target;
	var url = ele.href;
	if (!url) { /* this is a workaround for Konqueror */
		ele = ele.parentNode;
		url = ele.href;
	}
	if (url) {
		evt.stopEvent();
		ele.blur();
		if (ele.id == "idHome") {
			showArticle(false, url);
		} else {
			(new ArticleRequest()).init(url);
		}
		return false;
	}
}

var homeShow = true;

function showArticle(txt, url) {
	document.body.scrollTop = 0;
	if (txt) {
		getObj("divDoc").innerHTML = txt;
		hideObj("divHome");
		homeShow = false;
	} else {
		getObj("divDoc").innerHTML = "";
		showObj("divHome");
		homeShow = true;
	}
	var ls = document.getElementsByTagName("a");
	for (var i = 0; i < ls.length; i++) {
		var l = ls[i];
		if (l.className == "clsIndex") {
			l.parentNode.className = (l.href == url) ? "clsCurrent" : "";
		}
	}
}



function poorKCN() {
	var divKCNEx = document.createElement("div");
	with(divKCNEx) {
		style.position = "absolute";
		style.display = "none";
		style.border = "2px solid lightblue";
		style.backgroundColor = "yellow";
		style.width = "8em";
		style.height = "2.5em";
		style.padding = "3px";
		style.textAlign = "center";
		innerHTML = "能屈能伸的上帝<br/>&darr;";
	}
	getObj("divHome").appendChild(divKCNEx);
	
	/*
	 ** this doesn't work in IE6/IE7b1 in order to get width/height:
	 * var imgKCN = document.createElement("img");
	 */
	var imgKCN = new Image();
	imgKCN.onload = function() {
		imgKCN.oWidth = imgKCN.width;
		imgKCN.oHeight = imgKCN.height;
		imgKCN.loadState = 1;
	}
	imgKCN.loadState = 0;
	imgKCN.src = "pig.jpg";
	imgKCN.style.position = "absolute";
	imgKCN.style.display = "none";
	imgKCN.style.border = "1px solid blue";
	imgKCN.zIndex = 2;
	getObj("divHome").appendChild(imgKCN);
	
	var sndKCN = null;
	if (document.all) {
		sndKCN = document.createElement("embed");
		sndKCN.autostart = false;
		sndKCN.hidden = true;
		sndKCN.loop = 0;
		sndKCN.src = "pig.mp3";
		document.body.appendChild(sndKCN);
	}
	
	setInterval(function() {
		if (!homeShow) return;
		var o = getObj("idKCN");
		if (o) {
			var bet = Math.floor(Math.random() * 100);
			var recover = true;
			if (imgKCN.loadState == 2) {
				if (bet < 50) {
					var w = imgKCN.width = o.offsetWidth - 2;
					var h = imgKCN.height = imgKCN.oHeight * (w / imgKCN.oWidth);
					imgKCN.style.left = o.offsetLeft;
					imgKCN.style.top = o.offsetTop - (h - o.offsetHeight) / 2;
					imgKCN.style.display = "";
					if (sndKCN) {
						try {
							sndKCN.play();
						} catch(e) {
						}
					}
					divKCNEx.style.display = "none";
					imgKCN.loadState = 1;
					recover = false;
				}
			} else {
				if (bet < 10) {
					o.style.fontSize = "28px";
					o.style.fontWeight = "bold";

					var w = NaN, h = NaN;
					if (divKCNEx.style.pixelWidth) {
						w = divKCNEx.style.pixelWidth;
						h = divKCNEx.style.pixelHeight - 4;
					} else {
						var s = getComputedStyle(divKCNEx, null);
						w = parseInt(s.width);
						h = parseInt(s.height);
					}
					w = (w - o.offsetWidth) / 2;
					if (isNaN(w)) w = 35;
					if (isNaN(h)) h = 35;
					divKCNEx.style.left = (o.offsetLeft - w) + "px";
					divKCNEx.style.top = (o.offsetTop - h - 10) + "px";
					divKCNEx.style.display = "";
					if (imgKCN.loadState) {
						imgKCN.loadState = 2;
						imgKCN.style.display = "none";
					}
					recover = false;
				}
			}
			if (recover) {
				o.style.fontSize = "14px";
				o.style.fontWeight = "normal";
				divKCNEx.style.display = "none";
				if (imgKCN.loadState) {
					imgKCN.style.display = "none";
					imgKCN.loadState = 1;
				}
			}
		}
	}, 1000);
}



function boot() {
	var ls = document.getElementsByTagName("a");
	for (var i = 0; i < ls.length; i++) {
		var l = ls[i];
		if (l.className == "clsIndex") {
			addEvent(l, "click", jumpArticle);
		}
	}

	getObj("idHome").parentNode.className = "clsCurrent";
	
	var ss = document.createElement("div");
	ss.id = "divStatus";
	ss.style.display = "none";
	document.body.appendChild(ss);
	
	poorKCN();
}
