/*
 * descript:
 *     这组件主要是放置一般网页常用的功能，如数字的检查、字符串前后空白的去除等等…
 * update date:
 *     2007-02-02
 *     2006-06-29
 *
 * author:
 *     Camus Chou (周文瑞)
 * varsion : 
 *     1.1.1.1
 *         . 修正isEmailFormat()的判断规则
 *     1.1.1
 * 
*/

/*
 * prototype list
 * 	String:
 * 		trim()：传回去除前后空白的值
 * 		ltrim()：传回去除左边空白的值
 * 		rtrim()：传回去除右边空白的值
 * 	
 * 	Node:
 * 		swapNode(targetNode);
 */

/*
 * object list
 * 	LabelValueObj: 可同时储存 label 与 value 两个值的对象。
 * 		getLabel();
 * 		getValue();
 */ 
 
/*
 * function list
 * 		sendPost(url)：用来将原本用Get连结的方式改成用Post
 * 		isNumeric(value)：检查是否为数字
 * 		isInteger(value)：检查是否为整数数字
 * 		isPositiveInteger(value)：检查是否为正整数数字
 * 		isPositiveFloat(value)：检查是否为正浮点数数字
 * 		isWestDate(year, month, day)：检查是否为有效的公元日期
 * 		compareWestDate(date1, date2)：比对 date1 与 date2 那个公元日期比较大
 * 		isAnyOneChecked(obj)： 判断传进来的checkbox或radio数组(或对象)是否有任何一个被勾选了。
 *		isEmailFormat(email)：判断传进来的字符串是否符何Email格式
 * 		isAboveMaxNumOfWord(string, maxNum, analyzed2BytesWord)：判断传进来的字符串是否大于指定的字数
 * 		existOneByteWord(string)：判断传进来的字符串中，是否存在1Byte的字(英文与符号)
 * 		exist2BytesWord(string)：判断传进来的字符串中，是否存在2Byte的字(中文字或全角符号)
 * 		isTwId(twId)：判断传进来的字符串是否为台湾身分证号。
 * 		isCnId(id, year, month, day, gender)：判断传进来的字符串是否为中国身分证号。
 * 		isCnTwId(id, year, month, day, gender)：判断传进来的字符串是否为中国或是台湾的身分证号。
 * 
 * 		checkOperation(obj, checkedFlag)：执行勾选/取消勾选所传入的checkbox数组(或对象)
 * 		checkAll(obj) ：执行勾选所传入的checkbox数组(或对象)
 * 		uncheckAll(obj)：执行取消勾选所传入的checkbox数组(或对象)
 * 		reverseCheck(obj)：执行反向勾选所传入的checkbox数组(或对象)。
 * 
 * 		selectAllOptions(selectObj)：将传入的select对象中的所有选项都选取起来
 * 		setSelectDefault (selectObj, defaultCode)：为传入的Select对象设定初值
 * 		deleteAllSelectOptions (selectObj)：将传入的Select对象中的所有选项清除
 * 
 * 		generateRandomString(len)：随机数产生一组字符串
 * 
 * 		isSpecifyHtmlTag(tagName, obj)： 判断传进来的对象是否为指定的html tag
 */ 
//===================================================================================================================//
    /*
        description:
            去除字符串前后空白。
            使用增加原 Javascript String 方法的方式，来让 Javascript String 自身拥有去除前后空白的功能。
        brower version:
            IE?Netscape
        example:
            var testString = "   this is a sample.  ";
            alert("'" + testString + "'");
            alert("'" + testString.trim() + "'");
            alert("'" + testString.ltrim() + "'");
            alert("'" + testString.rtrim() + "'");
            
    */

    String.prototype.trim=trim;  //传回去除前后空白的值
    String.prototype.ltrim=ltrim;  //传回去除左边空白的值
    String.prototype.rtrim=rtrim;  //传回去除右边空白的值
    
    function trim() {
      return this.replace(/^\s+|\s+$/g, "");
    } 
    function ltrim() {
      return this.replace(/(^\s*)/g, "");
    }
    function rtrim() {
      return this.replace(/(\s*$)/g, "");
    }

//===================================================================================================================//
	/*
	 * description:
	 *     可同时储存 label 与 value 两个值的对象。
	 * brower version:
	 *     IE、Netscape
	 */ 

	function LabelValueObj(label, value) {
		this.label    = label;
		this.value    = value;
		this.getLabel = LabelValueObj_getLabel;
		this.getValue = LabelValueObj_getValue;
	}
	function LabelValueObj_getLabel() {
		return this.label;
	}
	function LabelValueObj_getValue() {
		return this.value;
	}
