/**
 * 最常用、可重用、业务无关、技术无关、框架无关、最精简的JS方法集合
 */
if (!Probiz) {
	var Probiz = new Object();
}
/*Prototype $() 替代方法*/
function $(el) {
	if (arguments.length > 1) {
		for (var i = 0, els = [], length = arguments.length; i < length; i++) {
			els.push($(arguments[i]));
		}
		return els;
	}
	if (typeof el == "string") {
		el = document.getElementById(el);
	}
	if ((typeof Prototype=='undefined') || (typeof Element == 'undefined') || (typeof Element.Methods=='undefined')) {
		return el;
	} else {
		return Element.extend(el);
	}
}
/* 根据条件设置显示还是隐藏 */
function fnShowCond(el,cond) {
	$(el).style.display=(cond==true)?"":"none";
}
/*隐藏组件*/
function fnHide(el) {
	$(el).style.display = "none";
}
/*显示组件*/
function fnShow(el) {
	$(el).style.display = "";
}
/*增加一个样式*/
function addClass(el, className) {
	removeClass(el, className);
	$(el).className += " " + className;
};
/*删除一个样式*/
function removeClass(el, className) {
	var regex = new RegExp("(^|\\s)" + className + "(\\s|$)", "g");
	$(el).className = $(el).className.replace(regex, "");
};
/*增加或删除一个样式*/
function toggleClass(el, className) {
	var ele=$(el);
	var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
	if (regex.test(ele.className)) {
		ele.className = ele.className.replace(regex, "");
	} else {
		ele.className += " " + className;
	}
};
/*切换旧样式到新样式*/
function fnSetStyle(el,reomveClassName,addClassName){		
	removeClass(el, reomveClassName);
	addClass(el, addClassName);
}
/*切换radio或checkbox的状态*/
function toggleChoice(el) {
    $(el).checked=!$(el).checked;
}
/*String增加trim方法，去除头尾的空格*/
String.prototype.trim = function(){
    return this.replace(/(^\s*)|(\s*$)/g, "");
}
/*去除字符串头尾的空格*/
function trim(str) {
    return str==null?null:str.trim();
} 

