/**
* project: lib.validate.js ver 0.1.1
* description: 폼 체크, 값 표준화
* author: jstoy project
* date: 2004-03-10
*
* 2004-03-10 ver 0.0.1
* 2004-04-21 ver 0.1.0 - lainTT (에러모드에 따른 부하최소화, trim 재구성)
* 2004-04-23 ver 0.1.1 - lainTT (체크박스 카운트 체크[mincheck, maxcheck] 추가)
*/

/**
* <pre>
* form check trigger function
* </pre>
*
* @param form Object
* @return boolean
*/

/*
1. 체크항목
   CRUD에 따른 필수입력

   isCK
   isUK
   isRK, isRK
   isRPK


*/



function validate(form, mode) {
    var checker = new FormChecker(form, mode);
    try {
        var result = checker.go();
    } catch (e) {
        alert(e);
        return false;
    }
    checker.destroy();
    return result;
}


FormChecker = function(form, mode) {
    /**
    * <pre>
    * pre-set error messages
    * </pre>
    */
    this.ERRMSG = {
    //    common   : "입력하신 내용이 규칙에 어긋납니다.\n규칙에 어긋나는 내용을 바로잡아주세요.",
    	common   : "",
        required : "반드시 입력하셔야 하는 사항입니다.",
        required_group : "이 항목들 중에 {requirenum}개 이상의 항목이 입력되어야 합니다.",
        notequal : "입력된 내용이 일치하지 않습니다.",
        invalid  : "입력된 내용이 형식에 어긋납니다.",
        minbyte  : "입력된 내용의 길이가 {minbyte}Byte 이상이어야 합니다.",
        maxbyte  : "입력된 내용의 길이가 {maxbyte}Byte를 초과할 수 없습니다.",
        mincheck : "{mincheck}개의 항목이상으로 선택하세요.",
        maxcheck : "{maxcheck}개의 항목이하로 선택하세요.",
		money : "금액형식으로 입력하세요",
		number : "숫자형식으로 입력하세요",
		cnt : "수량형식으로 입력하세요",
		alphabet : "영문자형식으로 입력하세요",
		alphanum : "5자이상 12자 미만,\n 영문,숫자, _ 문자만 사용할 수 있습니다",
		idpw : "4자이상 8자 미만,\n 영문,숫자만 사용할 수 있습니다",
		hangul : "한글로 입력하세요",
		email : "E-MAIL형식으로 입력하세요",
		jumin : "주민번호 형식으로 입력하세요",
		date : "날짜형식으로입력하세요",
		mode : "화면처리 모드를 입력하세요",
		ck : "등록시 반드시 입력하세요",
		uk : "수정시 반드시 입력하세요",
		dk : "삭제시 반드시 입력하세요",
		rk : "조회시 반드시 입력하세요"
    } 

    /**
    * <pre>
    * form check function mapping
    * </pre>
    */
    this.VALIDATE_FUNCTION = {
        trim    : this.func_trim,
        email   : this.func_isValidEmail,
        phone   : this.func_isValidPhone,
        userid  : this.func_isValidUserid,
        hangul  : this.func_hasHangul,
        number  : this.func_isNumeric,
        engonly : this.func_alphaOnly,
        jumin   : this.func_isValidJumin,
        bizno   : this.func_isValidBizNo
    }

    /**
    * <pre>
    * default option
    * </pre>
    */
    this.DEFAULT_OPTION = {
        text   : "trim",
        hidden : "trim"
    }

    /**
    * <pre>
    * default errordo
    * </pre>
    */
    this.DEFAULT_ERRORDO = {
        text   : "focus",
        select : "focus",
        check  : "focus",
        radio  : "focus",
        file   : "focus",
        hidden : ""
    }

    this.form = form;
    this.errObj = null;
    this.curObj = null;
    this.errMsg = this.ERRMSG["common"] != "" ? this.ERRMSG["common"]+"\n\n" : "";
    this.errMode = 2; // all:1, one:2, one per object:3
}

