/*  Ajax Javascript Development Framework		version 1.4.5
 *  (c) 2006-2008 purple.calm@gmail.com
 *
 * 
 *  For details, send mail to purple.calm@gmail.com
 *
 *	What's new
 *
 *	Other: added an upload file plugin
 *
 * version 1.4	This version we Created a $E Class
 *				Add Exception on Handle	1.4.1
 *				Add $G name space			1.4.2
 *				Repair the timeout Bug	1.4.4
 *
 *	version 1.3	This version we deal the params fairily in 1.3.0
 *				Repair the send method in 1.3.1
 *				Add Cancel method in 1.3.2
 *				Add Register&Remove Event method 1.3.3
 *				Add Register onload method 1.3.3
 *
 *	version 1.2	This version has solved the bug of Exceptions in FireFox
 *
 *	version 1.1	This version add check status in response handle and prototype's $() method
 *
 *
 *	lastmodified	purple.calm	12:48 PM 4/17/2008
 *
/*--------------------------------------------------------------------------*/


/**
 * here copy of prototype.js
 */

function $(element){
	var elements;
	if (arguments.length > 1) {
    	for (var i = 0, elements = [], length = arguments.length; i < length; i++)
    		elements.push($(arguments[i]));
    	return elements;
	}
	if (typeof element == "string")
		return document.getElementById(element);
}

window.errors=window.errors?window.errors:new Array();

Array.prototype.empty=function(){
	while(this.length)
		this.pop();
}

function childrenOf(element){
	var result=new Array();
	if(element.nodeType==1&&element.childNodes.length){
		var i=0;
		while(element.childNodes[i++].nodeType==1&&i!=element.childNodes.length)
			result.push(element.childNodes[i-1]);
	}
	return result;
}

/**
 * class _A
 *
 * @param	string	_url
 *		|	stands for request url
 *
 * @param	string	_method
 *		|	stands for [POST|GET] method for XMLHttpRequest
 *
 * @param	boolen	_need_handle
 *		|	stands for [true|false]	if XMLHttpRequest object need handle
 *
 */
function _A(_url,_method,_need_handle){
	
	this.$request=null;

	this.$deal=null;

	this.$fail=null;

	this.$useUnique=false
	
	if(window.XMLHttpRequest){

		this.$request=new XMLHttpRequest();

	}else if(typeof ActiveXObject != "undefined"){

		this.$request=new ActiveXObject("Microsoft.XMLHTTP");

	}else{

		return false;

	}
	
	this.$isSending=false;

	this.$url=(typeof _url=="undefined")?"":_url;

	this.$method=(typeof _method=="undefined")?"POST":_method;

	this.$params=null;
	
	this.$timeout=40000;

	this.ontimeout=function(){msg("time out");}

	this.$needhandle=(typeof _need_handle=="undefined")?true:_need_handle;

}

/**
 *
 * parser method
 * send the quest and set the success & fail handle
 *
 * @param	string	_deal
 *		|	stands for the string of success handle method
 *
 * @param	string	_fail_handle
 *		|	stands for the string of fail handle method
 *
 */
_A.prototype.parse=function(_deal,_fail_handle){

	this.$deal=_deal;

	this.$fail=_fail_handle;

	this.send();

}


/**
 * if you want an unique param added
 */
_A.prototype.useUnique=function(_use){

	if(typeof _use == "undefined" || _use){

		this.$useUnique=true;

	}else{

		this.$useUnique=false;

	}

}


/**
 *
 * getParams method
 * get all params
 *
 */
_A.prototype.getParams=function(){

	var method;

	var first=true;

	var result=new Array();

	for (method in this){

		if (typeof this[method]!="function" && method.charAt(0)!="$"){
			result.push(method+"="+encodeURIComponent(this[method]));
		}
	}

	this.$params=result.join("&");

	if(this.$useUnique){
		this.$params+="&UNKEY="+new Date().getTime();
	}
}

/**
 * clear method
 * clean all params
 */
_A.prototype.clear=function(){

	var method;

	for (method in this){

		if (typeof this[method]!="function" && method.charAt(0)!="$"){

			delete this[method];

		}
	}

	this.$params=null;
}

/**
 * send params
 */
