var BROWSER_IE = window.navigator.userAgent.indexOf("MSIE") != -1;
var SCRIPT_TIMEOUT = 20000;

function pageimport(url, fCallback, fError){
    if (typeof(fCallback) != "function") fCallback = new Function();
    if (typeof(fError) != "function") fError = new Function();

    var oScriptEl, oTimeoutHDL, oHead;
    var iutl = url.substring(url.lastIndexOf("."),url.length);
    if(iutl.indexOf("css")>0){
         oScriptEl = document.createElement("link");
         oScriptEl.type = "text/css";
         oScriptEl.rel = "stylesheet";
         oScriptEl.href = url;	
         oScriptEl.onreadystatechange = doCallback;
    } else if(iutl.indexOf("js")>0){
	     oScriptEl = document.createElement("script");
	     oScriptEl.type = "text/javascript";
	     oScriptEl.language = "javascript";
	     oScriptEl.src = url;
	     oScriptEl.onreadystatechange = doCallback;
    }
    if (BROWSER_IE){
         oScriptEl.onload = function(){
            this.readyState = "complete";
             doCallback(); 
         };
     };
    
     oTimeoutHDL = window.setTimeout(doError, SCRIPT_TIMEOUT);
     document.getElementsByTagName("head")[0].appendChild(oScriptEl);
    function doCallback(){
        if (oScriptEl.readyState == "complete" || oScriptEl.readyState == "loaded"){
             oScriptEl.onload = oScriptEl.onreadystatechange = new Function();
             fCallback();
             window.clearTimeout(oTimeoutHDL);
         }
     };

    function doError(){
         oScriptEl.parentNode.removeChild(oScriptEl);
     };     
};



//同步加载
function GetHttpRequest() 

{ 

      if ( window.XMLHttpRequest ) // Gecko 

        return new XMLHttpRequest() ; 

    else if ( window.ActiveXObject ) // IE 

        return new ActiveXObject("MsXml2.XmlHttp") ; 

} 



function AjaxPageimport(sId, url, fCallback, fError){ 

      var oXmlHttp = GetHttpRequest() ; 



      oXmlHttp.OnReadyStateChange = function()  

      { 

        if ( oXmlHttp.readyState == 4 ) 

          {

            if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 ) 

              {
              	
                  IncludeJS( sId, url, oXmlHttp.responseText,fCallback, fError );

              } 

            else 

              { 

                  alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ; 

              } 

          } 

      } 



      oXmlHttp.open('GET', url, true); 

      oXmlHttp.send(null); 
      
//      eval( oXmlHttp.responseText); 
      
} 



function IncludeJS(sId, fileUrl, source,fCallback, fError) { 
	
      if ( ( source != null ) && ( !document.getElementById( sId ) ) ){ 
      	
      	  if (typeof(fCallback) != "function") fCallback = new Function();
      	  
          if (typeof(fError) != "function") fError = new Function();
      	
          var oScript,oTimeoutHDL;
          
          var oHead = document.getElementsByTagName('HEAD').item(0); 
          
          var iutl = fileUrl.substring(fileUrl.lastIndexOf("."),fileUrl.length);
          
          if(iutl.indexOf("js")>0){
          	
	          oScript = document.createElement( "script" ); 
	
	          oScript.language = "javascript"; 
	
	          oScript.type = "text/javascript"; 
	
	          oScript.id = sId; 
	
	          oScript.defer = true; 
	
	          oScript.text = source;    
  	          
              oScript.onreadystatechange = doCallback;
	         
          }else if(iutl.indexOf("css")>0){
          	
	          oScript = document.createElement("link");
	          
	          oScript.type = "text/css";
	          
	          oScript.rel = "stylesheet";
	          
	          oScript.href = fileUrl;
	          
	          oScript.onreadystatechange = doCallback;
	          
          }
          
         if (BROWSER_IE){
	         oScript.onload = function(){
	            this.readyState = "complete";
	             doCallback(); 
	         };
         };
          
          oTimeoutHDL = window.setTimeout(doError, SCRIPT_TIMEOUT);
          
          oHead.appendChild( oScript );
	      
      } 
      
      function doCallback(){
//      	alert("oScript.readyState    "+oScript.readyState);
        if (oScript.readyState == "complete" || oScript.readyState == "loaded"){
             oScript.onload = oScript.onreadystatechange = new Function();
             fCallback();
             window.clearTimeout(oTimeoutHDL);
         }
     };

    function doError(){
         oScript.parentNode.removeChild(oScript);
     };     
     

} 






