﻿ /**
 * @type : intro
 * @desc : g4f_common.js는 프로젝트 전반에 걸쳐 전 시스템에서 공통으로 사용하는 자바 스크립트를 기술한
 * 자바스크립트 파일이다. 빈번히 사용되는 자바스크립트들이 화면마다 반복적으로 개발되지
 * 않도록 미리 정의되어 있어서 g4f_common.js를 업무화면에 import시키기만 하면 g4f_common.js에 정의되어
 * 있는 스크립트들에 대해서는 각 개발자가 별도로 개발할 필요가 없다.<br><br>
 *
 * 함수 Naming Rule은 다음과 같다.
 * <pre>
 *     - cf  : common function
 *     - co  : common object
 *     - cov : common object for validation
 * </pre>
 * @version : 1.0
 * @change  :
 * <pre>
 *     <font color="blue">V1.0</font>
 *     - 최초버전.
 * </pre>
 */



 /** 이 부분은 document로 generate되지 않습니다.
 * @JScript 참고자료
 * - isNaN : 다음은 모두 숫자로 본다. - "001", "0", "", null
 * - substr(index[, length]) -> index부터 끝까지 혹은 length갯수만큼.
 * - substring(start, end)  -> start index부터 end index전까지의 string
 * Date 오브젝트 생성자들 - dateObj = new Date()
 *                        - dateObj = new Date(dateVal)
 *                        - dateObj = new Date(year, month, date[, hours[, minutes[, seconds[,ms]]]])
 */
 
/**
 * @type   : function
 * @access : public
 * @desc   : 공통메세지에 정의된 메세지를 alert box로 보여준 후 리턴한다. cfGetMsg 참조. 
 * <pre>
 *     // 공통메세지
 *     var MSG_COM_ERR_002   = "@은(는) 필수 입력 항목입니다.";
 *     ...
 *     cfAlertMsg(MSG_COM_ERR_002,['사번']); 
 * </pre>
 * @sig    : msgId[, paramArray]
 * @param  : msgId - required g4f_message.js의 공통 메세지 영역에 선언된 메세지 ID
 * @param  : paramArray - optional 메세지에서 '@' 문자와 치환될 데이터 Array. Array의 index와 메세지 내의 '@' 문자의 순서가 일치한다.
 *           치환될 데이터는 [] 사이에 콤마를 구분자로 하여 기술하면 Array 로 인식된다.
 * @return : 치환된 메세지 스트링
 * @author : 임재현
 */

var gvContextPath = "/"+document.location.pathname.split("/")[1];
 