//===================================================================================================================//
	/*
	 * descript:
	 *     用来将原本用Get连结的方式改成用Post
	 * parameter:
	 * 	   url: Get方式的字符串，如：url?key1=value1&key2=value2......
	 */	
	function sendPost(url, target) {
		var tmp = url.indexOf("?");
        if (tmp >= 0) {
            // ** 1. 将参数取出来 ** //
            var linkUrl = url.substring(0, tmp);   // 要连结的 url
            var params  = url.substring(tmp + 1);  // 要传递的参数串
            
            // ** 2. 将参数串切割出来 ** //
            /*
             * 概念说明：
             *   1. 以「=」符号来切割字符串，得到一个数组。
             *   2. 从数组中的第1个元素(元素从0开始计算)开始，再以"&"开始切割，
             *      此时是从字符串的后面开始往前找，找到的第一个&的即是分割的token。
             *   3. 将&前的字符串为前一个元素的value，&后的字符串则为下一个key。
             * 
             * p.s.
             *    因为考虑到传递的参数值中可能会带有「=」与「&」的字符，所以
             *    此处并不使用「&」字符来切割字符串。
             */
            // 以「=」符号来切割字符串，得到一个数组。
            var keys   = new Array();    // 用来存放参数的key
            var values = new Array();    // 用来存被参数的value
            var result = params.split("="); // 将参数串以"="符号切割
            var index = 0;               // 参数个数的计数器，由0开始
            var addEqualFlag = false;    // 当此值为true时，则value前要加上"="符号，
                                         // 此值是用来避免 key=value1=value2 的情况，
                                         // 如没加此参数判断，会切成key = value1
                                         // 加上此参数后，会正确切成 key = value1=value2
            
            keys[index]   = result[0];
            values[index] = "";
            index ++;
            for (var i=1; i<result.length; i++)
            {
                tmp = result[i].lastIndexOf("&");
                if (tmp >= 0 && i < result.length - 1)
                {
                    if (addEqualFlag)
                      values[index-1] += "=" + result[i].substring(0,tmp);
                    else
                      values[index-1] = result[i].substring(0,tmp);
                    
                    
                    keys[index]   = result[i].substring(tmp + 1);
                    values[index] = "";
                    index ++;
                    addEqualFlag = false;
                }
                else
                {
                    if (addEqualFlag)
                      values[index-1] += "=" + result[i];
                    else
                      values[index-1] = result[i];
                    addEqualFlag = true;
                    
                }
            }
            // ** 3. 组成一个form ** //
            var formObj = document.createElement("FORM");
            formObj.name = "sendPostForm";
            formObj.method = "POST";
            formObj.action = linkUrl;
            if (target != null) {
            	formObj.target = target;
            }
            
            var inputObj = null;
            for (var i=0; i<keys.length; i++) {
            	
                if (keys[i].length > 0) { // 如果key的值是零长度字符串，就不传
                	inputObj = document.createElement("INPUT");
	            	inputObj.type = "hidden";    
	            	inputObj.name = keys[i];
	            	inputObj.value = values[i];
	            	formObj.appendChild(inputObj);
                }
                  
            }
            
            document.body.appendChild(formObj);
            
            // ** 4. 送出 **//
            formObj.submit();
            
            
        } else {
            location.href = url;
        }
	}
//===================================================================================================================//
	if (!document.all) {
		Node.prototype.swapNode = swapNode;
	}
	function swapNode(targetNode) {
		var targetNextNode   = targetNode.nextSibling;
		var targetParentNode = targetNode.parentNode;
		this.parentNode.replaceChild(targetNode, this);
		targetParentNode.insertBefore(this,targetNextNode);
	}
