function FormChecker(checkForm) {
    this.checkForm = checkForm;
    this.validatorList = new Array();
}

FormChecker.prototype.checkRequired = function(fieldName, errorMessage, focus) {
    this.validatorList.push(new RequiredValidator(this.checkForm, fieldName, errorMessage, focus));
}

FormChecker.prototype.checkMaxLength = function(fieldName, maxLength, errorMessage, focus) {
    this.validatorList.push(new MaxLengthValidator(this.checkForm, fieldName, maxLength, errorMessage, focus));
}

FormChecker.prototype.checkMaxLengthByte = function(fieldName, maxLength, errorMessage, focus) {
    this.validatorList.push(new MaxLengthByteValidator(this.checkForm, fieldName, maxLength, errorMessage, focus));
}

FormChecker.prototype.checkMinLength = function(fieldName, minLength, errorMessage, focus) {
    this.validatorList.push(new MinLengthValidator(this.checkForm, fieldName, minLength, errorMessage, focus));
}

FormChecker.prototype.checkMinLengthByte = function(fieldName, minLength, errorMessage, focus) {
    this.validatorList.push(new MinLengthByteValidator(this.checkForm, fieldName, minLength, errorMessage, focus));
}

FormChecker.prototype.checkRegex = function(fieldName, regex, errorMessage, focus) {
    this.validatorList.push(
        new RegexValidator(this.checkForm, fieldName, regex, errorMessage, focus));
}

FormChecker.prototype.checkAlphaNum = function(fieldName, errorMessage, focus) {
    this.validatorList.push(
        new RegexValidator(this.checkForm, fieldName,
            /^[a-zA-Z0-9]+$/, errorMessage, focus));
}

FormChecker.prototype.checkOnlyNumber = function(fieldName, errorMessage, focus) {
    this.validatorList.push(
        new RegexValidator(this.checkForm, fieldName,
            /^[0-9]+$/, errorMessage, focus));
}

FormChecker.prototype.checkDecimal = function(fieldName, errorMessage, focus) {
    this.validatorList.push(
        new RegexValidator(this.checkForm, fieldName,
            /^(\-)?[0-9]*(\.[0-9]*)?$/, errorMessage, focus));
}

FormChecker.prototype.checkEmail = function(fieldName, errorMessage, focus) {
    this.validatorList.push(
        new RegexValidator(this.checkForm, fieldName,
            /^((\w|[\-\.])+)@((\w|[\-\.])+)\.([A-Za-z]+)$/, errorMessage, focus));
}

FormChecker.prototype.checkSelected = function(fieldName, firstIdx, errorMessage, focus) {
    this.validatorList.push(new SelectionValidator(this.checkForm, fieldName, firstIdx, errorMessage, focus));
}

FormChecker.prototype.checkAtLeastOneChecked = function(fieldName, errorMessage, focus) {
    this.validatorList.push(new AtLeastOneCheckValidator(this.checkForm, fieldName, errorMessage, focus));
}

// 2007.10.15 김경희 추가 (select option 중복값 체크를 위해)
FormChecker.prototype.checkDuplicate = function(fieldName, newFieldName, errorMessage, focus) {
    this.validatorList.push(new DuplicateCheckValidator(this.checkForm, fieldName, newFieldName, errorMessage, focus));
}

// 2007.10.15 김경희 추가 (두개의 Element 값이 같은지 체크)
FormChecker.prototype.checkElementEqualsValue = function(fieldName, newFieldName, isEquals, errorMessage, focus) {
    this.validatorList.push(new ElementEqualsCheckValidator(this.checkForm, fieldName, newFieldName, isEquals, errorMessage, focus));
}

// 2007.10.17 김경희 추가 (값 비교를 위해)
FormChecker.prototype.compareValue = function(fieldName, fieldName2, equalOption, errorMessage, focus) {
    this.validatorList.push(new CompareCheckValidator(this.checkForm, fieldName, fieldName2, equalOption, errorMessage, focus));
}