function cfAlertMsg(msgId, paramArray) {
    if (cfIsNull(msgId)) {
        alert("존재하지 않는 메시지입니다.");
        return null;
    }
/*
    var msg;
    var code;
    if ( msgId.indexOf("MSG_")>=0)
        code = eval(msgId.cut(0,msgId.indexOf("MSG_")).trim());
    else if(msgId.indexOf("[DSET")>=0){
        code = msgId.substring(msgId.lastIndexOf("]")+1,msgId.length);
    }
    else if(msgId.indexOf("[TRNS")>=0){
        code = msgId.substring(msgId.lastIndexOf("]")+1,msgId.length);
    }
    else
        code = msgId;

    msg = new coMessage().getMsg(code, paramArray);
    alert(msg);
    return msg;
*/

    msg = new coMessage().getMsg(msgId, paramArray);
    alert(msg);
    return msg;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 공통메세지에 정의된 메세지를 confirm box로 보여준 후  사용자가 선태한 confirm 값을 리턴한다. cfGetMsg 참조.
 * <pre>
 *     // 공통메세지
 *     var MSG_COM_CRM_001   = "저장하시겠습니까?";
 *     ...
 *     cfConfirmMsg(MSG_COM_CRM_001);
 * </pre>
 * @sig    : msgId[, paramArray]
 * @param  : msgId      - required g4f_message.js의 공통 메세지 영역에 선언된 메세지 ID
 * @param  : paramArray - optional 메세지에서 '@' 문자와 치환될 스트링 Array. (Array의 index와
 *           메세지 내의 '@' 문자의 순서가 일치한다.)
 * @return : 사용자가 선택한 confirm 값 (true/false)
 * @author : 임재현
 */
function cfConfirmMsg(msgId, paramArray) {


    if (cfIsNull(msgId)) {
        alert("존재하지 않는 메시지입니다.");
        return null;
    }

    return confirm(new coMessage().getMsg(msgId, paramArray));
}

/**
 * @type   : function
 * @access : public
 * @desc   : 공통메세지에 정의된 메세지를 prompt box 로 보여주고 prompt창에 입력된 값을 리턴한다.
 *           만약 패스워드를 입력받는 prompt box를  띄우면서 공통메세지에 정의된 메세지를 보여주고 싶다면 
 *           다음과 같이 하면 된다.
 * <pre>
 *     // 공통메세지
 *     var MSG_INPUT_PASSWORD = "@님, 패스워드를 입력하십시오.";
 *     ...
 *     cfPromptMsg(MSG_INPUT_PASSWORD, ["홍길동"], "입력하세요.");
 * </pre>
 * @sig    : msgId[, paramArray[, defaultVal]]
 * @param  : msgId      - required g4f_message.js의 공통 메세지 영역에 선언된 메세지 ID
 * @param  : paramArray - optional 메세지에서 '@' 문자와 치환될 스트링 Array. (Array의 index와
 *           메세지 내의 '@' 문자의 순서가 일치한다.)
 * @param  : defaultVal - optional prompt box 의 입력필드에 보여줄 기본값.
 * @return : 입력받은 String 혹은 Integer 타입의 패스워드 데이터
 * @author : 임재현
 */
function cfPromptMsg(msgId, paramArray, defaultVal) {
    if (cfIsNull(msgId)) {
        alert("존재하지 않는 메시지입니다.");
        return null;
    }

    if ( cfIsNull( defaultVal) ) {
        defaultVal = "";
    }

    return prompt(new coMessage().getMsg(msgId, paramArray), defaultVal);
}


/**
 * @type   : function
 * @access : public
 * @desc   : 공통메세지에 정의된 메세지를 리턴한다.
 * <pre>
 * // 공통 메세지 영역
 * var MSG_NO_CHANGED        = "변경된 사항이 없습니다.";
 * var MSG_SUCCESS_LOGIN     = "@님 안녕하세요?";
 * ...
 * var message1 = cfGetMsg(MSG_NO_CHANGED);
 * var message2 = cfGetMsg(MSG_SUCCESS_LOGIN, ["홍길동"]);
 *
 * 위의 예에서 message2 의 값은 "홍길동님 안녕하세요?" 가 된다.
 * </pre>
 * @sig    : msgId[, paramArray]
 * @param  : msgId      - required common.js의 공통 메세지 영역에 선언된 메세지 ID
 * @param  : paramArray - optional 메세지에서 '@' 문자와 치환될 데이터 Array. Array의 index와
 *           메세지 내의 '@' 문자의 순서가 일치한다. 치환될 데이터는 [] 사이에 콤마를 구분자로 하여 기술하면 Array 로 인식된다.
 * @return : 치환된 메세지 스트링
 * @author : 임재현
 */
 
 
function cfGetMsg(msgId, paramArray) {
    return new coMessage().getMsg(msgId, paramArray);
}


/**
 * @type   : function
 * @access : public
 * @desc   : 값이 null 이거나 white space 문자로만 이루어진 경우 true를 리턴한다.
 * <pre>
 *     cfIsNull("  ");
 * </pre>
 * 위와같이 사용했을 경우 true를 리턴한다.
 * @sig    : value
 * @param  : value - required 입력값
 * @return : boolean. null(혹은 white space) 여부
 * @author : 임재현
 */
function cfIsNull(value) {
    if (value == null ||
        (typeof(value) == "string" && value.trim() == "")
       ) {
        return true;
    }

    return false;
}

/**
 * @type   : function
 * @access : public
 * @desc   : Element의 type을 알려준다. 리턴되는 element type string은 다음과 같다.
 * <pre>
 *     BUTTON   : html button input tag
 *     CHECKBOX : html checkbox input tag
 *     FILE     : html file input tag
 *     HIDDEN   : html hidden input tag
 *     IMAGE    : html image input tag
 *     PASSWORD : html password input tag
 *     RADIO    : html radio input tag
 *     RESET    : html reset input tag
 *     SUBMIT   : html submit input tag
 *     TEXT     : html text input tag
 *     SELECT   : html select tag
 *     TEXTAREA : html textarea tag
 *     null     : 기타
 * </pre>
 * @sig    : oElement
 * @param  : oElement - required element
 * @return : element의 type을 표현하는 string
 * @author : 임재현
 */
function cfGetElementType(oElement) {
    if (oElement == null) {
        return null;
    }

    switch (oElement.tagName) {
        case "INPUT":
            switch (oElement.type) {
                case "button" :
                    return "BUTTON";
                case "checkbox" :
                    return "CHECKBOX";
                case "file" :
                    return "FILE";
                case "hidden" :
                    return "HIDDEN";
                case "image" :
                    return "IMAGE";
                case "password" :
                    return "PASSWORD";
                case "radio" :
                    return "RADIO";
                case "reset" :
                    return "RESET";
                case "submit" :
                    return "SUBMIT";
                case "text" :
                    return "TEXT";
                default :
                    return null;
            }
        case "SELECT":
            return "SELECT"
        case "TEXTAREA":
            return "TEXTAREA"
        case "IMG":
            return "IMG";   //2004-12-22 정훈규추가
        default :
            return null;
    }
}


/**
 * @type   : function
 * @access : private
 * @desc   : html상에서 parent element에 대한 child element 들에 대해 일괄적으로 동일한 함수를 수행시킨다.
 * @sig    : parentObj, fnc[, argArr]
 * @param  : parentObj - required parent object
 * @param  : fnc - required 각 input element 마다 수행시킬 함수 포인터
 * @param  : argArr - optional 함수에 전달할 파라미터. 이 메소드를 통해 호출되는 함수는 무조건 두 개의 파라미터로만
 *           구성되어야 한다. 하나는 처리하려는 element, 나머지 하나는 처리시 필요한 파라미터들의 array 객체이다.
 * @author : 임재현
 */
function cfProcessChildElement(parentObj, fnc, argArr) {
    if( fnc(parentObj, argArr) == false ) {
        return false;
    }
    
    var childObj;  
    childObj = parentObj.getElementsByTagName("*");
    for (var i = 0; i < childObj.length; i++) {
        switch (childObj[i].tagName) {
            case "INPUT" :
            case "TEXTAREA" :
            case "SELECT" :
                if( fnc(childObj[i], argArr) == false ) {
                    return false;
                }
                break;
    
            default :
                break;
        }
    }
    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : object를 disable 시킨다.
 * <pre>
 *     cfDisable( obj );
 *     cfDisable( [obj1, obj2, obj3] );
 * 예)
 * cfDisable([document.detailForm]);
 * cfDisable([document.getElementById("oSaveBtn"), document.getElementById("oDeleteBtn")]);
 * cfDisable([form.oEmpno]);
 * cfDisable([document.getElementById("oEmpno")]);
 * </pre>
 * @sig    : oElement
 * @param  : oElement - required disable 하고자 하는 element
 * @author : 임재현
 */
function cfDisable(obj) {

    if (cfIsNull(obj)) {
        return;
    }
    
    if (obj.length != null) {
        for (var i = 0; i < obj.length; i++) {
            cfProcessChildElement(obj[i], cfDisableElement);
        }
    } else {
        cfProcessChildElement(obj, cfDisableElement);
    }
}

/*
    - <input type=text> 의 경우 disable시에 글자색을 지정할 수 없다. 따라서 disable 대신 readOnly로 바꾼다.
    - <input type=checkbox> 의 경우 ReadOnly가 없으며 disabled를 true로 할 경우 box내부 색깔을 바꿀 수가 없다. box 색바꿈 포기.
*/
function cfDisableElement(oElement, argArr) {
    switch (cfGetElementType(oElement)) {
        case "BUTTON" :
            oElement.disabled = true;
/*
            if (oElement.className != null &&
                (oElement.className.substr(0, 7) == "btnGrid" ||
                 oElement.className.substr(0, 7) == "btnIcon" ) &&
                oElement.currentStyle.backgroundImage.substr(oElement.currentStyle.backgroundImage.length - 15, 9) != "_disabled"
               ) {
                oElement.style.backgroundImage =
                    oElement.currentStyle.backgroundImage.substr(0, oElement.currentStyle.backgroundImage.length - 6) + "_disabled" +
                    oElement.currentStyle.backgroundImage.substr(oElement.currentStyle.backgroundImage.length - 6);
            }
*/
            break;

        case "CHECKBOX" :
        case "RADIO" :
        case "IMG":         
        case "IMAGE":       
        case "RESET" :
        case "SELECT" :
        case "SUBMIT" :
            oElement.disabled = true;
            break;

        case "FILE" :
        case "PASSWORD" :
        case "TEXT" :
        case "TEXTAREA" :
            oElement.readOnly = true;
            oElement.style.color = "#808080";            // EMEdit Disable시 색상과 동일.
            oElement.style.backgroundColor = "#DEDFDE";  // Text는 background가 하얀색으로 남는다. 따라서 스타일로 임의로 지정하였음.
            break;

        default :
            break;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : object를 enable 시킨다.
 * <pre>
 *     cfEnable( obj );
 *     cfEnable( [obj1, obj2, obj3] );
 *  예)
 * cfEnable([document.detailForm]);
 * cfEnable([document.getElementById("oSaveBtn"), document.getElementById("oDeleteBtn")]);
 * cfEnable([form.oEmpno]);
 * cfEnable([document.getElementById("oEmpno")]);
 * </pre>
 * @sig    : oElement
 * @param  : oElement - required enable 하고자 하는 element 혹은 element array
 * @author : 임재현
 */
function cfEnable(obj) {
    if (cfIsNull(obj)) {
        return;
    }

    if (obj.length != null) {
        for (var i = 0; i < obj.length; i++) {
            cfProcessChildElement(obj[i], cfEnableElement);
        }
    } else {
        cfProcessChildElement(obj, cfEnableElement);
    }
}

function cfEnableElement(oElement, argArr) {
    switch (cfGetElementType(oElement)) {
        case "BUTTON" :
            oElement.disabled = false;
/*
            if (oElement.className != null &&
                (oElement.className.substr(0, 7) == "btnGrid" ||
                 oElement.className.substr(0, 7) == "btnIcon"
                )
               ) {
                if (oElement.currentStyle.backgroundImage.substr(oElement.currentStyle.backgroundImage.length - 15, 9) == "_disabled") {
                    oElement.style.backgroundImage =
                        oElement.currentStyle.backgroundImage.cut(oElement.currentStyle.backgroundImage.length - 15, 9);
                }
            }
*/
            break;

        case "CHECKBOX" :
        case "RADIO" :
        case "RESET" :
        case "SELECT" :
        case "SUBMIT" :
        case "IMG" :           
        case "IMAGE" :         
            oElement.disabled = false;
            break;

        case "FILE" :
        case "PASSWORD" :
        case "TEXT" :
        case "TEXTAREA" :
            oElement.readOnly = false;
            oElement.style.color = "black";
            oElement.style.backgroundColor = "#F9F9F9";
            break;

        default :
            break;
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 입력받은 오브젝트들을 hide 하는 함수 <br>
 *           객체의 style 에서 display 속성을 none으로 치환하여 구현한다.<br>
 * <pre>
 *     cfHideObject( obj );
 *     cfHideObject( [obj1, obj2, obj3] );
 * ex)
 * cfHideObject( [form.oDeptno] ); 
 * cfHideObject( form.oDeptno );   
 * cfHideObject( document.getElementById("oDeleteBtn") ); 
 * </pre>
 * @sig    : objArr
 * @param  : objectArr - required 화면에서 숨기고자 하는 오브젝트 Array. 
 * @return : void
 * @author : 정연주
 */
function cfHideObject( obj ) {
    if (cfIsNull(obj)) {
        return;
    }
    var objArr;
    var oElement;

    if (obj.length == null) {
        objArr = new Array(1);
        objArr[0] = obj;
    } else {
        objArr = obj;
    }

    for (var objArrIdx = 0; objArrIdx < objArr.length; objArrIdx++) {
        if( objArr[objArrIdx].nodeType != undefined ){
            oElement = objArr[objArrIdx];
        } else {
            oElement = document.getElementById( objArr[objArrIdx] );
        }
        oElement.style.display = "none";
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 숨겨진 오브젝트들을 보여주는 함수 <br>
 *           객체의 style 에서 display 속성을 inline(default)으로 치환하여 구현한다.<br>
 * <pre>
 *     cfShowObject( obj );
 *     cfShowObject( [obj1, obj2, obj3] );
 * ex)
 * cfShowObject( [form.oDeptno] );  
 * cfShowObject( form.oDeptno );   
 * cfShowObject( document.getElementById("oDeleteBtn") );
 * </pre>
 * @sig    : objArr
 * @param  : objectArr - required 화면에서 보여주고자 하는 오브젝트 id Array. 오브젝트 Array. 
 * @return : void
 * @author : 정연주
 */
function cfShowObject( obj ) {
    if (cfIsNull(obj)) {
        return;
    }

    var objArr;
    var oElement;

    if (obj.length == null) {
        objArr = new Array(1);
        objArr[0] = obj;
    } else {
        objArr = obj;
    }

    for (var objArrIdx = 0; objArrIdx < objArr.length; objArrIdx++) {
        if( objArr[objArrIdx].nodeType != undefined ){
            oElement = objArr[objArrIdx];
        } else {
            oElement = document.getElementById( objArr[objArrIdx] );
        }
        //oElement.style.display = "inline";
        oElement.style.display = "";
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 화면상의 입력과 관련된 오브젝트에 대한 유효성 검사를 실시한다. 유효성 검사를 받는 오브젝트들은 "validExp" 라는
 *           속성값을 설정해야 한다. "validExp" 라는 속성은 원래 html 객체에는 정의되어 있지 않은 속성이지만 다른 속성들을
 *           설정하는 것과 같은 방법으로 설정하면 자동으로 해당 오브젝트의 속성으로 인식된다.<br>
 *           혹은 setAttribute 함수를 이용해서 별도로 작성해줄 수 있다. ex) document.getElementById("oSal").setAttribute("validExp", "급여:yes" );
 *           <br>
 *           - 해당 오브젝트에 대한 child 오브젝트들까지도 검사한다. 예를들어, 검사받을 오브젝트들을 &lt;div&gt; 태그로 감싸고
 *             &lt;div&gt; 태그의 id를 파라미터로 준다면 &lt;div&gt; 태그내의 모든 오브젝트들이 자동으로 검사받게 된다. 또,
 *             &lt;table&gt;안에 입력필드들은 &lt;table&gt;의 id를 파라미터로 주면 된다.<br><br>
 *           - 입력값의 앞과 뒤의 공백은 유효성 검사를 하면서 자동으로 trim된다.
 * <pre>
 *    예1)
 *    ...
 *    document.getElementById("oSal").setAttribute("validExp", "급여:yes" );
 *    function fncSave() {
 *        if (<b>cfValidate([oInputTable])</b>) {
 *            form.submit();
 *        }
 *    }
 *    ...
 *
 *    &lt;table <b>id="oInputTable"</b> ....&gt;
 *        ...
 *        &lt;input id="oSal" width="50" <b>validExp="급여:no:minByteLength=2&maxByteLength=6&number"</b>&gt;
 *        ...
 *    &lt;/table&gt;
 *    ...
 * </pre>
 * <pre>
 *    예2) cfValidate([form.oEmpno, form.ename])
 * </pre>
 * validExp 속성값은 정해진 형식에 맞게 작성되어야 한다.<br>
 * <pre>
 *        "item_name:필수여부:valid_expression"
 *
 *        - "item_name"에는 해당 항목에 대한 이름을 기술한다.
 *        - "필수여부"에는 해당 오브젝트가 필수 항목인지 여부를 yes|true|1 혹은 no|false|0 타입으로 기술한다.
 *        - "valid_expression" 은  cfValidateValue 함수의 설명을 참조하기 바란다.
 *        - 필수항목인지만 체크하려면 "valid_expression" 을 표기하지 않으면 된다.
 *          예)
 *          &lt;object id="oDelivYmd" classid="CLSID:E6876E99-7C28-43AD-9088-315DC302C05F" width="80" <b>validExp="배달일자:yes"</b>&gt;
 *              ...
 *          &lt;/object&gt;
 *        - validExp 내에 임의로 ",", ":", "=", "&", 문자를 사용하고자 한다면 "\\,", "\\:", "\\=", "\\&" 라고 표기해야 한다.<br>
 * </pre>
 * @sig    : objArr
 * @param  : objectArr - required 유효성검사를 하고자 하는 오브젝트들의 Array.
 * @return : boolean. 유효성 여부.
 * @author : 임재현
 */
function cfValidate(obj) {
    if (cfIsNull(obj)) {
        return;
    }
    var objArr;
    var oElement;
    var validYN = false;

    if (obj.length == null) {
        objArr = new Array(1);
        objArr[0] = obj;
    } else {
        objArr = obj;
    }
    var checkObjName = "";		//체크한 오브젝트 네임
    for (var objArrIdx = 0; objArrIdx < objArr.length; objArrIdx++) {
        oElement = objArr[objArrIdx];

        switch (oElement.tagName) {
            case "TABLE":
            case "DIV":
            case "FIELDSET":
                if( !cfProcessChildElement(oElement, cfValidateElement) ){
                    return false;
                }
                break;

            default:
				//체크박스와 라디오버튼은 한번만 체크
            	if(cfGetElementType(oElement) == "RADIO" || cfGetElementType(oElement) == "CHECKBOX"){
					
					if(checkObjName != oElement.name){
						if (!cfValidateElement(oElement)) {
	                    	return false;
	                	} 
	                	checkObjName = oElement.name;
					}
            	}else{
	                if (!cfValidateElement(oElement)) {
	                    return false;
	                }            	
            	}
        }
    }
    
    return true;

}

//오브젝트에 대한 유효성 검사를 실시한다. 기존 cfValidate 를 변경하여 웹표준에서도 적용되게 처리 함.
function cfValidate_cn(obj) {
    if (cfIsNull(obj)) {
        return;
    }
    var objArr;
    var oElement;
    var validYN = false;

    if (obj.length == null) {
        objArr = new Array(1);
        objArr[0] = obj;
    } else {
        objArr = obj;
    }
    var checkObjName = "";      //체크한 오브젝트 네임
    for (var objArrIdx = 0; objArrIdx < objArr.length; objArrIdx++) {
        oElement = objArr[objArrIdx];

        switch (oElement.tagName) {
            case "TABLE":
            case "DIV":
            case "FIELDSET":
                if( !cfProcessChildElement(oElement, cfValidateElement_cn) ){
                    return false;
                }
                break;

            default:
                //체크박스와 라디오버튼은 한번만 체크
                if(cfGetElementType(oElement) == "RADIO" || cfGetElementType(oElement) == "CHECKBOX"){
                    
                    if(checkObjName != oElement.name){
                        if (!cfValidateElement_cn(oElement)) {
                            return false;
                        } 
                        checkObjName = oElement.name;
                    }
                }else{
                    if (!cfValidateElement_cn(oElement)) {
                        return false;
                    }               
                }
        }
    }
    
    return true;

}

/**
 * @type   : function
 * @access : private
 * @desc   : 모든 오브젝트에 대해 유효성 검사를 한다.
 * @sig    : oElement
 * @param  : oElement - required 검사 대상 Element.
 * @return : boolean. 유효성 여부.
 * @author : 임재현
 */
function cfValidateElement(oElement) {
    var validExp = oElement.getAttribute("validExp");
    if (cfIsNull(validExp)) {
        return true;
    }

    var value;
    var itemValidExp = new covItemValidExp(validExp);

    switch (oElement.tagName) {
        case "INPUT":
        case "SELECT":
        case "TEXTAREA":
        
			if(cfGetElementType(oElement) == "RADIO" || cfGetElementType(oElement) == "CHECKBOX"){
				var objVal = "";
				var obj = document.getElementsByName(oElement.name);				
				for(var i=0; i < obj.length; i++ ){					
					if(!obj[i].disabled){
						if(obj[i].checked)	objVal += obj[i].value.trim() + ",";
					}
				}
				if(objVal.length > 0)	objVal = objVal.substring(0, objVal.length-1);
				value = objVal;
			}else{
	            oElement.value = oElement.value.trim();  // element의 값을 trim 시켜준다.
	            value = oElement.value;			
			}
            break;

        default:
            return true;
    }

    if (!itemValidExp.validate(value)) {
        cfAlertMsg( itemValidExp.errMsg, [itemValidExp.itemName] );
		//포커스
        if(oElement.enable != false && oElement.disabled!=true) {
            oElement.focus();
        }

        return false;
    }

    return true;
}

 //모든 오브젝트에 대해 유효성 검사를 한다. 기존 cfValidateElement 를 변경하여 웹표준에서도 적용되게 처리 함.
function cfValidateElement_cn(oElement) {
     var validExp = oElement.className.toLowerCase();
    if(validExp.indexOf("validexp") != -1){
    //문자 분리 순수 validExp 문자열만
      validExp = validExp.substring(validExp.indexOf("validexp")+9,validExp.length);    
    }else{
      validExp = "";
    }
    
    if (cfIsNull(validExp)) {
        return true;
    }

    var value;
    var itemValidExp = new covItemValidExp(validExp);

    switch (oElement.tagName) {
        case "INPUT":
        case "SELECT":
        case "TEXTAREA":
        
            if(cfGetElementType(oElement) == "RADIO" || cfGetElementType(oElement) == "CHECKBOX"){
                var objVal = "";
                var obj = document.getElementsByName(oElement.name);                
                for(var i=0; i < obj.length; i++ ){                 
                    if(!obj[i].disabled){
                        if(obj[i].checked)  objVal += obj[i].value.trim() + ",";
                    }
                }
                if(objVal.length > 0)   objVal = objVal.substring(0, objVal.length-1);
                value = objVal;
            }else{
                oElement.value = oElement.value.trim();  // element의 값을 trim 시켜준다.
                value = oElement.value;         
            }
            break;

        default:
            return true;
    }

    if (!itemValidExp.validate(value)) {
        cfAlertMsg( itemValidExp.errMsg, [itemValidExp.itemName] );
        //포커스
        if(oElement.enable != false && oElement.disabled!=true) {
            oElement.focus();
        }

        return false;
    }

    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 특정 값에 대한 유효성검사를 수행한다.
 * <pre>
 *     cfValidateValue(50, "minNumber=100");
 * </pre>
 * 위의 경우 50은 최소값 100을 넘지 않으므로 false가 리턴된다.<br>
 * 유효성 검사를 수행하기 위해서는 검사조건을 명시해야 하는데
 * 검사조건은 'valid expression' 이라고 불리우는 String 값으로 표현된다. valid expression에 대한 표기형식은
 * 다음과 같다.
 * <pre>
 *      validator_name=valid_value[&validator_name=valid_value]..
 *
 *      예) "minNumber=100"
 * </pre>
 * - validator_name은 검사유형을 의미하며 valid_value는 기준 값이 된다. <br>
 * - 검사항목은 하나 이상일 수 있으며 검사항목간에는 "&" 문자로 구분하여 필요한 만큼 나열하면 된다. <br>
 * - valid_value에 ",", ":", "=", "&", 문자를 사용하고자 한다면 "\\,", "\\:", "\\=", "\\&" 라고 표기해야 한다.<br>
 * - 위의 예에서는 "minNumber" (최소값)라는 유효성 검사항목을 명시하였고 minNumber 에대한 기준값으로 "100" 이 설정되어 있다.
 * 만일 100보다 작은 값을 입력했을 때는 100 이상의 값을 입력하라는 alert box가 뜨게 된다.
 * - validator_name은 미리 정의되어 있는 것만 사용할 수 있고 각 검사유형마다 valid_value의 형태도 다르다.(valid_value가 없는 것도 있다.)
 * 현재 정의된 검사유형은 다음과 같다.
 * <br><br>
 * <table border=1 style="border-collapse:collapse; border-width:1pt; border-style:solid; border-color:000000;">
 *      <tr>
 *          <td align="center" bgcolor="#CCCCFFF">검사유형</td>
 *          <td align="center" bgcolor="#CCCCFFF">기준값 형태</td>
 *          <td align="center" bgcolor="#CCCCFFF">설명</td>
 *          <td align="center" bgcolor="#CCCCFFF">예</td>
 *      </tr>
 *      <tr>
 *          <td>length</td>
 *          <td>0보다 큰 정수</td>
 *          <td>자릿수 검사. 입력값의 자릿수가 기준값과 일치하는지를 검사한다. 일반적으로 HTML에서는 한글, 영문, 숫자 모두 1자리씩 인식된다.</td>
 *          <td>length=6</td>
 *      </tr>
 *      <tr>
 *          <td>byteLength</td>
 *          <td>0보다 큰 정수</td>
 *          <td>Byte로 환산된 자릿수 검사. 입력값의 자릿수를 byte로 환산하여 자릿수가 기준값과 일치하는지를 검사한다.(숫자 및 영문은 1byte, 한글은 2byte이다.)</td>
 *          <td>byteLength=6</td>
 *      </tr>
 *      <tr>
 *          <td>minLength</td>
 *          <td>0보다 큰 정수</td>
 *          <td>최소자릿수 검사. 입력값의 자릿수가 기준값 이상이 되는지를 검사한다.</td>
 *          <td>minLength=6</td>
 *      </tr>
 *      <tr>
 *          <td>minByteLength</td>
 *          <td>0보다 큰 정수</td>
 *          <td>Byte로 환산된 최소자릿수 검사. 입력값의 자릿수를 byte로 환산하여 자릿수가 기준값 이상이 되는지를 검사한다.(숫자 및 영문은 1byte, 한글은 2byte이다.)</td>
 *          <td>minByteLength=6</td>
 *      </tr>
 *      <tr>
 *          <td>maxLength</td>
 *          <td>0보다 큰 정수</td>
 *          <td>최대자릿수 검사. 입력값의 자릿수가 기준값 이하가 되는지를 검사한다.</td>
 *          <td>maxLength=6</td>
 *      </tr>
 *      <tr>
 *          <td>maxByteLength</td>
 *          <td>0보다 큰 정수</td>
 *          <td>Byte로 환산된 최대자릿수 검사. 입력값의 자릿수를 byte로 환산하여 자릿수가 기준값 이하가 되는지를 검사한다.(숫자 및 영문은 1byte, 한글은 2byte이다.)</td>
 *          <td>maxByteLength=6</td>
 *      </tr>
 *      <tr>
 *          <td>number</td>
 *          <td>None or decimal format string. decimal format string 형식은 "(정수자릿수.소수자릿수)" 이다.</td>
 *          <td>숫자검사. 입력값이 숫자인지를 검사한다. 만일 입력값에 대한 decimal format을 지정하였을 때는 format에 맞는지도 검사한다.</td>
 *          <td>number, number=(5.2)</td>
 *      </tr>
 *      <tr>
 *          <td>minNumber</td>
 *          <td>숫자</td>
 *          <td>최소수 검사. 입력값이 최소한 기준값 이상이 되는지를 검사한다.</td>
 *          <td>minNumber=100</td>
 *      </tr>
 *      <tr>
 *          <td>maxNumber</td>
 *          <td>숫자</td>
 *          <td>최대수 검사. 입력값이 기준값 이하인지를 검사한다.</td>
 *          <td>maxNumber=300</td>
 *      </tr>
 *      <tr>
 *          <td>inNumber</td>
 *          <td>"숫자~숫자" 형식으로 표기.</td>
 *          <td>범위값 검사. 입력값이 기준이 되는 두 수와 같거나 혹은 두 수 사이에 존재하는 값인지를 검사한다.</td>
 *          <td>inNumber=100~300</td>
 *      </tr>
 *      <tr>
 *          <td>minDate</td>
 *          <td>YYYYMMDD 형식의 날짜 스트링.</td>
 *          <td>최소날짜 검사. 입력된 날짜가 기준날짜이거나 기준날짜 이후인지를 검사한다.</td>
 *          <td>minDate=20020305</td>
 *      </tr>
 *      <tr>
 *          <td>maxDate</td>
 *          <td>YYYYMMDD 형식의 날짜 스트링. 예) maxDate=20020305</td>
 *          <td>최대날짜 검사. 입력된 날짜가 기준날짜이거나 기준날짜 이전인지를 검사한다.</td>
 *          <td>maxDate=20020305</td>
 *      </tr>
 *      <tr>
 *          <td>minDateYM</td>
 *          <td>YYYYMM 형식의 날짜 스트링.</td>
 *          <td>최소날짜 검사. 입력된 날짜가 기준날짜이거나 기준날짜 이후인지를 검사한다.</td>
 *          <td>minDate=200203</td>
 *      </tr>
 *      <tr>
 *          <td>maxDateYM</td>
 *          <td>YYYYMM 형식의 날짜 스트링. 예) maxDateYM=200203</td>
 *          <td>최대날짜 검사. 입력된 날짜가 기준날짜이거나 기준날짜 이전인지를 검사한다.</td>
 *          <td>maxDate=200203</td>
 *      </tr> 
 *      <tr>
 *          <td>format</td>
 *          <td>format character들과 다른 문자들을 조합한 스트링.<br>
 *              <table>
 *                  <tr>
 *                      <td><b>format character</b></td>
 *                      <td><b>desc</b></td>
 *                  </tr>
 *                  <tr>
 *                      <td>#</td>
 *                      <td>문자와 숫자</td>
 *                  </tr>
 *                  <tr>
 *                      <td>h, H</td>
 *                      <td>한글(H는 공백포함)</td>
 *                  </tr>
 *                  <tr>
 *                      <td>A, Z</td>
 *                      <td>문자(Z는 공백포함)</td>
 *                  </tr>
 *                  <tr>
 *                      <td>0, 9</td>
 *                      <td>숫자 (9는 공백포함)</td>
 *                  </tr>
 *              </table>
 *          </td>
 *          <td>형식 검사. 입력된 값이 지정된 형식에 맞는지를 검사한다.</td>
 *          <td>format=000-000</td>
 *      </tr>
 *      <tr>
 *          <td>ssn</td>
 *          <td>주민등록번호 13자리</td>
 *          <td>주민등록번호 검사. 입력한 주민등록번호가 유효한지를 검사한다.</td>
 *          <td>ssn</td>
 *      </tr>
 *      <tr>
 *          <td>fsn</td>
 *          <td>외국인등록번호 13자리</td>
 *          <td>외국인등록번호 검사. 입력한 외국인등록번호가 유효한지를 검사한다.</td>
 *          <td>fsn</td>
 *      </tr> 
 *      <tr>
 *          <td>csn</td>
 *          <td>사업자등록번호 10자리</td>
 *          <td>사업자등록번호 검사. 입력한 사업자등록번호가 유효한지를 검사한다.
 *              (예, 2019009930)
 *          </td>
 *          <td>csn</td>
 *      </tr>
 *      <tr>
 *          <td>filterIn</td>
 *          <td>필터링하여 얻고자 하는 스트링을 ";"문자를 구분자로 사용하여 나열한다.(단 ";" 문자를 필터링하고 싶을 땐 "\;"라고 표기한다.
 *          </td>
 *          <td>입력값에 지정된 문자나 스트링 이외에 다른 값이 있는지를 검사한다. 하나도 없다면 유효하다.</td>
 *          <td>filter=%;<;임재현;\\;;haha<br>(입력값 내에 "%","<","임재현",";","haha" 중에 하나라도 있는지 검사한다.)
 *          </td>
 *      </tr>
 *      <tr>
 *          <td>filterOut</td>
 *          <td>필터링하여 걸러내고 싶은 스트링을 ";"문자를 구분자로 사용하여 나열한다.(단 ";" 문자를 필터링하고 싶을 땐 "\;"라고 표기한다.
 *          </td>
 *          <td>입력값에 지정된 문자나 스트링이 있는지를 검사한다. 하나도 없다면 유효하다.</td>
 *          <td>filter=%;<;임재현;\\;;haha<br>(입력값 내에 "%","<","임재현",";","haha" 중에 하나라도 있는지 검사한다.)
 *          </td>
 *      </tr>
 *      <tr>
 *          <td>email</td>
 *          <td>이메일 주소</td>
 *          <td>입력한 메일주소가 유효한 이메일 형식인지를 검사한다.</td>
 *          <td>email</td>
 *      </tr>
 *      <tr>
 *          <td>date</td>
 *          <td>format character의 조합으로 이루어진 날자에 대한 패턴 스트링.<br>
 *              <table>
 *                  <tr>
 *                      <td><b>format character</b></td>
 *                      <td><b>desc</b></td>
 *                  </tr>
 *                  <tr>
 *                      <td>YYYY</td>
 *                      <td>4자리 년도</td>
 *                  </tr>
 *                  <tr>
 *                      <td>YY</td>
 *                      <td>2자리 년도. 2000년 이후</td>
 *                  </tr>
 *                  <tr>
 *                      <td>MM</td>
 *                      <td>2자리 숫자의 달</td>
 *                  </tr>
 *                  <tr>
 *                      <td>DD</td>
 *                      <td>2자리 숫자의 일</td>
 *                  </tr>
 *                  <tr>
 *                      <td>hh</td>
 *                      <td>2자리 숫자의 시간. 12시 기준</td>
 *                  </tr>
 *                  <tr>
 *                      <td>HH</td>
 *                      <td>2자리 숫자의 시간. 24시 기준 </td>
 *                  </tr>
 *                  <tr>
 *                      <td>mm</td>
 *                      <td>2자리 숫자의 분</td>
 *                  </tr>
 *                  <tr>
 *                      <td>ss</td>
 *                      <td>2자리 숫자의 초</td>
 *                  </tr>
 *              </table>
 *          </td>
 *          <td>날짜 검사. 입력된 스트링값을 날짜로 환산하여 유효한 날짜인지를 검s사한다.</td>
 *          <td>date=YYYYMMDD  일 때 입력값이 '20020328' 일 경우 -> 유효<br>
 *              date=YYYYMMDD  일 때 입력값이 '20020230' 일 경우 -> 오류<br>
 *              date=Today is YY-MM-DD' 일 때 입력값이 'Today is 02-03-28' 일 경우 -> 유효<br><br>
 *              참고) format문자가 중복해서 나오더라도 처음 나온 문자에 대해서만 format문자로 인식된다.
 *                    YYYY와 YY, hh와 HH 도 중복으로 본다. 날짜는 년,월이 존재할 때만 정확히 체크하고
 *                    만일 년, 월이 없다면 1 ~ 31 사이인지만 체크한다.
 *          </td>
 *      </tr>
 *      <tr>
 *          <td>inNumberAlpha</td>
 *          <td>검사할 문자열</td>
 *          <td>숫자와 문자로 조합된 문자열인지 검사한다.</td>
 *          <td>inNumberAlpha</td>
 *      </tr> 
 *      <tr>
 *          <td>inAlpha</td>
 *          <td>검사할 문자열</td>
 *          <td>영문자로 된 문자열인지 검사한다.</td>
 *          <td>inAlpha</td>
 *      </tr>  
 * </table>
 * @sig    : value, validExp
 * @param  : value    - required 검사 대상이 되는 값.
 * @param  : validExp - required 사용자가 지정한 Valid Expression String.
 * @return : boolean. 유효성 여부.
 * @author : 임재현
 */
function cfValidateValue(value, validExp) {
    var valueValidExp = new covValueValidExp(validExp);

    if (!valueValidExp.validate(value)) {
        return false;
    }

    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 날짜값을 가지고 있는 input text의 값을 비교해서 시작일이 마감일보다 크면 false를 리턴한다.
 *           두값이 모두 있을때에만 비교를 하고 둘중하나에만 값이 들어 있을경우 true를 리턴한다.
 * <pre>
 *     cfCheckFromTo(form.fromDt,form.toDt, "시작일자", "종료일자");
 * </pre>
 * @sig    : fromDt,toDt, msg1, msg2
 * @param  : fromDt - required 시작일을 담은 input text 객체
 * @param  : toDt   - required 마감일 담은  input 객체
 * @param  : msg1   - required 시작일과 매칭되는 메시지
 * @param  : msg2   - required 마감일과 매칭되는 메시지
 * @return : true(시작일이 종료일보다 작을 때)/false
 * @author : 정연주
 */

function cfCheckFromTo(fromDt,toDt, msg1, msg2){
    
    var sFrom = eval(fromDt).value.trim();
    var sTo   = eval(toDt).value.trim();
    
    if( cfIsNull(sFrom) || cfIsNull(sTo) ) {
        return true;
    }
    
    if( !cfValidateValue(sFrom, "date=YYYY.MM.DD") ){
        cfAlertMsg( MSG_COM_ERR_018, [msg1] );
        eval(fromDt).focus();
        return false;
    }

    if( !cfValidateValue(sTo, "date=YYYY.MM.DD") ){
        cfAlertMsg( MSG_COM_ERR_018, [msg2] );
        eval(toDt).focus();
        return false;
    }
    
    if(!cfValidateValue(sFrom, "maxDate=" + sTo) ){
        cfAlertMsg(MSG_COM_ERR_048,[msg1,msg2]);
        eval(fromDt).focus();
        return false;
    }
    
    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 날짜값을 가지고 있는 input text의 값을 비교해서 시작일이 마감일보다 크면 false를 리턴한다.
 *           두값이 모두 있을때에만 비교를 하고 둘중하나에만 값이 들어 있을경우 true를 리턴한다.
 * <pre>
 *     cfCheckFromToYM(form.fromDt,form.toDt, "시작일자", "종료일자");
 * </pre>
 * @sig    : fromDt,toDt, msg1, msg2
 * @param  : fromDt - required 시작일을 담은 input text 객체
 * @param  : toDt   - required 마감일 담은  input 객체
 * @param  : msg1   - required 시작일과 매칭되는 메시지
 * @param  : msg2   - required 마감일과 매칭되는 메시지
 * @return : true(시작일이 종료일보다 작을 때)/false
 * @author : 한현주
 */
function cfCheckFromToYM(fromDt,toDt, msg1, msg2){
    
    var sFrom = eval(fromDt).value.trim();
    var sTo   = eval(toDt).value.trim();
    
    if( cfIsNull(sFrom) || cfIsNull(sTo) ) return true;
    
    if( !cfValidateValue(sFrom, "date=YYYY.MM") ){
        cfAlertMsg( MSG_COM_ERR_018, [msg1] );
        eval(fromDt).focus();
        return false;
    }

    if( !cfValidateValue(sTo, "date=YYYY.MM") ){
        cfAlertMsg( MSG_COM_ERR_018, [msg2] );
        eval(toDt).focus();
        return false;
    }
    
    if(!cfValidateValue(sFrom, "maxDateYM=" + sTo) ){
        cfAlertMsg(MSG_COM_ERR_048,[msg1,msg2]);
        eval(fromDt).focus();
        return false;
    }
    
    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 값이 지정된 그룹내에 존재하는지를 알려준다.
 * <pre>
 *     cfIsIn(3, [1, 2, 3]);                     // -> true
 *     cfIsIn(3, [4, 5, 6]);                     // -> false
 *     cfIsIn('F', ['A', 'B', 'F']);             // -> true
 *     cfIsIn('F', ['A', 'B', 'C']);             // -> false
 *     cfIsIn("lim", ["lim", "kim", "park"]);    // -> true
 *     cfIsIn("lim", ["lee", "kim", "park"]);    // -> false
 * </pre>
 * @sig    : value, valueArray
 * @param  : value      - required 비교하고 싶은 값
 * @param  : valueArray - required 비교하고 싶은 값에 대한 비교 대상이 되는 값들의 집합. array 타입이며 array
 *           내의 각 element의 데이터 타입은 value 파라미터의 타입과 일치해야 한다.
 * @return : boolean. 값이 지정된 그룹내에 존재하는지 여부.
 * @author : 임재현
 */
function cfIsIn(value, valueArray) {
    for (var i = 0; i < valueArray.length; i++) {
        if (value == valueArray[i]) {
            return true;
        }
    }

    return false;
}


/**
 * @type   : function
 * @access : public
 * @desc   : 입력 폼 중에서 하나 이상의 값이 존재하는지 검사
 *           객체의 name 속성을 참조하며, <input type=text> 에 한한다.
 * <pre>
 *     cfExistValues(form.sal,form.comm);
 * </pre>
 * @sig    :
 * @param  : 체크하고자 하는 입력 폼 IDs
 * @return : true(하나라도 존재)/false(하나도 존재하지 않음)
 * @author : 정훈규
 */
function cfExistValues(){
    var isOk=false;
    var i = 0;
    var arrName = "";
    var oId;

    if(!arguments.length) return true;

    while(arguments[i]){
        oId = eval(arguments[i++]);

        if(!cfIsNull(oId.value)) {
            isOk = true;
            break;
        }
        arrName += "["+oId.name + "] ";
    }

    if(!isOk) {
        cfAlertMsg(MSG_COM_ERR_067, [arrName]);     // 중의 하나는 반드시 입력해야 합니다.
        eval(arguments[0]).focus();
    }

    return isOk;
}

/**
 * @type   : function
 * @access : private
 * @desc   : Object를 초기화한다.
 * <pre>
 *     cfIniObject( document.getElementById("oInputTable") );
 *     cfIniObject( [form.oEmpno, form.oContents, form.oRd[0]], "0" );
 *     cfIniObject( form.oEmpno, "0000" );
 * </pre>
 * @sig    : obj[, iniVal]
 * @param  : obj    - required 초기화할 대상 오브젝트
 * @param  : iniVal - optional 초기값 
 * @author : 정연주
 */
function cfIniObject(obj, iniVal) {
    if (cfIsNull(obj)) {
        return;
    }
    if (obj.length != null) {
        for (var i = 0; i < obj.length; i++) {
            cfProcessChildElement(obj[i], cfIniElement, iniVal);
        }
    } else {
        cfProcessChildElement(obj, cfIniElement, iniVal);
    }
}

/**
 * @type   : function
 * @access : private
 * @desc   : element를 초기화한다.
 * @sig    : oElement[, iniVal]
 * @param  : oElement - required 초기화할 대상 오브젝트
 * @param  : iniVal    - optional 초기값
 * @author : 정연주
 */
function cfIniElement(oElement, iniVal) {
    if( cfIsNull( iniVal ) ){
        iniVal = "";
    }

    switch (cfGetElementType(oElement)) {
        case "BUTTON" :
        case "RESET" :
        case "SUBMIT" :
        case "IMG" :           
        case "IMAGE" :         
            break;

        case "CHECKBOX" :
        case "RADIO" :
            oElement.checked = false;
            break;

        case "SELECT" :
            oElement.selectedIndex = 0;
            break;

        case "FILE" :
        case "PASSWORD" :
        case "TEXT" :
        case "TEXTAREA" :
            oElement.value = iniVal;
            break;

        default :
            break;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : window.open으로 서브창을 띄울 때 서브창의 위치를 간단하게 지정할 수 있다.
 * @sig    : width, height, position, [sURL] [, sName] [, sFeatures] [, bReplace]
 * @param  : width - 서브창의 넓이
 * @param  : height - 서브창의 높이
 * @param  : position  - 서브창의 위치 (default : 5) <br><br>
 * <table border='1'>
 *     <tr>
 *         <td>1</td>
 *         <td>2</td>
 *         <td>3</td>
 *     </tr>
 *     <tr>
 *         <td>4</td>
 *         <td>5</td>
 *         <td>6</td>
 *     </tr>
 *     <tr>
 *         <td>7</td>
 *         <td>8</td>
 *         <td>9</td>
 *     </tr>
 * </table>
 * @param  : sURL      - required window.open의 sURL 파라미터와 동일
 * @param  : sName     - required window.open의 sName 파라미터와 동일
 * @param  : sFeatures - required window.open의 sFeatures 파라미터와 동일
 * @param  : bReplace  - required window.open의 bReplace 파라미터와 동일
 * @author : 임재현
 */
function cfOpen(sWidth, sHeight, position, sURL, sName, sFeatures, bReplace) {
    var left = 0;
    var top = 0;

    var featureNames  = ["status", "menubar", "toolbar"];
    var featureValues = ["no", "no", "no"];
    var featureTypes  = ["boolean", "boolean", "boolean"];

    if (sFeatures != null) {
        cfParseOpenFeature(sFeatures, featureNames, featureValues, featureTypes);
    }

    var status = featureValues[0];
    var menubar = featureValues[1];
    var toolbar = featureValues[2];

    if (sWidth != null && sHeight != null) {
        width = sWidth*1 + 10; // window의 좌우 border 5px씩 감안.
        height = sHeight*1 + 29; // titlebar는 기본으로 감안.

        if (menubar) {
            height = height + 48;
            //IE인 경우 menubar가 yes이면 height가 20px 늘어난다.
            if( document.all ) {
                height = height - 20;
                sHeight = sHeight - 20;
            }  
        }

        if (toolbar) {
            height = height + 27;
        }

        if (status) {
            height = height + 20;
        }

        switch (position) {
            case 1 :
                left = 0;
                top = 0;
                break;

            case 2 :
                left = (screen.availWidth - width) / 2;
                top = 0;
                break;

            case 3 :
                left = screen.availWidth - width;
                top = 0;
                break;

            case 4 :
                left = 0;
                top = (screen.availHeight - height) / 2;
                break;

            case 5 :
                left = (screen.availWidth - width) / 2;
                top = (screen.availHeight - height) / 2;
                break;

            case 6 :
                left = screen.availWidth - width;
                top = (screen.availHeight - height) / 2;
                break;

            case 7 :
                left = 0;
                top = screen.availHeight - height;
                break;

            case 8 :
                left = (screen.availWidth - width) / 2;
                top = screen.availHeight - height;
                break;

            case 9 :
                left = screen.availWidth - width;
                top = screen.availHeight - height;
                break;

            default :
                left = (screen.availWidth - width) / 2;
                top = (screen.availHeight - height) / 2;
                break;
        }
        
        //IE의 height 보정
        if( document.all ){
            sHeight = sHeight - 3.5;
        }

        if (cfIsNull(sFeatures)) {
            sFeatures = "width=" +sWidth+ ",height=" +sHeight + ",left=" + left + ",top=" + top;
        } else {
            sFeatures = sFeatures +",width=" +sWidth+ ",height=" +sHeight + ",left=" + left + ",top=" + top;
        }
    }

    var newWindow = window.open(sURL, sName, sFeatures, bReplace);
    newWindow.focus();
    return newWindow;
}

/**
 * @type   : function
 * @access : private
 * @desc   : features 스트링을 파싱하여 array에 셋팅하는 내부 함수
 * @sig    : features, fNameArray, fValueArray, fTypeArray
 * @param  : features    - required features를 표현한 스트링
 * @param  : fNameArray  - required 추출해야 할 feature의 이름에 대한 array
 * @param  : fValueArray - required 추출해야 할 feature의 기본값에 대한 array
 * @param  : fTypeArray  - required 추출해야 할 feature의 데이터타입에 대한 array
 * @author : 임재현
 */
function cfParseOpenFeature(features, fNameArray, fValueArray, fTypeArray) {
    if (features == null) {
        return;
    }

    var featureArray = features.split(",");
    var featurePair;

    for (var i = 0; i < featureArray.length; i++) {
        featurePair = featureArray[i].trim().split("=");

        for (var j = 0; j < fNameArray.length; j++) {
            if (featurePair[0] == fNameArray[j]) {
                switch (fTypeArray[j]) {
                    case "string" :
                        fValueArray[j] = featurePair[1];
                        break;
                    case "number" :
                        fValueArray[j] = Number(featurePair[1]);
                        break;
                    case "boolean" :
                        if (featurePair[1].toUpperCase() == "YES" || featurePair[1].toUpperCase() == "TRUE" || featurePair[1] == "1") {
                            fValueArray[j] = true;
                        } else {
                            fValueArray[j] = false;
                        }
                        break;
                }
            }
        }
    }
}


//---------------------------------------- 이하 객체선언 ------------------------------------------------------------------------------//

///////////////////////////// coMessage /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 메세지를 관리하는 객체이다.
 * @author : 임재현
 */
function coMessage() {
    // method
    this.getMsg = coMessage_getMsg;
}

/**
 * @type   : method
 * @access : public
 * @object : coMessage
 * @desc   : 공통메세지에 정의된 메세지를 치환하여 알려준다.
 * @sig    : message[, paramArray]
 * @param  : message    - required common.js의 공통 메세지 영역에 선언된 메세지 ID
 * @param  : paramArray - optional 메세지에서 '@' 문자와 치환될 스트링 Array. (Array의 index와
 *           메세지 내의 '@' 문자의 순서가 일치한다.)
 * @return : 치환된 메세지 스트링
 */
function coMessage_getMsg(message, paramArray) {
    if (cfIsNull(message)) {
        return null;
    }

    var index = 0;
    var re = /@/g;
    var count = 0;

    if (paramArray == null) {
        return message;
    }

    while ( (index = message.indexOf("@", index)) != -1) {
        if (paramArray[count] == null) {
            paramArray[count] = "";
        }

        message = message.substr(0, index) + String(paramArray[count]) +
                  message.substring(index + 1);

        index = index + String(paramArray[count++]).length;
    }

    return message;
}

///////////////////////////// coMap /////////////////////////////
/**
 * @type   : object
 * @access : public
 * @desc   : String parameter 에 대한 name과 value 쌍들을 가진 객체
 * @author : 임재현
 */
function coMap() {
    // fields

    this.names = new Array();
    this.values = new Array();
    this.count = 0;

    // methods
    this.getValue          = coMap_getValue;
    this.put               = coMap_put;
    this.getNameAt         = coMap_getNameAt;
    this.getValueAt        = coMap_getValueAt;
    this.size              = coMap_size;
    this.getMaxNameLength  = coMap_getMaxNameLength;
}

/**
 * @type   : method
 * @access : public
 * @object : coMap
 * @desc   : name에 맞는 파라미터값을 리턴한다.
 * @sig    : name
 * @param  : name - required map의 name으로 사용할 값
 * @return : 파라미터값
 */
function coMap_getValue(name) {
    for (var i = 0; i < this.count; i++) {
        if (this.names[i] == name) {
            return this.values[i];
        }
    }

    return null;
}

/**
 * @type   : method
 * @access : public
 * @object : coMap
 * @desc   : 새로운 map을 추가한다. 같은 name가 존재할 경우 overwrite한다.
 * @sig    : name, value
 * @param  : name  - required map의 name로 사용할 값
 * @param  : value - required map의 value로 사용할 값
 * @return : 파라미터값
 */
function coMap_put(name, value) {
    for (var i = 0; i < this.count; i++) {
        if (this.names[i] == name) {
            this.values[i] = value;
            return;
        }
    }

    this.names[this.count] = name;
    this.values[this.count++] = value;
}

/**
 * @type   : method
 * @access : public
 * @object : coMap
 * @desc   : 지정된 index에 있는 map의 name을 알려준다.
 * @sig    : index
 * @param  : index - map의 index
 * @return : name
 */
function coMap_getNameAt(index) {
    return this.names[index];
}

/**
 * @type   : method
 * @access : public
 * @object : coMap
 * @desc   : 지정된 index에 있는 map의 value를 알려준다.
 * @sig    : index
 * @param  : index - required map의 index
 * @return : value
 */
function coMap_getValueAt(index) {
    return this.values[index];
}

/**
 * @type   : method
 * @access : public
 * @object : coMap
 * @desc   : map의 name-value 쌍의 갯수를 알려준다.
 * @return : name-value 쌍의 갯수
 */
function coMap_size() {
    return this.count;
}

/**
 * @type   : method
 * @access : public
 * @object : coMap
 * @desc   : map 내의 name 값들을 String으로 환산하여 최대길이를 알려준다.
 * @return : max name length
 */
function coMap_getMaxNameLength() {
    var maxLength = 0;

    for (var i = 0; i < this.count; i++) {
        if (String(this.names[i]).length > maxLength) {
            maxLength = String(this.names[i]).length;
        }
    }

    return maxLength;
}

///////////////////////////// coParameterMap /////////////////////////////
/**
 * @type   : object
 * @access : public
 * @desc   : String parameter 에 대한 name과 value 쌍들을 가진 객체
 * @author : 임재현
 */
function coParameterMap() {
    // fields

    /**
     * @type   : field
     * @access : private
     * @object : coParameterMap
     * @desc   : 파라미터 이름을 담고있는 array
     */
    this.names = new Array();

    /**
     * @type   : field
     * @access : private
     * @object : coParameterMap
     * @desc   : 파라미터 값을 담고있는 array
     */
    this.values = new Array();

    /**
     * @type   : field
     * @access : private
     * @object : coParameterMap
     * @desc   : 파라미터의 개수
     */
    this.count = 0;

    // methods
    this.getValue          = coParameterMap_getValue;
    this.put               = coParameterMap_put;
    this.getNameAt         = coParameterMap_getNameAt;
    this.getValueAt        = coParameterMap_getValueAt;
    this.size              = coParameterMap_size;
    this.getMaxNameLength  = coParameterMap_getMaxNameLength;
    this.getMaxValueLength = coParameterMap_getMaxValueLength;
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : name에 맞는 파라미터값을 리턴한다.
 * @sig    : name
 * @param  : name - required map의 name으로 사용할 값
 * @return : 파라미터값
 */
function coParameterMap_getValue(name) {
    for (var i = 0; i < this.count; i++) {
        if (this.names[i] == name) {
            return this.values[i];
        }
    }

    return null;
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : 새로운 map을 추가한다. 같은 name가 존재할 경우 overwrite한다.
 * @sig    : name, value
 * @param  : name  - required map의 name로 사용할 값
 * @param  : value - required map의 value로 사용할 값
 * @return : 파라미터값
 */
function coParameterMap_put(name, value) {
    for (var i = 0; i < this.count; i++) {
        if (this.names[i] == name) {
            this.values[i] = value;
            return;
        }
    }

    this.names[this.count] = name;
    this.values[this.count++] = value;
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : 지정된 index에 있는 map의 name을 알려준다.
 * @sig    : index
 * @param  : index - required map의 index
 * @return : name
 */
function coParameterMap_getNameAt(index) {
    return this.names[index];
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : 지정된 index에 있는 map의 value를 알려준다.
 * @sig    : index
 * @param  : index - required map의 index
 * @return : value
 */
function coParameterMap_getValueAt(index) {
    return this.values[index];
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : map의 name-value 쌍의 갯수를 알려준다.
 * @return : name-value 쌍의 갯수
 */
function coParameterMap_size() {
    return this.count;
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : map 내의 name 값들을 String으로 환산하여 최대길이를 알려준다.
 * @return : max name length
 */
function coParameterMap_getMaxNameLength() {
    var maxLength = 0;

    for (var i = 0; i < this.count; i++) {
        if (String(this.names[i]).length > maxLength) {
            maxLength = String(this.names[i]).length;
        }
    }

    return maxLength;
}

/**
 * @type   : method
 * @access : public
 * @object : coParameterMap
 * @desc   : map 내의 value 값들을 String으로 환산하여 최대길이를 알려준다.
 * @return : max value length
 */
function coParameterMap_getMaxValueLength() {
    var maxLength = 0;

    for (var i = 0; i < this.count; i++) {
        if (String(this.values[i]).length > maxLength) {
            maxLength = String(this.values[i]).length;
        }
    }

    return maxLength;
}

/**
 * @type   : object
 * @access : public
 * @desc   : A,img 링크 클릭시 점선 제거하는 공통 오브젝트
 * @author : 김혜경
 */
function coBluring(){
if(event.srcElement.tagName=="A"||event.srcElement.tagName=="IMG") document.body.focus();
}
//document.onfocusin=coBluring;

//-------------------------- 유효성 검사를 위한 객체 선언 -----------------------------//
/*
 * @Validator 객체의 구조
 *   - 속성 : exception,   -> validity의 sub속성이다. validity가 true면 exception은 무조건 false이고
 *                            validity가 false인 경우 false의 원인이 exception인지 여부를 알려준다.
 *                            exception은 사용자 입력에 대한 실제 validation과는 무관한 에러를 의미한다.
 *                            true/false 중 하나.
 *            message,     -> 오류메세지를 담고 있다.
 *            validity,    -> 유효성검사결과를 담고 있다. true/false 중 하나.
 *            value        -> 유효성 검사 대상 값.
 *
 *   - 메소드 : validate() -> 유효성 검사를 수행한다.
 *                            유효할 경우, validity를 true로하고 true를 return하고
 *                            유효하지 않을 경우,  validity를 false로하고 false를 return하고
 *                            message에 오류메세지를 기술한다.
 *                            exception의 경우는 exception을 true로 하고 message에 메세지를 기술한다.
 *
 *   - 추가시 할일 :
 *     1) validator객체를 정의한다.
 *     2) covValidExp 객체의 getValidators 메소드에 validator객체를 등록한다.
 */

///////////////////////////// covValueValidExp /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 유효성 검사에 대한 표현(expression)을 객체화 하였다.
 *             - expression 형식<br>
 *               항목이름:필수항목여부:유효성항목<br>
 *               예) "접수번호:yes:length=6"
 *             - 유효성 항목 형식
 *               유효성항목명=유효값[&유효성항목명=유효값]..
 *               예) "length=13&ssn"
 * @sig    : expression
 * @param  : expression - required valid expression string.
 * @author : 임재현
 */
function covValueValidExp(expression) {
    // data;
    this.validItems = new Array();
    this.errMsg = "";

    // method
    this.init = covValueValidExp_init;
    this.parse = covValueValidExp_parse;
    this.validate = covValueValidExp_validate;

    // initialize
    this.init(expression);
}

/**
 * @type   : method
 * @access : private
 * @object : covValueValidExp
 * @desc   : 초기화를 수행한다.
 * @sig    : expression
 * @param  : expression - required valid expression string.
 * @author : 임재현
 */
function covValueValidExp_init(expression) {
    this.parse(expression);
}

/**
 * @type   : method
 * @access : private
 * @object : covValueValidExp
 * @desc   : covValidExp 객체의 parse 메소드.
 *           valid expression을 parsing한다.
 * @sig    : expression
 * @param  : expression - required valid expression string.
 */
function covValueValidExp_parse(expression) {
    if (cfIsNull(expression)) {
        return;
    }

    var validItemExps = expression.advancedSplit("&", "i");
    var validItem;

    for (var i = 0; i < validItemExps.length; i++) {
        validItemPair = validItemExps[i].trim().advancedSplit("=", "i");
        validItem = new Object();
        validItem.name  = validItemPair[0].trim();
        validItem.value = validItemPair[1];  // parsedExp[1] 은 존재하지 않을 수도 있지만 자바스크립트에서는
        this.validItems[i] = validItem;      // 이런 경우 "undefined" 라는 값을 리턴한다.
    }
}

/**
 * @type   : method
 * @access : private
 * @object : covValueValidExp
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value - required 검사대상값
 */
function covValueValidExp_validate(value) {
    var validators = new Array();
    var count = 0;

    for (var i = 0; i < this.validItems.length; i++) {
        switch (this.validItems[i].name) {
            case "length" :
                validators[count++] = new covLengthValidator(this.validItems[i].value);
                break;

            case "byteLength" :
                validators[count++] = new covByteLengthValidator(this.validItems[i].value);
                break;

            case "minLength" :
                validators[count++] = new covMinLengthValidator(this.validItems[i].value);
                break;

            case "minByteLength" :
                validators[count++] = new covMinByteLengthValidator(this.validItems[i].value);
                break;

            case "maxLength" :
                validators[count++] = new covMaxLengthValidator(this.validItems[i].value);
                break;

            case "maxByteLength" :
                validators[count++] = new covMaxByteLengthValidator(this.validItems[i].value);
                break;

            case "number" :
                validators[count++] = new covNumberValidator(this.validItems[i].value);
                break;

            case "minNumber" :
                validators[count++] = new covMinNumberValidator(this.validItems[i].value);
                break;

            case "maxNumber" :
                validators[count++] = new covMaxNumberValidator(this.validItems[i].value);
                break;

            case "inNumber" :
                validators[count++] = new covInNumberValidator(this.validItems[i].value);
                break;
                
            case "inNumberAlpha" :
                validators[count++] = new covInNumberAlphaValidator(this.validItems[i].value);
                break;
                
            case "inAlpha" :
                validators[count++] = new covInAlphaValidator(this.validItems[i].value);
                break;                

            case "minDate" :
                validators[count++] = new covMinDateValidator(this.validItems[i].value);
                break;

            case "maxDate" :
                validators[count++] = new covMaxDateValidator(this.validItems[i].value);
                break;

            case "minDateYM" :
                validators[count++] = new covMinDateYMValidator(this.validItems[i].value);
                break;

            case "maxDateYM" :
                validators[count++] = new covMaxDateYMValidator(this.validItems[i].value);
                break;
                
            case "format" :
                validators[count++] = new covFormatValidator(this.validItems[i].value);
                break;

            case "ssn" :
                validators[count++] = new covSsnValidator(this.validItems[i].value);
                break;

            case "fsn" :
                validators[count++] = new covFsnValidator(this.validItems[i].value);
                break;
                
            case "csn" :
                validators[count++] = new covCsnValidator(this.validItems[i].value);
                break;

            case "filterIn" :
                validators[count++] = new covFilterInValidator(this.validItems[i].value);
                break;

            case "filterOut" :
                validators[count++] = new covFilterOutValidator(this.validItems[i].value);
                break;

            case "email" :
                validators[count++] = new covEmailValidator(this.validItems[i].value);
                break;

            case "date" :
                validators[count++] = new covDateValidator(this.validItems[i].value);
                break;

            default :
                break;
        }
    }

    for (var i = 0; i < validators.length; i++) {
        if (!validators[i].validate(value)) {
            this.errMsg = validators[i].message;
            return false;
        }
    }

    return true;
}

///////////////////////////// covItemValidExp /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 유효성 검사에 대한 표현(expression)을 객체화 하였다.
 *             - expression 형식<br>
 *               항목이름:필수항목여부:유효성항목<br>
 *               예) "접수번호:yes:length=6"
 *             - 유효성 항목 형식
 *               유효성항목명=유효값[&유효성항목명=유효값]..
 *               예) "length=13&ssn"
 * @sig    : expression, itemName
 * @param  : expression - required valid expression string.
 * @param  : itemName   - required 아이템명
 * @author : 임재현
 */
function covItemValidExp(expression, itemName) {
    // data;
    this.itemName;
    this.required;
    this.valueValidExp;

    // method
    this.parse = covItemValidExp_parse;
    this.validate = covItemValidExp_validate;

    // initialize
    this.parse(expression, itemName);
}

/**
 * @type   : method
 * @access : public
 * @object : covItemValidExp
 * @desc   : valid expression을 parsing한다.
 * @sig    : expression, itemName
 * @param  : expression - required valid expression string.
 * @param  : itemName   - required 아이템명
 */
function covItemValidExp_parse(expression, itemName) {
    if (cfIsNull(expression)) {
        return;
    }

    var columns = expression.advancedSplit(":", "i");
    
    if (cfIsNull(columns[1])) {
        return;
    }

    if (cfIsNull(columns[0])) {
        if (!cfIsNull(itemName)) {
            this.itemName = itemName.trim();
        } else {
            return;
        }
    } else {
        this.itemName = columns[0].trim();
    }

    this.required = (columns[1].trim().toUpperCase() == "YES" ||
                     columns[1].trim().toUpperCase() == "TRUE" ||
                     columns[1].trim() == "1"
                    ) ? true : false;

    if ((columns[2]) != null) {
        this.valueValidExp = new covValueValidExp(columns[2].trim());
    }
}

/**
 * @type   : method
 * @access : public
 * @object : covItemValidExp
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value - required 검사할 값
 */
function covItemValidExp_validate(value) {
    // 표현식에 필수항목들(아이템명, 필수여부)을 기술하지 않을 경우는 표현식이 없다고 간주.
    if (cfIsNull(this.itemName) || cfIsNull(this.required)) {
        return true;
    }

    if (this.required && cfIsNull(value)) {
        this.errMsg = MSG_COM_ERR_002;
        return false;
    }

    if (!this.required && cfIsNull(value)) {
        return true;
    }

    if (this.valueValidExp == null) {
        return true;
    }

    if (!this.valueValidExp.validate(value)) {
        this.errMsg = this.valueValidExp.errMsg;
        return false;
    }

    return true;
}

///////////////////////////// covColumnValidExp /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : Grid의 컬럼 유효성 검사 표현식
 * @sig    : expression, oGrid
 * @param  : expression - required valid expression string.
 * @param  : oGrid      - required 검사대상 Grid 오브젝트
 * @author : 임재현
 */
function covColumnValidExp(expression, oGrid) {
    // data;
    this.colId;
    this.errMsg = "";
    this.errRow = -1;
    this.errItemName = "";
    this.itemValidExp;
    this.property = "NORMAL";  // NORMAL, KEY, SINGLEKEY 속성이 있다.

    // method
    this.parse    = covColumnValidExp_parse;
    this.validate = covColumnValidExp_validate;

    // initialize
    this.parse(expression, oGrid);
}

/**
 * @type   : method
 * @access : public
 * @object : covColumnValidExp
 * @desc   : valid expression을 parsing한다.
 * @sig    : expression, oGrid
 * @param  : expression - required valid expression string.
 * @param  : oGrid      - required 검사대상 Grid 오브젝트
 */
function covColumnValidExp_parse(expression, oGrid) {
    var index = -1;

    var expArr = expression.advancedSplit(":", "i");

    if (expArr.length < 3) {
        return;
    }

    var itemName = null;

    this.colId = expArr[0].trim();

    if (new coGridFormat(oGrid.Format).existsColumn(this.colId)) {
        itemName = oGrid.ColumnProp(this.colId, "Name");
    }

    this.itemValidExp = new covItemValidExp(expArr[1] + ":" + expArr[2] + ":" + expArr[3], itemName);
    if (!cfIsNull(expArr[4]) && expArr[4].toUpperCase().trim() == "KEY") {
        this.property = "KEY";
    } else if (!cfIsNull(expArr[4]) && expArr[4].toUpperCase().trim() == "SINGLEKEY") {
        this.property = "SINGLEKEY";
    }
}

/**
 * @type   : method
 * @access : public
 * @object : covColumnValidExp
 * @desc   : validation을 수행한다.
 * @sig    : oDataSet, row
 * @param  : oDataSet - required 검사대상 DataSet
 * @param  : row - required 검사대상 DataSet의 특정 row 번호
 */
function covColumnValidExp_validate(oDataSet, row) {
    if (oDataSet == null ||
        oDataSet.tagName != "OBJECT" ||
        oDataSet.attributes.classid.nodeValue.toUpperCase() !== "CLSID:3267EA0D-B5D8-11D2-A4F9-00608CEBEE49" ||
        oDataSet.CountRow < 1
       ) {
        return true;
    }

    var startIdx = 1;
    var endIdx = oDataSet.CountRow;
    var value;
    var rowYN = false;

    if (row != null) {
        startIdx = row;
        endIdx = row;
        rowYN = true;
    }

    for (var i = startIdx; i <= endIdx; i++) {
        value = (oDataSet.NameValue(i, this.colId) == null) ?
                 null : oDataSet.NameString(i, this.colId).trim();  // DataSet의 data를 trim 시킨다.

        if (this.itemValidExp != null && !this.itemValidExp.validate(value)) {
            this.errMsg = this.itemValidExp.errMsg;
            this.errRow = i;
            this.errItemName = this.itemValidExp.itemName;
            return false;
        }
    }

    return true;
}

///////////////////////////// covGridValidExp /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : Grid에 대한 유효성검사 표현식
 * @sig    : oGrid
 * @param  : oGrid - required 검사대상 Grid
 * @author : 임재현
 */
function covGridValidExp(oGrid) {
    // data;
    this.oGrid = oGrid;
    this.columnValidExps = new Array();
    this.errMsg;
    this.errRow;
    this.errColId;
    this.errItemName = "";

    // method
    this.parse = covGridValidExp_parse;
    this.validate = covGridValidExp_validate;

    // initialize
    this.parse();
}

/**
 * @type   : method
 * @access : public
 * @object : covGridValidExp
 * @desc   : valid expression을 parsing한다.
 */
function covGridValidExp_parse() {
    if (cfIsNull(this.oGrid) || cfIsNull(this.oGrid.validExp)) {
        return;
    }

    var columns = this.oGrid.validExp.trim().advancedSplit(",", "it");

    for (var i = 0; i < columns.length; i++) {
        this.columnValidExps[i] = new covColumnValidExp(columns[i], this.oGrid);
    }
}

/**
 * @type   : method
 * @access : public
 * @object : covGridValidExp
 * @desc   : validation을 수행한다.
 * @sig    : [row[, colId[, ignoreStatus]]]
 * @param  : row - optional 검사대상 Grid의 특정 row 번호
 * @param  : colId - optional 검사대상 Grid의 특정 컬럼의 id
 * @param  : ignoreStatus - optional Grid 검사시 row status에 상관없이 모두 검사할 것인지의 여부.
 */
function covGridValidExp_validate(row, colId, ignoreStatus) {
    var oDataSet = document.all(this.oGrid.DataId);

    if (oDataSet == null ||
        oDataSet.tagName != "OBJECT" ||
        oDataSet.attributes.classid.nodeValue.toUpperCase() !== "CLSID:3267EA0D-B5D8-11D2-A4F9-00608CEBEE49" ||
        oDataSet.CountRow < 1
       ) {
        return true;
    }

    var startIdx;
    var endIdx;
    var nestedStartIdx;
    var nestedEndIdx;
    var keyColValidExps = new Array();
    var singleKeyColValidExps = new Array();

    // 키컬럼 추출
    var keyColCnt = 0;
    var singleKeyColCnt = 0;
    for (var i = 0; i < this.columnValidExps.length; i++) {
        if (this.columnValidExps[i].property == "KEY") {
            keyColValidExps[keyColCnt++] = this.columnValidExps[i];
        } else if (this.columnValidExps[i].property == "SINGLEKEY") {
            singleKeyColValidExps[singleKeyColCnt++] = this.columnValidExps[i];
        }
    }

    if (row != null) {
        startIdx = row;
        endIdx = row;
    } else {
        startIdx = 1;
        endIdx = oDataSet.CountRow - 1;
    }

    // 중복키 체크
    if (keyColValidExps.length > 0 || singleKeyColValidExps.length > 0) {
        var isEqual;

        for (var i = startIdx; i <= endIdx; i++) {

            if (row != null) {
                nestedStartIdx = 1;
            } else {
                nestedStartIdx = i + 1;
            }

            for (j = nestedStartIdx; j <= oDataSet.CountRow; j++) {
                if (i == j) {
                    continue;
                }

                // 일반키컬럼 검사.
                {
                    isEqual = true;
                    for (var k = 0; k < keyColValidExps.length; k++) {
                        if (oDataSet.NameValue(i, keyColValidExps[k].colId) !=
                            oDataSet.NameValue(j, keyColValidExps[k].colId)
                           ) {
                            isEqual = false;
                            break;
                        }
                    }

                    if (isEqual) {
                        this.errMsg = cfGetMsg(MSG_COM_ERR_032, ["@"]);

                        if (row != null) {
                            this.errRow = row;  // row를 지정하였을 때는 해당 row에 대한 error로 간주
                        } else {
                            this.errRow = j; // row지정이 없으면 중복된 두개의 데이터중 순서상 나중에 있는 row를 error로 간주
                        }

                        for (var k = 0; k < keyColValidExps.length; k++) {
                            this.errItemName = this.errItemName + keyColValidExps[k].itemValidExp.itemName + ", ";
                        }

                        this.errItemName = this.errItemName.substring(0, this.errItemName.lastIndexOf(","));
                        return false;
                    }
                }

                // 싱글키컬럼 검사.
                for (var k = 0; k < singleKeyColValidExps.length; k++) {
                    if (oDataSet.NameValue(i, singleKeyColValidExps[k].colId) ==
                        oDataSet.NameValue(j, singleKeyColValidExps[k].colId)
                       ) {
                        this.errMsg = cfGetMsg(MSG_COM_ERR_032, ["@"]);

                        if (row != null) {
                            this.errRow = row;  // row를 지정하였을 때는 해당 row에 대한 error로 간주
                        } else {
                            this.errRow = j; // row지정이 없으면 중복된 두개의 데이터중 순서상 나중에 있는 row를 error로 간주
                        }

                        this.errItemName = singleKeyColValidExps[k].itemValidExp.itemName;
                        return false;
                    }
                }
            }
        }
    }

    if (row != null) {
        startIdx = row;
        endIdx = row;
    } else {
        startIdx = 1;
        endIdx = oDataSet.CountRow;
    }

    // validation 수행
    for (var i = startIdx; i <= endIdx; i++) {
        if (ignoreStatus || oDataSet.RowStatus(i) != 0) {
            for (var j = 0; j < this.columnValidExps.length; j++) {
                columnValidExp = this.columnValidExps[j];

                if (!columnValidExp.validate(oDataSet, i)) {
                    this.errMsg = columnValidExp.errMsg;
                    this.errRow = i;
                    this.errColId = columnValidExp.colId;
                    this.errItemName = columnValidExp.errItemName;
                    return false;
                }
            }
        }
    }

    return true;
}

///////////////////////////// covLengthValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'length' 항목에 대한 validator. 값이 지정된 길이를 가지고 있는지 검사한다.
 * @param  : length - required 유효한 기준길이.
 * @author : 임재현
 */
function covLengthValidator(length) {
    // data;
    this.message = "";
    this.validity = false;
    this.length = length;

    // method
    this.validate = covLengthValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covLengthValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covLengthValidator_validate(value) {
    if (value.length != this.length) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_005, ["@", String(this.length)]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covByteLengthValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'byteLength' 항목에 대한 validator. 값이 지정된 byte단위의 길이를 가지고 있는지 검사한다.
 * @param  : length - required 유효한 기준길이.
 * @author : 임재현
 */
function covByteLengthValidator(length) {
    // data;
    this.message = "";
    this.validity = false;
    this.length = length;

    // method
    this.validate = covByteLengthValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covByteLengthValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covByteLengthValidator_validate(value) {
    if (cfGetByteLength(value) != this.length) {
        // 한글의 Byte를 계산한다. (공동이용 DB는 2Byte(ksc5601), 그 외는 3Byte(utf-8)
        var hangulByte = cfGetHangulByte();
    
        this.message = new coMessage().getMsg(MSG_COM_ERR_027, ["@", String(this.length), String(Math.floor(this.length / hangulByte ))]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMinLengthValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'minLength' 항목에 대한 validator. 값이 지정된 길이 이상인지를 검사한다.
 * @sig    : length
 * @param  : length - required 유효한 기준길이.
 * @author : 임재현
 */
function covMinLengthValidator(length) {
    // data;
    this.message = "";
    this.validity = false;
    this.length = length;

    // method
    this.validate = covMinLengthValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMinLengthValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMinLengthValidator_validate(value) {
    if (value.length < this.length) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_011, ["@", String(this.length)]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMinByteLengthValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'minByteLength' 항목에 대한 validator. 값이 지정된 byte단위의 길이 이상인지를 검사한다.
 * @sig    : length
 * @param  : length - required 유효한 기준길이.
 * @author : 임재현
 */
function covMinByteLengthValidator(length) {
    // data;
    this.message = "";
    this.validity = false;
    this.length = length;

    // method
    this.validate = covMinByteLengthValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMinByteLengthValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMinByteLengthValidator_validate(value) {
    if (cfGetByteLength(value) < this.length) {
    
        // 한글의 Byte를 계산한다. (공동이용 DB는 2Byte(ksc5601), 그 외는 3Byte(utf-8)
        var hangulByte = cfGetHangulByte();
    
        this.message = new coMessage().getMsg(MSG_COM_ERR_028, ["@", String(this.length), String(Math.floor(this.length / hangulByte ))]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMaxLengthValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'maxLength' 항목에 대한 validator. 값이 지정된 길이 이상인지를 검사한다.
 * @sig    : length
 * @param  : length - required 유효한 기준길이.
 * @author : 임재현
 */
function covMaxLengthValidator(length) {
    // data;
    this.message = "";
    this.validity = false;
    this.length = length;

    // method
    this.validate = covMaxLengthValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMaxLengthValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMaxLengthValidator_validate(value) {
    if (value.length > this.length) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_012, ["@", String(this.length)]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMaxByteLengthValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'maxByteLength' 항목에 대한 validator. 값이 지정된 byte단위의 길이 이하인지를 검사한다.
 * @sig    : length
 * @param  : length - required 유효한 기준길이.
 * @author : 임재현
 */
function covMaxByteLengthValidator(length) {
    // data;
    this.message = "";
    this.validity = false;
    this.length = length;

    // method
    this.validate = covMaxByteLengthValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMaxByteLengthValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMaxByteLengthValidator_validate(value) {
    if (cfGetByteLength(value) > this.length) {

        // 한글의 Byte를 계산한다. (공동이용 DB는 2Byte(ksc5601), 그 외는 3Byte(utf-8)
        var hangulByte = cfGetHangulByte();
        this.message = new coMessage().getMsg(MSG_COM_ERR_029, ["@", String(this.length), String(Math.floor(this.length / hangulByte))]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covNumberValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'number' 항목에 대한 validator. 값이 숫자인지를 검사한다. 또한 format을 지정하였을 경우에는 format에 맞는지 검사한다.
 * <pre>
 *     "number" 로 지정시 : 숫자인지 체크
 *     "number=(5.2)" 로 지정시 : 숫자이면서 정수부 5자리 이하, 소수부 2자리 이하인지를 체크
 * </pre>
 * @author : 임재현
 */
function covNumberValidator(format) {
    // data;
    re = /\(\s*(\d+)\s*.\s*(\d+)\s*\)/;
    this.iLength;
    this.dLength;

    this.message = "";
    this.validity = false;

    // method
    this.validate = covNumberValidator_validate;

    // initialize
    {
        if (cfIsNull(format)) {
            return;
        }

        r = format.match(re);

        if (r == null) {
            return;
        }

        this.iLength = Number(r[1]);
        this.dLength = Number(r[2]);
    }
}

/**
 * @type   : method
 * @access : public
 * @object : covNumberValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covNumberValidator_validate(value) {
    if (isNaN(value)) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_007, ["@"]);
        return false;
    } else if (!cfIsNull(this.iLength)) {
        var strValue = String(value);
        var idx = strValue.indexOf('.');
        var iNumStr = strValue.substr(0, idx);
        var dNumStr = strValue.substr(idx + 1);

        if (iNumStr.length > this.iLength) {
            this.message = new coMessage().getMsg(MSG_COM_ERR_059, ["@", String(this.iLength)]);
            return false;
        } else if (dNumStr.length > this.dLength) {
            this.message = new coMessage().getMsg(MSG_COM_ERR_060, ["@", String(this.dLength)]);
            return false;
        }
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMinNumberValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'minNumber' 항목에 대한 validator. 값이 지정된 최소값을 넘는지를 검사한다.
 * @sig    : minNumber
 * @param  : minNumber - required 유효한 기준 최소값.
 * @author : 임재현
 */
function covMinNumberValidator(minNumber) {
    // data;
    this.message = "";
    this.validity = false;
    this.minNumber = minNumber;

    // method
    this.validate = covMinNumberValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMinNumberValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMinNumberValidator_validate(value) {
    // 기준값이 숫자가 아닌경우 무조건 true;
    if (isNaN(this.minNumber)) {
        this.validity = true;
        return true;
    }

    if (isNaN(value)) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_007, ["@"]);
        return false;
    }

    this.minNumber = Number(this.minNumber);
    value          = Number(value);

    if (value < this.minNumber) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_013, ["@", String(this.minNumber)]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMaxNumberValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'maxNumber' 항목에 대한 validator. 값이 지정된 최대값을 넘지 않는지를 검사한다.
 * @sig    : maxNumber
 * @param  : maxNumber 유효한 기준 최대값.
 * @author : 임재현
 */
function covMaxNumberValidator(maxNumber) {
    // data;
    this.message = "";
    this.validity = false;
    this.maxNumber = (maxNumber == null) ? "" : maxNumber.trim();

    // method
    this.validate = covMaxNumberValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMaxNumberValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMaxNumberValidator_validate(value) {
    // 기준값이 숫자가 아닌경우 무조건 true;
    if (isNaN(this.maxNumber)) {
        this.validity = true;
        return true;
    }

    if (isNaN(value)) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_007, ["@"]);
        return false;
    }

    this.maxNumber = Number(this.maxNumber);
    value          = Number(value);

    if (value > this.maxNumber) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_014, ["@", String(this.maxNumber)]);
        return false;
    }

    this.validity = true;
    return true;
}


///////////////////////////// covInNumberValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'inNumber' 항목에 대한 validator. 값이 지정된 범위 내의 값인지를 검사한다.
 * @sig    : inNumber
 * @param  : inNumber - required 숫자의 범위를 나타내는 스트링. 예) "1~100"
 * @author : 임재현
 */
function covInNumberValidator(inNumber) {
    // data;
    this.message = "";
    this.validity = false;
    this.minNumber;
    this.maxNumber;

    // method
    this.validate = covInNumberValidator_validate;

    // initialize
    this.minNumber = inNumber.substring(0, inNumber.indexOf("~"));
    this.maxNumber = inNumber.substr(inNumber.indexOf("~") + 1);

    this.minNumber = (this.minNumber == null) ? "" : this.minNumber.trim();
    this.maxNumber = (this.maxNumber == null) ? "" : this.maxNumber.trim();
}

/**
 * @type   : method
 * @access : public
 * @object : covInNumberValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covInNumberValidator_validate(value) {
    // 기준값이 숫자가 아닌경우 무조건 true;
    if (isNaN(this.minNumber) || isNaN(this.maxNumber)) {
        this.validity = true;
        return true;
    }

    if (isNaN(value)) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_007, ["@"]);
        return false;
    }

    this.minNumber = Number(this.minNumber);
    this.maxNumber = Number(this.maxNumber);
    value     = Number(value);

    if (value < this.minNumber || value > this.maxNumber) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_006, ["@", String(this.minNumber), String(this.maxNumber)]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covInNumberAlphaValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'inNumberAlpha' 항목에 대한 validator. 값이 지정된 범위 내의 값인지를 검사한다.
 * @sig    : inNumberAlpha
 * @author : 한현주
 */
function covInNumberAlphaValidator() {
    // data;
    this.message = "";
    this.validity = false;

    // method
    this.validate = covInNumberAlphaValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covInNumberAlphaValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covInNumberAlphaValidator_validate(value) {

	if(!cfChkAlpa_Number(value)){
        this.message = new coMessage().getMsg(MSG_COM_ERR_079, ["@"]);
        return false;	
	}
	
    this.validity = true;
    return true;	
}

///////////////////////////// covInAlphaValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'inAlpha' 항목에 대한 validator. 값이 지정된 범위 내의 값인지를 검사한다.
 * @sig    : inAlpha
 * @author : 한현주
 */
function covInAlphaValidator() {
    // data;
    this.message = "";
    this.validity = false;

    // method
    this.validate = covInAlphaValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covInAlphaValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covInAlphaValidator_validate(value) {

	if(!cfIsAlphaOnly(value)){
        this.message = new coMessage().getMsg(MSG_COM_ERR_081, ["@"]);
        return false;	
	}
	
    this.validity = true;
    return true;	
}

///////////////////////////// covMinDateValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'minDate' 항목에 대한 validator. 값이 지정된 날짜를 넘는지를 검사한다.
 *           'YYYYMMDD' 형식으로 날짜를 표기해야 한다.
 *             예) minDate=20020315
 * @sig    : minDate
 * @param  : minDate - required 유효한 기준 최소값.
 * @author : 임재현
 */
function covMinDateValidator(minDate) {
    // data;
    this.message = "";
    this.validity = false;
    this.minDate = minDate;

    // method
    this.validate = covMinDateValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMinDateValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMinDateValidator_validate(value) {
    if (!(new covDateValidator("YYYY.MM.DD").validate(value))) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_018, ["@"]);
        return false;
    }

    if (value < this.minDate) {
        var msgParams = new Array(4);
        msgParams[0] = "@";
        msgParams[1] = this.minDate.substring(0,4);
        msgParams[2] = this.minDate.substring(5,6) == "0" ? this.minDate.substring(6,7) : this.minDate.substring(5,7);
        msgParams[3] = this.minDate.substring(8,9) == "0" ? this.minDate.substring(9,10) : this.minDate.substring(8,10)
        this.message = new coMessage().getMsg(MSG_COM_ERR_025, msgParams);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMinDateYMValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'minDateYM' 항목에 대한 validator. 값이 지정된 날짜를 넘는지를 검사한다.
 *           'YYYYMM' 형식으로 날짜를 표기해야 한다.
 *             예) minDate=200203
 * @sig    : minDate
 * @param  : minDate - required 유효한 기준 최소값.
 * @author : 한현주
 */
function covMinDateYMValidator(minDate) {
    // data;
    this.message = "";
    this.validity = false;
    this.minDate = minDate;

    // method
    this.validate = covMinDateYMValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMinDateYMValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMinDateYMValidator_validate(value) {
    if (!(new covDateValidator("YYYY.MM").validate(value))) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_018, ["@"]);
        return false;
    }

    if (value < this.minDate) {
        var msgParams = new Array(3);
        msgParams[0] = "@";
        msgParams[1] = this.minDate.substring(0,4);
        msgParams[2] = this.minDate.substring(5,6) == "0" ? this.minDate.substring(6,7) : this.minDate.substring(5,7);
        this.message = new coMessage().getMsg(MSG_COM_ERR_025, msgParams);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMaxDateValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'maxDate' 항목에 대한 validator. 값이 지정된 최대값을 넘지 않는지를 검사한다.
 * @sig    : maxDate
 * @param  : maxDate - required 유효한 최대날짜값.
 * @author : 임재현
 */
function covMaxDateValidator(maxDate) {
    // data;
    this.message = "";
    this.validity = false;
    this.maxDate = maxDate;

    // method
    this.validate = covMaxDateValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMaxDateValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMaxDateValidator_validate(value) {
    if (!(new covDateValidator("YYYY.MM.DD").validate(value))) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_018, ["@"]);
        return false;
    }

    if (value > this.maxDate) {
        var msgParams = new Array(4);
        msgParams[0] = "@";
        msgParams[1] = this.maxDate.substring(0,4);
        msgParams[2] = this.maxDate.substring(5,6) == "0" ? this.maxDate.substring(6,7) : this.maxDate.substring(5,7);
        msgParams[3] = this.maxDate.substring(8,9) == "0" ? this.maxDate.substring(9,10) : this.maxDate.substring(8,10)
        this.message = new coMessage().getMsg(MSG_COM_ERR_024, msgParams);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covMaxDateYMValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'maxDate' 항목에 대한 validator. 값이 지정된 최대값을 넘지 않는지를 검사한다.
 * @sig    : maxDate
 * @param  : maxDate - required 유효한 최대날짜값.
 * @author : 한현주
 */
function covMaxDateYMValidator(maxDate) {
    // data;
    this.message = "";
    this.validity = false;
    this.maxDate = maxDate;

    // method
    this.validate = covMaxDateYMValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covMaxDateYMValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covMaxDateYMValidator_validate(value) {
    if (!(new covDateValidator("YYYY.MM").validate(value))) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_018, ["@"]);
        return false;
    }

    if (value > this.maxDate) {
        var msgParams = new Array(3);
        msgParams[0] = "@";
        msgParams[1] = this.maxDate.substring(0,4);
        msgParams[2] = this.maxDate.substring(5,6) == "0" ? this.maxDate.substring(6,7) : this.maxDate.substring(5,7);
        this.message = new coMessage().getMsg(MSG_COM_ERR_024, msgParams);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covFormatValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'format' 항목에 대한 validator. 값이 마스크로 표현된 형식과 일치하는지 검사한다.
 *             - format characters
 *               #    : 문자와 숫자
 *               h, H : 한글 (H는 공백포함)
 *               A, Z : 문자 (Z는 공백포함)
 *               0, 9 : 숫자 (9는 공백포함)
 * @sig    : format
 * @param  : format - required 포멧 스트링.
 * @author : 임재현
 */
function covFormatValidator(format) {
    // data;
    this.message  = "";
    this.validity = false;
    this.format   = format

    // method
    this.validate = covFormatValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covFormatValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covFormatValidator_validate(value) {
    if (value.length != this.format.length) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
        return false;
    }

    for (var i = 0; i < this.format.length; i++) {
        switch(this.format.charAt(i)) {
            case 'h' :
                var cCode = value.charCodeAt(i);
                if ( (value.charAt(i) == " ") ||
                     !((0xAC00 <= cCode && cCode <= 0xD7A3) || (0x3131 <= cCode && cCode <= 0x318E))
                   ) {
                    this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                    return false;
                }
                break;

            case 'H' :
                var cCode = value.charCodeAt(i);
                if ( (value.charAt(i) != " ") &&
                     !((0xAC00 <= cCode && cCode <= 0xD7A3) || (0x3131 <= cCode && cCode <= 0x318E))
                   ) {
                    this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                    return false;
                }
                break;

            case '0' :
                if (isNaN(value.charAt(i)) || value.charAt(i) == " ") {
                    this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                    return false;
                }
                break;

            case '9' :
                if (isNaN(value.charAt(i))) {
                    if (value.charAt(i) != " ") {
                        this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                        return false;
                    }
                }
                break;

            case 'A' :
                if ( (value.charAt(i) == " ") || !isNaN(value.charAt(i)) ) {
                    this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                    return false;
                }
                break;

            case 'Z' :
                if ( (value.charAt(i) != " ") && !isNaN(value.charAt(i)) ) {
                    this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                    return false;
                }
                break;

            case '#' :
                break;

            default :
                if (value.charAt(i) != this.format.charAt(i)) {
                    this.message = new coMessage().getMsg(MSG_COM_ERR_026, ["@", this.format]);
                    return false;
                }
                break;
        }
    }

    this.validity = true;
    return true;
}

///////////////////////////// covSsnValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'ssn' 항목에 대한 validator. 입력된 주민등록번호가 유효한지 검사한다.
 * @author : 임재현
 */
function covSsnValidator() {
    // data;
    this.message = "";
    this.validity = false;

    // method
    this.validate = covSsnValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covSsnValidator
 * @desc   : validation을 수행한다.
 * @sig    : ssn
 * @param  : ssn - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covSsnValidator_validate(ssn) {
    if ( ssn == null || ssn.trim().length != 13 || isNaN(ssn) )  {
        this.message = new coMessage().getMsg(MSG_COM_ERR_016, ["@"]);
        return false;
    }

    var jNum1 = ssn.substr(0, 6);
    var jNum2 = ssn.substr(6);

    /*
      잘못된 생년월일을 검사합니다.
      2000년도부터 성구별 번호가 바뀌였슴으로 구별수가 2보다 작다면
      1900년도 생이되고 2보다 크다면 2000년도 이상생이 됩니다.
      단 1800년도 생은 계산에서 제외합니다.
    */
    bYear = (jNum2.charAt(0) <= "2") ? "19" : "20";

    // 주민번호의 앞에서 2자리를 이어서 4자리의 생년을 저장합니다.
    bYear += jNum1.substr(0, 2);

    // 달을 구합니다. 1을 뺀것은 자바스크립트에서는 1월을 0으로 표기하기 때문입니다.
    bMonth = jNum1.substr(2, 2) - 1;

    bDate = jNum1.substr(4, 2);

    bSum = new Date(bYear, bMonth, bDate);

    // 생년월일의 타당성을 검사하여 거짓이 있을시 에러메세지를 나타냄
    if ( bSum.getYear() % 100 != jNum1.substr(0, 2) || bSum.getMonth() != bMonth || bSum.getDate() != bDate) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_016, ["@"]);
        return false;
    }

    total = 0;
    var temp = new Array(13);

    for (i = 1; i <= 6; i++) {
        temp[i] = jNum1.charAt(i-1);
    }

    for (i = 7; i <= 13; i++) {
        temp[i] = jNum2.charAt(i-7);
    }

    for (i = 1; i <= 12; i++) {
        k = i + 1;

        // 각 수와 곱할 수를 뽑아냅니다. 곱수가 만일 10보다 크거나 같다면 계산식에 의해 2로 다시 시작하게 됩니다.
        if(k >= 10) k = k % 10 + 2;

        // 각 자리수와 계산수를 곱한값을 변수 total에 누적합산시킵니다.
        total = total + (temp[i] * k);
    }

    // 마지막 계산식을 변수 last_num에 대입합니다.
    last_num = (11- (total % 11)) % 10;

    // laster_num이 주민번호의마지막수와 같은면 참을 틀리면 거짓을 반환합니다.
    if(last_num != temp[13]) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_016, ["@"]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covFsnValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'fsn' 항목에 대한 validator. 입력된 외국인등록번호가 유효한지 검사한다.
 * @author : 한현주
 */
function covFsnValidator() {
    // data;
    this.message = "";
    this.validity = false;

    // method
    this.validate = covFsnValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covFsnValidator
 * @desc   : validation을 수행한다.
 * @sig    : fsn
 * @param  : fsn - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covFsnValidator_validate(fsn) {
    if ( fsn == null || fsn.trim().length != 13 || isNaN(fsn) )  {
        this.message = new coMessage().getMsg(MSG_COM_ERR_080, ["@"]);
        return false;
    }

	var sum=0;
	var odd=0;
	buf = new Array(13);
	for(i=0; i<13; i++) { 
		buf[i]=parseInt(fsn.charAt(i)); 
	}
	odd = buf[7]*10 + buf[8];
	
	if(odd%2 != 0) { 
		this.message = new coMessage().getMsg(MSG_COM_ERR_080, ["@"]);
        return false;
	}
	
	if( (buf[11]!=6) && (buf[11]!=7) && (buf[11]!=8) && (buf[11]!=9) ) {
		this.message = new coMessage().getMsg(MSG_COM_ERR_080, ["@"]);
        return false;
	}
	
	multipliers = [2,3,4,5,6,7,8,9,2,3,4,5];
	for(i=0, sum=0; i<12; i++) { 
		sum += (buf[i] *= multipliers[i]);
	}
	sum = 11 - (sum%11);
	if(sum >= 10) { sum -= 10; }
	sum += 2;
	if(sum >= 10) { sum -= 10; }
	if(sum != buf[12]) { 
		this.message = new coMessage().getMsg(MSG_COM_ERR_080, ["@"]);
        return false;
	}
	
    this.validity = true;
    return true;
}

///////////////////////////// covCsnValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 'csn' 항목에 대한 validator. 입력된 사업자등록번호가 유효한지 검사한다.
 * @author : 임재현
 */
function covCsnValidator() {
    // data;
    this.message = "";
    this.validity = false;

    // method
    this.validate = covCsnValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covCsnValidator
 * @desc   : validation을 수행한다.
 * @sig    : csn
 * @param  : csn - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covCsnValidator_validate(csn) {
    if ( csn == null || csn.length != 10 || isNaN(csn) )  {
        this.message = new coMessage().getMsg(MSG_COM_ERR_017, ["@"]);
        return false;
    }

    var sum = 0;
    var nam = 0;
    var checkDigit = -1;
    var checkArray = [1,3,7,1,3,7,1,3,5];

    for(i=0 ; i < 9 ; i++)
      sum += csn.charAt(i) * checkArray[i];

    sum = sum + ((csn.charAt(8) * 5 ) / 10);

    nam = Math.floor(sum) % 10;

    checkDigit = ( nam == 0 ) ? 0 : 10 - nam;

    if ( csn.charAt(9) != checkDigit) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_017, ["@"]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covFilterInValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 지정된 문자 이외에 다른 문자가 들어있을 경우 유효하지 않은 것으로 판단한다.
 *           특정 문자들에 대한 특수문자가 아래에 나와있다.<br>
 * <pre>
 *         ;    - \;
 *         한글 - \h
 *         영문 - \a
 *         숫자 - \n
 * </pre>
 * @sig    : fStr
 * @param  : fStr - required filter에 대한 표현
 * @author : 임재현
 */
function covFilterInValidator(fStr) {
    // data;
    this.message = "";
    this.validity = false;
    this.fStrArr = fStr.advancedSplit(";", "i");

    for (var i = 0; i < this.fStrArr.length; i++) {
        if (this.fStrArr[i] == "\\h") {
            this.fStrArr[i] = "한글";
        } else if (this.fStrArr[i] == "\\a") {
            this.fStrArr[i] = "영문";
        } else if (this.fStrArr[i] == "\\n") {
            this.fStrArr[i] = "숫자";
        }
    }

    // method
    this.validate = covFilterInValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covFilterInValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covFilterInValidator_validate(value) {
    var isIn = false;
    var c
    var cCode;

    for (var i = 0; i < value.length; i++) {
        isIn = false;
        c = value.charAt(i);
        cCode = value.charCodeAt(i);

        for (var j = 0; j < this.fStrArr.length; j++) {
            if (this.fStrArr[j] == "한글" &&
                ((0xAC00 <= cCode && cCode <= 0xD7A3) || (0x3131 <= cCode && cCode <= 0x318E))
               ) {
                isIn = true;
            } else if ( this.fStrArr[j] == "영문" &&
                        ((0x61 <= cCode && cCode <= 0x7A) || (0x41 <= cCode && cCode <= 0x5A))
                      ) {
                isIn = true;
            } else if (this.fStrArr[j] == "숫자" && !isNaN(c)) {
                isIn = true;
            } else if (this.fStrArr[j] == c) {
                isIn = true;
            }
        }

        if (!isIn) {
            this.message = new coMessage().getMsg(MSG_COM_ERR_036, ["@", this.fStrArr.toString()]);
            return false;
        }
    }

    this.validity = true;
    return true;
}

///////////////////////////// covFilterOutValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 지정된 스트링들이 들어있을 경우 유효하지 않은것으로 판단한다.
 *           분리자는 ";"를 사용한다. ";" 혹은 ";"문자가 들어간 스트링을 필터링하려 할 경우는
 *           "\\;"라고 표기해야 한다.
 * @sig    : fStr
 * @param  : fStr - required filter에 대한 표현
 * @author : 임재현
 */
function covFilterOutValidator(fStr) {
    // data;
    this.message = "";
    this.validity = false;
    this.fStrArr = fStr.advancedSplit(";", "i");

    // method
    this.validate = covFilterOutValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covFilterValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covFilterOutValidator_validate(value) {
    for (var i = 0; i < this.fStrArr.length; i++) {
        if (value.indexOf(this.fStrArr[i]) != -1) {
            this.message = new coMessage().getMsg(MSG_COM_ERR_033, ["@", this.fStrArr.toString()]);
            return false;
        }
    }

    this.validity = true;
    return true;
}

///////////////////////////// covEmailValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 입력값이 email 형식에 적합한지를 검사한다.
 * @author : 임재현
 */
function covEmailValidator() {
    // data;
    this.message = "";
    this.validity = false;

    // method
    this.validate = covEmailValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covEmailValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value - required 유효성 검사 대상값.
 * @return : boolean. 유효성 여부.
 */
function covEmailValidator_validate(value) {
    var format = /^((\w|[\-\.])+)@((\w|[\-\.])+)\.([A-Za-z]+)$/;

    if (value.search(format) == -1) {
        this.message = new coMessage().getMsg(MSG_COM_ERR_037, ["@"]);
        return false;
    }

    this.validity = true;
    return true;
}

///////////////////////////// covDateValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 값이 Date형식인지를 검사한다.
 *
 *            format문자 :  YYYY,  -> 4자리 년도
 *                          YY,    -> 2자리 년도. 2000년 이후.
 *                          MM,    -> 2자리 숫자의 달.
 *                          DD,    -> 2자리 숫자의 일.
 *                          hh,    -> 2자리 숫자의 시간. 12시 기준
 *                          HH,    -> 2자리 숫자의 시간. 24시 기준
 *                          mm,    -> 2자리 숫자의 분.
 *                          ss     -> 2자리 숫자의 초.
 *
 *            예)
 *                'YYYYMMDD' -> '20020328'
 *                'YYYY/MM/DD' -> '2002/03/28'
 *                'Today : YY-MM-DD' -> 'Today : 02-03-28'
 *
 *            참고)
 *                  format문자가 중복해서 나오더라도 처음 나온 문자에 대해서만
 *                  format문자로 인식된다. YYYY와 YY, hh와 HH 도 중복으로 본다.
 *                  날짜는 년,월이 존재할 때만 정확히 체크하고 만일 년, 월이 없다면
 *                  1 ~ 31 사이인지만 체크한다.
 *
 * @sig    : dateExp
 * @param  : dateExp - required Date Format expression.
 *             예) 2002년 3월 12일 -> "YYYY-MM-DD"(Date Format Expression) -> "2002-03-12"
 * @author : 임재현
 */
function covDateValidator(dateExp) {
    // data;
    this.message = "";
    this.validity = false;
    this.dateExp = dateExp;
    this.year = null;
    this.month = null;

    // method
    this.validate = covDateValidator_validate;
    this.checkLength = covDateValidator_checkLength;
    this.checkYear = covDateValidator_checkYear;
    this.checkMonth = covDateValidator_checkMonth;
    this.checkDay = covDateValidator_checkDay;
    this.checkHour = covDateValidator_checkHour;
    this.checkMin = covDateValidator_checkMin;
    this.checkSec = covDateValidator_checkSec;
    this.checkRest = covDateValidator_checkRest;
}

/**
 * @type   : method
 * @access : public
 * @object : covDateValidator
 * @desc   : validation을 수행한다.
 * @sig    : value
 * @param  : value   - required 검사대상이 되는 Date 스트링 값.
 * @return : boolean - 유효성 여부
 */
function covDateValidator_validate(value) {
    this.value = value;

    if ( this.checkLength(value) &&
         this.checkYear(value) &&
         this.checkMonth(value) &&
         this.checkDay(value) &&
         this.checkHour(value) &&
         this.checkMin(value) &&
         this.checkSec(value) &&
         this.checkRest(value)
       ) {
        this.validity = true;
        return true;
    } else {
        this.validity = false;
        return false;
    }
}

function covDateValidator_checkLength() {

    if (this.value.length == this.dateExp.length) {
        return true;
    } else {
        this.message = new coMessage().getMsg(MSG_COM_ERR_005, ["@", String(this.dateExp.length)]);
        return false;
    }
}

function covDateValidator_checkYear() {
    var index = -1;

    if ( (index = this.dateExp.indexOf("YYYY")) != -1 ) {
        subValue = this.value.substr(index, 4);
        if ( !isNaN(subValue) &&
             (subValue > 0)
           ) {
            this.dateExp = this.dateExp.cut(index, 4);
            this.value = this.value.cut(index, 4);
            this.year = subValue;
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_015, ["@"]);
            return false;
        }
    }

    if ( (index = this.dateExp.indexOf("YY")) != -1 ) {
        subValue = "20" + this.value.substr(index, 2);
        if ( !isNaN(subValue) &&
             (subValue > 0)
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            this.year = subValue;
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_015, ["@"]);
            return false;
        }
    }

    return true;
}

function covDateValidator_checkMonth() {
    var index = -1;

    if ( (index = this.dateExp.indexOf("MM")) != -1 ) {
        subValue = this.value.substr(index, 2);
        if ( !isNaN(subValue) &&
             (subValue > 0) &&
             (subValue <= 12)
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            this.month = subValue;
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_019, ["@"]);
            return false;
        }
    }

    return true;
}

function covDateValidator_checkDay() {
    var index = -1;
    var days = 0;

    if ( (index = this.dateExp.indexOf("DD")) != -1 ) {
        if ( (this.year != null) && (this.month != null) ) {
            days = (this.month != 2) ? GLB_DAYS_IN_MONTH[this.month-1] : (( (this.year % 4) == 0 && (this.year % 100) != 0 || (this.year % 400) == 0 ) ? 29 : 28 );
        } else {
            days = 31;
        }

        subValue = this.value.substr(index, 2);
        if ( (!isNaN(subValue)) &&
             (subValue > 0) &&
             (subValue <= days)
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_020, ["@"]);
            return false;
        }
    }

    return true;
}

function covDateValidator_checkHour() {
    var index = -1;

    if ( (index = this.dateExp.indexOf("hh")) != -1 ) {
        subValue = this.value.substr(index, 2);
        if ( !isNaN(subValue) &&
             (subValue >= 0) &&
             (subValue <= 12)
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_021, ["@"]);
            return false;
        }
    }

    if ( (index = this.dateExp.indexOf("HH")) != -1 ) {
        subValue = this.value.substr(index, 2);
        if ( !isNaN(subValue) &&
             (subValue >= 0) &&
             (subValue < 24)
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_021, ["@"]);
            return false;
        }
    }

    return true;
}

function covDateValidator_checkMin() {
    var index = -1;

    if ( (index = this.dateExp.indexOf("mm")) != -1 ) {
        subValue = this.value.substr(index, 2);
        if ( !isNaN(subValue) &&
             (subValue >= 0) &&
             (subValue < 60 )
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            this.month = subValue;
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_022, ["@"]);
            return false;
        }
    }

    return true;
}

function covDateValidator_checkSec() {
    var index = -1;

    if ( (index = this.dateExp.indexOf("ss")) != -1 ) {
        subValue = this.value.substr(index, 2);
        if ( (!isNaN(subValue)) &&
             (subValue >= 0) &&
             (subValue < 60 )
           ) {
            this.dateExp = this.dateExp.cut(index, 2);
            this.value = this.value.cut(index, 2);
            this.month = subValue;
            return true;
        } else {
            this.message = new coMessage().getMsg(MSG_COM_ERR_023, ["@"]);
            return false;
        }
    }

    return true;
}

function covDateValidator_checkRest() {
    if (this.value == this.dateExp) {
        return true;
    }

    return false;
}


///////////////////////////// covNullValidator /////////////////////////////
/**
 * @type   : object
 * @access : private
 * @desc   : 무조건 valid한 결과를 가진 validator.
 * @author : 임재현
 */
function covNullValidator() {
    // data;
    this.message = "";
    this.validity = true;

    // method
    this.validate = covNullValidator_validate;
}

/**
 * @type   : method
 * @access : public
 * @object : covNullValidator
 * @desc   : validation을 수행한다.
 * @return : boolean - 무조건 true.
 */
function covNullValidator_validate() {
    this.message = new coMessage().getMsg(MSG_COM_INF_007);
    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 자바스크립트의 숫자 앞에 지정된 자릿수만큼 zero character 를 삽입한다.
 * <pre>
 *     cfDigitalNumber(125, 5);
 * </pre>
 * 위와같이 사용했을 경우 "00123" 이라는 String을 리턴한다.
 * @sig    : length, number
 * @param  : length - required 숫자를 표현하는 길이
 * @param  : number - required 변환될 숫자
 * @return : 변환된 스트링
 * @author : 임재현
 */
function cfDigitalNumber(number, length) {
    var numStr = number + "";
    var zeroChars = "";

    for (var i = 0; i < (length - numStr.length); i++) {
        zeroChars = zeroChars + "0";
    }
    return (zeroChars + numStr);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 지정한 수만큼 소수점 아래로 0을 붙인다.
 * <pre>
 *     cfFractionFormat( '-2,123.3',2);
 * </pre>
 * 위와같이 사용했을 경우 "-2,123.30" 이라는 String을 리턴한다.
 * @sig    : number, pos
 * @param  : number - required 문자열
 * @param  : pos    - required 정밀도(소수점이하 자리수)
 * @return : 변환된 스트링
 * @author : 정연주
 */
function cfFractionFormat( number, pos ){
    var numStr = String( number );
    var ptPos  = numStr.indexOf(".");
    var cnt    = 0;

    if ( ptPos < 1 ){
        numStr += ".";
        cnt = pos;
    } else {
        var subLen = numStr.substr( ptPos + 1 ).length;
        if ( pos > subLen ){
            cnt = pos - subLen;
        }
    }

    var str0 = "";

    for ( var i = 0 ; i < cnt ; i ++ ){
        str0 += "0";
    }

    return numStr + str0;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 숫자 String를 받아서 콤마를 넣어 만든다.
 *           코머포함한 숫자 Valid까지 처리함
 * <pre>
 *  cfCommaEdit( "-123a4.3", 1)  -> false
 *  cfCommaEdit( "-1234.3", 1)   -> -1,234.3
 *  cfCommaEdit( "-1234.3", 4)   -> false
 *  cfCommaEdit( "-1234.3")      -> -1,234.3
 * </pre>
 * @sig    : numStr, primeLen
 * @param  : numStr   - required  숫자 String
 * @param  : primeLen - optional  소수점 이하 자리수 체크
 * @return : 콤마처리된 값 혹은 false
 * @author : 정연주
 */
function cfCommaEdit( numStr, primeLen ){

    var pureNum         = "";
    var newVal          = "";
    var headNum         = 0 ;
    var loopCount       = 0 ;
    var minus           = "";
    var commaIndex      = 0 ;
    var nStr            = "";
    var modfyStr        = "";
    var pStr            = "";
    var dotIndex        = 0 ;
    var dotValue        = "";

    numStr = numStr + "";

    if( cfIsNull( numStr ) ){
        return "";
    } else {
        numStr = String( numStr );

        dotIndex    = numStr.lastIndexOf(".") ;
        commaIndex  = numStr.indexOf(",") ;     // -1 일이면 Comma가 없는 숫자

        if ( dotIndex != -1 ){                   // 소수점이 있는 숫자
            pStr = numStr.substr(dotIndex+1) ;
            if ( primeLen > 0 && pStr.length != primeLen ){
                return false ;
            }
            if ( !cfChkNumPositive ( pStr )){
                return false ;
            }
            modfyStr = numStr.substr(0,dotIndex) ;
            nStr     = modfyStr.replace(/,/g,'') ;
        }else{
            modfyStr = numStr ;
            nStr     = numStr.replace(/,/g,'') ;
        }

        if ( nStr.substr(0,1) == '-' ) { minus = "-" ; nStr = nStr.substr(1); }

        for( i = 0 ; i < ( nStr.length ); i++ ){
            pureNum = pureNum + nStr.substr(i,1);
        }

        if(pureNum.toString().length > 3){
            headNum = pureNum.length % 3;
            loopCount = ( pureNum.toString().length - headNum ) / 3;
            if(headNum != 0)
                newVal = pureNum.substr(0,headNum) + ",";
            newVal = newVal + pureNum.substr(headNum, 3);

            for( var idx= 0 ; idx < ( loopCount - 1) ; idx++){
                newVal = newVal + ",";
                newVal = newVal + pureNum.substr(headNum + (3*(idx+1)), 3);
            }
        }else newVal = pureNum;

        if ( !cfChkNum( minus+pureNum ) ){
            return false ;
        }

        if ( (commaIndex != -1) && (modfyStr != minus+newVal) ){
            return false ;
        }

        if ( dotIndex != -1 && pStr.length != 0 )  // 소수점이 있는 숫자
            return minus+newVal+"."+pStr ;
        else
            return minus+newVal;
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 컴마를 없앤 숫자를 반환한다.
 * <pre>
 *     cfNumeric( "-12,345.09" ) -> -12345.09
 * </pre>
 * @sig    : number
 * @param  : number - required 문자열
 * @return : 치환된 문자열 스트링
 * @author : 왕정일
 */
function cfNumeric(number) {
    number = number + "";
    number = number.replace(/,/g,"");
    var nm = parseFloat(number).toString();
    return (isNaN(nm)?0:nm);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 숫자를 제외한 모든 문자를 제거한다.
 * <pre>
 *     cfGetNumberOnly("2006.01.02");"
 *     위와같이 사용했을 경우 '20060102'를 return
 * </pre>
 * @sig    : sOrg
 * @param  : sOrg - required 문자열
 * @return : 치환된 문자열 스트링
 * @author : 정연주
 */
function cfGetNumberOnly(sOrg) {
	return sOrg.replace(/[^0-9]/g, "");
}

/**
 * @type   : function
 * @access : public
 * @desc   : 양의 정수인지 체크한다.
 * <pre>
 *  cfChkNumPositive(-123)  -> false
 *  cfChkNumPositive(123)   -> true
 *  cfChkNumPositive(123.4) -> false
 * </pre>
 * @sig    : toCheck
 * @param  : toCheck  - check data
 * @return : true(양수)/false(음수)
 * @author : 정연주
 */
function cfChkNumPositive( toCheck ){
    var chkStr = toCheck+"" ;
    var isNum  = true ;

    for (j = 0 ; isNum && (j < chkStr.length) ; j++){
        if ((chkStr.substring(j,j+1) < "0") || (chkStr.substring(j,j+1) > "9")){
            isNum = false ;
        }
    }
    return isNum;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 숫자인지, 범위에 적합한지 체크한다.
 * @sig    : toCheck, totLen, primeLen
 * @param  : toCheck  - check data
 * @param  : totLen   - 총자릿수
 * @param  : primeLen - 소수점이하 자리수
 * @param  : limit    - 범위
 * @return : true(Number)/false - Not Number
 * @author : 정연주
 */
function cfChkNum( toCheck, totLen, primeLen ){
    var isNum       = true ;
    var dotIndex    = 0 ;
    var nStr        = toCheck+"" ;  // 정수부분
    var pStr        = "" ;          // 소수부분

    dotIndex = toCheck.lastIndexOf(".") ;

    if ( cfIsNull(nStr) ) return false;

    if ( dotIndex != -1 ){           // 소수점이 있는 숫자

        pStr = toCheck.substr(dotIndex+1) ;
        if ( (primeLen > 0 && pStr.length > primeLen) || toCheck.substring(toCheck.length-1)=="." ){
            return false ;
        }

        if ( !cfChkNumPositive ( pStr )){
            return false ;
        }
        nStr = toCheck.substr(0,dotIndex) ;
    }

    if ( primeLen > 0 && nStr.length > totLen-primeLen ){
        return false ;
    }

    for (j = 0 ; isNum && (j < nStr.length) ; j++){
        if ((nStr.substring(j,j+1) < "0") || (nStr.substring(j,j+1) > "9")){
            if ( nStr.substring(j,j+1) == "-" ){
                if ( j != 0 ){
                   isNum = false;
                }
            }else{
                isNum = false ;
            }
        }
    }
    if ( nStr == "-" ) isNum = false ;
    return isNum;
}


/**
 * @type   : function
 * @access : public
 * @desc   : 지정된 textBox의 안에 오직 숫자만 입력 가능토록 한다.
 * <pre>
 *    cfSetObjNumberOnly([sId,sNm])
 * </pre>
 * @sig    : objectArray
 * @param  : objectArray 숫자만 입력받도록 하는 object들
 * @return : void
 * @author : 왕정일
 */
function cfSetObjNumberOnly(objArray) {
    if (eval(objArray).length != null) {

        for ( i = 0 ; i < objArray.length ; i++) {
            eval(objArray[i]).onkeypress = function (){cfNumberOnly()};
        }

    } else {
        eval(objArray).onkeypress = function (){cfNumberOnly()};
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력텍스트 박스에 숫자만 입력할 수 있게 한다.
 * <pre>
 *     onkeypress="cfNumberOnly(event);"
 *     위와같이 사용했을 경우 숫자만 입력가능하게 한다. - . 는 허용
 *     스페이스 불가
 * </pre>
 * @sig    : e
 * @param  : e - required 이벤트 
 * @return : void
 * @author : 정연주
 */
function cfNumberOnly(e) {
    if(window.event){   //IE
        e = window.event
        var lkeycode = e.keyCode; 
    }else{               //W3C
        var lkeycode = e.charCode; 
    } 

    if(  !(48 <= lkeycode && lkeycode <=57) 
       && lkeycode != 0             // 기타 key
       && lkeycode != 45            // -
       && lkeycode != 46 ) {        // .
        if( window.event ){
            e.keyCode = 0;
        }else{
            e.preventDefault();
        }
    } 
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력텍스트 박스에 영문과 숫자만 입력.
 * <pre>
 *     onkeypress="cfAlpaNumberOnly(event);"
 * </pre>
 * 위와같이 사용했을 경우 영문과 숫자만 입력.
 * @sig    : e
 * @param  : e - required 이벤트 
 * @return : void
 * @author : 정연주
 */
function cfAlpaNumberOnly(e) {

    if(window.event){  //IE
        e = window.event
        var lkeycode = e.keyCode; 
    } else{              //W3C
        var lkeycode = e.charCode; 
    } 

    var bAlpaNumber = true;

    if  ( lkeycode == 0 ) {  // - . 는 통과
        // 통과
    } else if  ( lkeycode < 48 ) {
        bAlpaNumber = false;
    } else if ( lkeycode >= 48 && lkeycode <= 57 ){   // 숫자
        // 통과
    } else if ( lkeycode > 57 && lkeycode < 65 ){
        bAlpaNumber = false;
    } else if ( lkeycode >= 65 && lkeycode <= 90 ){   // Alphabat 대문자
        // 통과
    } else if ( lkeycode > 90 && lkeycode < 97 ){
        bAlpaNumber = false;
    } else if ( lkeycode >= 97 && lkeycode <= 122 ){  // Alphabat 소문자
        // 통과
    } else{
        bAlpaNumber = false;
    }
    
    if( !bAlpaNumber ){
        if( window.event ){
            e.keyCode = 0;
        }else{
            e.preventDefault();
        }
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력텍스트 박스에 한글만 입력.
 * <pre>
 *     onkeypress="cfKoreanOnly(event);"
 * </pre>
 * 위와같이 사용했을 경우 한글만 입력.
 * @sig    : e
 * @param  : e - required 이벤트 
 * @return : void
 * @author : 한현주
 */
function cfKoreanOnly(e) {

    if(window.event){  //IE
        e = window.event
        var lkeycode = e.keyCode; 
    } else{              //W3C
        var lkeycode = e.charCode; 
    } 

	if (lkeycode != 0 &&((lkeycode<65)||(lkeycode>90))) {
	
		if(window.event){  //IE
			e.returnValue=false; 
		} else{              //W3C
			var lkeycode = e.charCode; 
			e.preventDefault();
		}	
	}	
}

/**
 * @type   : function
 * @access : public
 * @desc   : INPUT TEXT에 영문 입력시 대문자로 변환(코드성 데이터 입력시)
 * <pre>
 *    onkeyup=cfUpperCase(this, event)
 * </pre>
 * @sig    : obj, e
 * @param  : obj - 해당 오브젝트
 * @param  : e - required 이벤트 
 * @return : void
 * @author : 한현주
 */
function cfUpperCase(obj,e){

    if(window.event){    //IE
        e = window.event
    }

    var lkeycode = e.keyCode; 
    
	if( !((65 <= lkeycode && lkeycode <=90) || (97 <= lkeycode && lkeycode <=122) || lkeycode == 13) )
		e.keyCode = 0;		// 이벤트 cancel
	if( e.type == "keyup" && lkeycode > 47 && lkeycode < 58 && parseInt(obj.value.charAt( obj.value.length-1)) )
		obj.value = obj.value.substring(0, obj.value.length-1 );        
	if( (65 <= lkeycode && lkeycode <=90) || (97 <= lkeycode && lkeycode <=122))
		obj.value = obj.value.toUpperCase();
}

/**
 * @type   : function
 * @access : public
 * @desc   : 사용자가 누른 key가 enter key 인지 여부를 알려준다.
 * <pre>
 *     function fncOnKeyDown(e) {
 *         ...
 *         if (cfIsEnterKey(e)) {
 *             ...
 *         }
 *     }
 *     ...
 *     &lt;input type="text" onkeydown="fncOnKeyDown(event)"&gt;
 * </pre>
 * @return : enter key 여부
 * @author : 임재현
 */
function cfIsEnterKey(e) {

    if(window.event){    //IE
        e = window.event
    } 
    var lkeycode = e.keyCode; 

    if (lkeycode == 13) {
        return true;
    }

    return false;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 조회조건 폼에 EnterKey 이벤트를 부여
 *           input text, input password에 한한다.
 * <pre>
 *     cfSetEvent(fnc, [obj1, obj2])
 * </pre>
 * ex) cfSetEvent(fncSearchList, [form.sEmpno, form.sEname, form.sDname]);
 * @sig    : fun, obj
 * @param  : fun - required 이벤트 발생시 수행할 function 명
 * @param  : obj - required 특정 function에 해당하는 event를 줄 object 의 array
 * @return : void
 * @author : 정연주
 */
function cfSetEvent(fnc,obj){
    try{
        if(fnc == null || fnc == undefined) {
            return false;
        }

        if (obj.length == null) {
            objArr = new Array(1);
            objArr[0] = obj;
        } else {
            objArr = obj;
        }

        var oElement
        for (var objArrIdx = 0; objArrIdx < objArr.length; objArrIdx++) {
            oElement = objArr[objArrIdx];
            
            switch (cfGetElementType(oElement)) {
                case "TEXT" :
                case "HIDDEN" :
                case "PASSWORD" :
                case "SUBMIT" :
                case "RESET" :
                    cfAttachEvent( oElement, "keydown", function(event){if( cfIsEnterKey(event)) fnc()}, false );
                    break;
                default:
                    break;
            }
        }
    }catch(e){}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오브젝트에 event listener를 추가한다.
 * <pre>
 *     cfAttachEvent(obj, evt, fnc, useCapture )
 * </pre>
 * @sig    : obj, evt, fnc, useCapture
 * @param  : obj - required 특정 function에 해당하는 event를 줄 object
 * @param  : evt - required 해당하는 event type
 * @param  : useCapture - optional 사용자가 capture를 초기화할지 여부. default는 false
 * @return : boalean
 * @author : 정연주
 */
function cfAttachEvent(obj, evt, fnc, useCapture ){

    if(!useCapture) useCapture = false;

    if( obj.addEventListener){      //W3C DOM
        return obj.addEventListener(evt, fnc, useCapture);
    }else if( obj.attachEvent ){    //MS DOM
        return obj.attachEvent("on"+evt, fnc);
    }else {
        return false;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 사용자의 입력값이 Byte로 환산된 최대길이를 넘을 경우 입력이 안되도록 하는 함수. <br>
 *           안타깝게도 Windows XP 환경에서는 한글에 대한 키이벤트가 발생하지 않아서 동작하지 않는다.<br>
 *           오브젝트 선언시 onkeydown 이벤트에 다음과 같이 기술해 주어야만 한다.
 * <pre>
 *     onkeydown="cfValidateMaxByteLength(10, event);"
 * </pre>
 * 현재는 html의 text input, textarea에만 적용된다.
 * @sig    : length, e
 * @param  : length   - required max byte length
 * @param  : e        - required 이벤트
 * @author : 정연주
 */
function cfValidateMaxByteLength(length, e) {
    var value = "";

    if(window.event){    //IE
        e = window.event;
        var vElement = e.srcElement;
        var lkeycode = e.keyCode;  
    } else{                //W3C
        var vElement = e.currentTarget;
        var lkeycode = e.which; 
    } 
    
    if (lkeycode == 8 ||   // backspace
        lkeycode == 33 ||  // PgUp key
        lkeycode == 34 ||  // PgDn key
        lkeycode == 35 ||  // end key
        lkeycode == 36 ||  // home key
        lkeycode == 37 ||  // left key
        lkeycode == 38 ||  // up key
        lkeycode == 39 ||  // right key
        lkeycode == 40 ||  // down key
        lkeycode == 46     // delete key
       ) {
        return true;
    }

    switch (cfGetElementType(vElement)) {
        case "TEXT" :
        case "TEXTAREA" :
            value = vElement.value;
            break;

        default :
            return;
    }
    
    if(window.event){    //IE
        if (cfGetByteLength(value) > length ) {
            vElement.blur();
            vElement.focus();
            vElement.value = vElement.value.substr(0, vElement.value.length - 1);
            event.returnValue = false;
            return;
        }
    
        if (vElement.onkeyup == null) {
            vElement.onkeyup =
                function() {
                    if (cfGetByteLength(vElement.value) > length) {
                        vElement.blur();
                        vElement.focus();
                        vElement.value = vElement.value.substr(0, vElement.value.length - 1);
                    }
                }
        }  
    
        if (cfGetByteLength(value) == length ) {
           // 완성한글 : 0xAC00 <= c && c <= 0xD7A3
           // 자음 : 0x3131 <= c
           // 모음 : c <= 0x318E
            var c = value.charCodeAt(value.length - 1);
    
            if ( (0xAC00 <= c && c <= 0xD7A3) || (0x3131 <= c && c <= 0x318E) ) {
                e.returnValue = true;
            } else {
                e.returnValue = false;
                
                if( window.event ){
                    e.returnValue = false;
                }else{
                    e.preventDefault();
                }    
            }
        } else {
            e.returnValue = true;
        }          
    }else{    //W3C
        var rtnValue = value;
        for(var idx=0; idx<value.length; idx++){
            if (cfGetByteLength(value.substr(0, idx)) >= length ) {
                rtnValue = value.substr(0, idx-1);
                break;
            }
        }
        vElement.value = rtnValue;
    
       if (vElement.onkeyup == null) {
            vElement.onkeyup =
                function() {
                    var rtnValue = vElement.value;
                    for(var idx=0; idx<vElement.value.length; idx++){
                        if (cfGetByteLength(vElement.value.substr(0, idx)) >= length ) {
                            rtnValue = vElement.value.substr(0, idx);
                            break;
                        }
                    }
                    vElement.value = rtnValue;
                }
        }
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 스트링의 자릿수를 Byte 단위로 환산하여 알려준다. 영문, 숫자는 1Byte이고 한글은 2Byte이다.(자/모 중에 하나만 있는 글자도 2Byte이다.)
 * <pre>
 *     cfGetByteLength('한글');
 * </pre>
 * 위와같이 사용했을 경우 4 를 리턴한다.
 * @sig    : value
 * @param  : value - required 스트링
 * @return : 스트링의 길이
 * @author : 차종호
 */
function cfGetByteLength(value){
    var byteLength = 0;

    if (cfIsNull(value)) {
        return 0;
    }

    var c;

    // 한글의 Byte를 계산한다. (공동이용 DB는 2Byte(ksc5601), 그 외는 3Byte(utf-8)
    var hanguleByte = cfGetHangulByte();

    for(var i = 0; i < value.length; i++) {
        c = escape(value.charAt(i));

        if (c.length == 1) {
            byteLength ++;
        } else if (c.indexOf("%u") != -1)  {
            byteLength += hanguleByte*1;
        } else if (c.indexOf("%") != -1)  {
            byteLength += c.length/3;
        }
    }

    return byteLength;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 한글의 Byte를 리턴한다. <br>
 *          - 공동이용DB는 ko16ksc5601 한글을 2Byte로 인식하고,<br>
 *          - 다른 시스템DB는 utf8 한글을 3Byte로 인식한다.)<br>
 * <pre>
 *     cfGetHangulByte();
 * </pre>
 * 위와같이 사용했을 경우 2 혹은 3을 리턴한다.
 * @sig    : void
 * @param  : void
 * @return : Byte length
 * @author : 정연주
 */
function cfGetHangulByte(){

    // 공동이용DB, 유학생 DB는 ko16ksc5601 한글을 2Byte로 인식한다.
    // 단, 유학생업무 중 포탈DB를 사용하는 부분은 제외
    if( gvContextPath == "/cop" || ( gvContextPath == "/isi" && (document.location + "").indexOf("/isi/emp") == -1 ) ){  
        return 2;
    } else {                      // 다른 시스템DB는 utf8 한글을 3Byte로 인식한다.
        return 3;
    }
}
/**
 * @type   : function
 * @access : public
 * @desc   : 입력값이 영문과 숫자인지 체크
 * <pre>
 *     cfNoHangul("123");
 * </pre>
 * 위와같이 사용했을 경우 영문과 숫자인지 체크
 * @sig    : sOrg
 * @param  : sOrg - required 체크할 문자열
 * @return : true(한글이 존재하지 않음)/false(한글이 존재함)
 * @author : 왕정일
 */
function cfNoHangul(sOrg) {
    var AlphaDigit;
    var IDLength;
    var NumberChar, CompChar;
    var ChkFlag;

    AlphaDigit= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    IDLength = sOrg.length;

    for (i = 0; i < IDLength; i++) {
        NumberChar = sOrg.charAt(i);
        ChkFlag = false;
        for (j = 0; j < AlphaDigit.length ; j++) {
            CompChar = AlphaDigit.charAt(j);
            if (NumberChar.toLowerCase() == CompChar.toLowerCase()){
                ChkFlag = true;
            }
        }
        if (ChkFlag == false) return false;
    }
    return true;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 특수 문자의 사용을 확인한다.
 * <pre>
 *     cfNoSpecialChar("123*")
 * </pre>
 * 위와같이 사용했을 경우 특수문자가 존재하는지 확인한다.
 * 체크하는 특수문자 : '<>!@#$%^&*"
 * @sig    : sOrg
 * @param  : sOrg - required 체크할 문자열
 * @return : true(특수문자가 존재하지 않음)/false(특수문자가 존재함)
 * @author : 왕정일
 */
function cfNoSpecialChar(sOrg) {
    var AlphaDigit;
    var IDLength;
    var NumberChar, CompChar;
    var ChkFlag;

    AlphaDigit= "'<>!@#$%^&*" + '"';

    IDLength = sOrg.length;

    for (i = 0; i < IDLength; i++) {
        NumberChar = sOrg.charAt(i);
        ChkFlag = true;
        for (j = 0; j < AlphaDigit.length ; j++) {
            CompChar = AlphaDigit.charAt(j);
            if (NumberChar.toLowerCase() == CompChar.toLowerCase()){
                ChkFlag = false;
            }
        }
        if (ChkFlag == false) return false;
    }
    return true;
}


/**
 * @type   : function
 * @access : public
 * @desc   : 지정된 textbox에 입력한 자리수 이상으로 입력을 하면 다음 obj로 포커스를 이동한다.
 * <pre>
 *     cfAutotab(obj1, 6, obj2);"
 * </pre>
 * @sig    : obj1, len, obj2
 * @param  : obj1 - required 길이 체크를 할 obj
 * @param  : len  - required 길이
 * @param  : obj2 - required 포커싱 될 obj
 * @return : void
 * @author : 서진영
 */
function cfAutotab ( obj1,len, obj2 ){
    if(eval(obj1).value.length >= len ){
      eval(obj2 ).focus() ;
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 서버에 있는 file을 다운로드 한다.
 * <pre>
 *    spec 은 laf.xml에 정해진 값에 따라 가져온다. 실제 파일의 서버 경로는 spec으로 가져온 값과  filename 으로 결정된다.
 *
 *    cfDownLoadFile(spec, dir, filename, downloadfilename )
 * </pre>
 * @sig    : spec, dir, filename, downloadfilename
 * @param  : spec - required 업무 구분 , (pt,ptmngt,promotion,cop)
 * @param  : dir  - required 파일이 위치한 하위 폴더
 * @param  : filename  - required 다운 받을 파일 이름
 * @param  : downloadfilename - required 다운로드 창이 뜰때 보여질 파일의 이름
 * @return : void
 * @author : 왕정일
 */
function cfDownLoadFile(spec, dir, filename, downloadfilename ){

    var vInFrame = '<iframe name="fileFrame" id="fileFrame" style="display:none; position:absolute; left:0; top:0; width:0; height:0" FrameBorder="0">' +
                   '</iframe>';

    var vAction = gvContextPath + '/DownFront';

    var vFormText = '<form name="fileForm"  id="fileForm" method="post" action="'+vAction+'" target="fileFrame">'
                  + '<input type="hidden" name="spec">'
                  + '<input type="hidden" name="dir">'
                  + '<input type="hidden" name="filename">'
                  + '<input type="hidden" name="downloadfilename">'
                  + '</form>';

    // page에 다운로드를 위한 iframe 이 존재하지 않으면 새로 만든다.
    if (document.getElementById('fileFrame') == null ) {

        if( document.all ){   //IE
	
	        for (var i = 0; i < document.all.length; i++) {
	            if (document.all[i].tagName == "BODY") {
	                document.all[i].insertAdjacentHTML("beforeEnd", vInFrame);
	                break;
	            }
	        }
	    } else {              //W3C
	        var parentObj = document.getElementsByTagName("BODY");
	
	        var objFrame = document.createElement("iframe"); 
	        objFrame.setAttribute("id","fileFrame"); 
	        objFrame.setAttribute("name","fileFrame"); 
	        objFrame.setAttribute("style", "display:none; position:absolute; left:0; top:0; width:0; height:0"); 
	        objFrame.setAttribute("FrameBorder", "0"); 
	        parentObj[0].appendChild(objFrame);
	    
	    }
    }

    // page에 다운로드를 위한 form 이 존재 하지 않으면 새로 만든다.
    if (document.getElementById('fileForm') == null ) {
        if( document.all ){   //IE
	        for (var i = 0; i < document.all.length; i++) {
	            if (document.all[i].tagName == "BODY") {
	                document.all[i].insertAdjacentHTML("beforeEnd", vFormText);
	                break;
	            }
	        }
	    } else {               //W3C
	        var parentObj = document.getElementById("fileFrame");
	
	        var objForm = document.createElement("Form");
	        objForm.setAttribute("id", "fileForm"); 
	        objForm.setAttribute("name", "fileForm"); 
	        objForm.setAttribute("target", "fileFrame"); 
	        objForm.setAttribute("action", vAction); 
	        objForm.setAttribute("method", "post"); 
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "spec"); 
	        oElement.setAttribute("value", "1"); 
	        objForm.appendChild( oElement );
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "dir"); 
	        oElement.setAttribute("value", ""); 
	        objForm.appendChild( oElement );
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "filename"); 
	        oElement.setAttribute("value", ""); 
	        objForm.appendChild( oElement );
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "downloadfilename"); 
	        oElement.setAttribute("value", ""); 
	        objForm.appendChild( oElement );
	
	        parentObj.appendChild(objForm);	    
	    }
    } 

    document.fileForm.action = vAction;
    document.fileForm.spec.value = spec;
    document.fileForm.dir.value = dir;
    document.fileForm.filename.value = filename;
    document.fileForm.downloadfilename.value = downloadfilename;

    document.fileForm.submit();
}






/**
 * @type   : function
 * @access : public
 * @desc   : 서버에서 현재시간을 읽어와서 자바스크립트의 Date 오브젝트로 변환한다.
 *           Date 오브젝트로부터 스트링 형태로 날짜 혹은 시간을 얻으려면 Date.format() 메소드를 참조할 것.
 * @return : Date 오브젝트
 * @author : 임재현
 */
function cfGetCurrentDate() {
    var dataSet;
    var dateString;

    if (document.all("coCurrentDateGDS") == null) {
        dataSet = document.createElement("<OBJECT>");
        dataSet.classid = "CLSID:3267EA0D-B5D8-11D2-A4F9-00608CEBEE49";
        dataSet.id = "coCurrentDateGDS";
        dataSet.SyncLoad = "true";
        dataSet.DataId = gvContextPath + "/GetCurrentDateR.pcg";
        // </head> 태그 직전에 DataSet 삽입
        for (var i = 0; i < document.all.length; i++) {
            if (document.all[i].tagName == "HEAD") {
                document.all[i].insertAdjacentElement("beforeEnd", dataSet);
                break;
            }
        }
    } else {
        dataSet = document.all("coCurrentDateGDS");
    }

    dataSet.Reset();
    dateString = dataSet.NameValue(1, "dateString");
    dataSet.clearData();

    if (cfIsNull(dateString)) {
        return null;
    }

    return new Date(dateString.substr(0, 4),
                    Number(dateString.substr(4, 2)) -1,
                    dateString.substr(6, 2),
                    dateString.substr(8, 2),
                    dateString.substr(10, 2),
                    dateString.substr(12, 2)
                   )
}


/**
 * @type   : function
 * @access : public
 * @desc   : emedit나 text box에 현재 날짜를 setting한다.
 * @sig    : objArray ,Format
 * @param  : textbox,Emeidt 형태의 object Array
 * @param  : 날짜 포맷
 * <pre>
 *    cfSetCurrentDate(['oStartDate','oEndDate'],'YYYYMMDD')
 * </pre>
 * @return : String
 * @author : 왕정일
 */
function cfSetCurrentDate(objArray, format){

    var vCurDate = cfGetCurrentDate().format(format);

    if (objArray.length != null) {

        for ( i=0; i < objArray.length ; i++) {

            if ( cfGetElementType(eval(objArray[i])) == 'TEXT' || cfGetElementType(eval(objArray[i])) == 'HIDDEN') {
                eval(objArray[i]).value = vCurDate;
            } else if (cfGetElementType(objArray[i]) == 'GE') {
                eval(objArray[i]).Text = vCurDate;
            }
        }
    } else {

        if ( cfGetElementType(eval(objArray)) == 'TEXT' || cfGetElementType(eval(objArray)) == 'HIDDEN') {
            eval(objArray).value = vCurDate;
        } else if (cfGetElementType(eval(objArray)) == 'GE') {
            eval(objArray).Text = vCurDate;
        }
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 배치작업이 시작됨을 알려주는 서브창을 띄우고, 배치작업을 실제로 실행할 페이지를 실행시킨다. 이 때, 배치작업을 실제로 실행할
 *           페이지는 가시화면 영역 밖에 띄워지고 또한 페이지로 넘겨줄 데이터가 있으면 파라미터로 넘겨주되, 데이터가 여러개이면
 *            하나의 object로 만들어서 넘겨주면 된다.
 * <pre>
 *     예)
 *         var paramObj = new Object();
 *         paramObj.a = param1;
 *         paramObj.b = param2;
 *         cfNotifyBatchJobStart(url, paramObj);
 * </pre>
 * @sig    : url, paramObj
 * @param  : url - required 배치작업을 실제로 실행할 페이지의 url
 * @param  : paramObj 배치작업을 실제로 실행할 페이지에 전달할 오브젝트
 * @author : 임재현
 */
function cfNotifyBatchJobStart(url, paramObj) {
    window.open("/comtask/notify_batchJob_start.html", "notifyBatchWindow", "left=0,top=0,height=100,width=300,status=no,toolbar=no,menubar=no,location=no,scrollbars=no");
    //IE에서만 제공되는 함수임(수정해야 함)
    window.showModelessDialog(url, paramObj, "dialogLeft:3000; dialogHeight:0; dialogWidth:0px; dialogHeight:0px; help:no; status:no; scroll:no")
}

/**
 * @type   : function
 * @access : public
 * @desc   : 배치작업을 실제로 실행한 페이지를 닫고 배치작업이 시작됨을 알려주었던 서브창에 배치작업이 끝났다는 메시지를 띄운다.
 * @author : 임재현
 */
function cfNotifyBatchJobEnd() {
    window.close();
    window.open("/comtask/notify_batchjob_end.html", "notifyBatchWindow", "left=0,top=0,height=100,width=300,status=no,toolbar=no,menubar=no,location=no,scrollbars=no");
}


/**
 * @type   : function
 * @access : public
 * @desc   : Loading 화면을 화면에 띠운다.
 * @sig    : iFrameId, posx, posy
 * @param  : iFrameID
 * @param  : x 위치
 * @param  : y 위치
 * <pre>
 *    cfStartLoading('LowerFrame')
 * </pre>
 * @return : void
 * @author : 왕정일
 */
function cfStartLoading(iFrameId, posx, posy ) {

    var x;
    var y;

    if (posx == null && posx == null) {

        x = document.body.clientWidth/2 + document.body.scrollLeft - 145;
        y = document.body.clientHeight/2 + document.body.scrollTop - 44;

    } else {

        x = posx;
        y = posy;
    }

    document.getElementById(iFrameId).style.posLeft=x;
    document.getElementById(iFrameId).style.posTop=y;

    //해당 DataSet은 반드시 SyncLoad가 false여야한다.

    document.getElementById(iFrameId).style.display = "";
}

/**
 * @type   : function
 * @access : public
 * @desc   : Loading 화면을 없앤다.
 * @sig    : iFrameId
 * @param  : iFrameID
 * <pre>
 *    cfEndLoading('LowerFrame')
 * </pre>
 * @return : void
 * @author : 왕정일
 */
function cfEndLoading(iFrameId) {
if(iFrameId)
    document.getElementById(iFrameId).style.display = "none";
}

/**
 * @type   : function
 * @access : public
 * @desc   : body 태그 끝에 iframe 을 등록한다.
 * @sig    : iFrameID
 * @param  : iFrameID
 * <pre>
 *    cfSetLoadFrame('LowerFrame')
 * </pre>
 * @return : void
 * @author : 왕정일
 */
function cfSetLoadFrame(iFrameId) {

    var vFrameId;

    if(iFrameId !=null) {
        vFrameId = iFrameId;
    } else vFrameId = 'LowerFrame';

    if(document.all(vFrameId)!=null) return;    //정훈규 추가, fncOnload()를 두번 이상 호출할 경우가 있음..

    var vInFrame = '<iframe id="'+vFrameId+ '" style="display:none; position:absolute; left:600px; top:800px; width:333px; height:133px" FrameBorder="0" src="/images/loading.gif">' +
                   '</iframe>';

    for (var i = 0; i < document.all.length; i++) {
        if (document.all[i].tagName == "BODY") {
            document.all[i].insertAdjacentHTML("beforeEnd", vInFrame);
            break;
        }
    }

}

/**
 * @type   : function
 * @access : public
 * @desc   : 텍스트 박스에 날짜입력을 위해 달력을 오픈하는 팝업<br>
 *			  통일성을 위해 "onclick" 이벤트 발생시 호출하도록 한다.<br>
 * @sig    : obj, event, inputName
 * @param  : event - onclick
 * @param  : obj - 이벤트를 호출하는 오브젝트
 * @param  : event - 이벤트
 * @param  : inputName - 값을 넘겨받을 텍스트박스명 문자열
 * <pre>
 *    cfOpenCalendar(this,event,inputName)
 * </pre>
 * @return : void
 * @author : 한현주
 */  	
function cfOpenCalendar(obj, event, inputName)
{
	var sURL = null;
	var vArguments = new Object();
	var sFeature = null;

	var dlg_width  = 200;
	var dlg_height = 200;

	//화면의 위치
	var innerX,innerY;
	if (self.innerWidth) { // IE 기반
		innerX = self.screen.left;
		innerY = self.screen.top;
	}
	else if (document.documentElement && document.documentElement.clientTop) { // Explorer 6 Strict 
		innerX = document.documentElement.clientLeft;
		innerY = document.documentElement.clientTop;
	}
	else if (document.body) { // 기타 나머지
		innerX = document.body.clientLeft;
		innerY = document.body.clientTop;
	}

	//스크롤 된 사이즈
	var scrollX,scrollY;
	if (self.pageYOffset) { //  IE 기반
		scrollX = self.pageXOffset;
		scrollY = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop) {	// Explorer 6 Strict
		scrollX = document.documentElement.scrollLeft;
		scrollY = document.documentElement.scrollTop;
	}
	else if (document.body) { // 기타 나머지
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
	}
	var dlg_left   = cfGetRealOffsetLeft(obj) + (event.screenX - event.clientX) + innerX - scrollX;
	var dlg_top    = cfGetRealOffsetTop(obj)  + (event.screenY - event.clientY) + innerY - scrollY + obj.offsetHeight;

	if (dlg_left + dlg_width > screen.availWidth) {
		dlg_left = screen.availWidth - dlg_width;
	}
	if (dlg_top + dlg_height > screen.availHeight) {
		dlg_top = dlg_top - dlg_height - obj.offsetHeight;
	}
	if (dlg_top < 0) dlg_top = 0;

	sURL = gvContextPath + "/common/comtask/calendar.jsp?inputName="+inputName;
	vArguments = new Object();
	vArguments.control = obj;
	sFeature = "toolbar=no,location=no,directories=no,status=no,scrollbars=no,menubar=no,width="+dlg_width+", height="+dlg_height+", left="+dlg_left+", top="+dlg_top;
	window.open(sURL, 'cal' , sFeature);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 스크린의 RealOffsetTop 가져오기<br>
 *			 달력팝업의 위치를 계산하기 위해 사용
 * @sig    : obj
 * @param  : obj - 이벤트를 호출하는 오브젝트
 * <pre>
 *    GetRealOffsetTop(obj)
 * </pre>
 * @return : void
 * @author : 한현주
 */  
function cfGetRealOffsetTop(obj)
{
	return (obj ? obj.offsetTop + cfGetRealOffsetTop(obj.offsetParent) : 0);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 스크린의 RealOffsetLeft 가져오기<br>
 *			 달력팝업의 위치를 계산하기 위해 사용 
 * @sig    : obj
 * @param  : obj - 이벤트를 호출하는 오브젝트
 * <pre>
 *    GetRealOffsetLeft(obj)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfGetRealOffsetLeft(obj)
{
	return (obj ? obj.offsetLeft + cfGetRealOffsetLeft(obj.offsetParent) : 0);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>
 * @sig    : comboNm
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : cdGrpSeq - 가져올 콤보박스의 코드키값
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * @param  : lang - 보여줄 언어명
 * <pre>
 *    cfCodeComboChg(comboNm, cdGrpSeq, selectedCode, initKey, initText, lang)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfCodeComboChg(comboNm, cdGrpSeq, selectedCode, initKey, initText, lang) {
	
	var frameName = "codeFrame" + new Date().valueOf();
	var style = "display:none; position:absolute; left:0; top:0; width:0; height:0";
	var url = "";
	if(location.protocol == "https:")	url = "https://"+location.host;
	url += gvContextPath + "/common/comtask/comboChgHidden.jsp?"
	     + "comboNm=" + comboNm 
         + "&cdGrpSeq=" + cdGrpSeq 
         + "&selectedCode=" + selectedCode 
         + "&initKey=" + initKey
         + "&initText=" + initText
         + "&lang=" + lang;

    if( document.all ){   //IE	
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
		document.body.insertBefore(codeFrame);
		codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

		var iframe = document.getElementById(frameName);
    	iframe.src = url;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>
 * @sig    : column
 * @param  : column - 정렬할 컬럼명
 * @param  : order - 정렬순서
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * <pre>
 *    cfGrpCodeComboChg(column, order, comboNm, selectedCode, initKey, initText)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfGrpCodeComboChg(column, order, comboNm, selectedCode, initKey, initText) {
	
	var frameName = "codeFrame" + new Date().valueOf();
	var style = "display:none; position:absolute; left:0; top:0; width:0; height:0";
	
	var url = "";
	if(location.protocol == "https:")	url = "https://"+location.host;
	url += gvContextPath + "/common/comtask/grpCodeComboHidden.jsp?"
		+ "&column=" + column 
		+ "&order=" + order 
	    + "&comboNm=" + comboNm             
        + "&selectedCode=" + selectedCode 
        + "&initKey=" + initKey
        + "&initText=" + initText;

    if( document.all ){   //IE	
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
		document.body.insertBefore(codeFrame);
		codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

		var iframe = document.getElementById(frameName);
    	iframe.src = url;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 지정 체크박스를 모두 체크한다.<br>
 * @sig    : chk_obj
 * @param  : chk_obj - 이벤트가 일어나는 오브젝트
 * @param  : obj_name - 체크, 언체크할 체크박스 이름 
 * <pre>
 *    cfAllCheck(chk_obj, obj_name)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfAllCheck(chk_obj, obj_name){

	var obj = document.getElementsByName(obj_name);
	
	for(var i=0; i < obj.length; i++ ){
		
		if(!obj[i].disabled){
			if(chk_obj.checked){
				obj[i].checked = true;
			}else{
				obj[i].checked = false;
			}
		}
	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 체크된 엘리먼트의 갯수를 가져온다.<br>(라디오버튼, 체크박스만 해당)
 * @sig    : obj_name
 * @param  : obj_name - 체크를 확인할 체크박스, 라디오버튼 이름
 * <pre>
 *    cfGetCheckCnt(obj_name)
 * </pre>
 * @return : int cnt
 * @author : 한현주
 */ 
function cfGetCheckCnt(obj_name){

	var obj = document.getElementsByName(obj_name);
	var cnt = 0;
	for(var i=0; i < obj.length; i++ ){		
		if(obj[i].checked){
			cnt++;
		}
	}
	return cnt;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 우편번호 조회을 위한 팝업<br>
 * @sig    : inputName1, inputName2, inputName3
 * @param  : inputName1 - 우편번호를 받을 오브젝트명
 * @param  : inputName2 - 기본주소를 받을 오브젝트명
 * @param  : inputName3 - 상세주소를 받을 오브젝트명
 * <pre>
 *    cfOpenPostNumList(inputName1, inputName2, inputName3)
 * </pre>
 * @return : void
 * @author : 한현주
 */  	
function cfOpenPostNumList(inputName1, inputName2, inputName3){

	var sWidth  = 480;
	var sHeight = 430;
	var sURL = gvContextPath + "/common/comtask/PstNumListPopupR.jsp?inputName1="+inputName1+"&inputName2="+inputName2+"&inputName3="+inputName3;
	var sName = "PostNum";
	cfOpen(sWidth, sHeight, '5', sURL, sName);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 생년월일 콤보박스에서 선택 년,월에 따른 일자를 계산한다.<br>('년'콤보박스, '월'콤보박스에 적용)
 * @sig    : yearObjNm, monthObjNm, dateObjNm, initKey, initText, selectedCode
 * @param  : yearObjNm - 선택 '년도' 오브젝트명
 * @param  : monthObjNm - 선택  '월' 오브젝트명
 * @param  : dateObjNm - 세팅할 '일' 오브젝트명
 * @param  : initKey - '일' 오브젝트의 default Key값
 * @param  : initText - '일' 오브젝트의 default Text값
 * @param  : selectedCode - '일' 오브젝트의 선택값
 * <pre>
 *    cfChgBirthDate(yearObjNm, monthObjNm, dateObjNm, initKey, initText, selectedCode)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfChgBirthDate(yearObjNm, monthObjNm, dateObjNm, initKey, initText, selectedCode){

	var dateObj = document.getElementById(dateObjNm);
	var month = document.getElementById(monthObjNm).value;
	var year = document.getElementById(yearObjNm).value;

	// 콤보 Data 삭제
	var selectCnt = dateObj.length;
	for(var i=0; i < selectCnt; i++) dateObj.remove(0);	
	
	//초기데이터 세팅
	if((initKey != null && initKey != '') && (initText != null && initText != '')){
		var option = document.createElement("OPTION");
		if( document.all ){   //IE			
			option.value = initKey;
			option.text  = initText;
			dateObj.add(option);
		} else {              //W3C	
	    	option.setAttribute("value", initKey); 
			option.text = initText;
	    	dateObj.appendChild(option);
		}
	}

	// 신규 Data Add
	var date = 31;
	if(month == '04' || month == '06' || month == '09' || month == '11')	date = 30;
	else if(month == '02'){
		if(parseInt(year)%4 == 0)	date = 29;
		else date = 28;
	}
	
	for(var i=1; i<=date; i++){
		var option = document.createElement("OPTION");
		var j = i;
		if(i<10)	j = '0'+i;
		if( document.all ){   //IE			
			option.value = j;
			option.text  = j;
			if(j == selectedCode)	option.selected = true;
			dateObj.add(option);
		} else {              //W3C	
    		option.setAttribute("value", j); 
			option.text = j;
			if(j == selectedCode)	option.setAttribute('selected', true);
    		dateObj.appendChild(option);
		}	
	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 리포트를 프린트하는 함수 
 * <pre>
 * cfPrintReport( "Rexpert1.rex", "/prototype/ReportTest.nav?aaa=1&bbb=2", "userId=aaa:pgmId=bbb^33:44", "1", "report" );
 * </pre>
 *
 * @sig    : reportNm, url, param, paperTy, windowNm
 * @param  : reportNm - 리포트 파일명(rexfile 루트 하위 경로 포함)
 * @param  : url - XML DataSet을 형성하는 action url, 서버에 전달하고자 하는 파라미터도 함께 넘긴다.
 * @param  : param - 리포트에 전달할 파라미터, userId=aaa:pgmId=bbb^33:44형태
 * @param  : paperTy - 출력형태( 1:세로, 2:가로 ) 디폴트는 세로
 * @param  : windowNm - 출력할 윈도우명  디폴트는 "report"
 * @return : void
 * @author : 정연주 
 */  	
function cfPrintReport( reportNm, url, param, paperTy, windowNm, zoomSize ){

    var vPaperTy = "1";
    var width  = "700";
    var height = "1000";
    var vWindowNm = "report";
    var vZoomSize = "80";

    if ( !cfIsNull(paperTy) ) {
        vPaperTy = paperTy;
    }

    if ( paperTy == "2" ) {
        vPaperTy = "2";
        width   = "900";
        height  = "712";		//80%비율에서 가장 이상적임
    } else {
        vPaperTy = "1";
        width   = "656";		//80%비율에서 가장 이상적임
        height  = "760";
    }

    if ( !cfIsNull( windowNm ) ){
        vWindowNm = windowNm;
    }

    if ( !cfIsNull( zoomSize ) ){
        vZoomSize = zoomSize;
    }
   
    var vInFrame = '<iframe name="reportFrame" id="reportFrame" style="display:none; position:absolute; left:0; top:0; width:0; height:0" FrameBorder="0">' +
                   '</iframe>';

    var vAction = gvContextPath + '/common/comtask/RexViewer.jsp';
    
    var targetWindow = cfOpen( width, height, 5, vAction, vWindowNm );

    var vFormText = '<form name="reportForm"  id="reportForm" method="post" action="'+vAction+'" target="' + targetWindow.name + '">'
                  + '<input type="hidden" name="pRptNames">'
                  + '<input type="hidden" name="pRptParams">'
                  + '<input type="hidden" name="pUrl">'
                  + '<input type="hidden" name="pZoomSize">'
                  + '</form>';

    // page에 리포트출력를 위한 iframe 이 존재하지 않으면 새로 만든다.
    if (document.getElementById('reportFrame') == null ) {

        if( document.all ){   //IE
	
	        for (var i = 0; i < document.all.length; i++) {
	            if (document.all[i].tagName == "BODY") {
	                document.all[i].insertAdjacentHTML("beforeEnd", vInFrame);
	                break;
	            }
	        }
	    } else {              //W3C
	        var parentObj = document.getElementsByTagName("BODY");
	
	        var objFrame = document.createElement("iframe"); 
	        objFrame.setAttribute("id","reportFrame"); 
	        objFrame.setAttribute("name","reportFrame"); 
	        objFrame.setAttribute("style", "display:none; position:absolute; left:0; top:0; width:0; height:0"); 
	        objFrame.setAttribute("FrameBorder", "0"); 
	        parentObj[0].appendChild(objFrame);
	    
	    }
    }

    // page에 리포트출력를 위한 form 이 존재 하지 않으면 새로 만든다.
    if (document.getElementById('reportForm') == null ) {
        if( document.all ){   //IE
	        for (var i = 0; i < document.all.length; i++) {
	            if (document.all[i].tagName == "BODY") {
	                document.all[i].insertAdjacentHTML("beforeEnd", vFormText);
	                break;
	            }
	        }
	    } else {               //W3C
	        var parentObj = document.getElementById("reportFrame");
	
	        var objForm = document.createElement("Form");
	        objForm.setAttribute("id", "reportForm"); 
	        objForm.setAttribute("name", "reportForm"); 
	        objForm.setAttribute("target", "reportFrame"); 
	        objForm.setAttribute("action", vAction); 
	        objForm.setAttribute("method", "post"); 
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "pRptNames"); 
	        oElement.setAttribute("value", "1"); 
	        objForm.appendChild( oElement );
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "pRptParams"); 
	        oElement.setAttribute("value", ""); 
	        objForm.appendChild( oElement );
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "pUrl"); 
	        oElement.setAttribute("value", ""); 
	        objForm.appendChild( oElement );

	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "pZoomSize"); 
	        oElement.setAttribute("value", ""); 
	        objForm.appendChild( oElement );
	        
	        parentObj.appendChild(objForm);	    
	    }
    } 

    document.reportForm.action = vAction;
    document.reportForm.pRptNames.value = reportNm;
    document.reportForm.pUrl.value = url;
    document.reportForm.pRptParams.value = param;
    document.reportForm.pZoomSize.value = vZoomSize;

    document.reportForm.submit();
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오직 숫자만 입력가능하게 만드는 펑션.<br>(onkeypress 이벤트에 호출한다)
 * @sig    : e
 * @param  : e - 이벤트
 * <pre>
 *    onkeypress="cfInputNumRT(event);"
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInputNumRT(e){

	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    }
  
    if(e.type == "keypress"){
	    if( !((48 <= lkeycode && lkeycode <=57) || lkeycode == 13 || lkeycode == 8 || lkeycode == 0) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }     
    }else{
	    if( !((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 13 || lkeycode == 8 || lkeycode == 46 || lkeycode == 229) ){						
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != ""){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			}
	    }  
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오직 숫자와 '-'만 입력가능하게 만드는 펑션.<br>(onkeypress 이벤트에 호출한다)
 * @sig    : e
 * @param  : e - 이벤트
 * <pre>
 *    onkeypress="cfInputNumMinusRT(event);"
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInputNumMinusRT(e){

	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    } 
    
    if(e.type == "keypress"){
	    if( !((48 <= lkeycode && lkeycode <=57) || lkeycode == 45 || lkeycode == 13 || lkeycode == 8 || lkeycode == 0) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }      
    }else{
	    if( !((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 109 || lkeycode == 13 || lkeycode == 8 || lkeycode == 46 || lkeycode == 229) ){
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != ""){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			}	
	    }    
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 숫자, -, <-, -> 만 입력가능하다.<br>(onkeypress 이벤트에 호출한다)
 * @sig    : e
 * @param  : e - 이벤트
 * <pre>
 *    onkeypress="cfInputNumDashRT(event);"
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInputNumDashRT(e) {

	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    } 
    
    if(e.type == "keypress"){
	    if( !((48 <= lkeycode && lkeycode <=57) || lkeycode == 60 || lkeycode == 62 || lkeycode == 45 || lkeycode == 13 || lkeycode == 8 || lkeycode == 0) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }      
    }else{
	    if( !((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 109 || lkeycode == 16 || lkeycode == 45 || lkeycode == 13 || lkeycode == 8 || lkeycode == 46 || lkeycode == 229) ){
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != ""){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			}	
	    }    
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오직 숫자와 dot(.)만 입력가능하게 만드는 펑션.<br>(onkeypress 이벤트에 호출한다)
 * @sig    : e
 * @param  : e - 이벤트
 * <pre>
 *    onkeypress="cfInputNumDotRT(event);"
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInputNumDotRT(e){

	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    }
    
    if(e.type == "keypress"){
	    if (!((48 <= lkeycode && lkeycode <=57) || lkeycode == 46 || lkeycode == 13 || lkeycode == 8  || lkeycode == 0 ) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }     
    }else{
	    if (!((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 190 || lkeycode == 13 || lkeycode == 8  || lkeycode == 46 || lkeycode == 229) ){
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != ""){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			}  	
	    }    
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오직 숫자와 dot(.), -만 입력가능하게 만드는 펑션.<br>(onkeypress 이벤트에 호출한다)
 * @sig    : e
 * @param  : e - 이벤트
 * <pre>
 *    onkeypress="cfInputNumDotMinusRT(event);"
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInputNumDotMinusRT(e){

	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    }
    
    if(e.type == "keypress"){
	    if (!((48 <= lkeycode && lkeycode <=57) || lkeycode == 46 || lkeycode == 45 || lkeycode == 13 || lkeycode == 8  || lkeycode == 0 ) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }     
    }else{
	    if (!((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 190 || lkeycode == 109 || lkeycode == 13 || lkeycode == 8  || lkeycode == 46 || lkeycode == 229 ) ){
			var eVal = e.srcElement.value;
			if(eVal.length > 0) e.srcElement.value = eVal.substring(0, eVal.length-1);   	
	    }    
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오직 숫자와  '~'만 입력가능하게 만드는 펑션.<br>(onkeypress 이벤트에 호출한다)
 * @sig    : e
 * @param  : e - 이벤트
 * <pre>
 *    onkeypress="cfInputNum4TelRT(event);"
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInputNum4TelRT(e){

	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    }
	
	if(e.type == "keypress"){
	    if (!((48 <= lkeycode && lkeycode <=57) || lkeycode == 126 || lkeycode == 13 || lkeycode == 8  || lkeycode == 0 ) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }	
	}else{
	    if (!((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 192 || lkeycode == 13 || lkeycode == 8  || lkeycode == 46 || lkeycode == 229 ) ){
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != ""){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			} 	
	    }
	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime으로 사용자가 숫자를 입력하는순간 원하는 포맷을 중간에 바로 추가<br>
 *           "jumin":주민(법인)번호, "postno":우편번호, "resno":사업자번호, "cuno":기업체번호, "date":날짜, "dateYM":날짜_년월, "time":시간_시분초 , "timeHM":시간_시분
 * @sig    : obj, gubun, e
 * @param  : obj - 해당 오브젝트
 * @param  : gubun - dash 삽입패턴 구분자 문자열
 * @param  : e - 이벤트
 * <pre>
 *    onkeyup="cfSetFormatRT(this,'date',event);"
 * </pre>
 * @return : 지정한 포맷이 들어간 문자열
 * @author : 한현주
 */ 
function cfSetFormatRT(obj, gubun, e){
	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    }

	if(e.type == "keypress"){
	    if( !((48 <= lkeycode && lkeycode <=57) || lkeycode == 13 || lkeycode == 8 || lkeycode == 0) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	} 
	    }else{
			var pos = cfGetCaretPosition(obj);
			var cntSep = cfGetSep(obj, pos);
		
			if(gubun == "date" || gubun == "dateYM"){
				cfSetDot(obj, gubun);			
			}else if(gubun == "time" || gubun == "timeHM"){
				cfSetColon(obj, gubun);
			}else{
				cfSetDash(obj, gubun);
			}	
			if(pos != -1) cfSetCaretToPos(obj, pos + (cfGetSep(obj,pos) - cntSep));
	    }          
    }else{
	    if( !((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || lkeycode == 13 || lkeycode == 8 || lkeycode == 46 || lkeycode == 229) ){
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != ""){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			}  	
	    }else{
			var pos = cfGetCaretPosition(obj);
			var cntSep = cfGetSep(obj, pos);
		
			if(gubun == "date" || gubun == "dateYM"){
				cfSetDot(obj, gubun);			
			}else if(gubun == "time" || gubun == "timeHM"){
				cfSetColon(obj, gubun);
			}else{
				cfSetDash(obj, gubun);
			}				
			if(pos != -1) cfSetCaretToPos(obj, pos + (cfGetSep(obj,pos) - cntSep));
	    }     
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 사용자가 원하는 포맷을 중간에 추가한 문자열 리턴하는 함수<br>
 *           "jumin":주민(법인)번호, "postno":우편번호, "resno":사업자번호, "cuno":기업체번호
 * @sig    : obj, gubun
 * @param  : obj - 해당 오브젝트
 * @param  : gubun - dash 삽입패턴 구분자 문자열
 * <pre>
 *    cfSetDash(this,'jumin');
 * </pre>
 * @return : dash가 추가된 문자열
 * @author : 한현주
 */ 
function cfSetDash(obj, gubun) {
	obj.value = cfSetDashStr(obj.value, gubun);
}

/**
 * @type   : function
 * @access : public
 * @desc   :  RealTime이 아닌경우에 대해 dash를 중간에 추가한 문자열을 리턴<br>
 *           "jumin":주민(법인)번호, "postno":우편번호, "resno":사업자번호, "cuno":기업체번호
 * @sig    : str, gubun
 * @param  : str - 포맷을 넣을 문자열
 * @param  : gubun - dash 삽입패턴 구분자 문자열
 * <pre>
 *    cfSetDashStr('7711111234567','jumin');
 * </pre>
 * @return : dash가 추가된 문자열
 * @author : 한현주
 */ 
function cfSetDashStr(str, gubun) {

	var data = str;
	var data_1 = cfGetNumberOnly(data);	// "-" 제거
	var retStr = str;
		
	// 주민(법인)번호 6자-7자 형태로 중간에 dash 삽입
	if (gubun == "jumin") {
		if (data.length > 14) {
			retStr = data_1.substring(0,6) + "-" + data_1.substring(6,13);
		} else if (data.length > 6) {
			if(data.substring(6,7) == "-") return str;
			else retStr = data_1.substring(0,6) + "-" + data_1.substring(6);
		}

	// 우편번호 3자-3자 형태로 중간에 dash 삽입
	} else if (gubun == "postno") {
		if (data.length > 7) {
			retStr = data_1.substring(0,3) + "-" + data_1.substring(3,6);
		} else if (data.length > 3) {
			if(data.substring(3,4) == "-") return str;
			else retStr = data_1.substring(0,3) + "-" + data_1.substring(3);
		}	

	// 사업자번호 3자-2자-5자 형태로 중간에 dash 삽입
	} else if (gubun == "resno") {
		if (data.length > 12) {
			retStr = data_1.substring(0,3) + "-" + data_1.substring(3,5) + "-" + data_1.substring(5,10);
		} else if (data.length > 6) {
			if(data.substring(3,4)=="-" && data.substring(6,7)=="-") return str;
			else retStr = data_1.substring(0,3) + "-" + data_1.substring(3,5) + "-" + data_1.substring(5,10);
		}else if (data.length > 3) {		
			if(data.substring(3,4)=="-") return str;
			else retStr = data_1.substring(0,3) + "-" + data_1.substring(3);
		}

	// 기업체번호 2자-3자-4자 형태로 중간에 dash 삽입 (
	} else if (gubun == "cuno") {
		if (data_1.length >= 9) {
			retStr = data_1.substring(0,2) + "-" + data_1.substring(2,5) + "-" + data_1.substring(5,9);
		} else if (data_1.length == 8) {
			retStr = data_1.substring(0,1) + "-" + data_1.substring(1,4) + "-" + data_1.substring(4,8);
		} else if (data_1.length == 7) {
			retStr = data_1.substring(0,3) + "-" + data_1.substring(3);
		} else if (data_1.length == 6) {
			retStr = data_1.substring(0,2) + "-" + data_1.substring(2);
		} else if (data_1.length == 5) {
			retStr = data_1.substring(0,1) + "-" + data_1.substring(1);
		} else if (data_1.length <= 4) {
			retStr = data_1;
		}
	} 
	return retStr;
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime이 아닌경우에 대해 dot를 중간에 추가해준다<br>
 *           "date":날짜, "dateYM":날짜_년월
 * @sig    : obj, gubun
 * @param  : obj - 해당 오브젝트
 * @param  : gubun - dot 삽입패턴 구분자 문자열
 * <pre>
 *    cfSetDot(this,'date');
 * </pre>
 * @return : dot가 추가된 문자열
 * @author : 한현주
 */ 
function cfSetDot(obj, gubun) {
	obj.value = cfSetDotStr(obj.value, gubun);
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime이 아닌경우에 대해 dot를 중간에 추가해준다<br>
 *           "date":날짜, "dateYM":날짜_년월
 * @sig    : str, gubun
 * @param  : str - dot를 추가할 문자열
 * @param  : gubun - dot 삽입패턴 구분자 문자열
 * <pre>
 *    cfSetDot('20061222','date');
 * </pre>
 * @return : dot가 추가된 문자열
 * @author : 한현주
 */ 
function cfSetDotStr(str, gubun) {
	if(cfIsNull(str) ) return "";
	
	var retStr = str;	//리턴할 문자열
	var data = str;
	var data_1 = cfGetNumberOnly(data);	// "." 제거

	// 날짜 4자-2자-2자 형태로 중간에 dash 삽입
	if (gubun == "date") {
		if (data.length > 10) {
			retStr = data_1.substring(0,4) + "." + data_1.substring(4,6) + "." + data_1.substring(6,8);
		} else if (data.length > 7) {
			if(data.substring(4,5)=="." && data.substring(7,8)==".") return str;
			else retStr = data_1.substring(0,4) + "." + data_1.substring(4,6) + "." + data_1.substring(6,8);
		}else if (data.length > 4) {		
			if(data.substring(4,5)==".") return str;
			else retStr = data_1.substring(0,4) + "." + data_1.substring(4);
		}
		
	// 날짜년월 4자-2자 형태로 중간에 dash 삽입
	} else if (gubun == "dateYM") {
		if (data.length > 7) {
			retStr = data_1.substring(0,4) + "." + data_1.substring(4,6);
		} else if (data.length > 4) {
			if(data.substring(4,5) == ".") return str;
			else retStr = data_1.substring(0,4) + "." + data_1.substring(4);
		}	
	}
	return retStr;
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime이 아닌경우에 대해 콜론을 중간에 추가해준다<br>
 *           "time":시간_시분초, "timeHM":시간_시분
 * @sig    : obj, gubun
 * @param  : obj - 해당 오브젝트
 * @param  : gubun - colon 삽입패턴 구분자 문자열
 * <pre>
 *    cfSetColon(this,'time');
 * </pre>
 * @return : 콜론이 추가된 문자열
 * @author : 한현주
 */ 
function cfSetColon(obj, gubun) {
	obj.value = cfSetColonStr(obj.value, gubun);
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime이 아닌경우에 대해 콜론을 중간에 추가해준다<br>
 *           "time":시간_시분초, "timeHM":시간_시분
 * @sig    : str, gubun
 * @param  : str - dot를 추가할 문자열
 * @param  : gubun - colon 삽입패턴 구분자 문자열
 * <pre>
 *    cfSetColonStr('130101','time');
 * </pre>
 * @return : colon이 추가된 문자열
 * @author : 한현주
 */ 
function cfSetColonStr(str, gubun) {
	if(cfIsNull(str) ) return "";
	
	var retStr = str;	//리턴할 문자열
	var data = str;
	var data_1 = cfGetNumberOnly(data);	// "." 제거

	// 시간 2자-2자-2자 형태로 중간에 dash 삽입
	if (gubun == "time") {
		if (data.length > 8) {
			retStr = data_1.substring(0,2) + ":" + data_1.substring(2,4) + ":" + data_1.substring(4,6);
		} else if (data.length > 5) {
			if(data.substring(2,3)==":" && data.substring(5,6)==":") return str;
			else retStr = data_1.substring(0,2) + ":" + data_1.substring(2,4) + ":" + data_1.substring(4,6);
		}else if (data.length > 2) {		
			if(data.substring(2,3)==":") return str;
			else retStr = data_1.substring(0,2) + ":" + data_1.substring(2);
		}
		
	// 날짜년월 4자-2자 형태로 중간에 dash 삽입
	} else if (gubun == "timeHM") {
		if (data.length > 5) {
			retStr = data_1.substring(0,2) + ":" + data_1.substring(2,4);
		} else if (data.length > 2) {		
			if(data.substring(2,3)==":") return str;
			else retStr = data_1.substring(0,2) + ":" + data_1.substring(2);
		}
	}
	return retStr;
}
/**
 * @type   : function
 * @access : public
 * @desc   : input 필드 객체(obj)에 금액 입력시, 실시간으로 3자리 마다 ,를 삽입<br>
 *           onkeyup에 이벤트 발생시 펑션을 호출한다
 * @sig    : obj,e
 * @param  : obj - 해당 오브젝트
 * @param  : e - 이벤트
 * <pre>
 *    cfSetCommaRT(this, event);
 * </pre>
 * @return : 콤마가 추가된 문자열
 * @author : 한현주
 */ 
function cfSetCommaRT(obj,e){
    
    if(window.event){  //IE
        e = window.event
        var lkeycode = e.keyCode; 
    } else{              //W3C
        var lkeycode = e.which; 
    } 

	var str = obj.value;
	var rtVal;
	
	if(e.type == "keyup"){
		if( lkeycode == 37 || lkeycode == 39 ) return;
	}
	
	rtVal = cfSetMoneyComma(str);
	
	if(rtVal != str)
		obj.value = rtVal;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 금액 문자열(str)에 3자리마다 콤마추가한 문자열을 리턴
 * @sig    : str
 * @param  : str - 콤마 추가할 문자열
 * <pre>
 *    cfSetMoneyComma('2006122');
 * </pre>
 * @return : 콤마가 추가된 문자열
 * @author : 한현주
 */ 
function cfSetMoneyComma(str){

	//값이 null 이나 0 이면 blank
	if(cfIsNull(str) ) return "";
	
	var rtStr;	// 리턴할 문자열

	//첫자가 -일때 -를 뺀금액으로 처리하고 나중에 -붙임
	var minus = "";
	if(str.substring(0,1) == "-"){ 
		rtStr = str.substring(1);		// '-' 뺀 문자 저장
		minus = "-";
	}else										// 그외의 모든 경우
		rtStr = str;
	
	//소수점 있을때 앞부분만 rtStr에 넣어처리하고 뒷부분은 따로 떼 두었다가 나중에 붙임.
	var belowzero = "";
	if (cfChkDot(rtStr)==true){
		arr = rtStr.split(".");
		rtStr = arr[0];		     	 //소수점 앞부분
		belowzero = "." + arr[1];    //소수점과 그 뒷부분
	}
	
	// 기존콤마제거
	rtStr = cfGetNumberOnly(rtStr);  

	var len = rtStr.length ;
	var result ="";

	if (len > 1 && str.substring(0,1)=="0") rtStr = rtStr.substring(1); // 첫번째 0이 있으면 제거
	
	for (var i=0; i < len;i++){  // 이제 실제로 콤마 표시함
		comma="";
		var schar = rtStr.charAt(i);
		where = len - 1 - i;
		if ((where % 3) == 0 && len > 3 && where != 0) comma = ",";		
		result = result +   schar + comma ;
	}
    rtStr = minus + result + belowzero;	// - 와 소수점 이하를 붙임
    
	return rtStr;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 금액에 소수점 있는지 체크. 존재한다면 true, 없다면 false
 * @sig    : str
 * @param  : str - 체크할 문자열
 * <pre>
 *    cfChkDot('20061222.122');
 * </pre>
 * @return : boolean
 * @author : 한현주
 */ 
function cfChkDot(str){
	for (var i=0; i< str.length; i++) {
		if(str.charAt(i) == "." )	return true;
	}
	return false;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력텍스트 박스에 영문만 입력.
 * <pre>
 *     onkeypress="cfAlpaOnly(event);"
 * </pre>
 * 위와같이 사용했을 경우 영문과 숫자만 입력.
 * @sig    : e
 * @param  : e - required 이벤트 
 * @return : void
 * @author : 한현주
 */
function cfAlpaOnly(e) {

    if(window.event){  //IE
        e = window.event
        var lkeycode = e.keyCode; 
    } else{              //W3C
        var lkeycode = e.which; 
    } 

    var bAlpaNumber = true;

    if(e.type == "keypress"){
	    if (!((65 <= lkeycode && lkeycode <= 90) || (97 <= lkeycode && lkeycode <= 122) || lkeycode == 13 || lkeycode == 8 || lkeycode == 0 )){  
	        bAlpaNumber = false;
	    }
    }else{
	    if (!((65 <= lkeycode && lkeycode <= 90) || lkeycode == 13 || lkeycode == 8 || lkeycode == 46 || lkeycode == 229 )){
	        bAlpaNumber = false;
	    }    
    }
    
    if( !bAlpaNumber ){
        if( window.event ){
            e.keyCode = 0;
        }else{
            e.preventDefault();
        }
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력값이 영문&숫자인지 체크
 * <pre>
 *     cfChkAlpa_Number("123abc");
 * </pre>
 * 위와같이 사용했을 경우 영문과 숫자인지 체크
 * @sig    : sOrg
 * @param  : sOrg - required 체크할 문자열
 * @return : true(영문&숫자로 이루어져있음)/false
 * @author : 한현주
 */
function cfChkAlpa_Number(sOrg) {
    var Alpha, Digit;
    var IDLength1, IDLength2;
    var EngStr, NumStr;
    var NumberChar, CompChar;
    var ChkNumFlag ,ChkAlpaFlag;
    var result = false;

    Alpha= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    Digit= "0123456789";
    
    EngStr = cfGetAlphaOnly(sOrg) ;
    NumStr = cfGetNumberOnly(sOrg) ;

    IDLength1 = EngStr.length;
    IDLength2 = NumStr.length;

    for (i = 0; i < IDLength1; i++) {
    
        NumberChar = EngStr.charAt(i);
        ChkAlpaFlag = false;               
        
        for (j = 0; j < Alpha.length ; j++) {
            CompChar = Alpha.charAt(j);
            if (NumberChar.toLowerCase() == CompChar.toLowerCase()){
                ChkAlpaFlag = true;
            }
        }      
    }

    for (i = 0; i < IDLength2; i++) {
    
        NumberChar = NumStr.charAt(i);
        ChkNumFlag = false;               
        
        for (j = 0; j < Digit.length ; j++) {
            CompChar = Digit.charAt(j);
            if (NumberChar.toLowerCase() == CompChar.toLowerCase()){
                ChkNumFlag = true;
            }
        }      
    }    
    
    if((ChkAlpaFlag == true) && (ChkNumFlag == true))
		result = true;

    return result;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력값에서 영문자만 추출하여리턴
 * <pre>
 *     cfGetAlphaOnly("123abc");
 * </pre>
 * @sig    : sOrg
 * @param  : sOrg - required 체크할 문자열
 * @return : 영문자로 이루어진 문자열
 * @author : 한현주
 */
function cfGetAlphaOnly(sOrg) {
	return sOrg.replace(/[^a-zA-Z]/g, "");
}

/**
 * @type   : function
 * @access : public
 * @desc   : 처리중 프레임을 보여준다. <br>flag 파라미터에는 true , false 값을 주어야 한다.
 * <pre>
 *     cfOpenRunning(true);
 * </pre>
 * @sig    : flag
 * @param  : flag - 처리중 여부
 * @return : void
 * @author : 한현주
 */
var _WaitLayer = null;
function cfOpenRunning(flag) {

	// FrameWait 가 존재하는지 확인해서 없으면 생성
	if (document.getElementById('waitLayer')==null && flag) {
	  	if (!flag) return;  
	  	
		var currentH = document.body.clientHeight;	// 현재 프레임의 높이(스크롤 영역 제외)

		var layerW = 780;
		if(!cfIsNull(gvContextPath) && gvContextPath == "/pt")
			layerW = 1000;
			
		var wait = "<table width='100%' height='"+currentH+"' border='0' cellpadding='0' cellspacing='0'>"
				 + "<tr><td valign='middle' align='center'><table border='0' cellspacing='0' cellpadding='0'>"
				 + "<tr><td bgcolor='#FFFFFF'><img src='/images/common/etc/loading.gif' style='border:double 4px #ccc;'></td></tr>"
				 + "</table></td>"
				 + "</tr></table>";
				 
		if( document.all ){   //IE
	        _WaitLayer = document.createElement("<div id='waitLayer' style='left:0; top:0; width:"+layerW+"px; height:"+currentH+"px; position:absolute; z-index:1; visibility:visible;'></div>");
			document.body.insertBefore(_WaitLayer);
			_WaitLayer.innerHTML = wait;		
		}else{				  //W3C
	        var parentObj = document.getElementsByTagName("BODY");
	        _WaitLayer = document.createElement("div"); 
	        _WaitLayer.setAttribute("id", "waitLayer"); 
	        _WaitLayer.setAttribute("style", "left:0; top:0; width:"+layerW+"px; height:"+currentH+"; position:absolute; z-index:1; visibility:visible;"); 
	        
	        parentObj[0].insertBefore(_WaitLayer, null);
			_WaitLayer.innerHTML = wait;	
		}
	} else {
		  if (flag) return;  
	}
	if (flag) {
		window.defaultStatus = "처리중 입니다......";
		window.status = "처리중 입니다......";
		window.document.body.style.cursor		= "wait";
	} else {	
		window.defaultStatus = "완료";
		window.status = "완료";
		window.document.body.style.cursor		= "default";	
		
		if(document.getElementById('waitLayer') != null){
			if( document.all ) {
				document.all.waitLayer.removeNode(true);
			}else{
				window.document.body.removeChild(document.getElementById('waitLayer'));
			}		
		}
	}	
}

/**
 * @type   : function
 * @access : public
 * @desc   : 아이프레임을 위한 처리중 프레임을 보여준다. <br>flag 파라미터에는 true , false 값을 주어야 한다.
 * <pre>
 *     cfOpenRunning2(true);
 * </pre>
 * @sig    : flag
 * @param  : flag - 처리중 여부
 * @return : void
 * @author : 한현주
 */
var _FrameWait = null;
function cfOpenRunning2(flag) {

	// FrameWait 가 존재하는지 확인해서 없으면 생성
	if (document.getElementById('__FrameWaitIframe__')==null && flag) {
	  	if (!flag) return;
		var currentW = 780;	// 현재 프레임의 너비(스크롤 영역 제외)
		var currentH = document.body.clientHeight;	// 현재 프레임의 높이(스크롤 영역 제외)
		var msgW = 312;		// 처리중 메시지창 너비
		var msgH = 158; 	// 처리중 메시지창 높이
		
		if ( currentW < msgW ) var leftPos = 0;
		else var leftPos = currentW/2 - msgW/2;
		
		if ( currentH < msgH ) var topPos = 0;
		else var topPos  = currentH/2 - msgH/2;
		
		var layerW = 780;
		if(!cfIsNull(gvContextPath) && gvContextPath == "/pt")
			layerW = 1000;

		var wait = "<table width='100%' height='100%' border='0'> " 
				 + "<tr align='center' valign='middle'></tr><td>" 
				 + "<IFRAME name='__FrameWaitIframe__' frameborder=0 style='position:absolute; left:"+leftPos+"px; top:"+topPos+"px; width:"+msgW+"px; height:"+msgH+"px; visibility:hidden;' src='"+gvContextPath + "/common/comtask/loading.htm' /> "
				 + "</td></tr></table> ";

		if( document.all ){   //IE
	        _FrameWait = document.createElement("<div id='FrameWait' style='position:absolute; left:0px; top:0px; width:"+layerW+"px; height:"+currentH+"px; z-index:1; visibility:hidden ;'></div>");
			document.body.insertBefore(_FrameWait);
			_FrameWait.innerHTML = wait;		
		}else{				  //W3C
	        var parentObj = document.getElementsByTagName("BODY");
	        _FrameWait = document.createElement("div"); 
	        _FrameWait.setAttribute("id", "FrameWait"); 
	        _FrameWait.setAttribute("style", "position:absolute; left:0px; top:0px; width:"+layerW+"px; height:"+currentH+"px; z-index:1; visibility:hidden;"); 
	        
	        parentObj[0].insertBefore(_FrameWait, null);
			_FrameWait.innerHTML = wait;	
		}				
	} 

	if ( flag ) {
		window.defaultStatus = "처리중 입니다......";
		window.status = "처리중 입니다......";
		window.document.body.style.cursor		= "wait";
		document.all.FrameWait.style.visibility	= "visible";
		document.all.__FrameWaitIframe__.style.visibility	= "visible";		
	} else {
		window.defaultStatus = "완료";
		window.status = "완료";
		parent.document.body.style.cursor		= "default";	

		if(parent.document.getElementById('FrameWait') != null){
			if( document.all ) {
				parent.document.all.FrameWait.removeNode(true);
			}else{
				parent.document.body.removeChild(parent.document.getElementById('FrameWait'));
			}		
		}		
	}	
}

/**
 * @type   : function
 * @access : public
 * @desc   : 부분인쇄를 한다.
 * <pre>
 *     cfPrintDiv('image1');
 * </pre>
 * @sig    : id
 * @param  : id - 부분인쇄할 div 영역의 이름
 * @return : void
 * @author : 한현주
 */
var div2print;
function cfPrintDiv (id) {

	if (document.all && window.print) {		//IE
    	div2print = document.all[id];
    	window.onbeforeprint = cfHideDivs;
    	window.onafterprint = cfShowDivs;
    	window.print();
  	}else if (document.layers) {			//NN
    	div2print = document[id];
    	cfHideDivs();
    	window.print();
  	} else{									//W3C
  		div2print = document.getElementById(id);
  		cfHideDivs();  	
    	window.print();
    	window.setTimeout(cfShowDivs, 1000, true);		//시간차를 두기 위해 Timeout사용
 //   	alert('인쇄가 완료되었습니다.\nPrinting is finished.');
 //   	cfShowDivs();
  	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 부분인쇄를 위해 부분인쇄가 아닌 영역을 감춘다.
 * <pre>
 *     cfHideDivs();
 * </pre>
 * @return : void
 * @author : 한현주
 */
function cfHideDivs () {
  	/*if (document.all) {
    	var divs = document.all.tags('DIV');
    	for (var d = 0; d < divs.length; d++)
      		if (divs[d] != div2print)
        		divs[d].style.display = 'none';
  	}else if (document.layers) {
    	for (var l = 0; l < document.layers.length; l++)
      		if (document.layers[l] != div2print)
        		document.layers[l].visibility = 'hide';
  	}else{
    	var divs = document.getElementsByTagName('DIV');
    	for (var d = 0; d < divs.length; d++)
      		if (divs[d] != div2print)
        	divs[d].style.display = 'none';  
  	}*/
	document.getElementById("popupTitle").style.display = 'none';
	document.getElementById("button_default").style.display = 'none';
}

/**
 * @type   : function
 * @access : public
 * @desc   : 부분인쇄가 끝난 후 모든 영역을 보여준다.
 * <pre>
 *     cfShowDivs();
 * </pre>
 * @return : void
 * @author : 한현주
 */
function cfShowDivs () {
	/*if (document.all) {
  		var divs = document.all.tags('DIV');
  		for (var d = 0; d < divs.length; d++)
    		divs[d].style.display = 'block';
    }else if (document.layers) {
    	for (var l = 0; l < document.layers.length; l++)
      		if (document.layers[l] != div2print)
        		document.layers[l].visibility = 'block';    
    }else{
    	var divs = document.getElementsByTagName('DIV');
    	for (var d = 0; d < divs.length; d++)
      		if (divs[d] != div2print)
        		divs[d].style.display = 'block';    
    }*/
	document.getElementById("popupTitle").style.display = 'block';
	document.getElementById("button_default").style.display = 'block';
}

/**
 * @type   : function
 * @access : public
 * @desc   : 폼객체 안의 input type='text' 엘리먼트에 있는 콤마들을 제거하고 숫자만 반환한다.
 * <pre>
 *     cfDelMoneyComma(frmObj)
 * </pre>
 * @sig    : frmObj
 * @param  : frmObj - 콤마 제거할 엘리먼트들의 폼 객체
 * @return : void
 * @author : 한현주
 */
function cfDelMoneyComma(frmObj){
	var len = frmObj.elements.length;

	for ( var i = 0; i < len; i++ ) {
		
		if ( frmObj.elements[i].type == 'text' ) {
			frmObj.elements[i].value = cfGetNumberOnly( frmObj.elements[i].value );
		}
	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 영문자를 제외한 다른문자들은 제거하고 대문자의 영문자만 반환
 * <pre>
 *     cfGetUpperCase(obj)
 * </pre>
 * @sig    : obj
 * @param  : obj - 해당객체
 * @return : void
 * @author : 한현주
 */
function cfGetUpperCase(obj) {
	
	var sOrg = obj.value;
    var AlphaDigit;
    var IDLength;
    var NumberChar, CompChar;
    var returnChar = "";

    AlphaDigit= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    IDLength = sOrg.length;

    for (i = 0; i < IDLength; i++) {
        NumberChar = sOrg.charAt(i);

        for (j = 0; j < AlphaDigit.length ; j++) {
            CompChar = AlphaDigit.charAt(j);
            if (NumberChar.toUpperCase() == CompChar.toUpperCase()){
                returnChar += NumberChar.toUpperCase();
            }
        }
    }
	obj.value = returnChar;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 실시간으로 입력되는 글자수를 제한한다.
 * <pre>
 *     obkeydown="cfByteLengthRT_Obj( event, obj, limitLen )";
 * </pre>
 * @sig    : event, obj, limitLen
 * @param  : event - 이벤트
 * @param  : obj - 해당객체
 * @param  : limitLen - 제한길이 
 * @return : void
 * @author : 한현주
 */
function cfByteLengthRT_Obj( event, obj, limitLen ){
	val = cfByteLengthRT(event, obj.value, limitLen);
	if( val.length != obj.value.length ) obj.value = val;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 실시간으로 입력되는 글자수를 계산하여 글자수 초과시 alert창 보임
 * <pre>
 *     obkeydown="cfByteLengthRT(event, str, limitLen)";
 * </pre>
 * @sig    : event, obj, limitLen
 * @param  : event - 이벤트
 * @param  : str - 체크할 문자열
 * @param  : limitLen - 제한길이 
 * @return : void
 * @author : 한현주
 */
function cfByteLengthRT(event, str, limitLen) {
	var hangulByte = cfGetHangulByte();
	var nLen = 0;
	var hFlag = 0;
	var iLen = str.length;
	var i = 0;
	var val = ""
	for (i = 0; i < iLen; i++) {
  		tmp_chr = str.charAt(i);
  		if (tmp_chr > "~") {
  	 		if(hFlag == 0) {
  	 			nLen = nLen + 1;
  	 		}
//     		nLen = nLen + 2;
			nLen = nLen + hangulByte;
     		hFlag = 1;
     		if (i == iLen) {
     			nLen = nLen + 1;
     		}
  		} else {
  			if (hFlag == 1) nLen = nLen + 1;
			hFlag = 0;
   			nLen = nLen + 1;
		}
  		if( nLen < limitLen ) val += tmp_chr;
	}
	if (hFlag == 1) nLen = nLen + 1;


    if(window.event){    //IE
        event = window.event
    }

	if( event.keyCode ==  8 || event.keyCode == 46 || event.keyCode == 45 || event.keyCode == 91 ||
		event.keyCode ==  9 || event.keyCode == 13 || event.keyCode == 16 || event.keyCode == 17 ||
		event.keyCode == 18 || event.keyCode == 92 || event.keyCode == 93 || event.keyCode == 116||
		(112 <= event.keyCode && event.keyCode <= 123 ) ||(33 <= event.keyCode && event.keyCode <= 40 ) ||
		event.keyCode == 27 			
	){
		return str;
	}

	if (nLen == limitLen) {
		alert("더 이상 입력하실 수 없습니다.\n입력하실 수 있는 최대 문자열 길이가 이미 입력 되셨습니다.");
	}
	else if (nLen > limitLen) {
		alert("입력하실 수 있는 최대 문자열 길이를 초과하셨습니다.\n 최대 입력가능 문자열 길이 => " + limitLen + "\n 입력하신 문자열 길이 => " + nLen);
	}
	return val;
}

/**
 * @type   : function
 * @access : public
 * @desc   : window.open으로 서브창을 띄울 때 서브창의 위치를 간단하게 지정할 수 있다.
 * @sig    : width, height, left, top, [sURL] [, sName] [, sFeatures] [, bReplace]
 * @param  : width     - 서브창의 넓이
 * @param  : height    - 서브창의 높이
 * @param  : left      - 서브창의 왼쪽좌표
 * @param  : top       - 서브창의 위쪽좌표
 * @param  : sURL      - required window.open의 sURL 파라미터와 동일
 * @param  : sName     - required window.open의 sName 파라미터와 동일
 * @param  : sFeatures - required window.open의 sFeatures 파라미터와 동일
 * @param  : bReplace  - required window.open의 bReplace 파라미터와 동일
 * @author : 임재현
 */
function cfOpen2(sWidth, sHeight, sLeft, sTop, sURL, sName, sFeatures, bReplace) {
	
	var left = sLeft;
	var top = sTop;
    
    var featureNames  = ["status", "menubar", "toolbar"];
    var featureValues = ["no", "no", "no"];
    var featureTypes  = ["boolean", "boolean", "boolean"];

    if (sFeatures != null) {
        cfParseOpenFeature(sFeatures, featureNames, featureValues, featureTypes);
    }

    var status = featureValues[0];
    var menubar = featureValues[1];
    var toolbar = featureValues[2];

    if (sWidth != null && sHeight != null) {
        width = sWidth*1 + 10; // window의 좌우 border 5px씩 감안.
        height = sHeight*1 + 29; // titlebar는 기본으로 감안.

        if (menubar) {
            height = height + 48;
            //IE인 경우 menubar가 yes이면 height가 20px 늘어난다.
            if( document.all ) {
                height = height - 20;
                sHeight = sHeight - 20;
            }  
        }

        if (toolbar) {
            height = height + 27;
        }

        if (status) {
            height = height + 20;
        }
        
        //IE의 height 보정
        if( document.all ){
            sHeight = sHeight - 3.5;
        }

        if (cfIsNull(sFeatures)) {
            sFeatures = "width=" +sWidth+ ",height=" +sHeight + ",left=" + left + ",top=" + top;
        } else {
            sFeatures = sFeatures +",width=" +sWidth+ ",height=" +sHeight + ",left=" + left + ",top=" + top;
        }
    }

    return window.open(sURL, sName, sFeatures, bReplace);
}

/**
 * @type   : function
 * @access : public
 * @desc   : INPUT TEXT에 영문 입력시 대문자로 변환(한글,숫자,영문 모두 입력 가능)
 * <pre>
 *    onkeypress=cfUpperCase2(this, event)
 * </pre>
 * @sig    : obj, e
 * @param  : obj - 해당 오브젝트
 * @param  : e - required 이벤트 
 * @return : void
 * @author : 한현주
 */
function cfUpperCase2(obj, e){
	
    if(window.event){  //IE
        e = window.event
        var lkeycode = e.keyCode; 
    } else{              //W3C
        var lkeycode = e.which; 
    } 
	
	if(lkeycode >= 97 && lkeycode <= 122){	//소문자일때

		if(window.event){  //IE
			e.keyCode = lkeycode - 32; 		//대문자; 
		} else{              //W3C
			e.preventDefault();			
			obj.value = obj.value + String.fromCharCode(lkeycode).toUpperCase();
		} 
	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스를 초기화한다.<br>
 			 동적으로 콤보박스 변경시 사용한다.
 * @sig    : comboNm, initKey, initText
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * <pre>
 *    cfInitCombo(comboNm, initKey, initText)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfInitCombo(comboNm, initKey, initText){
	// 초기화될 콤보
	var selectObj = document.getElementById(comboNm);

	// 콤보 Data 삭제
	var selectCnt = selectObj.length;
	for(var i=0; i < selectCnt; i++) selectObj.remove(0);	
	
	if(initKey != null && initKey != ""){
		// 신규 Data Add
		var option = document.createElement("OPTION");
	
		if( document.all ){   //IE			
			option.value = initKey;
			option.text  = initText;
			selectObj.add(option);
		} else {              //W3C	
		    option.setAttribute("value", initKey); 
			option.text = initText;
		    selectObj.appendChild(option);
		}
	}
}

/**
 * @type   : function
 * @access : public
 * @desc   : 이메일을 발송한다.
 * <pre>
 * cfSendEmail( "35", "aaa@test.com", "userName=테스트&id=test");
 * </pre>
 *
 * @sig    : no, email, param
 * @param  : no - 메일 번호
 * @param  : email - 메일받을 이메일주소
 * @param  : param - 메일에 전달할 파라미터, userName=테스트&id=test 형태
 * @return : void
 * @author : 한현주 
 */  	
function cfSendEmail( no, email, param ){

    var vInFrame = '<iframe name="mailFrame" id="mailFrame" style="display:none; position:absolute; left:0; top:0; width:0; height:0" FrameBorder="0">' +
                   '</iframe>';

    var vAction = 'http://sl.goeun.net/smartlist.html?menu=send&no='+no+'&mail_from=admin@g4f.go.kr&mail_to='+email;
    if(param != null && param != ""){
    	vAction = vAction + "&"+ param;
    }
    
    // page에 메일발송을 위한 iframe 이 존재하지 않으면 새로 만든다.
    if (document.getElementById('mailFrame') == null ) {

        if( document.all ){   //IE
	
	        for (var i = 0; i < document.all.length; i++) {
	            if (document.all[i].tagName == "BODY") {
	                document.all[i].insertAdjacentHTML("beforeEnd", vInFrame);
	                break;
	            }
	        }
	        
	    } else {              //W3C
	        var parentObj = document.getElementsByTagName("BODY");
	
	        var objFrame = document.createElement("iframe"); 
	        objFrame.setAttribute("id","mailFrame"); 
	        objFrame.setAttribute("name","mailFrame"); 
	        objFrame.setAttribute("style", "display:inline; position:absolute; left:0; top:0; width:200; height:100"); 
	        objFrame.setAttribute("FrameBorder", "0"); 
	        parentObj[0].appendChild(objFrame);	    
	    }
    }
    if( document.all ){   //IE
    	mailFrame.location.href = vAction+"&isIE=Y";
    }else{
   		mailFrame.location.href = vAction+"&isIE=N";
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>(포탈, 포탈관리)
 * @sig    : comboNm
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : cdGrpSeq - 가져올 콤보박스의 코드키값
 * @param  : cd - 가져올 콤보박스의 코드값
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * @param  : lang - 보여줄 언어명
 * <pre>
 *    cfCodeComboChg4Bbs(comboNm, cdGrpSeq, cd, selectedCode, initKey, initText, lang)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfCodeComboChg4Bbs(comboNm, cdGrpSeq, cd, selectedCode, initKey, initText, lang) {
	
	var frameName = "codeFrame" + new Date().valueOf();
	var style = "display:none; position:absolute; left:0; top:0; width:0; height:0";
	var url = "";
	if(location.protocol == "https:")	url = "https://"+location.host;
	url += gvContextPath + "/common/comtask/comboChgHidden4Bbs.jsp?"
		+ "comboNm=" + comboNm 
		+ "&cdGrpSeq=" + cdGrpSeq 
		+ "&cd=" + cd 
		+ "&selectedCode=" + selectedCode 
		+ "&initKey=" + initKey
		+ "&initText=" + initText
		+ "&lang=" + lang;

    if( document.all ){   //IE	
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
		document.body.insertBefore(codeFrame);
		codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

		var iframe = document.getElementById(frameName);
    	iframe.src = url;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 부분인쇄를 위해 팝업창을 띄운다.
 * <pre>
 *    cfPartPrint(divId, lang)
 * </pre> 
 * @sig    : divId, lang
 * @param  : divId - required 부분인쇄를 할 부분의 div id 값
 * @param  : lang - 보여줄 언어(KR:한글, EN:영어)
 * @return : void
 * @author : 한현주
 */ 
function cfPartPrint(divId, lang){
	var obj = document.getElementById(divId);
	var langCd = "KR";
	if(!cfIsNull(lang))		langCd = lang;

    var vAction = gvContextPath + "/common/comtask/InfoPrint.jsp";
	var targetWindow = cfOpen("700", "650", "5", vAction, "print", "status=0,menubar=0,toolbar=0,scrollbars=0");
    var vFormText = '<form name="printForm" id="printForm" method="post" action="'+vAction+'" target="' + targetWindow.name + '">'
                  + '<input type="hidden" name="content">'
                  + '<input type="hidden" name="lang">'
                  + '</form>';
	if (document.getElementById('printForm') == null ) {
		if( document.all ){   //IE
	        for (var i = 0; i < document.all.length; i++) {
	            if (document.all[i].tagName == "BODY") {
	                document.all[i].insertAdjacentHTML("beforeEnd", vFormText);
	                break;
	            }
	        }
	    } else {               //W3C	
	        var objForm = document.createElement("Form");
	        objForm.setAttribute("id", "printForm"); 
	        objForm.setAttribute("name", "printForm"); 
	        objForm.setAttribute("target", targetWindow.name); 
	        objForm.setAttribute("action", vAction); 
	        objForm.setAttribute("method", "post"); 
	
	        var oElement = document.createElement("input");
	        oElement.setAttribute("type", "hidden"); 
	        oElement.setAttribute("name", "content"); 
	        objForm.appendChild( oElement );
	        
	        var oElement2 = document.createElement("input");
	        oElement2.setAttribute("type", "hidden"); 
	        oElement2.setAttribute("name", "lang"); 
	        objForm.appendChild( oElement2 );

	        document.body.appendChild(objForm);	    
	    }
	}
    document.printForm.content.value = obj.innerHTML;
    document.printForm.lang.value = langCd;
    document.printForm.submit();
}

/**
 * @type   : function
 * @access : public
 * @desc   : input 필드 객체(obj)의 값이 순수한 영문자("A"-"Z", or "a"-"z") 인지 체크
 * <pre>
 * cfIsAlphaOnly("alsdkfjalsdkj");
 * </pre>
 * @sig    : value
 * @param  : value - 체크할 문자열
 * @return : boolean (true or false)
 * @author : 한현주 
 */ 
function cfIsAlphaOnly(value) {

	if(value == null || value == "") return false;
	
	var isValid = true;
  	for (var i = 0; i < value.length; i++) {
		if (!(  ((value.charAt(i) >= 'a') && (value.charAt(i) <= 'z')) ||	((value.charAt(i) >= 'A') && (value.charAt(i) <= 'Z')) ||  (value.charAt(i) == ' ')) ){
         	isValid = false;
			break;
     	}
   }
	return isValid;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>(포탈관리)
 * @sig    : lang, pGvrnCd, isAll, comboNm, selectedCode, initKey, initText
 * @param  : lang - 보여줄 언어(EN, KR)
 * @param  : pGvrnCd - 상위기관 코드
 * @param  : isAll - 상위기관에 해당하는 하위기관을 모두 가져올지 여부 (Y,N)
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * <pre>
 *    cfCodeComboChg4Gvrn(lang, pGvrnCd, isAll, comboNm, selectedCode, initKey, initText)
 * </pre>
 * @return : void
 * @author : 한현주
 */ 
function cfCodeComboChg4Gvrn(lang, pGvrnCd, isAll, comboNm, selectedCode, initKey, initText) {
	
	var frameName = "codeFrame" + new Date().valueOf();
	var style = "display:none; position:absolute; left:0; top:0; width:0; height:0";
	var url = "";
	if(location.protocol == "https:")	url = "https://"+location.host;
	url += gvContextPath + "/common/comtask/comboChgHidden4Gvrn.jsp?"
		+ "lang=" + lang 
        + "&pGvrnCd=" + pGvrnCd 
        + "&isAll=" + isAll 	
	    + "&comboNm=" + comboNm 
        + "&selectedCode=" + selectedCode 
        + "&initKey=" + initKey
        + "&initText=" + initText;

    if( document.all ){   //IE	
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
		document.body.insertBefore(codeFrame);
		codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

		var iframe = document.getElementById(frameName);
    	iframe.src = url;
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>(포탈관리)
 * @sig    : lang, pPartyCd,  comboNm, selectedCode, initKey, initText
 * @param  : lang - 보여줄 언어(EN, KR)
 * @param  : pPartyCd - 상위계열 코드
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * <pre>
 *    cfCodeComboChg4Party(lang, pPartyCd, comboNm, selectedCode, initKey, initText)
 * </pre>
 * @return : void
 * @author : 노태완
 */ 
function cfCodeComboChg4Party(lang, pPartyCd, comboNm, selectedCode, initKey, initText) {
   
	var frameName = "codeFrame" + new Date().valueOf();
	var style = "display:none; position:absolute; left:0; top:0; width:100; height:100";
	var url = "";
	if(location.protocol == "https:")	url = "https://"+location.host;
	url += contextPath + "/common/comtask/comboChgHidden4Party.jsp?"
		+ "lang=" + lang 
        + "&pPartyCd=" + pPartyCd         
	    + "&comboNm=" + comboNm 
        + "&selectedCode=" + selectedCode 
        + "&initKey=" + initKey
        + "&initText=" + initText;

    if( document.all ){   //IE	
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
		document.body.insertBefore(codeFrame);
		codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

		var iframe = document.getElementById(frameName);
    	iframe.src = url;
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : 입력값에서 영문과 숫자만 추출하여리턴
 * <pre>
 *     cfGetAlphaNumberOnly("ㅇㄹ123abc");
 * </pre>
 * @sig    : sOrg
 * @param  : sOrg - required 체크할 문자열
 * @return : 영문과 숫자로 이루어진 문자열
 * @author : 한현주
 */
function cfGetAlphaNumberOnly(sOrg) {
	return sOrg.replace(/[^a-zA-Z0-9]/g, "");
}

/**
 * @type   : function
 * @access : public
 * @desc   : 기관 조회을 위한 팝업(포탈관리)<br>
 * @sig    : inputName1, inputName2
 * @param  : inputName1 - 기관코드를 받을 오브젝트명
 * @param  : inputName2 - 기관명을 받을 오브젝트명
 * <pre>
 *    cfOpenGvrnCdList(inputName1, inputName2)
 * </pre>
 * @return : void
 * @author : 한현주
 */  	
function cfOpenGvrnCdList(inputName1, inputName2, inputedCode){

	var sWidth  = 370;
	var sHeight = 400;
	var sURL = gvContextPath + "/common/comtask/GvrnCdListPopupR.jsp?inputName1="+inputName1+"&inputName2="+inputName2+"&inputedCode="+inputedCode;
	var sName = "GvrnList";
	cfOpen(sWidth, sHeight, '5', sURL, sName);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 파일 사이즈 체크(IE에서 정상동작, FireFox에서는 config 수정해야 정상동작)<br>
 * @sig    : filePath
 * @param  : filePath - 파일경로
 * <pre>
 *    getFileSize(filePath)
 * </pre>
 * @return : 파일사이즈
 * @author : 한현주
 */  
function getFileSize(filePath) {
	var len = 0;

	if ( navigator.appName.indexOf("Netscape") != -1) {
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
		} catch(e) {
			alert("signed.applets.codebase_principal_support를 설정해주십시오.\n"+e);
			return -1;
		}
		try {
			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			file.initWithPath ( filePath );
			len = file.fileSize;
		} catch(e) {
			alert("에러 발생:"+e);
		}
	} else if (navigator.appName.indexOf('Microsoft') != -1) {
	    //IE 7.0에서는 dynsrc 속성을 지원하지 않는다.
        if(navigator.userAgent.indexOf('MSIE') > 0 && navigator.appVersion.indexOf('MSIE 7.') > 0){
        }
        //IE 8.0에서는 dynsrc 속성을 지원하지 않는다.
        else if(navigator.userAgent.indexOf('MSIE') > 0 && navigator.appVersion.indexOf('MSIE 8.') > 0){
        }else{
    		var img = new Image();
    		img.dynsrc = filePath;
    		len = img.fileSize;
        }
	}
	return len;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 원하는 소수점 자리까지 반올림<br>
 * @sig    : str, len
 * @param  : str - 반올림할 숫자
 * @param  : len - 원하는 소수점 자리 
 * <pre>
 *    cfMakeNumberRound(str, len)
 * </pre>
 * @return : 반올림된 숫자
 * @author : 한현주
 */ 
function cfMakeNumberRound(orgStr, len){
	
	var str = cfNumeric(orgStr.toString());
	
	if(cfIsNull(str)){
		str = "0";
	}

	var pos2 = 10;
	for(var i=0; i<len; i++){
		pos2 *= 10;
	}

	var rtnVal = Math.round(str*pos2)/pos2;
	return rtnVal;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 지정한 수만큼 소수점 아래로 0을 붙이거나 소수점 이하 숫자를 절삭한다.
 * <pre>
 *     onBlur="cfFractionFormat_Obj( this, 2 );"
 * </pre>
 * @sig    : obj, pos
 * @param  : obj    - required 오브젝트
 * @param  : pos    - required 정밀도(소수점이하 자리수)
 * @return : 변환된 오브젝트 밸류
 * @author : 한현주
 */
function cfFractionFormat_Obj( obj, pos ){
	obj.value = cfFractionFormat2(obj.value, pos);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 지정한 수만큼 소수점 아래로 0을 붙이거나 소수점 이하 숫자를 절삭한다.
 * <pre>
 *     cfFractionFormat2( '-123.234234', 2 );
 *     cfFractionFormat2( '-123.2', 2 );
 * </pre>
 * @sig    : str, pos
 * @param  : str    - required 문자열
 * @param  : pos    - required 정밀도(소수점이하 자리수)
 * @return : 변환된 스트링
 * @author : 한현주
 */
function cfFractionFormat2( str, pos ){
    var numStr = str;
    var ptPos  = numStr.indexOf(".");
    var cnt    = 0;
	var rtnVal;

    if ( ptPos < 1 ){
        numStr += ".";
        cnt = pos;
    } else {
        var subLen = numStr.substr( ptPos + 1 ).length;
        if ( pos > subLen ){
            cnt = pos - subLen;
        }
    }
	
	if(cnt > 0){
	    var str0 = "";		
	    for ( var i = 0 ; i < cnt ; i ++ ){
	        str0 += "0";
	    }	
	    rtnVal = numStr + str0;
	}else{
		rtnVal = numStr.substring(0, ptPos+pos+1);
	}    
    return rtnVal;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 실시간으로 입력되는 글자수를 제한한다.
 * <pre>
 *     obkeyup="cfFractionFormatRT_Obj( obj, limitLen )";
 * </pre>
 * @sig    : event, obj, limitLen
 * @param  : event - 이벤트
 * @param  : obj - 해당객체
 * @param  : limitLen - 제한길이 
 * @return : void
 * @author : 한현주
 */
function cfFractionFormatRT_Obj(obj, limitLen ){
	val = cfFractionFormatRT(obj.value, limitLen);
	if( val.length != obj.value.length ) obj.value = val;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 실시간으로 입력되는 글자수를 계산하여 글자수 초과시 alert창 보임
 * <pre>
 *     obkeyup="cfFractionFormatRT(str, limitLen)";
 * </pre>
 * @sig    : str, limitLen
 * @param  : str - 체크할 문자열
 * @param  : limitLen - 제한길이 
 * @return : void
 * @author : 한현주
 */
function cfFractionFormatRT(str, limitLen) {
	var numStr = str;
    var ptPos  = numStr.indexOf(".");
    var rtnVal = str;

	if(ptPos >= 1){

	    var nLen = numStr.substr(ptPos+1).length;

		if (nLen > limitLen) {
			cfAlertMsg(MSG_COM_ERR_084,[limitLen]); 
			rtnVal = cfFractionFormat2( str, limitLen );
		}
	}
	return rtnVal;
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime으로 사용자가 숫자, 영문자를 입력하는순간 원하는 포맷을 중간에 바로 추가<br>
 *           "###-##-####"형태로 포맷을 지정해준다.
 * @sig    : obj, format, e
 * @param  : obj - 해당 오브젝트
 * @param  : format - fotmat Mask
 * @param  : e - 이벤트
 * <pre>
 *    onkeyup="cfSetFormatMaskRT(this,'####-##-###',event);"
 * </pre>
 * @return : 지정한 포맷이 들어간 문자열
 * @author : 한현주
 */ 
function cfSetFormatMaskRT(obj, format, e){    
	if(window.event){    //IE
       	e = window.event;
       	var lkeycode = e.keyCode;  
    }else{				//W3C
    	var lkeycode = e.which; 
    }
    
    if(e.type == "keypress"){
	    if( !((48 <= lkeycode && lkeycode <=57) || (65 <= lkeycode && lkeycode <=90) || (97 <= lkeycode && lkeycode <=122) || lkeycode == 13 || lkeycode == 8 || lkeycode == 0) ){
			if( window.event ){
	    		e.returnValue = false;
	    	}else{
	        	e.preventDefault();
	    	}    	
	    }else{
			var pos = cfGetCaretPosition(obj);
			var cntSep = cfGetSep(obj, pos);
		
			cfSetFormatMask(obj, format);
			
			if(pos != -1) cfSetCaretToPos(obj, pos + (cfGetSep(obj,pos) - cntSep));
	    }     
    }else{
	    if( !((48 <= lkeycode && lkeycode <=57) || (96 <= lkeycode && lkeycode <=105) || (65 <= lkeycode && lkeycode <=90) || lkeycode == 13 || lkeycode == 8 || lkeycode == 46 || lkeycode == 229) ){
			var charVal = String.fromCharCode(lkeycode);
			if(charVal != null && charVal != "" && !cfIsAlphaOnly(charVal)){
				var eVal = e.srcElement.value;				
				if(eVal.length > 0) e.srcElement.value = eVal = eVal.replace(charVal, "");
			} 	
	    }else{
			var pos = cfGetCaretPosition(obj);
			var cntSep = cfGetSep(obj, pos);
		
			cfSetFormatMask(obj, format);
			
			if(pos != -1) cfSetCaretToPos(obj, pos + (cfGetSep(obj,pos) - cntSep));
	    }     
    }  
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime이 아닌 경우에 대해 지정포맷을 중간에 추가해준다<br>
 *           "###-##-####"형태로 포맷을 지정해준다.
 * @sig    : obj, format
 * @param  : obj - 해당 오브젝트
 * @param  : format - fotmat Mask
 * <pre>
 *    cfSetColon(this,'time');
 * </pre>
 * @return : 지정한 포맷이 들어간 문자열
 * @author : 한현주
 */ 
function cfSetFormatMask(obj, format) {
	obj.value = cfSetFormatMaskStr(obj.value, format);
}

/**
 * @type   : function
 * @access : public
 * @desc   : RealTime이 아닌 경우에 대해 지정포맷을 중간에 추가해준다<br>
 *           "###-##-####"형태로 포맷을 지정해준다.
 * @sig    : str, format
 * @param  : str - 포맷을 적용할 문자열
 * @param  : format - fotmat Mask
 * <pre>
 *    cfSetFormatMaskStr('123120','###-###');
 * </pre>
 * @return : colon이 추가된 문자열
 * @author : 한현주
 */ 
function cfSetFormatMaskStr(str, format) {
	if(cfIsNull(str) ) return "";
		
	var strAlphaNum = cfGetAlphaNumberOnly(str);	// 적용할 문자열
    
	var strValue = format;
	
	for(var i = 0; i < strAlphaNum.length; i++) {
		strValue = strValue.replace("#", strAlphaNum.charAt(i));
	}
	
	strValue = strValue.replace(/([#]|[^0-9A-Za-z])*$/g, "");

	return strValue;                     
}

/**
 * @type   : function
 * @access : public
 * @desc   : 입력값에서 숫자와 '~'만 추출하여리턴
 * <pre>
 *     cfGetTelNumberOnly("123~123abc");
 * </pre>
 * @sig    : sOrg
 * @param  : sOrg - required 체크할 문자열
 * @return : 숫자로 이루어진 문자열
 * @author : 한현주
 */
function cfGetTelNumberOnly(sOrg) {

    var num = sOrg + "";
    var tmp = "";

    for (var i = 0; i < num.length; i ++) {
        if ( (num.charAt(i) >= 0 && num.charAt(i) <= 9) || num.charAt(i) == '~')
            tmp = tmp + num.charAt(i);
    }
    return tmp;
}

/**
 * @type   : function
 * @access : public
 * @desc   : Form, DIV, Table ,TD ,TR 등에서 text, checkBox, text area, radio, hidden, 기타XML 의 name=value식의 String을 만듬
 * <pre>
 *     cfGetParamValStr(form, [aaa,bbb],[ccc]);
 * </pre>
 * @sig    : dLayer
 * @param  : dLayer 	  - required 파라미터 스트링을 얻어올 객체
 * @param  : discardIds   - 빼고싶은 ID 배열
 * @param  : discardNames - 빼고싶은 이름 배열
 * @return : name=value로 이루어진 문자열
 * @author : 한현주
 */
function cfGetParamValStr(dLayer, discardIds, discardNames) {
	//public functions
	this.addLayer				=cfAddLayer;						// 파라미터 스트링을 얻어올 레이어를 삽입한다.
    this.getParamVal			=cfGetParamVal;						// 파라미터스트링을 얻는다.
    this.setDiscardNames		=cfSetDiscardNames;					// 빼고싶은 이름을 세팅한다.
    this.setDiscardIds			=cfSetDiscardIds;  					// 빼고싶은 ID를 세팅한다.

	//private function
	this.dataLayers				=new Array();						// 데이터 레이어 Pool
	this.dIds					=null;								// discard Id Pool
	this.dNames					=null;								// discard Name Pool
	this.dLSize					=0;									// 데이터 레이어 개수.
	this.isDiscard				=cfIsDiscard;
	this.getParamValFunction	=cfGetParamValStringFuncton;	
	
	//creator behavior
	if(dLayer!=null) 			this.addLayer(dLayer);				//생성자에 레이어가 있을때
	if(discardIds!=null) 		this.setDiscardIds(discardIds);		//생성자에 discard id가 있을때
	if(discardNames!=null) 		this.setDiscardNames(discardNames);	//생성자에 discardName이 있을때
	return  this.getParamVal();
}

/**
 * @type   : function
 * @access : public
 * @desc   : 오브젝트를 추가한다.
 * <pre>
 *     cfAddLayer(lLayer);
 * </pre>
 * @sig    : lLayer
 * @param  : lLayer - required 추가할 오브젝트
 * @author : 한현주
 */
function cfAddLayer(lLayer){
   	this.dataLayers[this.dLSize++]=lLayer;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 파라미터 스트링을 가져온다.
 * <pre>
 *     cfGetParamVal();
 * </pre>
 * @return : 파라미터 스트링
 * @author : 한현주
 */
function cfGetParamVal(){
	var qry="";
	for(var i=0;i<this.dLSize;i++){
		qry+=this.getParamValFunction(this.dataLayers[i].all);
	}
	qry=qry.substring(0,qry.length-1);  	
	return qry;
}

/**
 * @type   : function
 * @access : public
 * @desc   : 빼고싶은 name을 세팅한다.
 * <pre>
 *     cfSetDiscardNames(dNames);
 * </pre>
 * @sig    : dNames
 * @param  : dNames - required 빼고싶은 엘리먼트 name
 * @author : 한현주
 */
function cfSetDiscardNames(dNames){
	this.dNames =","+dNames+",";
}

/**
 * @type   : function
 * @access : public
 * @desc   : 빼고싶은 id를 세팅한다.
 * <pre>
 *     cfSetDiscardIds(dIds);
 * </pre>
 * @sig    : dIds
 * @param  : dIds - required 빼고싶은 엘리먼트 id 
 * @author : 한현주
 */
function cfSetDiscardIds(dIds){
	this.dIds = ","+dIds+",";
}

/**
 * @type   : function
 * @access : public
 * @desc   : 파라미터 스트링을 만든다.
 * <pre>
 *     cfGetParamValStringFuncton(objs);
 * </pre>
 * @sig    : objs
 * @param  : objs - required 파라미터 스트링을 만들 객체들
 * @return : 파라미터 스트링
 * @author : 한현주
 */
function cfGetParamValStringFuncton(objs){
	if(objs==null||objs.length==0) return null;
	var rCnt=objs.length;	// repeatCount
	var qry="";				// Query String
	for(var i=0;i<rCnt;i++){
		var obj=objs[i];
		if(obj.name !=null && obj.name!="" && !this.isDiscard(obj)){
			if(obj.tagName=="INPUT"){
				if((obj.type=="checkbox" ||obj.type=="radio")){
					if(obj.checked==true)  qry+=obj.name+"="+obj.value+"&";
				}else qry+=obj.name+"="+obj.value+"&";
			}else if(obj.tagName=="TEXTAREA"){
				qry+=obj.name+"="+obj.innerText+"&";
			}else {
				qry+=obj.name+"="+obj.value+"&";
			}
		}
	}
	return qry;
}

/**
 * @type   : function
 * @access : public
 * @desc   : DiscardList 에 속한 오브젝트인지 확인
 * <pre>
 *     cfIsDiscard(obj);
 * </pre>
 * @sig    : obj
 * @param  : obj - required 확인할 오브젝트
 * @return : DiscardList 에 있는지 여부
 * @author : 한현주
 */
function cfIsDiscard(obj){
	var rtValue=false;
	if(this.dNames!=null && obj.name!=null) 			rtValue= this.dNames.match(","+obj.name+",");
	if(!rtValue && this.dIds!=null && obj.id !=null) 	rtValue= this.dIds.match(","+obj.id+",");
	return rtValue;
}

///////////////////////////// 커서의 포커스 위치를 찾기 위한 메소드 /////////////////////////////
function cfSetSelectedTextRange(elm, selectionStart, selectionEnd) {
	if (elm.setSelectionRange) {
		elm.focus();
		elm.setSelectionRange(selectionStart, selectionEnd);
	}
	else if (elm.createTextRange) {
		var range = elm.createTextRange();

		range.collapse(true);
		range.moveEnd('character', selectionEnd);
		range.moveStart('character', selectionStart);
		range.select();
	}
}

function cfSetCaretToPos (elm, pos) {
	cfSetSelectedTextRange(elm, pos, pos);
}

function cfGetCaretPosition(elm) {
	if (typeof elm.selectionStart != "undefined")
		return elm.selectionStart;
	else if (document.selection)
		return Math.abs(document.selection.createRange().moveStart("character",-1000000));
}
	
function cfGetSep(obj, pos) {
	var cnt = 0;
	
	for(var i = 0; i < pos; i++) {
		if(/[^a-zA-Z0-9]/g.test(obj.value.charAt(i))) cnt++;
	}
	return cnt;
}
/////////////////////////////////////////////////////////////////////////////////////////

//정보마당 스크랩을 위한 윈도우창 팝업
function MM_openBrWindow(theURL,winName,features) { //v2.0
  window.open(theURL,winName,features);
}

/**
 * @type   : function
 * @access : public
 * @desc   : 처리중 프레임을 보여준다. <br>flag 파라미터에는 true , false 값을 주어야 한다.
 * <pre>
 *     cfDisableWindow(true);
 * </pre>
 * @sig    : flag
 * @param  : flag - 처리중 여부
 * @return : void
 * @author : 한현주
 */
var _DisableLayer = null;
function cfDisableWindow(flag) {

	// FrameWait 가 존재하는지 확인해서 없으면 생성
	if (document.getElementById('disableLayer')==null && flag) {
	  	if (!flag) return;  
	  	
		var currentH = document.body.clientHeight;	// 현재 프레임의 높이(스크롤 영역 제외)
		var layerW = 780;
		if(!cfIsNull(gvContextPath) && gvContextPath == "/pt")
			layerW = 1000;
			
		var wait = "<table width='100%' height='"+currentH+"' border='0' cellpadding='0' cellspacing='0'>"
				 + "<tr><td valign='middle' align='center'></td>"
				 + "</tr></table>";
				 
		if( document.all ){   //IE
	        _DisableLayer = document.createElement("<div id='disableLayer' style='left:0; top:0; width:"+layerW+"px; height:"+currentH+"px; position:absolute; z-index:1; visibility:visible;'></div>");
			document.body.insertBefore(_DisableLayer);
			_DisableLayer.innerHTML = wait;		
		}else{				  //W3C
	        var parentObj = document.getElementsByTagName("BODY");
	        _DisableLayer = document.createElement("div"); 
	        _DisableLayer.setAttribute("id", "disableLayer"); 
	        _DisableLayer.setAttribute("style", "left:0; top:0; width:"+layerW+"px; height:"+currentH+"px; position:absolute; z-index:1; visibility:visible;"); 
	        
	        parentObj[0].insertBefore(_DisableLayer, null);
			_DisableLayer.innerHTML = wait;	
		}
	} else {
		  if (flag) return;  
	}
	if (flag) {
		window.document.body.style.cursor		= "wait";
	} else {	
		window.document.body.style.cursor		= "default";	
		
		if(document.getElementById('disableLayer') != null){
			if( document.all ) {
				document.all.disableLayer.removeNode(true);
			}else{
				window.document.body.removeChild(document.getElementById('disableLayer'));
			}		
		}
	}	
}

/**
 * @type   : function
 * @access : public
 * @desc   : IP주소를 IP number로 변환
 * <pre>
 *     cfDisableWindow(10.10.10.1);
 * </pre>
 * @sig    : ipAddress
 * @param  : ipAddress - IP 주소
 * @return : void
 * @author : 류정호
 */
function cfConvertIpAddress(ipAddress){
    //IP 형식 체크
    var regExp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; 
    if(!regExp.test(ipAddress)){
        return null;
    }

    //IP주소 범위 체크
    var addressArray = ipAddress.split(".");
    var partOfAddress;
    for(var i=0; i<addressArray.length; i++){
        partOfAddress = Number(addressArray[i]);
        if(partOfAddress < 0 || partOfAddress >255){
            return null;
        }
    }

    return (Number(addressArray[0])*16777216) + (Number(addressArray[1])*65536) + (Number(addressArray[2])*256) + Number(addressArray[3]);
}



/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>(방문예약관리-접수창구)
 * @sig    : lang, pOrgnCd, comboNm, selectedCode, initKey, initText
 * @param  : lang - 보여줄 언어(EN, KR)
 * @param  : pOrgnCd - 담당기관 코드
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * <pre>
 *    cfCodeComboDeskSeq(lang, pOrgnCd, comboNm, selectedCode, initKey, initText)
 * </pre>
 * @return : void
 * @author : 박동철
 */ 
function cfCodeComboDeskSeq(lang, pOrgnCd, comboNm, selectedCode, initKey, initText) {
    
    var frameName = "codeFrame" + new Date().valueOf();
    var style = "display:none; position:absolute; left:0; top:0; width:0; height:0";
    var url = "";
    if(location.protocol == "https:")   url = "https://"+location.host;
    url += contextPath + "/common/comtask/comboChgHidden4DeskSeq.jsp?"
        + "lang=" + lang 
        + "&pOrgnCd=" + pOrgnCd 
        + "&comboNm=" + comboNm 
        + "&selectedCode=" + selectedCode 
        + "&initKey=" + initKey
        + "&initText=" + initText;

    if( document.all ){   //IE  
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
        document.body.insertBefore(codeFrame);
        codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

        var iframe = document.getElementById(frameName);
        iframe.src = url;
    }
}

/**
 * @type   : function
 * @access : public
 * @desc   : 해당콤보박스의 값을 Hidden Frame을 써서 동적으로 바꾼다.<br>(방문예약관리-운영창구)
 * @sig    : lang, pOrgnCd, comboNm, selectedCode, initKey, initText
 * @param  : lang - 보여줄 언어(EN, KR)
 * @param  : pDeskSeq - 접수창구 코드
 * @param  : pSelectDate - 선택일자
 * @param  : comboNm - 변경될 콤보박스 이름
 * @param  : selectedCode - 선택될 코드값
 * @param  : initKey - 초기 Option 키값
 * @param  : initText - 초기 Option 텍스트값
 * <pre>
 *    cfCodeComboOperDeskNo(lang, pDeskSeq, pSelectDate, comboNm, selectedCode, initKey, initText)
 * </pre>
 * @return : void
 * @author : 박동철
 */ 
function cfCodeComboOperDeskNo(lang, pDeskSeq, pSelectDate, comboNm, selectedCode, initKey, initText) {
    
    var frameName = "codeFrame" + new Date().valueOf();
    var style = "display:none; position:absolute; left:0; top:0; width:0; height:0";
    var url = "";
    if(location.protocol == "https:")   url = "https://"+location.host;
    url += contextPath + "/common/comtask/comboChgHidden4OperDeskNo.jsp?"
        + "lang=" + lang 
        + "&pDeskSeq=" + pDeskSeq 
        + "&pSelectDate=" + pSelectDate 
        + "&comboNm=" + comboNm 
        + "&selectedCode=" + selectedCode 
        + "&initKey=" + initKey
        + "&initText=" + initText;

    if( document.all ){   //IE  
        var codeFrame = document.createElement("<iframe name='" + frameName + 
                                               "' style='" + style + 
                                               "'  border='0' frameborder='0' src=''></iframe>");
        document.body.insertBefore(codeFrame);
        codeFrame.src = url;

    } else {              //W3C
        var parentObj = document.getElementsByTagName("BODY");

        var objFrame = document.createElement("iframe"); 
        objFrame.setAttribute("id", frameName); 
        objFrame.setAttribute("name", frameName); 
        objFrame.setAttribute("style", style); 
        objFrame.setAttribute("frameBorder", "0"); 
        parentObj[0].appendChild(objFrame);

        var iframe = document.getElementById(frameName);
        iframe.src = url;
    }
}


/**
 * @type   : function
 * @access : public
 * @desc   : Xecureweb을 이용한 파일업로드
 * @sig    : form, obj_name
 * @param  : form - submit form 객체
 * @param  : obj_name - file object name
 * <pre>
 *    cfXecureFileUpload(form, "addFile");
 * </pre>
 * @return : void
 * @author : 정연주
 */ 
function cfXecureFileUpload(form, obj_name){
    var action = form.action;
    form.action = gvContextPath + "/SecureUpload";
    document.charset="euc-kr";
    
    var obj = document.getElementsByName(obj_name);
    for(var idx=0; idx < obj.length; idx++ ){
        if( !cfIsNull(obj[idx].value)){
            FileUploadEx3( obj[idx].value, form, 0 );
            var oElement = document.createElement("input");
            oElement.setAttribute("type", "hidden"); 
            oElement.setAttribute("name", "XecureUploadFile"); 
            var filename = obj[idx].value;
            filename = filename.substring(filename.lastIndexOf('\\')+1);
            oElement.setAttribute("value", filename); 
            form.appendChild( oElement );
        }
    }
    
    document.charset="utf-8";
    form.action = action;
}