//
// my utils functions, wbshang<wbshang@gmail.com>
//
/**
 * create the XMLHttpRequest object
 */
function getObjReq() {
	var request = false;
	try {
		request = new XMLHttpRequest();
	} catch (trymicrosoft) {
		try {
			request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (othermicrosoft) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				request = false;
			}  
		}
	}

	if (!request)
		alert("Error initializing XMLHttpRequest!");
	return request;
}

/**
 * parse the response text of XMLHttpRequest
 */
function parseResponse(text) {
	if(text.length == 0)
		return '';
	if(text.charAt(0) == '{')
		text = '(' + text + ')';
	else if(text.charAt(0) != '[')
		return text;
	return eval(text);
}

function doHttpRequest(url,postData,callbackFunc,sync) {
	document.body.style.cursor = "wait";
	var request = getObjReq();
	var async = sync ? false : true;
	request.open(postData?"POST":"GET", url, async);
	if(async) {
		request.onreadystatechange = function() {
			if (request.readyState == 4) {
				if (request.status == 200) {
					callbackFunc(parseResponse(request.responseText));
					document.body.style.cursor = "default";
				}
			}
		}
	}
	if(postData) {
		request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		request.setRequestHeader("Content-Length",postData.length);
	}
	request.send(postData);
	if(!async) {
		callbackFunc(parseResponse(request.responseText));
		document.body.style.cursor = "default";
	}
	return request;
}

/**
 * add a event on a element
 * three phases:
 *  1. capturing phase, from Document object down through the document tree to the target node
 *  2. the target node itself
 *  3. bubbling phase, from the target element up to the Document object
 * usage: addEvent(window, 'load', setAnchors, false);
 * param useCapture: whether to trigger this event during the capturing phase of event propagation
 */
function addEvent(elm, evType, fn, useCapture) {
	if (elm.addEventListener)
		elm.addEventListener(evType, fn, useCapture);
	else if (elm.attachEvent) {
		var r = elm.attachEvent('on' + evType, fn);
		return r;
	}
	else
		elm['on' + evType] = fn;
	return true;
}

/**
 * className operations
 */
function hasClassName(ele, className) {
	var tmp;
	if(ele == null || !ele.className)
		return false;
	tmp = " " + ele.className + " ";
	return (tmp.indexOf(" " + className + " ") >= 0);
}

function addClassName(ele, className) {
	if(hasClassName(ele, className))
		return; 
	ele.className = [ele.className, className].join(' ');
}

function removeClassName(ele, className) {
	if(!hasClassName(ele, className))
		return; 
	var pattern = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');
	ele.className = ele.className.replace(pattern, ' ');
}

function getElementsByClassName(node, classname, tagname) {
    var a = [];
    var re = new RegExp('\\b' + classname + '\\b');
    var els = node.getElementsByTagName(tagname ? tagname : "*");
    for(var i=0,j=els.length; i<j; i++) {
        if(re.test(els[i].className))
			a.push(els[i]);
	}
    return a;
}

/**
 * add a instance method for Array
 * Searches the array for a given value
 * Returns the corresponding key if the value is found in the array, FALSE otherwise.
 */
Array.prototype.find = function(value) {
	for(var i=0; i<this.length; i++) {
		if(this[i] == value)
			return i;
	}
	return false;
};

/**
 * method bind
 *  for example, in the following code snip:
 *      this.cHandler = this.clickBut.bind(a,b,c);
 *  now, 
 *		this.cHandler = function() {
 *			return this.clickBut.apply(a,[b,c].concat(arguments));
 *		}
 */
Function.prototype.bind = function(obj){
	if(typeof this != "function"){
		throw new Error("Bind must be called as a method of a function object.");
	}
	var func = this;
	// get all arguments except the first one
	var baseArgs = Array.prototype.splice.call(arguments, 1, arguments.length); 

	return function() {
		var args = baseArgs.concat(); // duplicate baseArgs
		for(var i=0; i<arguments.length; i++)
			args.push(arguments[i])

		return func.apply(obj, args)
	}
};

/**
 * parse the part of location
 * param part: hash or search
 */
function parse_location(part) {
	var str = location[part];
	if(str.length > 0)
		str = str.substring(1);
	var a = str.split('&');
	var params = {};
	for(var i=0; i<a.length; i++) {
		var b = a[i].split('=');
		if(b.length == 2)
			params[b[0]] = b[1];
	}
	return params;
}

/**
 * generate a uri
 */
function generate_uri(baseuri, p) {
	if(typeof p == "string")
		return baseuri + '?' + p;
	else
		return baseuri + '?' + p.join("&");
}

/**
 * update page state
 * param level - the message level:
 *  1: message
 *  2: warning
 *  3: error
 *  4: emphasis, use a alert currently
 */
var stateTimeoutID = 0;
function update_state(msg, level) {
	if(!level)
		level = 1;
	var msgtxt = "";
	if(typeof msg == "object") {
		for(var i in msg)
			msgtxt += i + ": " + msg[i] + '; ';
	}
	else
		msgtxt = msg;
	if(level == 4) {
		alert(msgtxt);
		return;
	}
	var sa = document.getElementById("state_area");
	if(!sa) {
		sa = document.createElement("div");
		sa.id = "state_area";
		document.body.appendChild(sa);
	}
	sa.innerHTML = msgtxt;
	sa.className = "message-level"+level;
	if(stateTimeoutID)
		window.clearTimeout(stateTimeoutID);
	stateTimeoutID = window.setTimeout(
		'document.getElementById("state_area").className = "invisible"', 15000);
}

function lock_page(msg) {
	var lock_layer = document.getElementById("lock_layer");
	if(!lock_layer) {
		lock_layer = document.createElement("div");
		lock_layer.id = "lock_layer";
		document.body.appendChild(lock_layer);
	}
	if(typeof msg == "undefined")
		msg = "处理中，请稍后";
	lock_layer.innerHTML = msg;
	lock_layer.style.display = "block";
}

function unlock_page() {
	try {
		document.getElementById("lock_layer").style.display = "none";
	} catch(e) {}
}

