﻿/*Class对象
接受参数:无
返回类型:无

应用技术：
javascript,ajax

制作人：
黄若儒 Roy.Huang

注意:
1、全部采用静态写法，方便继承且减少资源耗损
2、本类为全局管理类（类似于工厂类），用于全局控制整个包系统中的创建包、获取包、设置命名空间、获取类、动态导入类、继承等
*/
var Class=function(){}

Class.PACKAGE_PATH="/SCRIPT/";//默认包路径
Class.CONFIG_NAME_SPACE="Config";//配置类命名空间
Class.SCRIPT_ENCODE="utf-8";//script默认编码
Class.SCRIPT_TYPE="text/javascript";//script默认类型
Class.SCRIPT_LANGUAGE="javascript";//script默认语言
Class.AJAX_VERSIONS=["MSXML2.XMLHttp.5.0","MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp","Microsoft.XMLHttp"];//ajax创建版本
Class.SCRIPT_LOADED_PATH=[];//已经用加载过的js文件地址

Class.createPackage=function(n){//创建一个包
	if(n==null && n.length()<=0)
		return this.onError(7);
	var p=n.split(".");
	var o=window;
	for(var i=0;i<p.length;i++){
		if(!o[p[i]])
			o[p[i]]={};
		o=o[p[i]];
	}
	return o;
};

Class.getPackage=function(n){//返回一个包
	var p=null;
	try{
		p=eval(n);
	}
	catch(e){
		this.onError(4,n);
	}
	return p;
};

Class.setNameSpace=function(s,c){//为一个类设置命名空间
	if(s==null || s.length<=0 || s.indexOf(".")==-1)
		return this.onError(0);
	var p=s.lastIndexOf(".");
	var f=s.substring(p+1);
	p=this.createPackage(s.substring(0,p));
	if(p[f] && p[f]!=c)
		return this.onError(2,s);
	p[f]=c;
};

Class.getClass=function(n,l){//通过命名空间获取一个类
	var c=null;
	try{
		if(n==null || n.length<=0)
			return this.onError(10);
		c=eval(n);
		if(!c) throw "Can't Load";
	}
	catch(e){
		if(l!=false){
			try{
				this.loadClass(n);
				c=eval(n);
				if(!c) throw "Can't Load";
			}
			catch(e){
				this.onError(5,n);
			}
		}
	}
	return c;
};

Class.loadClass=function(ns,fn){//根据命名空间加载类
	if(ns==null)
		return this.onError(13);
	ns=ns.split(",");
	for(var i=0;i<ns.length;i++)
		ns[i]=this.NameSpaceToPath(ns[i]);
	return this.loadFile(ns.join(","),fn);
};

Class.loadFile=function(ps,fn){//根据路径加载类
	try{
		var loadList=[];
		var pa=ps.split(",");
		for(var i=0;i<pa.length;i++){
			var pn=pa[i];
			if(pn==null || pn.length<=0)
				return this.onError(11);
			pn=this.relPathToAbsPath(pn);
			if(pn.lastIndexOf("/")==pn.length-1)
				loadList=loadList.concat(this.getClass(this.CONFIG_NAME_SPACE).getFileByPath(pn));
			else
				loadList.push(pn);
		}
		for(var i=0;i<loadList.length;i++)
			if(this.isLoaded(loadList[i]))
				loadList.splice(i--,1);
		
		if(loadList.length<=0 && fn)
			fn();
		else if(loadList.length>0)
			this.loadFileByAjax(loadList,fn);
	}
	catch(e){
		this.onError(9,ps);
	}
};

Class.loadFileByAjax=function(loadList,fn){//通过ajax加载类
	try{
		var base=this;
		var loadeds=0;
		var asynchronous=fn?true:false;
		var ajax=null;
		for(var i=0;i<loadList.length;i++){
			base.SCRIPT_LOADED_PATH.push(loadList[i]);
			ajax=base.createAjax();
			ajax.onreadystatechange=base.bind(function(){
				if(this.readyState==4 && fn){
					if(this.status==200 || this.status==0){
						base.setScript(this.responseText);
						if(++loadeds>=loadList.length)
							fn();
					}
					else
						base.onError(14,loadList[i]);
				}
			},ajax);
			ajax.open("get",loadList[i],asynchronous);
			ajax.send(null);
			if(!asynchronous){
				if(ajax.status==200 || ajax.status==0)
					base.setScript(ajax.responseText);
				else
					throw 14;
			}
		}
	}
	catch(e){
		this.onError(14,loadList);
	}
};

Class.extend=function(){//全继承
	var s=arguments[0];
	var p=arguments[arguments.length-1];
	if(arguments.length<2)
		s=new Function();
	s.prototype=new p();
	s.prototype.constructor=s;
	this.extendStatic(s,p);
	return s;
};