_A.prototype.send=function(){

	this.getParams();

	if(this.$method=="GET"){

		this.$request.open(this.$method,this.$url+"?"+this.$params,this.$needhandle);

	}else{

		this.$request.open(this.$method,this.$url,this.$needhandle);

	}
	
	var quest=this.$request,s=this.callSuccess,f=this.callFail,deal=this.$deal,fail=this.$fail;
	var _self=this;
	
	timeout=window.setTimeout(this.timeout,this.$timeout,this);
	
	if(this.$needhandle){
		var handle=this.handle;
		this.$request.onreadystatechange=function(){
			handle(quest,s,f,deal,fail,timeout,_self);
		}
	}
	
	this.$request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

	if(this.$method=="GET"){

		this.$request.send(null);
		
		this.handle(quest,s,f,deal,fail,timeout);

	}else{

		this.$request.send(this.$params);

	}

	this.$isSending=true;

}

/**
 * get response
 * use method
 * 
 * example
 * 
 *	after parse
 *
 * 1.xml responseXML
 *		ajaxObject.$("xml");
 *
 * 2.text responseText
 *		ajaxObject.$("text");
 *
 * 3.body responseBody
 *		ajaxObject.$("body");
 *
 * 4.stream responseStream
 *		ajaxObject.$("stream");
 *
 * 5.header	response Header
 *		1. ajaxObject.$("header");
 *		2. ajaxObject.$("header","Content-Type");
 *		3. ajaxObject.$("Content-Type");
 *
 * 6.allHeader response all header
 *		ajaxObject.$("allHeader");
 *
 * 7.error
 *
 * 8.errorCode
 *
 * 9.default responseText
 *		ajaxObject.$();
 *
 */
_A.prototype.$=function(method){

	if(!arguments.length)
		return this.$request.responseText;

	switch(method){
		case "text":
			return this.$request.responseText;

		case "xml":
			return this.$request.responseXML;

		case "body":
			return this.$request.responseBody;

		case "stream":
			return this.$request.responseStream;

		case "allHeader":
			return this.$request.getAllResponseHeader();

		case "error":
			return this.$error;

		case "errorCode":
			return this.$errorCode;

		case "header":
			if(arguments.length==2){
				return this.$request.getResponseHeader(arguments[1]);
			}
			return this.$request.getResponseHeader();

		default:
			return this.$request.getResponseHeader(method);
	}

}

/**
 *
 * set success and fail handle
 *
 */
_A.prototype.handle=function(r,s,f,d,g,t,_self){
		
	try{

		if(r.readyState==4){

			_self.$isSending=false;
			
			window.clearTimeout(t);

			if(r.status==200||r.status==304||r.status==0){

				s(d);

			}else{
				
				_self.$errorCode=r.status;
				_self.$error=r.statusText;
				
				f(g);
				
				throw new HandleException(r.status,r.statusText);
			}

		}

	}catch(e){
		window.errors.push("Name"+ e.name +"\nMessage:"+e.message+"\nStatus:"+r.status);
	}

}

_A.prototype.callSuccess=function(_deal){
	try{
		if(typeof _deal=="function"){
			_deal.call();
		}else{
			if(_deal.charAt(_deal.length-1)!=")"){
				eval(_deal+"()");
			}else{
				eval(_deal);
			}
		}
	}catch(e){
		throw new HandleException("Call Sucess Method Error");
	}
}

_A.prototype.callFail=function(_fail){
	try{
		if(typeof _fail=="function"){
			_fail.call();
		}else{
			if(_fail.charAt(_deal.length-1)!=")"){
				eval(_fail+"()");
			}else{
				eval(_fail);
			}
		}
	}catch(e){
		throw new HandleException("Call Fail Method Error");
	}
}

_A.prototype.timeout=function(_self){

	if(!_self.$isSending){
		return false;
	}

	try{
		_self.$errorCode=-1;
		_self.$error="Time Out";
		_self.cancel(_self);
		_self.ontimeout();
		
		throw new HandleException(-1,"Time Out");
	}catch(e){
		window.errors.push("Name:"+e.name+"\nMessage:"+e.message+"ErrorCode:"+e.code);
	}
}

/**
 *
 * Cancel this request
 *
 */
_A.prototype.cancel=function(_self){
	try{
		if(_self.$isSending){
			_self.$request.abort();
			_self.$isSending=false;
		}
	}catch(e){}
}

function HandleException(code,name){
	this.code=code;
	this.name=name;
}

HandleException.prototype=new Error("Ajax Exception");

HandleException.prototype.constructor=HandleException;



/**
 *
 * Register a Event
 *
 * @param n
 *		| stands for the Event Node
 *
 * @param e
 *		| stands for the Event Name
 *
 * @param f
 *		| stands for the Function when Event
 *
 */