FormChecker.prototype.go = function() {
    var oldRequired = new Array;
    for (var i=0; i<this.form.elements.length; i++) {
        var el = this.form.elements[i];
        if (!this.isValidElement(el)) continue;

        var elType = this.getType(el);
        var required   = el.getAttribute("REQUIRED");
        var requirenum = el.getAttribute("REQUIRENUM");
        var money = el.getAttribute("MONEY");
		var number = el.getAttribute("NUMBER");
		var cnt = el.getAttribute("CNT");
		var alphabet = el.getAttribute("ALPHABET");
		var alphanum = el.getAttribute("ALPHANUM");
		var idpw = el.getAttribute("IDPW");
		var hangul = el.getAttribute("hangul");
		var email = el.getAttribute("email");
		var jumin = el.getAttribute("jumin");
		var date = el.getAttribute("date");

		var ck = el.getAttribute("isCK");
		var uk = el.getAttribute("isUK");
		var dk = el.getAttribute("isDK");
		var rk = el.getAttribute("isRK");
		

		if( ck != null ) {
			if( ck != "" ) {
                if (this.isEmpty(el, elType))
                    if (!this.raiseError(el,"ck")) return false;
			}
		}
		if( uk != null ) {
			if( uk != "" ) {
                if (this.isEmpty(el, elType))
                    if (!this.raiseError(el,"uk")) return false;
			}
		}
		if( dk != null ) {
			if( dk != "" ) {
                if (this.isEmpty(el, elType))
                    if (!this.raiseError(el,"dk")) return false;
			}
		}
		if( rk == 2)
		{
			//alert("여기로");
		}
		else if( rk != null ) {
			if( rk != "" ) {
                if (this.isEmpty(el, elType))
                    if (!this.raiseError(el,"rk")) return false;
			}
		}

        if (required != null) {
            if (required == "") {
                if (this.isEmpty(el, elType))
                    if (!this.raiseError(el,"required")) return false;
            } else {
                var flOldRequired = false;
                for (var j=0; j<oldRequired.length; j++)
                    if (oldRequired[j] == required) flOldRequired = true;

                if (!flOldRequired) {
                    oldRequired[oldRequired.length] = required;
                    var reqNum = 0;
                    var reqHname = new Array;
                    for (var j=0; j<this.form.elements.length; j++) {
                        var reqEl = this.form.elements[j];
                        var reqElType = this.getType(reqEl);
                        if (!this.isValidElement(reqEl)) continue;
                        if (reqEl.getAttribute("REQUIRED") == required) {
                            if (!this.isEmpty(reqEl, reqElType)) reqNum++;
                            reqHname[reqHname.length] = this.getName(reqEl);
                        }
                    }
                    if (reqNum < requirenum)
                        if (!this.raiseError(el,"required_group",reqHname.join(", "))) return false;
                }
            }
        }

		if (number != null) {
			if(!this.isNumeric(el)){
			   if (!this.raiseError(el,"number")) return false;
			}
		}
	    if (cnt != null) {
			this.delComma(el,1);
			if(!this.isNumericCnt(el)){
			   if (!this.raiseError(el,"cnt")) return false;
			}
		}

		if (money !== null) {
			this.delComma(el,1);
			if(!this.isNumeric(el)){
				if (!this.raiseError(el,"money")) return false;
			}
		}

	 

		if (alphabet != null) {
			if(!this.alphaOnly(el)){
			   if (!this.raiseError(el,"alphabet")) return false;
			}
		}

		if (alphanum != null) {
			if(!this.isValidUserid(el)){
			   if (!this.raiseError(el,"alphanum")) return false;
			}
		}

		if (idpw != null) {
			if(!this.isValidIdPw(el)){
			   if (!this.raiseError(el,"idpw")) return false;
			}
		}

		if (hangul != null) {
			if(!this.hasHangul(el)){
			   if (!this.raiseError(el,"hangul")) return false;
			}
		}

	    if (email != null) {
			if(!this.isValidEmail(el)){
			   if (!this.raiseError(el,"email")) return false;
			}
		}

	    if (jumin != null) {
			if(!this.isValidJumin(el,el.value)){
			   if (!this.raiseError(el,"jumin")) return false;
			}
		}
		if (date != null) {
			if(!this.chkDate(el)){
			   if (!this.raiseError(el,"date")) return false;
			}else{
			
			}
		}

        if (elType == "text" || elType == "hidden") {
            var minbyte = el.getAttribute("MINBYTE");
            var maxbyte = el.getAttribute("MAXBYTE");
            var option  = el.getAttribute("OPTION") ? el.getAttribute("OPTION") : this.DEFAULT_OPTION[elType];
            var match   = el.getAttribute("MATCH");
            var span    = el.getAttribute("SPAN");
            var glue    = el.getAttribute("GLUE");
            var pattern = eval(el.getAttribute("PATTERN"));
			
			//최소 입력 byte 체크
            if (minbyte != null) {
                minbyte = parseInt(minbyte,10);
                var _tmp = el.value;
                var elLen = 0;
                for (j=0; j<_tmp.length; j++) {
                    var chr = _tmp.charAt(j);
                    elLen += (chr.charCodeAt() > 128) ? 2 : 1;
                }
               	if (elLen < minbyte)
                	if (!this.raiseError(el,"minbyte")) return false;
            }
			//최대 입력 byte 체크
            if (maxbyte != null) {
                maxbyte = parseInt(maxbyte,10);
                var _tmp = el.value;
                var elLen = 0;
                for (j=0; j<_tmp.length; j++) {
                    var chr = _tmp.charAt(j);
                    elLen += (chr.charCodeAt() > 128) ? 2 : 1;
                }
				if (elLen > maxbyte)
					if (!this.raiseError(el,"maxbyte")) return false;
            }

			//다른 속성과 같은지 비교
            if (match != null) {
                if (typeof this.form.elements[match] == "undefined")
                    throw "Element '"+ match +"' is not found.";
                else if (el.value != this.form.elements[match].value)
                    if (!this.raiseError(el,"notequal")) return false;
            }
			
			//select box의 OPTION 체크
			if (el.value != "" && option !== null) {
				var elOption = option.split(" ");
				for (var j in elOption) {
					var _option = elOption[j];
					if (typeof this.VALIDATE_FUNCTION[_option] == "undefined") {
						throw "Function map '"+ _option +"' is not found.";
					} else if (span !== null) {
						var _value = new Array();
						for (var j = 0; j < span; j++) {
							if (typeof this.form.elements[i+j] == "undefined")
								throw (i+j) +"th Element is not found.";
							_value[j] = this.form.elements[i+j].value;
						}
						var value = _value.join(glue === null ? "" : glue);
						var tmpMsg = this.VALIDATE_FUNCTION[_option](el, value);
						if (tmpMsg !== true)
						if (!this.raiseError(el,tmpMsg)) return false;
					} else {
						var tmpMsg = this.VALIDATE_FUNCTION[_option](el);
						if (tmpMsg !== true)
							if (!this.raiseError(el,tmpMsg)) return false;
					}
				}
			}
			//정규식 체크
			if (el.value != "" && pattern !== null) {
				try {
					pattern = new RegExp(pattern);
				} catch (e) {
					throw "Invalid Regular Expression '"+ pattern +"'";
				}
				if (!pattern.test(elValue))
					if (!this.raiseError(el,"invalid")) return false;
			}  
		
		}
		//체크박스 중 반드시 체크되어야 할 개수 체크  
		else if (elType == "check") {
			var mincheck = parseInt(el.getAttribute("MINCHECK"),10);
			var maxcheck = parseInt(el.getAttribute("MAXCHECK"),10);
			if (mincheck > 0 || maxcheck > 0) {
				var elCheck  = this.form.elements[el.name];
				var elCheckNum = 0;
				if(elCheck.length){
					for (var j=0; j<elCheck.length; j++) {
						if (elCheck[j].checked == true) elCheckNum++;
					}
				}else{
				    if (elCheck.checked == true) elCheckNum++;
				}
				if (mincheck > 0 && elCheckNum < mincheck) {
					if (!this.raiseError(el,"mincheck")) return false;
				}
				if (maxcheck > 0 && elCheckNum > maxcheck) {
					if (!this.raiseError(el,"maxcheck")) return false;
				}
			}
		}
	}
	return !this.isErr;
}