//==================================================================================================================//
	/*
	 * descript:
	 *      检查是否为数字
	 * parameter:
	 * 	    value:要被检查的字符串
	 * return:
	 * 		true : 数字
	 * 		false: 非数字
	 * 
	 * since: 1.1
	 */	
	function isNumeric(value) {
		if (typeof(value) == 'number') {
			return true;
		} else {
			var data = value.match(/^-?\d+(\.?\d+)?/g);
			return (data == value);
		}
	}
	/*
	 * descript:
	 *      检查是否为整数数字
	 * parameter:
	 * 	    value:要被检查的字符串
	 * return:
	 * 		true : 整数数字
	 * 		false: 非整数数字
	 * 
	 * since: 1.1
	 */	
	function isInteger(value) {
		if (typeof(value) == 'number') {
			if (("" + value).indexOf(".") < 0) {
				return true;
			} else {
				return false;
			}
		} else {
			var data = value.match(/^-?\d+/g);
			return (data == value);
		}
	}
	/*
	 * descript:
	 *      检查是否为正整数数字
	 * parameter:
	 * 	    value:要被检查的字符串
	 * return:
	 * 		true : 正整数数字
	 * 		false: 非正整数数字
	 * 
	 * since: 1.1
	 */	
	function isPositiveInteger(value) {
		if (typeof(value) == 'number') {
			if (value > 0 && ("" + value).indexOf(".") < 0) {
				return true;
			} else {
				return false;
			}
		} else {
			var data = value.match(/\d+/g);
			return (data == value);
		}
	}
	/*
	 * descript:
	 *      检查是否为正浮点数数字
	 * parameter:
	 * 	    value:要被检查的字符串
	 * return:
	 * 		true : 正浮点数数字
	 * 		false: 非正浮点数数字
	 * 
	 * since: 1.1
	 */	
	function isPositiveFloat(value) {
		if (typeof(value) == 'number') {
			if (value > 0) {
				return true;
			} else {
				return false;
			}
		} else {
			var data = value.match(/\d+(\.?\d+)?/g);
			return (data == value);
		}
	}
	
	function isEnglishAndNumeric (value) {
		if (value == null) {
			return false;
		}
		value = value.trim();
		if (value.length == 0) {
			return false;
		}
		
		if (value.match(/[^a-z|^A-Z|^0-9]/g)) {
			return false;
		} else {
			return true;
		}
		
	}
//==================================================================================================================//
	/*
	 * descript:
	 *      检查是否为有效的公元日期
	 * parameter:
	 * 	    year : 公元年
	 * 	    month: 月
	 *      day  : 日
	 * return:
	 * 		true : 有效的公元日期
	 *		false: 无效的公元日期
	 * 
	 * since: 1.1
	 */	
	function isWestDate(year, month, day) {
		if (year == null)
			return false;

		month = month == null ? 1 : month;
		day   = day   == null ? 1 :day;

		if (isInteger(year) && isPositiveInteger(month) && isPositiveInteger(day)) {
			// 检查年份是否合理
			if (year <= 0) {
				return false;
			}
			
			// 检查月份是否合理
			if (month > 12 || month < 1) {
				return false;
			}
			
			// 检查日期是否合理
			if (day < 1) {
				return false;
			}
			if (month == 1 || month == 3 || month == 5 || month == 7 || 
			    month == 8 || month == 10 || month == 12) {
				if (day > 31) {
					return false;
				}
			} else if (month != 2) {
				if (day > 30) {
					return false;
				}
			} else {
				var febDay = 28;
				// 判断是否为闰年
				if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
					febDay = 29;
				}
				
				if (day > febDay) {
					return false;
				}
			}
			
			return true;
		} else {
			return false;
		}
	}
	
//==================================================================================================================//	
	/*
	 * descript:
	 *      比对 date1 与 date2 那个公元日期比较大
	 * parameter:
	 * 	    date1: Array 对象，代表公元日期，数组中依序放置 公元年、月、日
	 * 	    date2: Array 对象，代表公元日期，数组中依序放置 公元年、月、日
	 * return:
	 * 		= 0; 两个日期相等
	 * 		> 0; date1 > date2
	 * 		< 0; date2 > date1
	 * 
	 * since: 1.1
	 */	
	function compareWestDate(date1, date2) {

		if (typeof(date1) != "object" &&
		    date1[0] == 'undefined') {
			throw new Error(1000001, "input argument data1 is not a array");
		}
		if (typeof(date2) != "object" &&
		    date2[0] == 'undefined') {
			throw new Error(1000002, "input argument data2 is not a array");
		}

		var year1  = date1[0];
		var month1 = date1[1] == null ? 1 : date1[1];
		var day1   = date1[2] == null ? 1 : date1[2];
		
		var year2  = date2[0];
		var month2 = date2[1] == null ? 1 : date2[1];
		var day2   = date2[2] == null ? 1 : date2[2];

		if (!isWestDate(year1, month1, day1)) {
			throw new Error(1000003, "input argument data1 is not a valid date");
		}

		if (!isWestDate(year2, month2, day2)) {
			throw new Error(1000004, "input argument data2 is not a valid date");
		}

		var westDate1 = new Date();
		westDate1.setFullYear(year1);
		westDate1.setMonth(month1 - 1);
		westDate1.setDate(day1);
		
		var westDate2 = new Date();
		westDate2.setFullYear(year2);
		westDate2.setMonth(month2 - 1);
		westDate2.setDate(day2);
		
		return westDate1.getTime() - westDate2.getTime();
	}