JSLoader=function (){    
    var cbArr = new Array();    
    function execCBs(){    
        for(var i=0;i<cbArr.length;i++){    
            if(cbArr[i].cb){    
                try{    
                    if(typeof(cbArr[i].cb) == "function"){    
                        if(typeof(cbArr[i].scope)!="undefined")    
                            cbArr[i].cb.call(cbArr[i].scope)    
                        else   
                            cbArr[i].cb();    
                    }    
                }    
                catch(e){alert('script error!')};    
                cbArr.splice(i--,1);    
            }    
        }    
    };    
    return {    
        //加载后的回调    
        onReady : function(callBack,d){    
            cbArr.push({cb : callBack,scope : d});    
        },    
        //回调方法的运行    
        execFcs : function(){    
            execCBs();    
        },    
        Ajax : {    
            //AJAX实现  
            request:function(sId,fileName,obj){
            	 var oXmlHttp = GetHttpRequest() ; 
			      oXmlHttp.OnReadyStateChange = function(){ 
			        if( oXmlHttp.readyState == 4 ){
			            if(oXmlHttp.status == 200 || oXmlHttp.status == 304){
                              obj.success(oXmlHttp,sId,fileName);			                
			              }else{ 
			                  alert('XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')') ; 
			              } 
			          } 
			      } 
			      oXmlHttp.open('GET', fileName, true); 
			      oXmlHttp.send(null); 
            }  
        }    
    };    
}();    
   