//객체 소멸자
FormChecker.prototype.destroy = function() {
    if (this.isErr == true) {
        alert(this.errMsg);
        var _tmp = this.errObj.getAttribute("errordo");
        if (!_tmp) _tmp = this.DEFAULT_ERRORDO[this.getType(this.errObj)];
        var onError = _tmp ? _tmp.split(" ") : [];
        for (var i in onError) {
            switch (onError[i]) {
            case "delete": this.errObj.value = ""; break;
            case "select": this.errObj.select(); break;
            case "focus":  this.errObj.focus(); break;
            }
        }
    }
    this.errMsg = "";
    this.errObj = null;
    this.curObj = null;
}

//에러 메시지 띄우는 함수
FormChecker.prototype.raiseError = function(el, type, elName) {
    var pattern = /\{([a-zA-Z0-9_]+)\}/i;
    var msg = this.ERRMSG[type] ? this.ERRMSG[type] : type;
    
	//2006-03-31 Servant Label 사용
	//var elName = elName ? elName : this.getName(el);
	var elLabel = el.getAttribute("label");
    var elName = (elLabel != null && elLabel!="") ? elLabel : elName ? elName : this.getName(el);

    if (el.getAttribute("errmsg") != null) msg = el.getAttribute("errmsg");
    if (pattern.test(msg) == true) {
        while (pattern.exec(msg)) msg = msg.replace(pattern, el.getAttribute(RegExp.$1));
    }
    if (!this.errObj || this.errMode != 2) {
        if (this.curObj == el && el.getAttribute("errmsg") == null) {
            if (this.errMode == 1)
                this.errMsg += "   - "+ msg +"\n";
        } else if (this.curObj != el) {
            if (this.curObj)
                this.errMsg += "\n";
            this.errMsg += "["+ elName +"]\n   - "+ msg +"\n";
        }
    }
    if (!this.errObj) this.errObj = el;
    this.curObj = el;
    this.isErr  = true;
    return this.errMode == 2 ? false : true;
}