//==================================================================================================================//
	/*
	 * descript:
	 *      判断传进来的checkbox或radio数组(或对象)是否有任何一个被勾选了。
	 * parameter:
	 * 	    obj: checkbox 数组(或对象)
	 * return:
	 * 		true : 至少有一个checkbox或radio被勾选
	 * 		false: 完全没有一个checkbox或radio被勾选
	 * 
	 * since: 1.1
	 */	
	function isAnyOneChecked(obj) {
		if (obj == null) {
			throw new Error(1000010, "input argument obj is null");
		}
		if (obj.length == null) { // 非数组
			if (obj.tagName.toUpperCase() != 'INPUT' || (obj.type.toLowerCase() != "checkbox" && obj.type.toLowerCase() != "radio")) {
				throw new Error(1000011, "input argument obj is not a checkbox or radio obj");
			}
			return obj.checked;
			
		} else { // 数组
			if (obj[0].tagName.toUpperCase() != 'INPUT' || (obj[0].type.toLowerCase() != "checkbox" && obj[0].type.toLowerCase() != "radio")) {
				throw new Error(1000011, "input argument obj is not a checkbox or radio obj");
			}
			for (var i=0; i<obj.length; i++) {
				if (obj[i].checked) {
					return true;
				}
			}
			return false;
		}
	}
//==================================================================================================================//
	/*
	 * descript:
	 *      判断传进来的字符串是否符何Email格式
	 * parameter:
	 * 	    email: 字符串
	 * return:
	 * 		true : 为Email格式字符串
	 * 		false: 非Email格式字符串
	 * 
	 * since: 1.1
	 * update: 2007-02-02 version 1.1.1.1
	 */	
	function isEmailFormat(email) {
		//var data = email.match(/^\S+@\S+\.\S+$/);
		//var data = email.match(/^[a-zA-Z0-9]+([\._-][a-zA-Z0-9]+)*@[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)+$/);
		//var data = email.match(/^[a-zA-Z0-9]+([\._-][a-zA-Z0-9]+)*@([a-zA-Z0-9]+([_-][a-zA-Z0-9]+)*)(\.([a-zA-Z0-9]+([_-][a-zA-Z0-9]+)*))+$/);
		//  2007-02-02
		var data = email.match(/^[a-zA-Z0-9]+([\.\-_a-zA-Z0-9]+)*@([a-zA-Z0-9]+([_-][a-zA-Z0-9]+)*)(\.([a-zA-Z0-9]+([_-][a-zA-Z0-9]+)*))+$/);
		if (!data || !email) {
			return false;
		} else {
			return true;
		}
	}
//==================================================================================================================//
	/*
	 * descript:
	 *      判断传进来的字符串是否大于指定的字数
	 * parameter:
	 * 	    string: 字符串
	 * 		maxNum: 最大字数
	 * 		resolved2BytesWord: 是否要将中文字解析成两个字数。true:要，false:不要 (预设为false)
	 *      cnByteNum: 一个中文字算几个byte。(预设为2个)
	 * return:
	 * 		true : 传进来的字符串大于指定的字数
	 * 		false: 传进来的字符串小于、等于指定的字数
	 * 
	 * since: 1.1
	 */	
	function isAboveMaxNumOfWord(string, maxNum, analyzed2BytesWord, cnByteNum) {
		analyzed2BytesWord = analyzed2BytesWord == null ? false : analyzed2BytesWord;
		cnByteNum = cnByteNum == null ? 2 : cnByteNum;
		
		if (!analyzed2BytesWord) {
			return string.length > maxNum;
		} else {
			var realNum = 0;
			for (var i=0; i<string.length; i++) {
				if (escape(string.charAt(i)).length >= 4) {
					realNum += cnByteNum;
				} else {
					realNum ++;
				}
			}

			return (realNum > maxNum)
		}
	}
//==================================================================================================================//
	/*
	 * descript:
	 *      判断传进来的字符串是否小于指定的字数
	 * parameter:
	 * 	    string: 字符串
	 * 		minNum: 最小字数
	 * 		resolved2BytesWord: 是否要将中文字解析成两个字数。true:要，false:不要 (预设为false)
	 *      cnByteNum: 一个中文字算几个byte。(预设为2个)
	 * return:
	 * 		true : 传进来的字符串小于指定的字数
	 * 		false: 传进来的字符串大于、等于指定的字数
	 * 
	 * since: 1.1
	 */	
	function isUnderMinNumOfWord(string, minNum, analyzed2BytesWord, cnByteNum) {
		analyzed2BytesWord = analyzed2BytesWord == null ? false : analyzed2BytesWord;
		cnByteNum = cnByteNum == null ? 2 : cnByteNum;
		
		if (!analyzed2BytesWord) {
			return string.length < minNum;
		} else {
			var realNum = 0;
			for (var i=0; i<string.length; i++) {
				if (escape(string.charAt(i)).length >= 4) {
					realNum += cnByteNum;
				} else {
					realNum ++;
				}
			}

			return (realNum < minNum)
		}
	}	
