/**************************************************************************
* validation
**************************************************************************/
function customValidate(targetArr) {
	var handler = validationFailureHandler();
	for(var i=0;i<targetArr.length;i++){
		 var input = targetArr[i];

		 if(!validInput(input)){
			  return false;
		 }
		 
		 if(!input.required && input.value == ""){
			continue; 
		 }
		 
		 //입력값의 최대 바이트 수 체크
		 if(input.dataset.maxlengthb){
			 if(!isMaxByte(input.value, input.dataset.maxlengthb)){
				 handler.tooLong(input);
				 return false;
			 }
		 }
		 
		 //입력값의 포맷형식 체크
		 if(input.dataset.fmtType){
			 if(input.dataset.fmtType == "day"){
				 if(!isDate(input.value)){
					 handler.typeMismatch(input);
					 return false;
				 }
			 }
			 
			 if(input.dataset.fmtType == "time"){
				 if(!isTime(input.value)){
					 handler.typeMismatch(input);
					 return false;
				 }
			 }
		
			if(input.dataset.fmtType == "zeroLpadNumber"){
				if(!isDigitString(input.value)){
				 handler.typeMismatch(input);
				 return false;
			 }
			}
		 }
	}
	
	return true;
} 

/**
 * 문자열이 숫자형인지의 여부를 반환한다.
 * @param exceptChar - 추가 허용할 문자
 * @return 숫자형여부
 */
function isNumber(str, exceptChar) {
    return (/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/).test(str.replaceAll(exceptChar,"")) ? true : false;
};

/**
 * 문자열이 숫자형문자 인지의 여부를 반환한다.(0~9만 허용)
 * @param 
 * @return 숫자형문자 여부
 */
function isDigitString(str) {
    return (/^[0-9]+$/).test(str) ? true : false;
};

// 시간체크
function isTime(str) {
	
	str = str.replaceAll(":","");
	
	if(str.length != 6){
		return false;
	}
	
	if (!isNumber(str, "")) {
		return false;
	}
	
	var hour = str.substring(0,2);
	var minute = str.substring(2,4);
	var second = str.substring(4,6);
	
	if(hour>="00" && hour<="23"){
		if(minute>="00" && minute<="59"){
			if(second>="00" && second<="59"){
				return true;
			}
		}
	}

	return false;
}

// 날짜체크
function isDate(str) {
	
	str = str.replaceAll("-","");
	
	if(str.length != 8){
		return false;
	}
	
	if (!isNumber(str, "")) {
		return false;
	}
	
	// 숫자, length 확인
	var year = str.substring(0,4);
	var month = str.substring(4,6);
	var day = str.substring(6,8);
	
	// 유효날짜 확인
	if (year>="0001" && year<="9999" && month>="01" && month<="12") {
		febDays = "29";
		if ((parseInt(year,10) % 4) == 0) {
			if ((parseInt(year,10) % 100) == 0 && (parseInt(year,10) % 400) != 0){
				febDays = "28";
			}
		}else{
			febDays = "28";
		}
		if (month=="01" && day>="01" && day<="31") return true;
		if (month=="02" && day>="01" && day<=febDays) return true;
		if (month=="03" && day>="01" && day<="31") return true;
		if (month=="04" && day>="01" && day<="30") return true;
		if (month=="05" && day>="01" && day<="31") return true;
		if (month=="06" && day>="01" && day<="30") return true;
		if (month=="07" && day>="01" && day<="31") return true;
		if (month=="08" && day>="01" && day<="31") return true;
		if (month=="09" && day>="01" && day<="30") return true;
		if (month=="10" && day>="01" && day<="31") return true;
		if (month=="11" && day>="01" && day<="30") return true;
		if (month=="12" && day>="01" && day<="31") return true;
		return false;
	}
	
	
	return false;
}



/**
 * 문자열이 지정한 최소길이 이상인지의 여부를 반환한다.
 * @param minLen - 최소길이
 * @return 최소길이 이상인지의 여부
 */