//실제 element인지 체크하는 하무
FormChecker.prototype.isValidElement = function(el) {
    return (el.tagName.toLowerCase() == "fieldset" || el.tagName.toLowerCase() == "object" ||
        el.name == null || el.name == "") ? false : true;
}

//비어있는지 체크하는 함수
FormChecker.prototype.isEmpty = function(el, type) {
    switch (type) {
    case "file": case "text": case "hidden":
        if (el.value == null || el.value == "") return true;
        break;
    case "select":
        if (el[el.selectedIndex].value == null || el[el.selectedIndex].value == "") return true;
        break;
    case "check": case "radio":
        var elCheck = this.form.elements[el.name];
        var elChecked = false;
        for (var j=0; j<elCheck.length; j++) {
            if (elCheck[j].checked == true) elChecked = true;
        }
        if (elChecked == false) return true;
        break;
    }
    return false;
}

//element의 type을 알아내는 함수
FormChecker.prototype.getType = function(el) {
    switch (el.tagName.toLowerCase()) {
    case "select": return "select";
    case "textarea": return "text";
    case "input":
        switch (el.type.toLowerCase()) {
        case "radio": return "radio";
        case "checkbox": return "check";
        case "file": return "file";
        case "text": case "password": return "text";
        case "hidden": return "hidden";
        }
        break;
    }
}