//==================================================================================================================//
	/*
	 * descript:
	 *      判断传进来的字符串中，是否存在1Byte的字(英文与符号)
	 * parameter:
	 * 	    string: 字符串
	 * return:
	 * 		true : 传进来的字符串中存在1Byte的字(英文与符号)
	 * 		false: 传进来的字符串中并不存在1Byte的字(英文与符号)
	 * 
	 * since: 1.1
	 */	
	function existOneByteWord(string) {
		var len = string.length;
		for (var i=0; i<string.length; i++) {
			if (escape(string.charAt(i)).length < 4) {
				return true;
			}
		}
		return false;
	}
	/*
	 * descript:
	 *      判断传进来的字符串中，是否存在2Byte的字(中文字或全角符号)
	 * parameter:
	 * 	    string: 字符串
	 * return:
	 * 		true : 传进来的字符串中存在2Byte的字(中文字或全角符号)
	 * 		false: 传进来的字符串中并不存在2Byte的字(中文字或全角符号)
	 * 
	 * since: 1.1
	 */	
	function exist2BytesWord(string) {
		var len = string.length;
		for (var i=0; i<string.length; i++) {
			if (escape(string.charAt(i)).length >= 4) {
				return true;
			}
		}
		return false;
	}
//==================================================================================================================//	
	/*
	 * descript:
	 *      判断传进来的字符串是否为台湾身分证号。
	 * parameter:
	 * 	    twId: 字符串
	 * return:
	 * 		true : 是台湾身分证号
	 * 		false: 不是台湾身分证号
	 * 
	 * since: 1.1
	 */	
	function isTwId(twId) {
		if (typeof(twId).toLowerCase() != "string") {
			return false;
		}
		if (twId.length != 10) {
			return false;
		}
		twId = twId.toUpperCase();
		var headChar = twId.charAt(0);
		var bodyNum  = twId.substring(1);
		
		if (headChar > 'Z' || headChar < 'A') {
			return false;
		}
		
		if (!isPositiveInteger(bodyNum)) {
			return false;
		}
		
		if (bodyNum.charAt(0) != '1' && bodyNum.charAt(0) != '2') {
			return false;
		}
		
		// 开始进入规则检查
		var codes = new Array("10", "11", "12", "13", "14", "15", "16", "17", "34", "18", "19", "20", "21", "22", "35", "23", "24", "25", "26", "27", "28", "29", "32", "30", "31", "33");
		var headCode = codes[headChar.charCodeAt(0) - "A".charCodeAt(0)];

		var chkSum = 0;
		chkSum += parseInt(headCode.charAt(0)) * 1;
		chkSum += parseInt(headCode.charAt(1)) * 9;
		for (var i=8; i>=1; i--) {
			chkSum += parseInt(bodyNum.charAt(8-i)) * i;
		}
		var chkCode = Math.floor(chkSum % 10);
		chkCode = chkCode != 0 ? 10 - chkCode : chkCode;
		return parseInt(bodyNum.charAt(8)) == chkCode;
	}

	/*
	 * descript:
	 *      判断传进来的字符串是否为中国身分证号。
	 * parameter:
	 * 	    id: 字符串
	 * 		year: 出生年 (可不填)
	 *      month: 出生月 (可不填)
	 *      day:   出生日 (可不填)
	 *      gender: 性别 (可不填) 0:女 1:男
	 *      
	 *      注意：出生年、月、日要就全填，不然就都不填。
	 *           当出生年、月、日都有填时，性别可不填。
	 *           当出生年、月、日都没有填时，性别也不可以填。
	 * return:
	 * 		true : 是中国身分证号
	 * 		false: 不是中国身分证号
	 * 
	 */		
	function isCnId(id, year, month, day, gender, advCheck) {
		var result = false;
		
		advCheck = advCheck == null ? true : false;
		
		if (id.length == 15) {
			if (year != null && month != null && day != null) {
				result = advCheckCnId (id, year, month, day, gender);
			}
		} else if (id.length == 18) {
			if (advCheck) {
				result = advCheckCnId (id, year, month, day, gender);
				if (!result) {
					return result;
				}
			}
			
			var wi = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1); 
			// verify digit 
			var vi = new Array(1,0,'X',9,8,7,6,5,4,3,2); 
			var ai = new Array(); 
			var verify = id.substring(17, 18).toUpperCase(); 
			
			var remaining = 0; 
			id = id.substring(0, 17); 
			
			var sum = 0; 
			var k   = 0;
			for (var i = 0; i < 17; i++) { 
				k = id.substring(i, i + 1); 
			    ai[i] = k; 
			} 
			
			for (var i = 0; i < 17; i++) { 
				sum = sum + wi[i] * ai[i]; 
			} 
			remaining = sum % 11;

			if (verify == (remaining == 2 ?  "X" : vi[remaining])) {
				result = true;
			}
		}
		return result;
	}
	
	function advCheckCnId (idNum, year, month, day, gender) {
		var varYear;
		var varMonth;
		var varDay;
		var varGender;
		var result = false;
		
		if(idNum.length == 15){
			/** data setting */
			varYear = '19' + idNum.substring(6, 8);
			varMonth = idNum.substring(8, 10);
			varDay = idNum.substring(10, 12);
			varGender = idNum.charAt(14);
		}else{
			/** data setting */
			varYear = idNum.substring(6, 10);
			varMonth = idNum.substring(10, 12);
			varDay = idNum.substring(12, 14);
			varGender = idNum.charAt(16);
		}

		/** check birthday  & gender */
		if(parseInt(year, 10) == parseInt(varYear, 10) && parseInt(month, 10) == parseInt(varMonth, 10) && parseInt(day, 10) == parseInt(varDay, 10)){
			if (gender != null) {
				/** 奇數為男，偶數為女 */
				if(gender == 1){
					result = ((varGender & 1) == 1) ? true:false; 
				}else{
					result = ((varGender & 1) == 0) ? true:false; 
				}
			} else {
				result = true;
			}
		}
		return result;
	}
	
	/*
	 * descript:
	 *      判断传进来的字符串是否为中国或是台湾的身分证号。
	 * parameter:
	 * 	    id: 字符串
	 * 		year: 出生年 (可不填)
	 *      month: 出生月 (可不填)
	 *      day:   出生日 (可不填)
	 *      gender: 性别 (可不填) 0:女 1:男
	 *      
	 *      注意：出生年、月、日要就全填，不然就都不填。
	 *           当出生年、月、日都有填时，性别可不填。
	 *           当出生年、月、日都没有填时，性别也不可以填。
	 * return:
	 * 		true : 是中国或是台湾身分证号
	 * 		false: 不是中国或是台湾身分证号
	 * 
	 */
	function isCnTwId(id, year, month, day, gender, cnAdvCheck) {
		if (id.length == 10) {
			return isTwId(id);
		} else if (id.length == 15 || id.length == 18) {
			return isCnId(id, year, month, day, gender, cnAdvCheck);
		} else {
			return false;
		}
	}