JSLoader.jsCache = {currentLevel:1,levelCounter:1,ready:false};    
JSLoader.require=function(sId,fileName){    
   
    var inStack = false;    
    if(JSLoader.jsCache[fileName]){    
        return;    
    }else{    
        var js = new Js(fileName);    
        JSLoader.jsCache[fileName] = js;    
        JSLoader.jsCache.ready=false;    
        var currentLevel = JSLoader.jsCache.levelCounter++;    
        JSLoader.Ajax.request(sId,fileName,{    
                success:function(response,sId,fileName){    
                        JSLoader.jsCache[fileName].loaded = true;    
                        JSLoader.jsCache[fileName].content =  response.responseText;   
                        JSLoader.jsCache[fileName].fileName  = fileName;  
                        JSLoader.jsCache[fileName].sId  = sId;  
                        JSLoader.jsCache[currentLevel] = JSLoader.jsCache[fileName]  
                        executeScript(currentLevel);    
                    },    
                scope:this   
            }    
   
        );    
    }    
   
    function executeScript(executeLevel){    
        if(executeLevel == JSLoader.jsCache.currentLevel    
            && JSLoader.jsCache[executeLevel].loaded){    
   
            Include_JS(JSLoader.jsCache[executeLevel]);
//            executeJs(JSLoader.jsCache[executeLevel]);  
               
   
            if(executeLevel == (JSLoader.jsCache.levelCounter - 1))    
                JSLoader.execFcs();    
   
            if(++JSLoader.jsCache.currentLevel < JSLoader.jsCache.levelCounter    
                    && JSLoader.jsCache[JSLoader.jsCache.currentLevel]    
                    && JSLoader.jsCache[JSLoader.jsCache.currentLevel].loaded){    
                executeScript(JSLoader.jsCache.currentLevel);    
            }    
        }    
    };    

	function Include_JS(jsObj,f_Callback, f_Error) { 
		
	
	      if ( ( jsObj.content != null ) && ( !document.getElementById( jsObj.sId ) ) ){ 
	      	
	      	  if (typeof(f_Callback) != "function") f_Callback = new Function();
	      	  
	          if (typeof(f_Error) != "function") f_Error = new Function();
	      	
	          var o_Script,o_TimeoutHDL;
	          
	          var oHead = document.getElementsByTagName('HEAD').item(0); 
	          
	          var iutl = jsObj.fileName.substring(jsObj.fileName.lastIndexOf("."),jsObj.fileName.length);
	          
	          if(iutl.indexOf("js")>0){
	          	
		          o_Script = document.createElement( "script" ); 
		
		          o_Script.language = "javascript"; 
		
		          o_Script.type = "text/javascript"; 
		
		          o_Script.id = sId; 
		
		          o_Script.defer = true; 
		
		          o_Script.text = jsObj.content; 
		          
	              o_Script.onreadystatechange = doCallback;
		         
	          }else if(iutl.indexOf("css")>0){
	          	
		          o_Script = document.createElement("link");
		          
		          o_Script.type = "text/css";
		          
		          o_Script.rel = "stylesheet";
		          
		          o_Script.href = jsObj.fileName;
		          
		          o_Script.onreadystatechange = do_Callback;
		          
	          }
	          
	         if (BROWSER_IE){
		         o_Script.onload = function(){
		            this.readyState = "complete";
		             do_Callback(); 
		         };
	         };
	          
	          o_TimeoutHDL = window.setTimeout(do_Error, SCRIPT_TIMEOUT);
	          
	          oHead.appendChild( o_Script );
		      
	      } 
	      
	      function do_Callback(){
	//      	alert("oScript.readyState    "+oScript.readyState);
	        if (o_Script.readyState == "complete" || o_Script.readyState == "loaded"){
	             o_Script.onload = o_Script.onreadystatechange = new Function();
	             jsObj.content = null;    
                 jsObj.excuted = true;    
                 jsObj.content = false;  
	             f_Callback();
	             window.clearTimeout(o_TimeoutHDL);
	         }
	     };
	
	    function do_Error(){
	         o_Script.parentNode.removeChild(oScript);
	     };     
	     
	
	}  
    function executeJs(jsObj){    
        if(window.executeScript){    
            window.executeScript(jsObj.content);    
        }else if(window.execScript){    
            window.execScript(jsObj.content)    
        }else{    
            window.eval(jsObj.content);    
        }    
        jsObj.content = null;    
        jsObj.excuted = true;    
        jsObj.content = false;    
    }    
   
    function Js(fn){    
        this.fileName=fn;    
        this.loaded=false;    
        this.content=null;    
        this.excuted=false;    
    }    
}  

































 /**
  * @param {boolean} debug true 意味着当前模式为调试模式，如果程序捕捉到错误，将会alert错误，反之，不会。默认为true
  */