//element의 명을 알아내는 함수
FormChecker.prototype.getName = function(el) {
    return (el.getAttribute("HNAME") == null || el.getAttribute("HNAME") == "")
        ? el.name : el.getAttribute("HNAME");
}

/**
* validate functions
*/
FormChecker.prototype.func_isValidEmail = function(el,value) {
	if(el.value == "" ) {
		return true;
	}
	var value = value ? value : el.value;
	var pattern = /^[_a-zA-Z0-9-\.]+@[\.a-zA-Z0-9-]+\.[a-zA-Z]+$/;
	return (pattern.test(value)) ? true : "invalid";
}

FormChecker.prototype.isValidEmail = function(el,value) {
   if(el.value == "" ) {
		return true;
	}
	var value = value ? value : el.value;
	var pattern = /^[_a-zA-Z0-9-\.]+@[\.a-zA-Z0-9-]+\.[a-zA-Z]+$/;
	return (pattern.test(value)) ? true : false;
}

FormChecker.prototype.func_isValidUserid = function(el) {
   var pattern = /^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$/;
   return (pattern.test(el.value)) ? true : "5자이상 12자 미만,\n 영문,숫자, _ 문자만 사용할 수 있습니다";
}

FormChecker.prototype.isValidIdPw = function(el) {
   var pattern = /^[a-zA-Z]{1}[a-zA-Z0-9_]{3,8}$/;
   return (pattern.test(el.value)) ? true : false; // "4자이상 8자 미만,\n 영문,숫자, _ 문자만 사용할 수 있습니다";
}

FormChecker.prototype.isValidUserid = function(el) {
   var pattern = /^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$/;
   return (pattern.test(el.value)) ? true : false;// "5자이상 12자 미만,\n 영문,숫자, _ 문자만 사용할 수 있습니다";
}

FormChecker.prototype.func_hasHangul = function(el) {
   var pattern = /[가-힝]/;
   return (pattern.test(el.value)) ? true : "반드시 한글을 포함해야 합니다";
}

FormChecker.prototype.hasHangul = function(el) {
   var pattern = /[가-힝]/;
   return (pattern.test(el.value)) ? true : false;
}

FormChecker.prototype.func_alphaOnly = function(el) {
   var pattern = /^[a-zA-Z]+$/;
   return (pattern.test(el.value)) ? true : "invalid";
}

FormChecker.prototype.alphaOnly = function(el) {
   var pattern = /^[a-zA-Z]+$/;
   return (pattern.test(el.value)) ? true : false;
}

FormChecker.prototype.func_isNumeric = function(el) {
   var pattern = /^[0-9]+$/;
   return (pattern.test(el.value)) ? true : "반드시 숫자로만 입력해야 합니다";
}

FormChecker.prototype.isNumeric = function(el) {
   var pattern = /^[0-9]+$/;
   return (pattern.test(el.value)) ? true : false;
}

FormChecker.prototype.isNumericCnt = function(el) {
   var pattern = /^[0-9,.]+$/;
   return (pattern.test(el.value)) ? true : false;
}


FormChecker.prototype.func_isValidJumin = function(el,value) {
    var pattern = /^([0-9]{6})-?([0-9]{7})$/;
    var num = value ? value : el.value;
    if (!pattern.test(num)) return "invalid";
    num = RegExp.$1 + RegExp.$2;

    var sum = 0;
    var last = num.charCodeAt(12) - 0x30;
    var bases = "234567892345";
    for (var i=0; i<12; i++) {
        if (isNaN(num.substring(i,i+1))) return "invalid";
        sum += (num.charCodeAt(i) - 0x30) * (bases.charCodeAt(i) - 0x30);
    }
    var mod = sum % 11;
    return ((11 - mod) % 10 == last) ? true : "invalid";
}