/*在原有url添加参数的简便方法*/
function fnAppendUrl(url,paramName,paramValue) {
	if (!url || !paramName || !paramValue) {
		return url;
	}
	var tmpUrl = removeParamFromUrl(url,paramName);
	return tmpUrl + (tmpUrl.indexOf('?') > -1 ? '&' : '?') + paramName+"="+paramValue;
}
/*在原有url删除指定参数的简便方法*/
function removeParamFromUrl(url, paramName) {
	return url.replace(new RegExp("("+paramName+"=[^&]*[&])|([?|&]"+paramName+"=[^&]*$)"), "");
}
/*动态创建指定类型的组件的简便方法*/
function createFormElement(parent,tagName, id, name, type, value) {
    var e = document.createElement(tagName);
    e.setAttribute("id", id||name);
    e.setAttribute("name", name||id);
    e.setAttribute("type", type);
    e.setAttribute("value", value);
    parent.appendChild(e);
    return e;
}
/*在指定或第一个form添加一个隐藏字段的简便方法*/
function fnAddHiddenField(fieldName,fieldValue,form) {
	if ($(fieldName)) {
		$(fieldName).value=fieldValue;
		return $(fieldName);
	}
	return createFormElement(form||document.forms[0],"INPUT",null,fieldName,"hidden",fieldValue);
}
/*选择某个下拉框指定值的简便方法*/
function fnSelectOption(selectObj,value) {
	for (var j = 0; j < selectObj.options.length ; j++) {
		if (value==selectObj.options[j].value) {
			selectObj.options[j].selected=true;
			selectObj.selectedIndex=j;
		}
	}
}
/**
* 取到当前的事件对象,同时兼容ie和ff的写法 
*/
function getEvent(){   
    if (document.all) {
    	return window.event;
    }         
    var func=getEvent.caller;             
    while(func!=null){     
        var arg0=func.arguments[0]; 
        if(arg0){ 
            if((arg0.constructor==Event || arg0.constructor ==MouseEvent) 
                || (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){     
               return arg0; 
            } 
        } 
        func=func.caller; 
    } 
    return null; 
}
/**
	取到当前事件的源对象
**/
function getEventSourceObject(){
	var evt=getEvent();
    return evt.srcElement || evt.target;
}

/**
 * 把传入的Java序列化对象（例如通过DWR转换的）或JSON对象的属性绑定到指定表单的同名属性的值。
 * 局限性：还不能支持多层（请在VO层先把对象属性扁平化）。还不能支持复杂的属性（例如属性是一个列表，需要递归才能处理，对于这些复杂的情况，可以在调用本方法后自己处理）。
 * 说明：DWR的方法更强，但太依赖id，不能支持一个页面有两个相似的form。
 */
function setFormValues(oData,sFormName) {
	if (!oData) {
		return;
	}
	var oForm = $(sFormName);
	if (!oForm) {
		alert("Form not found:"+sFormName);
		return;
	}
    for (var i = 0; i < oForm.elements.length; i++) {
      if (oForm[i].type in {button:0,submit:0,reset:0,image:0,file:0}) continue;
      var name="";
      if (oForm[i].name) {
        name = oForm[i].name;
      } else {
        if (oForm[i].id) name = oForm[i].id;
        else name = "element" + i;
      }
      if (oData[name]) {
      	oForm[i].value=oData[name];
      }
    }
}

/**
 * 把指定的form的属性组装为JSON对象(利用prototype)。
 * sFormName可以是form对象，也可以是任何id的对象。
 * 支持radio，select等控件。
 * 局限性：还不能支持多层（请在VO层先把对象属性扁平化）。还不能支持复杂的属性（例如属性是一个列表，需要递归才能处理，对于这些复杂的情况，可以在调用本方法后自己处理）。
 * 说明：DWR的方法更强，但太依赖id，不能支持一个页面有两个相似的form。
 */
function getFormValues(sFormName) {
	$importSync("/scripts/prototype/prototype.js");	
	return Form.serialize(sFormName, true);
}

function getFormQueryString(sFormName) {
	$importSync("/scripts/prototype/prototype.js");	
	return Form.serialize(sFormName, false);
}
function _defaultAjaxErrorHandler(errMsg,xhr) {
	alert(errMsg);
}
/*框架内部用，兼容异步/同步方式的状态改变处理器，主要功能是调用正确的ajaxCallback来进行进一步处理。ajaxCallback不能为空。*/
function _ajaxReadyStateHandler(xhr,sUrl,ajaxCallback, ajaxErrorCallbackHandler) {
    var readyState = xhr.readyState;
    if (readyState == 4) {
        var httpStatus = xhr.status;
        if (httpStatus >= 200 && httpStatus < 300) {
            ajaxCallback.call(this,xhr.responseText);
        } else {
        	var errMsg = "ERROR request: " + sUrl + "\n\nReadyState: " + readyState + "\nStatus: " + httpStatus + "\nHeaders: " + xhr.getAllResponseHeaders();
            var _ajaxErrorHandler = ajaxErrorCallbackHandler||_defaultAjaxErrorHandler;
            _ajaxErrorHandler.call(this,errMsg,xhr);
        }
    }
}
/*如要发参数要用POST，否则应在调用前把参数序列化加入URL.还没有处理超时。ajaxCallback不能为空。*/
function ajaxCall(prmUrl, prms, postOrGet, async, ajaxCallback, ajaxErrorCallbackHandler) {
	var xhr = null;
	if (window.ActiveXObject) {
		xhr = new ActiveXObject("Msxml2.XMLHTTP");
	} else if (window.XMLHttpRequest) {
		xhr = new XMLHttpRequest();
	}
	if (xhr == null) {
		return alert("XMLHttpRequest is not supported!");
	}
    var sUrl=prmUrl;
    if ((prms && prms.length > 0) && (postOrGet != "POST")) {
          	sUrl += (sUrl.match(/\?/) ? '&' : '?') + prms;
	}
	var _async = async==null?true:async;
	if (_async) {
       	xhr.onreadystatechange = function() { 
       		_ajaxReadyStateHandler(xhr,sUrl,ajaxCallback,ajaxErrorCallbackHandler);
       	}
	}
    xhr.open(postOrGet, sUrl, _async);
	xhr.send(postOrGet == "POST" ? prms : null);
	if (!_async) {
		_ajaxReadyStateHandler(xhr,sUrl,ajaxCallback,ajaxErrorCallbackHandler);
	}
}

/**
 *还不成熟，不能控制同步，不能控制get或post（可用参数控制），nocache还未生效，要用disableCaching，会显示Loading...
 *JS比较方便可以用普通写法，但不能同步所以外窗口不能调用里面的JS；但通过callback可以调用load进来的JS
 */
function fillDivWithPage(prmDivId, prmUrl, prms, fillCallback, postOrGet, async) {
	ajaxCall(prmUrl, prms, postOrGet||"POST", async, function(responseText){
		var target = $(prmDivId);
	    if (document.createRange) {
	        var rng = document.createRange();
	        rng.setStartBefore(target);
	        var htmlFrag = rng.createContextualFragment(responseText);
	        while (target.hasChildNodes()) {
	        	target.removeChild(target.lastChild);
	        }
	        target.appendChild(htmlFrag);
	    } else {
	        target.innerHTML=responseText;
	    }
	    if (fillCallback) {
	    	fillCallback.call(this);
	    }
	});
}
function _isLoaded(url) {
	var ss = document.getElementsByTagName(url.toLowerCase().lastIndexOf(".css")>0?"link":"script");
	for (i = 0; i < ss.length; i++) {
		var _url=ss.href||ss[i].src||ss[i].syncUrl;
		if (_url && _url.indexOf(url) != -1) {
			return true;
		}
	}
	return false;
}
/**用同步方式载入JS（CSS不需要），慢网络会有停顿*/
function $importSync(url, defer) {
	if (_isLoaded(url)) {
		return;
	}
	ajaxCall(url.indexOf(__ctxPath)==0?url:(__ctxPath+url), null, "GET", false, function(responseText){
		if (responseText != null) {
			var oHead = document.getElementsByTagName("head")[0];
			var oScript = document.createElement("script");
			oScript.type = "text/javascript";
			oScript.defer = defer || true;
			oScript.text = responseText;
			oScript.syncUrl=url;
			oHead.appendChild(oScript);
		}
	},function(){
		alert("Failed to load script: "+url);
	});
}
function JsCssLoader() {
	this.load = function (url) {
		if (_isLoaded(url)) {
			this.onsuccess();
			return;
		}
        //动态创建script/link结点装入外联的.js/.css文件
		if (url.toLowerCase().lastIndexOf(".css")>0) {
			var s=document.createElement("link");
			s.setAttribute("rel", "stylesheet");
			s.setAttribute("type", "text/css");
			s.setAttribute("href",url);
		} else {
			var s = document.createElement("script");
			s.type = "text/javascript";
			s.src = url;
		}
        //获取head结点，并将script/link插入到其中
		var head = document.getElementsByTagName("head")[0];
		head.appendChild(s);
           
        //保存自身以便在事件中引用
		var self = this;
        //使用readystatechange(IE)或onload(FF等)事件在载入成功后进行处理
		s.onload = s.onreadystatechange = function () {
            //在此函数中this指针指的是s结点对象，而不是JsCssLoader实例,
            //所以必须用self来调用onsuccess事件，下同。
			if (s.readyState && s.readyState == "loading") {
				return;
			}
			self.onsuccess(url);
		};
		s.onerror = function () {
			head.removeChild(s);
			self.onfailure(url,arguments);
		};
	};
    //定义载入成功事件
	this.onsuccess = function (url) {
	};
	//定义失败事件
	this.onfailure = function (url,args) {
		alert("Error loading JavaScript/StyleSheet: "+args[0]+" -- "+args[1]+" -- "+args[2]);
	};
}

/**动态载入脚本并执行callback。如果没有callback，一般只适合不需要等待就可继续的情况。已知问题：FF下CSS没有事件处理。IE下ext事件处理部分必须先装入。*/
function $import(urls,callback) {
	if (!(urls instanceof Array)) {
		alert("Invalid $import call syntax, must be array.");
		return;
	}
	var _loader=new JsCssLoader();
	if (urls.length>1) {
		_loader.onsuccess=function() {
			$import(urls.slice(1,urls.length),callback);
		}
	} else if (callback) {
		_loader.onsuccess=callback;
	}
	//这里永远只是载入数组里的第一个，因为其他的会在callback处理
	_loader.load(urls[0].indexOf(__ctxPath)==0?urls[0]:(__ctxPath+urls[0]));
}
function $importDwr(callback) {
	$import(["/scripts/dwr/engine.js","/scripts/dwr/util.js"],callback);
}
function $importDialog(callback) {
	$import(["/scripts/ext/ext-all.js",
	"/scripts/probiz/framework/interface.js",
	"/scripts/probiz/framework/probizExt.js"
	],callback);
}
function $importSimpleDialog(callback) {
	$import(["/scripts/probiz/framework/interface.js"],callback);
}
function $importMost(callback) {
	$import(["/scripts/dwr/engine.js",
	"/scripts/dwr/util.js",
	"/scripts/prototype/prototype.js",
	"/scripts/ext/ext-all.js",
	"/scripts/probiz/framework/interface.js",
	"/scripts/probiz/framework/probizExt.js",
	"/scripts/probiz/framework/commonDialog.js",
	"/scripts/probiz/framework/probizUpload.js",
	"/scripts/probiz/framework/validation.js"
	],callback);
}

/*以下为多个onload事件的简单处理框架，但无法像Ext.onReady那样完善和强大。注意：body以及JS不能再定义onload，应改用addOnload。*/
var onloadHandlers=[];
function addOnload(handler) {
	if (handler) {
		onloadHandlers.push(handler);
	}
}
function handleOnload() {
	for (var i = 0; i < onloadHandlers.length; ++i) {
		onloadHandlers[i].call(this);
	}
}
//addOnload(window.onload);
window.onload=handleOnload;
/*在Firebug记录调试信息的简便方法，但响应的log语句在调试通过后应删除以提高效率*/
function log(sMsg) {
	typeof console=='undefined'?alert(sMsg):console.log(sMsg);
}
function getProbizState() {
	return $("iframeSaveRecentView")==null?null:$("iframeSaveRecentView").contentWindow;
}
/*Cookie管理注意事项：Cookie会被发到服务器因而占用带宽，要提高性能就要减少Cookie的消耗，有以下原则：
 *原则1：尽量不使用Cookie，而且一般也不应有非全局的Cookie，还需要限制Cookie的path的范围
 *原则2：尽量在服务器端处理Cookie而不是客户端，客户端只读
 *原则3：Cookie必须尽量简短，且不能存储敏感数据
 *原则4：尽量集中管理全局Cookie（如在一个隐藏Frame处理；统一不设置path，因为隐藏页面只能读本身URL匹配的path的Cookie，但需采用异步方式，较麻烦－－Cookie的读取和进一步处理一般是在onload里面，或onclick等事件，以保证这时隐藏frame已经准备好）；
 */
function setCookie(name,value,expires,path,domain,secure) {
  document.cookie = name + "=" + escape (value) +
    ((expires) ? "; expires=" + expires.toGMTString() : "") +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
}
function getCookie(name) {
	var prefix = name + "=" 
	var start = document.cookie.indexOf(prefix) 
	if (start==-1) {
		return null;
	}
	start+=prefix.length;
	var end = document.cookie.indexOf(";", start) 
	if (end==-1) {
		end=document.cookie.length;
	}
	return unescape(document.cookie.substring(start, end));
}

/**
* 按比例缩小图片。如图片实际大小比要求的小，无需调整；否则，只需要调整width或hieight（浏览器会自动调整）
* oImg image对象
* reqWidth 期望中的width
* reqHeight 期望中的height 
*/
function fnResizeImage(oImg, reqWidth, reqHeight) {
	if (reqWidth >= oImg.width && reqHeight >= oImg.height){
		return;
	}
	if ((oImg.width/oImg.height) > (reqWidth/reqHeight)) {
		oImg.width = reqWidth;
	} else {
		oImg.height = reqHeight;
	}
}
function getCurrentUserId(){
	return getCookie("UID")||-2;
}
/**不严格的简单判断用户是否登录的方法，性能较好，缺省设置为5分钟更新一次*/
function isLogined() {
	return getCurrentUserId()>0;
}
function getCurrentUserName(loginRequired) {
	return (!loginRequired||isLogined())&&getCookie("UNAME")||"";
}