Class.extendPrototype=function(){//继承Prototype
	var s=arguments[0];
	var p=arguments[arguments.length-1];
	if(arguments.length<2)
		s=new Function();
	if((typeof(s)).toLowerCase()!="function" || (typeof(p)).toLowerCase()!="function")
		return this.onError(3);
	for(var i in p.prototype)
		s.prototype[i]=p.prototype[i];
	return s;
};

Class.extendStatic=function(){//继承Static
	var s=arguments[0];
	var p=arguments[arguments.length-1];
	if(arguments.length<2)
		s=new Function();
	for(var i in p)
		if(i.toLowerCase()!="prototype")
			s[i]=p[i];
	return s;
};

Class.createAjax=function(){//创建ajax对象
	var ajax=null;
	try{
		ajax=new XMLHttpRequest();
		if(ajax.overrideMimeType)
			ajax.overrideMimeType("text/xml");
	}
	catch(e){
		for(var i=0;i<this.AJAX_VERSIONS.length;i++){
			try{
				ajax=new ActiveXObject(this.AJAX_VERSIONS[i]);
			}
			catch(e){}
		}
	}
	if(!ajax) this.onError(8);
	return ajax;
};

Class.setScript=function(str){//设置script
	var h=document.getElementsByTagName("head")[0];
	var script=document.createElement("script");
	script.type=this.SCRIPT_TYPE;
	script.language=this.SCRIPT_LANGUAGE;
	script.charset=this.SCRIPT_ENCODE;
	script.text=str;
	h.appendChild(script);
};

Class.NameSpaceToPath=function(n){//将命名空间转为文件地址
	n=this.replaceAll(n,".","/");
	n=this.PACKAGE_PATH+n;
	if(n.lastIndexOf("*")==n.length-1)
		n=n.substring(0,n.length-1);
	else
		n+=".js";
	return n;
};

Class.relPathToAbsPath=function(rp){//将相对地址转为绝对地址
	var rst=rp;
	var p=-1;
	try{
		rst=this.replaceAll(rst,"\\","/");
		if(rst.indexOf("/")!=0){
			var np=location.pathname;
			np=this.replaceAll(np,"\\","/");
			if(np.lastIndexOf("/")!=np.length-1)
				np=np.substring(0,np.lastIndexOf("/")+1);
			rst=np+rst;
		}
		p=rst.indexOf("../");
		while(p>0){
			var ps=rst.substring(0,p);
			ps=ps.substring(0,ps.substring(0,ps.lastIndexOf("/")-1).lastIndexOf("/")+1);
			rst=ps+rst.substring(p+3,rst.length);
			p=rst.indexOf("../");
		}
		rst=this.replaceAll(rst,"./","");
	}
	catch(e){
		this.onError(12,rp);
	}
	return rst;
};

Class.bind=function(s,t){//对象转置执行
	return function(){return s.apply(t,arguments);};
};

Class.isLoaded=function(n){//判断该js文件是否已经加载
	if(n.indexOf(".")!=-1 && n.indexOf(this.PACKAGE_PATH)==-1)
		n=this.NameSpaceToPath(n);
	for(var i=0;i<this.SCRIPT_LOADED_PATH.length;i++)
		if(this.SCRIPT_LOADED_PATH[i]==n)
			return true;
	var s=document.getElementsByTagName("script");
	for(var i=0;i<s.length;i++)
		if(this.relPathToAbsPath(s[i].src)==n)
			return true;
	return false;
};

Class.replaceAll=function(str,charA,charB){//replace所有
	if(str==null || charA==null || charB==null || charA==charB)
		return this.onError(15);
	while(str.indexOf(charA)!=-1)
		str=str.replace(charA,charB);
	return str;
}

Class.onError=function(e,e1){//错误控制
	switch(e){
		case 0:alert("setNameSpace:方法第一参数必须是包括包名及类名的字符串");break;
		case 1:alert("Import:方法第一参数必须为一个包名命空间");break;
		case 2:alert("setNameSpace:在同一位置已存在相同的类:"+e1);break;
		case 3:alert("extendPrototype:方法中两个参数都必须为类对象(function)");break;
		case 4:alert("getPackage:该包不存在:"+e1);break;
		case 5:alert("getClass:无法获取该类:"+e1);break;
		case 6:alert("include:主程序存在名称相同，功能不同的类:"+e1);break;
		case 7:alert("createPackage:请填写正确的包名");break;
		case 8:alert("createAjax:无法创建AJAX对象");break;
		case 9:alert("loadFile:无法找到该文件:"+e1);break;
		case 10:alert("getClass:方法第一参数必须是包括包名及类名的字符串");break;
		case 11:alert("loadFile:方法第一参数必须为文件路径");break;
		case 12:alert("relToAbsPath:无效相对路径:"+e1);break;
		case 13:alert("loadClass:第一参数不能为空");break;
		case 14:alert("loadFileByAjax:无法找到该文件:"+e1);break;
		case 15:alert("replaceAll:操作错误，注意输入参数");break;
		default:alert(e);
	}
	return false;
};