//==================================================================================================================//	
	/*
	 * descript:
	 *      执行勾选/取消勾选所传入的checkbox数组(或对象)
	 * parameter:
	 * 	    obj: 要被勾选/取消勾选的checkbox数组(或对象)
	 * 		checkedFlag : 要执行勾选(true)或取消勾选(false)的动作
	 * 
	 * since: 1.1
	 */	
	function checkOperation(obj, checkedFlag) {
		if (obj == null) {
			throw new Error(1000010, "input argument obj is null");
		}
		if (obj.length == null) { // 非数组
			if (obj.tagName.toUpperCase() != 'INPUT' || obj.type.toLowerCase() != "checkbox") {
				throw new Error(1000020, "input argument obj is not a checkbox obj");
			}
			obj.checked = checkedFlag;
			
		} else { // 数组
			if (obj[0].tagName.toUpperCase() != 'INPUT' || obj[0].type.toLowerCase() != "checkbox" ) {
				throw new Error(1000020, "input argument obj is not a checkbox obj");
			}
			for (var i=0; i<obj.length; i++) {
				obj[i].checked = checkedFlag;
				
			}
		}
	}
	/*
	 * descript:
	 *      执行勾选所传入的checkbox数组(或对象)
	 * parameter:
	 * 	    obj: 要被勾选的checkbox数组(或对象)
	 * 
	 * since: 1.1
	 */	
	function checkAll(obj) {
		checkOperation (obj, true);
	}
	/*
	 * descript:
	 *      执行取消勾选所传入的checkbox数组(或对象)
	 * parameter:
	 * 	    obj: 要被取消勾选的checkbox数组(或对象)
	 * 
	 * since: 1.1
	 */	
	function uncheckAll(obj) {
		checkOperation (obj, false);
	}
	
	/*
	 * descript:
	 *      执行反向勾选所传入的checkbox数组(或对象)。
	 * 		反向勾选即为将还本勾选的变成取消勾选，原本没勾选的变成勾选。
	 * parameter:
	 * 	    obj: 要被反向勾选的checkbox数组(或对象)
	 * 
	 * since: 1.1
	 */	
	function reverseCheck(obj) {
		if (obj == null) {
			throw new Error(1000010, "input argument obj is null");
		}
		if (obj.length == null) { // 非数组
			if (obj.tagName.toUpperCase() != 'INPUT' || obj.type.toLowerCase() != "checkbox") {
				throw new Error(1000020, "input argument obj is not a checkbox obj");
			}
			if (obj.checked) {
				obj.checked = false;
			} else {
				obj.checked = true;
			}
			
		} else { // 数组
			if (obj[0].tagName.toUpperCase() != 'INPUT' || obj[0].type.toLowerCase() != "checkbox" ) {
				throw new Error(1000020, "input argument obj is not a checkbox obj");
			}
			for (var i=0; i<obj.length; i++) {
				if (obj[i].checked) {
					obj[i].checked = false;
				} else {
					obj[i].checked = true;
				}
				
			}
		}
	}
