/***************************************************************************************************
 *  Daon Soft 폼 검증 툴
 *  Designed By xanadu (방기배)
 *  !! 주의
 *  - 속성을 추가할 시에는  /commons/resource/css/validator.css 에도 항목을 추가해야 한다.(복사 & 붙여넣기)
 *  사용방법 :
 *   HTML -
 *    아래 예와 같이 속성명을 정의하고, Form Elements 에 class 속성으로 사용한다.
 *    <input type="" name="" value="" class="속성1 속성2 속성3" />
 *    예를 들어 반드시 입력해야 하며, 숫자만으로 되어있어야 하며, white space가 없어야 한다면,
 *    아래와 같이 사용한다.
 *    <input type="" name="" value="" class="required validate-digits validate-white-space" />
 *
 *   SCRIPT - 
 *     폼 전체 적용
 *     if(Validator.validate(검증대상Form객체)){
 *          문제가 없다면 수행할 코드....
 *          form.submit();
 *     }
 *     
 *     한 항목씩 사용
 *     var message = Validator["validate-full-jumin"](str);
 *     // 오류가 있으면 메시지를 반환                                                                       
 *     if(message) {
 *         alert(message);
 *         return false;
 *     }
 ***************************************************************************************************/
    var Validator = {

        validate : function(form) {         
            var elements = form.elements;
            for(var i = 0; i <elements.length;i++) {                
                var el = elements[i];               
                var classes = el.className.split(" ");
                for(var j = 0; j < classes.length; j++) {
                    // 각 클래스 명
                    var className = classes[j].replace(" ","");
                    var param;

                    /* className에 '_'(언더바)가 포함된경우 토큰으로 잘라서 앞부분을 함수 명으로 
                     * 사용하고  뒷 부분을 인자로 취하도록 한다.
                     * 
                     * 예 : validate-max-length_30 
                     *     : validate-max-length(x, y, 30) 맨뒤의 30이 인자로 취해짐
                     *     
                     * '_'가 여러개 포함 된 경우 이후 값들은 배열로 전달된다.(배열은 길이 제한이 없음)
                     * 예 : validate-limit-length_10_30
                     *     : validate-limit-length(x, y, Array([10,30])) 10과 30이 배열로 넘겨짐
                     */
                    if(className.indexOf("_") >= 0) {
                        var tmpArray = className.split("_");
                        className = tmpArray[0];
                        tmpArray.shift();
                        
                        if(tmpArray == null || tmpArray.length == 0) {
                            param = "";
                        } else if(tmpArray.length == 1) {
                            param = tmpArray[0];
                        } else {
                            param = tmpArray;
                        }
                    }

                    // 클래스명과 일치하는 메서드가 있으면...                               
                    if(Validator[className]) {
                        var message = Validator[className](el.value,el,param);
                        // 오류가 있으면 메시지를 반환                                                                      
                        if(message) {
                            Validator._handleError(message, el);
                            return false;
                        }
                    }
                }
            }
            return true;
        },

        /**
         * 오류 제어
         * @param {String} message
         * @param {HTMLFormElement} el
         */
        _handleError : function(message, el) {
            var title = Validator._getTitle(el);
            if(title != "")
                alert(title +"(은)는 " + message);
            else 
                alert(message);
            el.style.backgroundColor="#fdfde4";
            if (el.type != 'textarea')
                el.focus();            
        }, 

        _getTitle : function (el) {
            if (el.title)
                return el.title;
            else 
                return "";
        },

        // 필수입력
        "required" : function(v) {          
            return !v ? "필수 입력사항 입니다." : false;
        },
        // white space 없이 입력
        "validate-white-space" : function(v) {
            return /\s+/.test(v) ? "공백은 허용되지 않습니다." : false;
        },
        // 숫자만 입력
        "validate-digits" : function(v) {
            return isNaN(v) || /[^\d]/.test(v)? "숫자만 입력 가능합니다." : false;           
        },
        // 영문만 입력
        "validate-alpha" : function(v) {
            return /[^a-zA-Z\s+]/.test(v) ? "알파뱃만 입력 가능합니다." : false;
        },
        // 영문, 숫자, _(언더바) 만  입력
        "validate-basic-char" : function(v) {
            return !/[a-zA-Z0-9_]/.test(v) ? "알파뱃, 숫자, _(언더바)만 입력 가능합니다." : false;
        },
        // 영문과 숫자만 입력
        "validate-alpha-num" : function(v) {
            return /\W/.test(v) ? "알파뱃과 숫자만 입력 가능합니다." : false;
        },
        // 날자 사용가능한 숫자 입력
        "validate-date" : function(v) {
            var date = new Date(v);
            return isNaN(v) ? "날자 형식이 올바르지 않습니다." : false;
        },
        // 유효한 email 입력
        "validate-email" : function(v) {
            return !/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v) ? "이메일 형식이 올바르지 않습니다." : false;
        },
        // 유효한 URL 입력
        "validate-url" : function(v) {
            if(v) {
                return !/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(v) ? "URL형식이 올바르지 않습니다." : false;
            }
            return false;
        },
        // 하나라도 선택 입력(radio or checkbox)
        "validate-one-required" : function(v,elm) {         
            var field_obj  = document.getElementsByName(elm.name);
            if (field_obj.length > 1) {
                for (var idx = 0; idx < field_obj.length; idx++) {
                    if (field_obj[idx].checked) return false;
                }
            } else {
                if (field_obj.checked) return false;
            }
            return "항목을 선택하셔야 합니다.";
        },
        // 셀렉트 박스 필수 선택
        "validate-required-select" : function(v, elm) {
            var field_obj = document.getElementById(elm.name);

            if(field_obj.options[field_obj.selectedIndex].value != "")
                return false;

            return "항목을 선택하셔야 합니다.";

        },
        // 유효한 주민번호 앞자리 검증
        "validate-front-jumin" : function(v) {

            if (v.length !=6 || isNaN(v)) {
                return "주민등록번호 앞자리는 숫자 6자리만 가능합니다.";
            }

            return false ;
        },
        // 유요한 주민번호 뒷자리 검증
        "validate-back-jumin" : function(v) {
            var check_digit2;

            if (v.length!=7 || isNaN(v)) {
                return "주민등록번호 뒷자리는 숫자 7자리만 가능합니다.";
            }

            return false;
        },
        // 유효한 전체 주민번호 검증
        "validate-full-jumin" : function(v) {

            val = v.replace(/-/g, "");
            
            pin1 = val.substring(0,6);
            pin2 = val.substring(6,13);

            if (pin1.length!=6 || isNaN(pin1)) {
                return "주민등록번호 앞자리는 숫자 6자리만 가능합니다.";
            }
            
            var a1=pin1.substring(0,1)
            var a2=pin1.substring(1,2)
            var a3=pin1.substring(2,3)
            var a4=pin1.substring(3,4)
            var a5=pin1.substring(4,5)
            var a6=pin1.substring(5,6)
            
            check_digit1 = a1*2 + a2*3 + a3*4 + a4*5 + a5*6 + a6*7;
            
            if (pin2.length!=7 || isNaN(pin2)) {
                return "주민등록번호 뒷자리는 숫자 7자리만 가능합니다.";
            }

            var b2=pin2.substring(1,2)
            var b3=pin2.substring(2,3)
            var b4=pin2.substring(3,4)
            var b5=pin2.substring(4,5)
            var b6=pin2.substring(5,6)
            var b7=pin2.substring(6,7)
            
            check_digit2 = check_digit1 + b1*8 + b2*9 + b3*2 + b4*3 + b5*4 + b6*5;
            
            check_digit2 = check_digit2 % 11
            check_digit2 = 11 - check_digit2
            check_digit2 = check_digit2 % 10
            
            if (check_digit2 != b7){
                return "유효하지 않는 주민등록번호입니다.";
            }

            return false;
        },
        // BYTE 단위로 최대 글자수를 제한
        "validate-max-length" : function(v, elm, length) {
            var maxSize = parseInt(length, 10);
            var len = 0;
            var str = v.substring(0);
            if(str == null) return "길이를 확인할 값이 없습니다.";
            for(var i=0; i<str.length; i++) {
                var ch = escape(str.charAt(i));
                if(ch.length == 1) len++;
                else if(ch.indexOf("%u") != -1) len += 3;
                else if(ch.indexOf("%") != -1) len += ch.length/3;
            }

            if(maxSize < len) {
                return "최대 "+maxSize+" byte 까지 입력 가능합니다.";
            }
            return false;
        },
        // BYTE 단위로 최소 글자수를 제한
        "validate-min-length" : function(v, elm, length) {
            var minSize = parseInt(length, 10);
            var len = 0;
            var str = v.substring(0);
            if(str == null) return "길이를 확인 할 값이 없습니다.";
            for(var i=0; i<str.length; i++) {
                var ch = escape(str.charAt(i));
                if(ch.length == 1) len++;
                else if(ch.indexOf("%u") != -1) len += 3;
                else if(ch.indexOf("%") != -1) len += ch.length/3;
            }

            if(minSize > len) {
                return "최소 "+minSize+" byte 를 입력 해야 합니다.";
            }
            return false;
        },
        // BYTE 단위로 범위내의 글자수를 체크
        "validate-limit-length" : function(v, elm, param) {
            if(param.length == 2) {
                var minSize = parseInt(param[0], 10);
                var maxSize = parseInt(param[1], 10);
                var len = 0;
                var str = v.substring(0);
                if(str == null) return "길이를 확인 할 값이 없습니다.";
                for(var i=0; i<str.length; i++) {
                    var ch = escape(str.charAt(i));
                    if(ch.length == 1) len++;
                    else if(ch.indexOf("%u") != -1) len += 3;
                    else if(ch.indexOf("%") != -1) len += ch.length/3;
                }

                if(minSize > len || maxSize < len) {
                    return "최소 "+minSize+" byte 보다  같거나  크고, "+maxSize+" 보다  같거나  작아야 합니다.";
                }
            } else {
                return "최소 값과 최대 값 두개의 배열 인자가 필요합니다.";
            }
            
            return false;
        },
        // 전화번호 유효성 체크 02-222-2222 형식 '-' 토큰으로 잘라서 검증함
        "validate-tel-num" : function(v, elm, param) {
            if(v) {
                val = v.replace(/-/g, "");
            
                if(isNaN(val)) {
                    return "숫자, - 만 입력하셔야 합니다.";
                }
                
                var tmpArray = v.split("-");
                if(tmpArray.length != 3) {
                    return "-를 포함하여  정확히  입력하셔야 합니다.";
                }
                for(i = 0; i < tmpArray.length; i++ ) {
                    if(tmpArray[i] == "") return "정확히  입력하셔야 합니다.";
                }
            }
            
            return false;
        },
        // 웹상에서 사용가능한 이미지 파일 종류인지 확인한다. gif, jpg, png 만 인정함
        "validate-is-image" : function(v) {
            if(v) {
                var ext = "";
                if(v.indexOf(".") >= 0) {
                    ext= v.substring(v.lastIndexOf(".")+1);
                    if(ext.length != 3 || !(ext == "gif" || ext == "jpg" || ext == "png"))
                        return "파일은 gif, jpg, png 파일만 등록을 하실수 있습니다.";
                } else {
                    return "파일의 확장자가 없습니다.";
                }
            }
            return false;
        }
        
    }