// 2007.10.18 김경희 추가 (이미지파일 체크를 위해)
FormChecker.prototype.checkImageFile = function(fieldName, regex, errorMessage, focus) {
    this.validatorList.push(new ImageFileCheckValidator(this.checkForm, fieldName, regex, errorMessage, focus));
}

// 2007.10.19 송형기 추가 (특정 문자열에 특정 문자가 포함되었는지 검사)
FormChecker.prototype.checkContains = function(fieldName, checkContainText, errorMessage, focus) {
    this.validatorList.push(new ContainsCheckValidator(this.checkForm, fieldName, checkContainText, errorMessage, focus));
}

// 2007.10.23 김경희 추가 (Element와 value값이 같은지 체크)
FormChecker.prototype.checkEqualsValue = function(fieldName, checkValue, isEquals, errorMessage, focus) {
    this.validatorList.push(new EqualsCheckValidator(this.checkForm, fieldName, checkValue, isEquals, errorMessage, focus));
}

// 2007.10.23 민선기 추가 (주소가 http://로 시작하는지 체크)
FormChecker.prototype.checkUrl = function(fieldName, errorMessage, focus) {
    this.validatorList.push(new UrlCheckValidator(this.checkForm, fieldName,  errorMessage, focus));
}

// 2007.10.29 김경희 추가 (특수문자 체크)
FormChecker.prototype.checkSpecialChar = function(fieldName, errorMessage, focus) {
    this.validatorList.push(new SpecialCharCheckValidator(this.checkForm, fieldName,  errorMessage, focus));
}
// 2007.10.29 김경희 추가 (태그 체크)
FormChecker.prototype.checkHTMLTag = function(fieldName, errorMessage, focus) {
    this.validatorList.push(new HTMLTagCheckValidator(this.checkForm, fieldName,  errorMessage, focus));
}
FormChecker.prototype.validate = function() {
    for (vali = 0 ; vali < this.validatorList.length ; vali ++ ) {
        validator = this.validatorList[vali];
        if (validator.validate() == false) {
            alert(validator.getErrorMessage());
            if (validator.isFocus() == true) {
                this.checkForm[validator.getFieldName()].focus();
            }
            return false;
        }
    }
    return true;
}

FormChecker.prototype.getForm = function() {

    return this.checkForm;
}


// Validator is base class of all validators
function Validator() {
}

Validator.prototype.getFieldName = function() {
    return this.fieldName;
}

Validator.prototype.getErrorMessage = function() {
    return this.errorMessage;
}

Validator.prototype.isFocus = function() {
    return this.focus;
}