//==================================================================================================================//
	/*
	 * descript:
	 *      将传入的select对象中的所有选项都选取起来
	 * parameter:
	 * 	    selectObj: select物件
	 * 
	 * since: 1.1
	 */	
	function selectAllOptions(selectObj) {
		if (selectObj.tagName.toUpperCase() != 'SELECT') {
			throw new Error(1000030, "input argument obj is not a select obj");
		}
		
		for (var i=0; i<selectObj.options.length; i++) {
			selectObj.options[i].selected = true;
		}
	}
	
	/*
	 * descript:
	 *      为传入的Select对象设定初值
	 * parameter:
	 * 	    selectObj: select物件
	 * 		defaultCode: 要设定的初值
	 * 
	 * since: 1.1
	 */	
	function setSelectDefault (selectObj, defaultCode) {
		if (selectObj.tagName.toUpperCase() != 'SELECT') {
			throw new Error(1000030, "input argument obj is not a select obj");
		}
		for (var i=0; i<selectObj.options.length; i++) {
			if (selectObj.options[i].value == defaultCode) {
				selectObj.options[i].selected = true;
				break;
			}
		}
		
	}
	
	/*
	 * descript:
	 *      将传入的Select对象中的所有选项清除
	 * parameter:
	 * 	    selectObj: select物件
	 * 
	 * since: 1.1.1
	 */	
	function deleteAllSelectOptions (selectObj) {
		if (selectObj.tagName.toUpperCase() != 'SELECT') {
			throw new Error(1000030, "input argument obj is not a select obj");
		}
		for (var i=0; i<selectObj.options.length;) {
			selectObj.options[0] = null;
		}
		
	}	
//==================================================================================================================//
	/*
	 * descript:
	 *      随机数产生一组字符串
	 * parameter:
	 * 	    len: 要产生的字符串长度
	 * return:
	 * 		随机数产生的字符串
	 * since: 1.1.1
	 */	
	function generateRandomString(len) {
		var randomString = "";
		var randomNum;
		for (var i=0; i<len; i++) {
			randomNum = Math.floor(Math.random() * 62);
			if (randomNum <= 25) {
				randomString += String.fromCharCode(65 + randomNum);
			} else if (randomNum >= 52) {
				randomString += String.fromCharCode(48 + (randomNum - 52));
			} else {
				randomString += String.fromCharCode(97 + (randomNum - 26));
			}
		}
		return randomString;
	}	
//==================================================================================================================//
	/*
	 * descript:
	 *      判断传进来的对象是否为指定的html tag
	 * parameter:
	 * 	    tagName: 
	 * 			指定的html tag 名称，如果要判断的html tag是input tag 系列，请输入
	 *          type。如：hidden、text、checkbox…等。
	 *      obj: 要被判断的对象
	 * return:
	 * 		true: 传进来的对象是指定的 Html tag
	 * 		false: 传进来的对象不是指定的 Html tag
	 * since: 1.1.1
	 */	
	 function isSpecifyHtmlTag(tagName, obj) {
	 	tagName = tagName.toUpperCase();
	 	if (new String(typeof(obj)).toLowerCase() != 'object' ||
	 		obj.tagName == null) {
	 		return false;
	 	} else {
	 		var objTagName = obj.tagName.toUpperCase();
	 		objTagName = objTagName == "INPUT" ? obj.type.toUpperCase() : objTagName;
 			if (objTagName == tagName) {
 				return true;
 			} else {
 				return false;
 			}
	 	}
	 }