var RegisterEvent=function(n,e,f,r){

	var method=true;

	if(typeof r!="undefined"){
		method=(r!=false);
	}

	if(document.addEventListener){
		// level 2 DOM prototype
		var eve=e.indexOf("on")==0?e.replace("on",""):e;

		try{
			n.addEventListener(eve,f,method);
			return true;
			
		}catch(e){
			return false;
		}

	}else if(document.attachEvent){
		// only for IE 5.0+
		var eve=e.indexOf("on")==0?e:"on"+e;

		try{
			n.attachEvent(eve,f);
			return true;

		}catch(e){
			return false;
		}

	}else{
		return false;
	}
}

/**
 *
 * Remove a Event
 *
 * @param n
 *		| stands for the Event Node
 *
 * @param e
 *		| stands for the Event Name
 *
 * @param f
 *		| stands for the Function when Event
 *
 */
var RemoveEvent=function(n,e,f,r){

	var method=true;

	if(typeof r!="undefined"){
		method=(r!=false);
	}

	if(document.addEventListener){
		// level 2 DOM prototype
		var eve=e.indexOf("on")==0?e.replace("on",""):e;

		try{
			n.removeEventListener(eve,f,method);
			return true;
			
		}catch(e){
			return false;
		}

	}else if(document.attachEvent){
		// only for IE 5.0+
		var eve=e.indexOf("on")!=0?e.replace("on",""):e;
		try{
			n.detachEvent(eve,f);
			return true;

		}catch(e){
			return false;
		}

	}else{
		return false;
	}
}

try{
	Element.prototype.registerEvent=function(e,f,r){
		RegisterEvent(this,e,f,r);
	}

	Element.prototype.removeEvent=function(e,f,r){
		RemoveEvent(this,e,f,r);
	}
}catch(e){
	//parse error
}

var EventStopProp=function(event){

	if(document.addEventListener){
		// level 2 DOM prototype

		try{
			event.stopPropagation();
			event.preventDefault();
		}catch(e){
			return false;
		}

	}else if(document.attachEvent){
		// only for IE 5.0+
		try{
			event.cancelBubble=true;
			event.returnValue=false;
		}catch(e){
			return false;
		}

	}else{
		return false;
	}
}

function $E(tagName,settings){
	
	if(tagName){
	
		this.tagName=tagName;
		
		this.$node=document.createElement(this.tagName);
		
		this.firstChild=null;
		this.lastChild=null;
		this.previousSibling=null;
		this.nextSibling=null;
		this.childNodes=null;
		this.parentNode=null;
		
		$E.set(this.$node,settings);
	}
	
//	var self=this;

//	this.firstChild=(function(node){ return node.tagName; })(self.$node);
}

$E.set=function(node,settings){
	
	if(settings){
		//alert(node.tagName);
		for(var method in settings)
		if(typeof node[method]=="string"){
				node[method]=settings[method];
			}else{
				for(var subMethod in settings[method]){
					node[method][subMethod]=settings[method][subMethod];
				}
			}
	}	
}

$E.prototype={
	getNode: function(e){
		if(typeof e!="object"){
			return false;
		}
		
		if(e.$node)
			return e.$node;
			
		return e;
	},

	reset: function(settings){
	
		if(typeof settings=="undefined")
			var settings=this.$settings;
		else
			this.$settings=settings;
		
		$E.set(this.$node,settings);
	},

	insertTo: function(element){
		if(element){
			try{
				var n=this.getNode(element);
				n.appendChild(this.$node);
				this.refresh();
			}catch(e){
				alert(e.message);
			}
		}
	},

	remove: function(){
		try{
			this.$node.parentNode.removeChild(this.$node);
			this.refresh();
		}catch(e){
		}
	},

	show: function(display){
		try{
			this.$node.style.display=display?display:"block";
		}catch(e){
		}
	},

	appendBefore: function(parent,child){
		try{
			var c=this.getNode(child),p=this.getNode(parent);
			p.insertBefore(this.$node,c);
			this.refresh();
		}catch(e){
			alert(e.message);
		}
	},

	replace: function(node){

		try{
			var n=this.getNode(node);
			this.$node.parentNode.replaceChild(n,this.$node);
			this.$node=n;
			this.refresh();
		}catch(e){
		}

	},

	hide: function(){
		try{
			this.$node.style.display="none";
		}catch(e){
		}
	},

	appendChild: function(node){
		try{
			
			if(typeof node=="string"){
				var n=document.createTextNode(node);
			}else{
				var n=this.getNode(node);
			}
			this.$node.appendChild(n);
			this.refresh();
		}catch(e){
			alert(e.message);
		}
	},

	removeChild: function(node){
		try{
			var n=this.getNode(node);
			this.$node.removeChild(n);
			this.refresh();
		}catch(e){
			alert(e.message);
		}
	},

	insertBefore: function(node,child){
		try{
			var n=this.getNode(node);
			var c=this.getNode(child);
			this.$node.insertBefore(n,c);
			this.refresh();
		}catch(e){
			alert(e.message);
		}
	},

	replaceChild: function(node,child){
		try{
			var n=this.getNode(node);
			var c=this.getNode(child);
			this.$node.insertBefore(n,c);
			this.refresh();
		}catch(e){
			alert(e.message);
		}
	},

	refresh: function(){
		this.firstChild=this.$node.firstChild;
		this.lastChild=this.$node.lastChild;
		this.previousSibling=this.$node.previousSibling;
		this.nextSibling=this.$node.nextSibling;
		this.childNodes=this.$node.childNodes;
		this.parentNode=this.$node.parentNode;
	},

	addEventListener: function(e,f,r){
		RegisterEvent(this.$node,e,f,r);
	},

	removeEventListener: function(e,f,r){
		RemoveEvent(this.$node,e,f,r);
	}
}