// required validator
function RequiredValidator(form, fieldName, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
RequiredValidator.prototype = new Validator;
RequiredValidator.prototype.validate = function() {
    // 2007.10.12 김경희 수정( trim처리를 추가)
    return (this.form[this.fieldName].value).replace(/^\s*/, "").replace(/\s*$/, "") != '';
}


// max length validator
function MaxLengthValidator(form, fieldName, maxLength, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
    this.maxLength = maxLength;
}
MaxLengthValidator.prototype = new Validator;
MaxLengthValidator.prototype.validate = function() {
    return this.form[this.fieldName].value.length <= this.maxLength;
}


// max length(byte) validator
function MaxLengthByteValidator(form, fieldName, maxLength, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
    this.maxLength = maxLength;
}
MaxLengthByteValidator.prototype = new Validator;
MaxLengthByteValidator.prototype.validate = function() {
    stringValue = this.form[this.fieldName].value;

    var nbytes = 0;

    for (i=0; i<stringValue.length; i++) {
        var ch = stringValue.charAt(i);
        if(escape(ch).length > 4) {
            nbytes += 2;
        } else if (ch == '\n') {
            if (stringValue.charAt(i-1) != '\r') {
                nbytes += 1;
            }
        } else if (ch == '<' || ch == '>') {
            nbytes += 4;
        } else {
            nbytes += 1;
        }
    }
    return nbytes <=this.maxLength;

    //return(str.length+(escape(str)+"%u").match(/%u/g).length-1) <= this.maxLength; 정확한 바이트 계산이 되지 않음
}


// min length validator
function MinLengthValidator(form, fieldName, minLength, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
    this.minLength = minLength;
}
MinLengthValidator.prototype = new Validator;
MinLengthValidator.prototype.validate = function() {
    return this.form[this.fieldName].value.length >= this.minLength;
}


// min length(byte) validator
function MinLengthByteValidator(form, fieldName, minLength, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
    this.minLength = minLength;
}
MinLengthByteValidator.prototype = new Validator;
MinLengthByteValidator.prototype.validate = function() {

    stringValue = this.form[this.fieldName].value;

    var nbytes = 0;

    for (i=0; i<stringValue.length; i++) {
        var ch = stringValue.charAt(i);
        if(escape(ch).length > 4) {
            nbytes += 2;
        } else if (ch == '\n') {
            if (stringValue.charAt(i-1) != '\r') {
                nbytes += 1;
            }
        } else if (ch == '<' || ch == '>') {
            nbytes += 4;
        } else {
            nbytes += 1;
        }
    }
    return nbytes >=this.minLength;
    //return(str.length+(escape(str)+"%u").match(/%u/g).length-1) >= this.minLength; // 정확한 바이트 계산이 되지 않음
}


// regex pattern validator
function RegexValidator(form, fieldName, regex, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.regex = regex;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
RegexValidator.prototype = new Validator;
RegexValidator.prototype.validate = function() {
    var str = this.form[this.fieldName].value;
    if (str.length == 0) return true;
    return str.search(this.regex) != -1;
}


// check selected
function SelectionValidator(form, fieldName, firstIdx, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.firstIdx = firstIdx;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
SelectionValidator.prototype = new Validator;
SelectionValidator.prototype.validate = function() {
    var idx = this.form[this.fieldName].selectedIndex;
    return idx >= this.firstIdx;
}


// check checkbox checked
function AtLeastOneCheckValidator(form, fieldName, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
AtLeastOneCheckValidator.prototype = new Validator;
AtLeastOneCheckValidator.prototype.validate = function() {
    ele = this.form[this.fieldName];
    if (typeof(ele[0]) != "undefined") {
        // 2~
        for (var idxe = 0 ; idxe < ele.length ; idxe++) {
            if (ele[idxe].checked == true) {
                return true;
            }
        }
        return false;
    } else {
        // only 1
        return ele.checked == true;
    }
}


// 2007.10.15 김경희 추가 (select option 중복값 체크를 위해)
// check duplicate name
function DuplicateCheckValidator(form, fieldName, newFieldName, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.newFieldName = newFieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
DuplicateCheckValidator.prototype = new Validator;
DuplicateCheckValidator.prototype.validate = function() {
    var optionLength = this.form[this.fieldName].options.length;

    for (var idxe = 0; idxe < optionLength; idxe++)  {
         if( this.form[this.fieldName].options[idxe].text == this.form[this.newFieldName].value) {
            return false;
            break;
         }
    }
    return true;

}


// 2007.10.15 김경희 추가 (두 값이 값은지 비교)
function ElementEqualsCheckValidator(form, fieldName, newFieldName, isEquals, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.newFieldName = newFieldName;
    this.isEquals = isEquals;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
ElementEqualsCheckValidator.prototype = new Validator;
ElementEqualsCheckValidator.prototype.validate = function() {

    var elementType = this.form[this.fieldName].type;

    if (this.isEquals) {
        if (elementType == 'select-one') return this.form[this.fieldName].value != this.form[this.newFieldName].options[this.form[this.newFieldName].selectedIndex].value;
        else  return this.form[this.fieldName].value != this.form[this.newFieldName].value;;
    }

    else {

        if (elementType == 'select-one') return this.form[this.fieldName].value == this.form[this.newFieldName].options[this.form[this.newFieldName].selectedIndex].value;
        else return this.form[this.fieldName].value == this.form[this.newFieldName].value;

    }
}

// 2007.10.17 김경희 추가 (두 값 비교)
function CompareCheckValidator(form, fieldName, fieldName2, equalOption, errorMessage,  focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.fieldName2 = fieldName2;
    this.equalOption = equalOption;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
CompareCheckValidator.prototype = new Validator;
CompareCheckValidator.prototype.validate = function() {

    if (this.equalOption) return (Number(this.form[this.fieldName].value) >= Number(this.form[this.fieldName2].value));
    else return (Number(this.form[this.fieldName].value) > Number(this.form[this.fieldName2].value));
}


// 2007.10.18 김경희 추가 (이미지 파일 체크)
function ImageFileCheckValidator(form, fieldName, regex, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.regex = regex;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
ImageFileCheckValidator.prototype = new Validator;
ImageFileCheckValidator.prototype.validate = function() {

    return (this.form[this.fieldName].value).replace(/^\s*/, "").replace(/\s*$/, "") != '' ? this.form[this.fieldName].value.match(this.regex) != null : true;
}

// 2007.10.19 송형기 추가 (특정 문자열에 특정 문자가 포함되었는지 검사)
function ContainsCheckValidator(form, fieldName, checkContainText, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.checkContainText = checkContainText;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
ContainsCheckValidator.prototype = new Validator;
ContainsCheckValidator.prototype.validate = function() {
    if (this.form[this.fieldName].value.indexOf(this.checkContainText) >= 0) {
        return false;
    } else {
        return true;
    }
}


// 2007.10.23 김경희 추가 (Element와 value값이 같은지 체크)
function EqualsCheckValidator(form, fieldName, checkValue, isEquals, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.checkValue = checkValue;
    this.isEquals = isEquals;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
EqualsCheckValidator.prototype = new Validator;
EqualsCheckValidator.prototype.validate = function() {

    var elementType = this.form[this.fieldName].type;

    if (this.isEquals) {
        if (elementType == 'select-one') return this.form[this.fieldName].value !=  this.checkValue;
        else return this.form[this.fieldName].value != this.checkValue;;
    }

    else {
        if (elementType == 'select-one') return this.form[this.fieldName].value ==  this.checkValue;
        else return this.form[this.fieldName].value == this.checkValue;

    }
}


// 2007.10.23 민선기 추가 (주소가 http://로 시작하는지 체크)
function UrlCheckValidator(form, fieldName, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
UrlCheckValidator.prototype = new Validator;
UrlCheckValidator.prototype.validate = function() {

    var urlPattern = /^(?:(?:ftp|https?):\/\/)?(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?:com|edu|biz|org|gov|int|info|mil|net|name|museum|coop|aero|[a-z][a-z])\b(?:\d+)?(?:\/[^;"'<>()\[\]{}\s\x7f-\xff]*(?:[.,?]+[^;"'<>()\[\]{}\s\x7f-\xff]+)*)?/;

    if (!urlPattern.test(this.form[this.fieldName].value)) {
        return false;
    }else{
        return true;
    }
}

// 2007.10.29 김경희 추가 (특수문자 체크 )
function SpecialCharCheckValidator(form, fieldName, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
SpecialCharCheckValidator.prototype = new Validator;
SpecialCharCheckValidator.prototype.validate = function() {

    var strPattern = /[~!@\#$%^&*\()\-=+_']/gi;

    if (strPattern.test(this.form[this.fieldName].value)) {
        return false;
    }else{
        return true;
    }
}

// 2007.10.29 김경희 추가 (HTML태그 문자 체크)
function HTMLTagCheckValidator(form, fieldName, errorMessage, focus) {
    this.form = form;
    this.fieldName = fieldName;
    this.errorMessage = errorMessage;
    this.focus = focus;
}
HTMLTagCheckValidator.prototype = new Validator;
HTMLTagCheckValidator.prototype.validate = function() {

    var strPattern = /<\/?[^>]+(>|$)/g;

    if (strPattern.test(this.form[this.fieldName].value)) {
        return false;
    }else{
        return true;
    }
}