//==================================================================================================================//
	/*
	 * descript:
	 *      判斷傳進來的字串是否大於指定的字數
	 * parameter:
	 * 	    string: 字串
	 * 		maxNum: 最大字數
	 *      count: 超過ascii表127的字視為多長的字,若輸入1則視同不判斷2bytes以上的字
	 * return:
	 * 		true : 傳進來的字串大於指定的字數
	 * 		false: 傳進來的字串小於、等於指定的字數
	 * 
	 * since: 1.1
	 */	
	function isOverMaxNumOfWord(string, maxNum, count) {
		var realNum = 0;
		for (var i=0; i<string.length; i++) {
			    var codes=string.charCodeAt(i);
				if (codes<=127) {
					realNum ++;
				} else {
					realNum += count;
				}
		}
			return (realNum > maxNum)
	}

		

//==================================================================================================================//
//==================================================================================================================//
	/*
	 * descript:
	 *      检查字串是否填写、是否过长
	 * parameter:
	 * 	    string: 字串,长度,错误栏位
	 * return:
	 * 		true 为合法格式 false 不合法的格式
	 * 
	 * since: 1.1
	 */		
	function check104String(obj,num,show)    
	{   if(obj.value == '') {
	    	alert('请填写'+show);
	    	obj.focus();
	    	return false;
	    }  
	    if(obj.value.getByteLength() > parseInt(num)) {
	    	alert(show+'字串长度过长');
	    	obj.focus();
	    	return false;
	    }
	    return true;	
	} 
	
//==================================================================================================================//
	/*
	 * descript:
	 *      检查数字是否正碉、是否过长
	 * parameter:
	 * 	    string: 字串,长度,错误栏位
	 * return:
	 * 		true 为合法格式 false 不合法的格式
	 * 
	 * since: 1.1
	 */		
	function check104Num(obj,num,show)    
	{           
	    if(obj.value == '') {
	    	alert('请填写'+show);
	    	obj.focus();
	    	return false;
	    }  
	    if(obj.value.getByteLength() > parseInt(num)) {
	    	alert(show+'数字长度过长');
	    	obj.focus();
	    	return false;
	    }
		if(!isNumber(obj)) {
			alert(show+'非数字格式'); 
			obj.focus();
	    	return false;
		}	
	    return true;	
	} 	   	
	    
//==================================================================================================================//
	/*
	 * descript:
	 *      检查Email是否正碉、是否过长
	 * parameter:
	 * 	    string: 字串,长度,错误栏位
	 * return:
	 * 		true 为合法格式 false 不合法的格式
	 * 
	 * since: 1.1
	 */		
	function check104Email(obj,num,show)    
	{           
	    if(obj.value == '') {
	    	alert('请填写'+show);
	    	obj.focus();
	    	return false;
	    }  
	    if(obj.value.getByteLength() > parseInt(num)) {
	    	alert(show+'资料长度过长');
	    	obj.focus();
	    	return false;
	    }
		if(!isEmailFormat(obj)) {
			alert(show+'非合法Email格式'); 
			obj.focus();
	    	return false;
		}	
	    return true;	
	} 	 

//==================================================================================================================//
	/*
	 * descript:
	 *      检查网址是否正碉、是否过长
	 * parameter:
	 * 	    string: 字串,长度,错误栏位
	 * return:
	 * 		true 为合法格式 false 不合法的格式
	 * 
	 * since: 1.1
	 */		
	function check104Http(obj,num,show)    
	{           
	    if(obj.value == '') {
	    	alert('请填写'+show);
	    	obj.focus();
	    	return false;
	    }  
	    if(obj.value.getByteLength() > parseInt(num)) {
	    	alert(show+'资料长度过长');
	    	obj.focus();
	    	return false;
	    }
		if(!(new RegExp("^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$")).test(obj)) {
			alert(show+'非正式网址格式'); 
			obj.focus();
	    	return false;
		}	
	    return true;	
	} 
//==========================================================================
	/*
	 * descript:
	 *      对 form 裹所有<input type="text"> 的 value 值执行trim
	 * parameter:
	 * 	    form: form object
	 * 
	 * since: 1.2
	 */	
	function trimAll(form) {
		if (form != null && form.tagName.toUpperCase() == 'FORM') {
			var elements = form.elements;
			for (var i = 0; i < elements.length; i++) {
				if (elements[i].tagName.toUpperCase() == 'INPUT' && elements[i].type.toUpperCase() == 'TEXT') {
					elements[i].value = elements[i].value.trim();
				}
			}
		}
	}	