/*** Iframe ***/
function Iframe(settings,isUpload){
	if(window.ActiveXObject) {
		this.$node=document.createElement('<iframe id="' + settings.id + '" name="' + settings.name + '" />');
	}else{
		this.$node=document.createElement("iframe");
	}

	
	if(isUpload){
		this.$node.style.position="absolute";
		this.$node.style.left="-3456px";
		this.$node.style.top="-2345px";
	}
	
	if(settings)
		this.reset(settings);
}

Iframe.prototype=new $E();

Iframe.prototype.constructor=Iframe;

Iframe.prototype.loadTodo=function(todo){
	try{
		
		var _self=this;
		
		RegisterEvent(_self.$node,"load",function(){
			try{
				
				_self.response=_self.$node.contentWindow.document.body.innerHTML;
				todo(_self);
				
			}catch(e){
				alert("error occurred when iframe loaded\nname:"+e.name+"\nmessage:"+e.message);
			}
		});
	}catch(e){
		
	}
}

/*** Form ***/
function _Form(settings){
	
	this.$node=document.createElement("form");

	if(typeof settings.method =="undefined"){
		settings.method="post";
	}
	
	if(settings)
		this.reset(settings);
}

_Form.prototype=new $E();

_Form.prototype.constructor=_Form;

_Form.prototype.submit=function(){
	this.$node.submit();
}

_Form.prototype.setAction=function(action){
	this.$node.action=action;
}

_Form.prototype.setTarget=function(target){
	this.$node.target=target;
}

function Div(settings){

	this.$node=document.createElement("div");

	if(settings)
		this.reset(settings);
}

Div.prototype=new $E();

Div.prototype.constructor=Div;

function Li(settings){

	this.$node=document.createElement("li");

	if(settings)
		this.reset(settings);
}

Li.prototype=new $E();

Li.prototype.constructor=Li;


window.msg=window.alert;

var $G={

	version: "1.4.5",

	/** HTML Element **/
	H: $E,

	/** HTML From Element **/
	Form: _Form,

	/** HTML Iframe Element **/
	Iframe: Iframe,

	/** HTML Div Element **/
	Div: Div,

	/** HTML Li Element **/
	Li: Li,

	/** _A Quest **/
	Q: _A,

	debugModule: true,

	msg: window.msg,

	showError: window.msg,

	doNothing: function(){},

	newEve: RegisterEvent,

	delEve: RemoveEvent
}

if(!$G.debugModule){ window.alert=$G.doNothing; window.onerror=$G.doNothing; }

if(typeof Ajax=="undefined"){
	var Ajax=_A;
}

if(typeof PAjax=="undefined"){
	var PAjax=_A;
}

if(typeof window.LOAD=="undefined"){
	window.LOAD=new Array();
}

/**
 *
 *	Register an onload method
 *
 */
var RegOnload=function(arg){
	window.LOAD.push(arg);
}

var _INIT_ONLOAD_EVENT_=function(){

	for(var func,i=0;i<LOAD.length;i++){
		try{
			func=LOAD[i];
			if(typeof func=="string"){
				eval(func);
			}else if(typeof func=="function"){
				func.call();
			}
		}catch(e){
			window.errors.push(e.name+" "+e.message);
		}
	}

}

RegisterEvent(window,"load",_INIT_ONLOAD_EVENT_,true);