function isMin(str, minLen) {
    return str.length >= minLen;
};

/**
 * 문자열이 지정한 최대길이 이하인지의 여부를 반환한다.
 * @param maxLen - 최대길이
 * @return 최대길이 이하인지의 여부
 */
function isMax(str, maxLen) {
    return str.length <= maxLen;
};

/**
 * 문자열이 지정한 최소바이트수 이상인지의 여부를 반환한다.
 * @param minByte - 최소바이트수
 * @return 최소바이트수 이상인지의 여부
 */
function isMinByte(str, minByte) {
    return getByte(str) >= minByte;
};

/**
 * 문자열이 지정한 최대바이트수 이하인지의 여부를 반환한다.
 * @param maxByte - 최대바이트수
 * @return 최대바이트수 이하인지의 여부
 */
function isMaxByte(str, maxByte) {
    return getByte(str) <= maxByte;
};


/**
 * 문자열이 영어만으로 구성되어 있는지의 여부를 반환한다.
 * @param exceptChar - 추가 허용할 문자
 * @return 영어만으로 구성되어 있는지의 여부
 */
function isEng(str, exceptChar) {
    return (/^[a-zA-Z]+$/).test(str.replaceAll(exceptChar,"")) ? true : false;
};

/**
 * 문자열이 숫자와 영어만으로 구성되어 있는지의 여부를 반환한다.
 * @param exceptChar - 추가 허용할 문자
 * @return 숫자와 영어만으로 구성되어 있는지의 여부
 */
function isEngNum(str, exceptChar) {
    return (/^[0-9a-zA-Z]+$/).test(str.replaceAll(exceptChar,"")) ? true : false;
};

/**
 * 이메일 주소의 유효성 여부를 반환한다.
 * @return 유효성 여부
 */
function isEmail(str) {
    return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(str);
};

/**************************************************************************
* String util
**************************************************************************/
/**
 * 문자열의 byte 길이를 반환한다.
 * @return 문자열의 byte 길이
 */
function getByte(str) {
	
	if ( str == null || str.length == 0 ) {
        return 0;
    }
    var size = 0;
    for ( var i=0, len=str.length ; i < len ;i++ ) {
        var charCode = str.charCodeAt(i),
            charSize = 0;

        if ( charCode <= 0x00007F ) { //127
            charSize = 1;
        } else if ( charCode <= 0x0007FF) { //2047
            charSize = 2;
        } else if ( charCode <= 0x00FFFF) { //65535
            charSize = 3;
        } else {
            charSize = 4;
        }
        size += charSize;
    }
    return size;
};

/**
 * HTML 엔티티 문자코드를 특수문자로 치환한다.
 * @return 치환된 문자열
 */
function escapeHTMLEntity(str) {
	if(str == undefined || str == null){
		return ""
	}
	
	var regex = /&(amp|lt|gt|quot|#39);/g;
	var chars = {
    	'&amp;': '&',
    	'&lt;': '<',
    	'&gt;': '>',
    	'&quot;': '"',
    	'&#39;': "'"
	};
	
	if(regex.test(str)) {
        return str.replace(regex, (matched) => chars[matched] || matched);
    } else {
		return str;
	}
}

/**
 * 스네이크 표기법을 카멜 표기법으로 변경한다.
 * @return 치환된 문자열
 */
function snakeToCamel(text){
	text = text.toLowerCase();
	var arrUnderbar = text.match(/\_[a-zA-Z]/g);
	if(arrUnderbar){
		for(var j = 0; j < arrUnderbar.length; j++) {
	        text = text.replace(arrUnderbar[j], arrUnderbar[j].toUpperCase().replace("_", ""));
	    }
	}
	return text;
}

/**
 * 카멜 표기법을 케밥 표기법으로 변경한다.
 * @return 치환된 문자열
 */
function camelToKebab(text){
	return text.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
}