FormChecker.prototype.isValidJumin = function(el,value) {
    var pattern = /^([0-9]{6})-?([0-9]{7})$/;
    var num = value ? value : el.value;
    if (!pattern.test(num)) return false;
    num = RegExp.$1 + RegExp.$2;

    var sum = 0;
    var last = num.charCodeAt(12) - 0x30;
    var bases = "234567892345";
    for (var i=0; i<12; i++) {
        if (isNaN(num.substring(i,i+1))) return false;
        sum += (num.charCodeAt(i) - 0x30) * (bases.charCodeAt(i) - 0x30);
    }
    var mod = sum % 11;
    return ((11 - mod) % 10 == last) ? true : false;
}

FormChecker.prototype.func_isValidBizNo = function(el,value) {
    var pattern = /([0-9]{3})-?([0-9]{2})-?([0-9]{5})/;
    var num = value ? value : el.value;
    if (!pattern.test(num)) return "invalid";
    num = RegExp.$1 + RegExp.$2 + RegExp.$3;
    var cVal = 0;
    for (var i=0; i<8; i++) {
        var cKeyNum = parseInt(((_tmp = i % 3) == 0) ? 1 : ( _tmp  == 1 ) ? 3 : 7);
        cVal += (parseFloat(num.substring(i,i+1)) * cKeyNum) % 10;
    }
    var li_temp = parseFloat(num.substring(i,i+1)) * 5 + "0";
    cVal += parseFloat(li_temp.substring(0,1)) + parseFloat(li_temp.substring(1,2));
    return (parseInt(num.substring(9,10)) == 10-(cVal % 10)%10) ? true : "invalid";
}

FormChecker.prototype.func_isValidPhone = function(el,value) {
    var pattern = /^([0-9]{2,6})-?([1-9]{1}[0-9]{2,3})-?([0-9]{4})$/;
    var num = value ? value : el.value;
    if (pattern.exec(num)) {
        return true;
    } else {
        return "invalid";
    }
}

FormChecker.prototype.isValidPhone = function(el,value) {
    var pattern = /^([0-9]{6})-?([1-9]{1}[0-9]{2,3})-?([0-9]{4})$/;
    var num = value ? value : el.value;
    if (pattern.exec(num)) {
        return true;
    } else {
        return false;
    }
}



FormChecker.prototype.delComma = function (input,flag){
        var inputObj = null;

        //flag이 1일경우 : 폼의 필드값을 받아서 필드에 값 넘겨줄때, 
        //flag이 2일경우 : value값만 리턴
        if(flag==1){
            inputObj = input.value;
        }else{
            inputObj = input;
        }
        var leng = inputObj.length;
        var value = "";
        var checkValue = "";
        for(i=0;i<leng;i++){
            checkValue = inputObj.substring(i,i+1);
            if(checkValue == ","){
                value = value + "";
            }else{
                value = value + checkValue;
            }
        }

        if(flag==1){
            input.value = value;
        }else{
            return value;
        }
    }


FormChecker.prototype.chkDate = function (obj){
	   var leng = obj.value.length;
        var input = "";
        var checkValue = "";
        for(i=0;i<leng;i++){
            checkValue = obj.value.substring(i,i+1);
            if(checkValue == "/"){
                input = input + "";
            }else{
                input = input + checkValue;
            }
        }
	
	if(input.length!=8){
		return false;
	 }
  var inputYear = input.substr(0,4);
  var inputMonth = input.substr(4,2) - 1;
  var inputDate = input.substr(6,2);
  var resultDate = new Date(inputYear, inputMonth, inputDate);
  if ( resultDate.getFullYear() != inputYear ||
       resultDate.getMonth() != inputMonth ||
       resultDate.getDate() != inputDate) {
     return false;
  } else {
	   obj.value = input;
     return true;
  }
}



FormChecker.prototype.func_trim = function(el) {
    el.value = el.value.replace(/^\s+/, "").replace(/\s+$/, "");
    return true;
}