//(function(debug){
//	if(typeof window.bingo != "undefined") return;//防止多次加载
	
	//全局变量
	var debug
	var libQueue = [];//待加载外部库队列
	var namespaceList = [];//命名空间列表，结构{name : "namespace",state : "loading|loaded"}
	var fileList = [];//待加载文件列表
	var isAllLoaded = false;//是否所有文件都已加载完成
	var error = [
				   new Error("<pageimport: js file is not loaded>"),
				   new Error("<pageimport: waiting for all js files to be loaded>"),
				   new Error("pageimport: $import's caller is not a function"),
				   new Error("pageimport: pageimport can not work on your browser,please change another one"),
				   new Error("pageimport: the giving namespace is empty")
			   ];
	
	var agent = window.navigator.userAgent.toLowerCase();
	var script = document.getElementsByTagName("SCRIPT");
	var curFilePath = script[script.length-1].src;//当前路径
	var pageimport = {
		version : "0.1",
		browser : {
			version : (agent.match(/.+(?:pe6?|or|ox|it|ra|ie|rv)[\/: ]([\d.]+)/) || [])[1],
			name	: /(netscape|firefox|opera|msie|safari|konqueror)/.test(agent) ? RegExp.$1 :
						(/webkit/.test(agent) ? "safari" : (/mozilla/.test(agent) ? "mozilla" : "unknown")),
			mode 	: document.compatMode == "CSS1Compat" ? "standard" : "quirk"
		}
	};
	
	window.pageimport = pageimport;
	//window.$import = $import;在IE下有不可思议的bug，详见http://bbs.51js.com/thread-74614-1-3.html
	$import = _import;
	window.include = include;
	window.onerror = function(err){
		var msg = err.toString();
		if(/^<pageimport:/.test(msg)) return true;
		else if(/^pageimport:/.test(msg) && debug){
			alert(msg);
			return true;
		}
	};

	/**
	 * 按顺序执行队列里的函数,同时引入命名空间
	 */
	libQueue.run = function(){
		var i = this.length;
		while(i-- > 0){
			if(isAllLoaded){
				var spaces = namespaceList[i].name.split(/\./);
				alert("spaces   "+spaces)
				var len = spaces.length;
				if(len > 1){
					var obj = window[spaces[0]];
					if(typeof obj == "undefined") obj = window[spaces[0]] = {};
					for(var j = 1; j < len -1; j++){
						obj[spaces[j]] = obj[spaces[j]] || {};
						obj = obj[spaces[j]];
					}
					obj[spaces[j]] = window[spaces[j]];
				}
			}
			(this[i])();
		}
	};

	/**
	 * 将待执行函数推入队列
	 * @param {function} f 待执行函数
	 */
	libQueue.push = function(f){
		var len = this.length;
		for(var i = 0; i < len; i++){
			if(this[i] == f) return false;
		}
		this[i] = f;
		return true;
	};

	/**
	 * 检查命名空间是否冲突
	 * @param {string} namespace 命名空间
	 * @throws Error 如果命名空间有冲突
	 */
	function checkConflict(namespace){
		var className = /\.?([^.]*)$/.test(namespace) ? RegExp.$1 : namespace;
		var len = namespaceList.length;
		for(var i = 0; i < len; i++){
			if(new RegExp(className + "$").test(namespaceList[i].name))
				throw new Error("<pageimport: '" + namespace + "' conflicts with '" + namespaceList[i].name + "'>");
		}
	}

	/**
	 * 检查命名空间是否已经存在
	 * @param {string} namespace 命名空间
	 * @return true - 命名空间已经存在，-false 命名空间不存在
	 */
	function isNamespaceExist(namespace){
		var len = namespaceList.length;
		for(var i = 0; i < len; i++){
			if(namespaceList[i].name == namespace) return true;
		}
		return false;
	}

	/**
	 * 检查js文件是否已经加载
	 * @param {string} filePath js文件路径
	 * @return true - js文件已经加载，-false js文件没有加载
	 */
	function isFileHasLoaded(filePath){
		var len = fileList.length;
		for(var i = 0; i < len; i++){
			if(fileList[i] == filePath) return true;
		}
		return false;
	}

	/**
	 * 根据命名空间计算js文件路径
	 * @param {string} namespace 命名空间
	 * @return 对应该命名空间的js文件路径
	 */
	function getFilePath(namespace){
		var separator = /\//.test(curFilePath) ? "/" : "\\";//路径分隔符
		var lastIndex = curFilePath.lastIndexOf(separator);
		var curDir = lastIndex > 0 ? curFilePath.slice(0,lastIndex + 1) : curFilePath;//bingo当前所处目录
		return (curDir + namespace.replace(/\./g,separator) + ".js");
	}
	
	
	
	function Ajaximport(url){ 
	  var scriptEl
      var oXmlHttp = GetHttpRequest() ; 
      oXmlHttp.OnReadyStateChange = function()  { 
        if (oXmlHttp.readyState == 4){
            if(oXmlHttp.status == 200 || oXmlHttp.status == 304){
//               scriptEl =   loadFile(url, oXmlHttp.responseText);
            }else{ 
                  alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ; 
            } 
          } 
      } 
      oXmlHttp.open('GET', url, true); 
      oXmlHttp.send(null); 
      return  scriptEl;
} 
	
	/**
	 * 加载js文件
	 * @param {string} filePath js文件路径
	 * @return scriptElement
	 */
	function loadFile(filePath,retext){
		var scriptEle;
//		var scriptEle = document.createElement("script");
//		scriptEle.src = filePath;

              var iutl = filePath.substring(filePath.lastIndexOf("."),filePath.length);
	          
	          if(iutl.indexOf("js")>0){
	          	
		          scriptEle = document.createElement( "script" ); 
		
		          scriptEle.language = "javascript"; 
		
		          scriptEle.type = "text/javascript"; 
		
//		          scriptEle.id = sId; 
		          
		          scriptEle.src = filePath;
		
//		          scriptEle.defer = true; 
		
//		          scriptEle.text = retext; 
		          
//	              scriptEle.onreadystatechange = doCallback;
		         
	          }else if(iutl.indexOf("css")>0){
	          	
		          scriptEle = document.createElement("link");
		          
		          scriptEle.type = "text/css";
		          
		          scriptEle.rel = "stylesheet";
		          
		          scriptEle.href = filePath;
		          
//		          scriptEle.onreadystatechange = do_Callback;
		          
	          }

       
		document.getElementsByTagName("head")[0].appendChild(scriptEle);
		return scriptEle;
	}
	
	/**
	 * 加载js文件完成后执行该函数
	 * @param {string} className 加载的文件
	 */
	function loaded(namespace,path){
		var allLoaded = true;
		var len = namespaceList.length;
		for(var i = 0; i < len; i++){
			var n = namespaceList[i];
			if(n.name == namespace)	 n.state = "loaded";
			else if(allLoaded && n.state == "loading") allLoaded = false;
		}
		if(allLoaded) isAllLoaded = true;
//		if(path.indexOf("ext-all")<=0){
//			alert(path)
		  libQueue.run();
//		}  
		if(isAllLoaded) dispose();
	}
	
	/**
	 * 载入外部模块，同时bingo负责维护给定的命名空间，保证代码执行同步。
	 * bingo将根据指定命名空间，在bingo当前所在目录下查找并加载js文件。
	 * 比如:"util.text.Format"，bingo当前所在目录为js\，那么程序将加载的js文件为js\util\text\Format.js。
	 * <strong>注意：</strong>大小写敏感
	 * 如果待加载js文件不在bingo当前所在目录或其子目录之下，那么可以指定path，path就是完整的待加载js文件路径
	 * @param {string} namespace 命名空间，类似java的包的形式。形如："util.text.Format"
	 * @param {string} path 完整的待加载js文件路径
	 */
	function _import(namespace,path){
//		alert(namespace)
		if(!namespace) throw error[4];
		else if(isNamespaceExist(namespace)){
			var len = namespaceList.length;
			for(var i = 0; i < len; i++){
				var n = namespaceList[i];
				if(n.name == namespace){
					if(n.state == "loaded") return;
					else throw error[0];
				}
			}
			if(!isAllLoaded) throw error[1];
			else return;
		}
		else if(debug){
			try{
				checkConflict(namespace);
			}catch(e){alert(e.message);}
		}
		var filePath = path //? path : getFilePath(namespace);
		var f = arguments.callee.caller;
		alert("f  "+f)
		if(!f) throw error[3];//pageimport can not work on your browser
		if(typeof f == "function"){
			namespaceList.push({name : namespace,state : "loading"});			
			if(!isFileHasLoaded(filePath)){
				fileList.push(filePath);
//				if(path.indexOf("ext-all")<=0){
				   libQueue.push(f);
//				}
				var scriptEle = loadFile(filePath);
//				var scriptEle = Ajaximport(filePath);
				if(pageimport.browser.name == "msie"){
//					alert("browser.nam")
					scriptEle.onreadystatechange = function() {
						if(/loaded|complete/.test(this.readyState)) loaded(namespace,path);
					};
				}
				else scriptEle.onload = function(){loaded(namespace,path);}; 
			}
		}
		else throw error[2];
		throw error[0];
	}
	
	/**
	 * 载入外部模块，但bingo不维护命名空间，不保证代码执行同步。
	 * @param {string} path 完整的待加载js文件路径
	 */
	function include(path){
		if(!path && isFileHasLoaded(path)) return;
//		loadFile(path);
	}
	
	function dispose(){
		libQueue.run = null,libQueue.push = null;
		libQueue = null;
		namespaceList = null;
		fileList = null;
		checkConflict = null;
		isNamespaceExist = null;
//		isFileHasLoaded = null;
		getFilePath = null;
//		loadFile = null;
		loaded = null;
		_import = null;
		window.$import = null;
		if(pageimport.browser.name == "msie") CollectGarbage();
	}
//})(true);




