/**
 * osp paging config singleton
 */
var ospPagingConfig = {
    defaultFirstImage :"./images/common/btn/btn_f.gif",
    defaultLastImage :"./images/common/btn/btn_l.gif",
    defaultPrevImage :"./images/common/btn/btn_prev.gif",
    defaultNextImage :"./images/common/btn/btn_next.gif",
    defaultRowCount :10,
    defaultPagingCount :10,
    defaultAction :"javascript:void(0)",
    defaultActionName : "goPage"
};

/**
 * OSP Paging Class
 */
var OspPaging = Class.create( {
    /**
     * Constructor for this class
     *
     * @param pageNo        current page no
     * @param totalCount    total list count
     * @param rowCount      display row count
     * @param pagingCount   display paging count
     */
    initialize : function(pageNo, totalCount, actionName, rowCount, pagingCount) {
        this.pageNo = pageNo;
        this.totalCount = totalCount;
        this.actionName = actionName || ospPagingConfig.defaultActionName;
        this.rowCount = rowCount || ospPagingConfig.defaultRowCount;
        this.pagingCount = pagingCount || ospPagingConfig.defaultPagingCount;

        /* eval total page count */
        this.totalPageCount = Math.ceil(totalCount / this.rowCount);

        /* eval total page group */
        this.totalPageGroup = Math.ceil(this.totalPageCount / this.pagingCount);

        /* eval current page gorup */
        this.currentPageGroup = Math.ceil(pageNo / this.pagingCount);

        /* eval start page and end page */
        this.startPage = (this.currentPageGroup - 1) * this.pagingCount + 1;
        this.endPage = this.currentPageGroup * this.pagingCount;
        if (this.totalPageCount < this.endPage) {
            this.endPage = this.totalPageCount;
        }
    },

    /**
     * render paging html
     */
    render2Html : function() {
        //var htmlCode = "<table width=\"700\" class=\"tablePaging\">";
        //htmlCode += "<tr>";
        //htmlCode += "    <td>";
        var htmlCode = "";

        var actionEvent = null;

        /* ============================ */
        /* render first page image link */
        /* ============================ */
        if (this.pageNo > 1) {
            actionEvent = "javascript:" + this.actionName + "(1)";
        } else {
            actionEvent = ospPagingConfig.defaultAction;
        }
        htmlCode += "        <a href=\"#\" class=\"first\" onclick=\"" + actionEvent + "\">";
        htmlCode += "<img src=\"" + this.getFirstImage() + "\" alt=\"First Page\" />";
        htmlCode += "</a>";

        /* ================================= */
        /* render prev page group image link */
        /* ================================= */
        if (this.currentPageGroup > 1) {
            var prevPageNo = this.startPage - this.pagingCount;
            actionEvent = "javascript:" + this.actionName + "(" + prevPageNo + ")";
        } else {
            actionEvent = ospPagingConfig.defaultAction;
        }
        htmlCode += "        <a href=\"#\" class=\"prev\" onclick=\"" + actionEvent + "\">";
        htmlCode += "<img src=\"" + this.getPrevImage() + "\" alt=\"Previous Page Group\" />";
        htmlCode += "</a>";

        /* ================== */
        /* render paging link */
        /* ================== */
        htmlCode += "<span class=\"direction\">";
        for ( var index = this.startPage; index <= this.endPage; index++) {
            if (this.pageNo == index) {
                htmlCode += "        <a href=\"#\"><strong>" + index + "</strong></a>";
            } else {
                htmlCode += "        <a href=\"javascript:" + this.actionName + "(" + index + ")\">";
                htmlCode += index + "</a>";
            }
            if (index != this.endPage) {
                htmlCode += "        |";
            }
        }
        htmlCode += "</span>";

        /* ================================= */
        /* render next page group image link */
        /* ================================= */
        if (this.currentPageGroup < this.totalPageGroup) {
            var nextPageNo = ((this.endPage + 1) > this.totalPageCount ? this.totalPageCount
                    : this.endPage + 1);
            actionEvent = "javascript:" + this.actionName + "(" + nextPageNo + ")";
        } else {
            actionEvent = ospPagingConfig.defaultAction;
        }
        htmlCode += "        <a href=\"#\" class=\"next\" onclick=\"" + actionEvent + "\">";
        htmlCode += "<img src=\"" + this.getNextImage() + "\" alt=\"\" />";
        htmlCode += "</a>";

        /* =========================== */
        /* render last page image link */
        /* =========================== */
        if (this.pageNo < this.totalPageCount) {
            actionEvent = "javascript:" + this.actionName + "(" + this.totalPageCount + ")";
        } else {
            actionEvent = ospPagingConfig.defaultAction;
        }
        htmlCode += "        <a href=\"#\" class=\"last\" onclick=\"" + actionEvent + "\">";
        htmlCode += "<img src=\"" + this.getLastImage() + "\" alt=\"\" />";
        htmlCode += "</a>";

        htmlCode += "    </td>";
        htmlCode += "</tr>";
        htmlCode += "</table>";

        return htmlCode;
    },

    /**
     * render out to document
     */
    render : function() {
        document.write(this.render2Html());
    },

    /**
     * render out to target object as innerHTML
     *
     * @param targetId
     *            target object id
     */
    renderTo : function(targetId) {
        $(targetId).innerHTML = this.render2Html();
    },

    /**
     * 기본 이미지 이외의 다른 이미지를 지정한다.
     *
     * @param firstImage
     *            url for first link image
     * @param lastImage
     *            url for last link image
     * @param prevImage
     *            url for previous page group image
     * @param nextImage
     *            url for next page group image
     */
    setImageSet : function(firstImage, lastImage, prevImage, nextImage) {
        this.firstImage = firstImage || ospPagingConfig.defaultFirstImage;
        this.lastImage = lastImage || ospPagingConfig.defaultLastImage;
        this.prevImage = prevImage || ospPagingConfig.defaultPrevImage;
        this.nextImage = nextImage || ospPagingConfig.defaultNextImage;
    },

    /**
     * get first image url
     */
    getFirstImage : function() {
        return (this.firstImage || ospPagingConfig.defaultFirstImage);
    },

    /**
     * get first image url
     */
    getLastImage : function() {
        return (this.lastImage || ospPagingConfig.defaultLastImage);
    },

    /**
     * get previous page group image url
     */
    getPrevImage : function() {
        return (this.prevImage || ospPagingConfig.defaultPrevImage);
    },

    /**
     * get next page group image url
     */
    getNextImage : function() {
        return (this.nextImage || ospPagingConfig.defaultNextImage);
    },

    setRowCount : function(/* int */rowCount) {
        this.rowCount = rowCount || ospPagingConfig.defaultRowCount;
    },

    setPagingCount : function(/* int */pagingCount) {
        this.pagingCount = pagingCount || ospPagingConfig.defaultPagingCount;
    }
});

/**
 * Form Validator Class
 */
var FormValidator = Class.create( {
    /**
     * Constructor for this class
     *
     * @author Myoungseok, Seo
     * @param targetFormName
     */
    initialize : function(targetForm) {
        this.targetForm = targetForm;
        this.checkerList = [];
    },

    /**
     * get target form name
     */
    getFormName : function() {
        return this.targetForm;
    },

    /**
     * execute form validation
     */
    validate : function() {
        for ( var index = 0, length = this.checkerList.length ; index < length ; index++ ) {
            var fieldChecker = this.checkerList[index];
            if ( fieldChecker.check() == false ) {
                alert(fieldChecker.getErrorMessage());
                if ( fieldChecker.isFocus() ) {
                    this.targetForm[fieldChecker.getFieldName()].focus();
                } else {
                    document.location.href = fieldChecker.getRedirect();
                }
                return false;
            }
        }
        return true;
    },

    /**
     * validate required field
     */
    checkRequired : function(fieldName, errorMessage, focus) {
        this.checkerList.push(
                new RequiredFieldChecker(this.targetForm, fieldName, errorMessage, focus));
    },

    /**
     *
     */
    checkMaxLength : function(fieldName, maxLength, errorMessage, focus) {
        this.checkerList.push(
                new MaxLengthFieldChecker(this.targetForm, fieldName,
                        maxLength, errorMessage, focus));
    },

    /**
     *
     */
    checkMaxLengthByte : function(fieldName, maxLength, errorMessage, focus) {
        this.checkerList.push(
                new MaxLengthByteFieldChecker(this.targetForm, fieldName,
                        maxLength, errorMessage, focus));
    },

    /**
     *
     */
    checkMinLength : function(fieldName, minLength, errorMessage, focus) {
        this.checkerList.push(
                new MinLengthFieldChecker(this.targetForm, fieldName,
                        minLength, errorMessage, focus));
    },

    /**
     *
     */
    checkMinLengthByte : function(fieldName, minLength, errorMessage, focus) {
        this.checkerList.push(
                new MinLengthByteFieldChecker(this.targetForm, fieldName,
                        minLength, errorMessage, focus));
    },

    checkRegex : function(fieldName, regex, errorMessage, focus) {
        this.checkerList.push(
                new RegexFieldChecker(this.targetForm, fieldName,
                        regex, errorMessage, focus));
    },

    checkAlphaNum : function(fieldName, errorMessage, focus) {
        this.checkerList.push(
                new RegexFieldChecker(this.targetForm, fieldName,
                        /^[a-zA-Z0-9]+$/, errorMessage, focus));
    },

    checkOnlyNumber : function(fieldName, errorMessage, focus) {
        this.checkerList.push(
                new RegexFieldChecker(this.targetForm, fieldName,
                        /^[0-9]+$/, errorMessage, focus));
    },

    checkDecimal : function(fieldName, errorMessage, focus) {
        this.checkerList.push(
                new RegexFieldChecker(this.targetForm, fieldName,
                        /^(\-)?[0-9]*(\.[0-9]*)?$/, errorMessage, focus));
    },

    checkEmail : function(fieldName, errorMessage, focus) {
        this.checkerList.push(
                new RegexFieldChecker(this.targetForm, fieldName,
                        /^((\w|[\-\.])+)@((\w|[\-\.])+)\.([A-Za-z]+)$/, errorMessage, focus));
    },

    checkSelected : function(fieldName, firstIdx, errorMessage, focus) {
        this.checkerList.push(
                new SelectionFieldChecker(this.targetForm, fieldName,
                        firstIdx, errorMessage, focus));
    },

    checkAtLeastOneChecked : function(fieldName, errorMessage, focus) {
        this.checkerList.push(
                new AtLeastOneCheckFieldChecker(this.targetForm, fieldName,
                        errorMessage, focus));
    }
});

/**
 * Define a FieldChecker Module Class
 */
var FieldChecker = {
    getFieldName : function() {
        return this.fieldName;
    },
    getErrorMessage : function() {
        return this.errorMessage;
    },
    isFocus : function() {
        return this.focus;
    },
    getRedirect : function() {
        return this.redirect;
    }
};

/**
 * Required Field Checker Class
 */
var RequiredFieldChecker = Class.create(FieldChecker, {

    /**
     * Constructor for this class
     *
     * @param form          target form instance
     * @param fieldName     target field name
     * @param errorMessage  custom error message
     * @param focus         whether or not field focusing
     */
    initialize : function(form, fieldName, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    check : function() {
        return ( this.form[this.fieldName].value != '' );
    }

});


/**
 * Sql Injection Checker Class
 */
var SqlInjectionFieldChecker = Class.create(FieldChecker, {

    /**
     * Constructor for this class
     *
     * @param form          target form instance
     * @param fieldName     target field name
     * @param errorMessage  custom error message
     * @param focus         whether or not field focusing
     */
    initialize : function(form, fieldName, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    check : function() {
        var fieldValue = this.form[this.fieldName].value;
        if (fieldValue.indexOf("'") > -1 || fieldValue.indexOf("<") > -1
                || fieldValue.indexOf(">") > -1) {
            return false;
        }
        return true;
    }

});


var MaxLengthFieldChecker = Class.create(FieldChecker, {

    /**
     * Constructor for this class
     *
     * @param form
     *            target form instance
     * @param fieldName
     *            target field name
     * @param maxLength
     *            max length
     * @param errorMessage
     *            custom error message
     * @param focus
     *            whether or not field focusing
     */
    initialize : function(form, fieldName, maxLength, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.maxLength = maxLength;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    /**
     * get max length
     */
    getMaxLength : function() {
        return this.maxLength;
    },

    /**
     * check max length
     */
    check : function() {
        return (this.form[this.fieldName].value.length <= this.maxLength);
    }

});


var MaxLengthByteFieldChecker = Class.create(FieldChecker, {

    /**
     * Constructor for this class
     *
     * @param form          target form instance
     * @param fieldName     target field name
     * @param maxLength     max byte length
     * @param errorMessage  custom error message
     * @param focus         whether or not field focusing
     */
    initialize : function(form, fieldName, maxLength, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.maxLength = maxLength;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    /**
     * get max byte length
     */
    getMaxLength : function() {
        return this.maxLength;
    },

    /**
     * check max byte length
     */
    check : function() {
        str = this.form[this.fieldName].value;
        return ((str.length + (escape(str) + "%u").match(/%u/g).length - 1) <= this.maxLength);
    }

});


var MinLengthFieldChecker = Class.create(FieldChecker, {

    /**
     * Constructor for this class
     *
     * @param form
     *            target form instance
     * @param fieldName
     *            target field name
     * @param minLength
     *            min length
     * @param errorMessage
     *            custom error message
     * @param focus
     *            whether or not field focusing
     */
    initialize : function(form, fieldName, minLength, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.minLength = minLength;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    /**
     * get minimum length
     */
    getMinLength : function() {
        return this.minLength;
    },

    /**
     * check minimum length for target field value
     */
    check : function() {
        return (this.form[this.fieldName].value.length >= this.minLength);
    }

});


var MinLengthByteFieldChecker = Class.create(FieldChecker, {
    /**
     * Constructor for this class
     *
     * @param form          target form instance
     * @param fieldName     target field name
     * @param minLength     min byte length
     * @param errorMessage  custom error message
     * @param focus         whether or not focus on field
     */
    initialize : function(form, fieldName, minLength, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.minLength = minLength;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    /**
     * get minimum byte length
     */
    getMinLength : function() {
        return this.minLength;
    },

    /**
     * check minimum byte length for target field value
     */
    check : function() {
        str = this.form[this.fieldName].value;
        return ((str.length + (escape(str) + "%u").match(/%u/g).length - 1) >= this.minLength);
    }

});


var RegexFieldChecker = Class.create(FieldChecker, {

    initialize : function(form, fieldName, regex, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.regex = regex;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    getRegex: function() {
        return this.regex;
    },

    check : function() {
        var str = this.form[this.fieldName].value;
        if (str.length == 0) {
            return true;
        }
        return ( str.search(this.regex) != -1 );
    }

});


var SelectionFieldChecker = Class.create(FieldChecker, {

    initialize: function(form, fieldName, firstIdx, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.firstIdx = firstIdx;
        this.errorMessage = errorMessage;
        this.focus = focus;
    },

    getFirstIndex: function() {
        return this.firstIdx;
    },

    check : function() {
        var selectedIndex = this.form[this.fieldName].selectedIndex;
        return ( selectedIndex >= this.firstIdx );
    }

});

var AtLeastOneCheckFieldChecker = Class.create(FieldChecker, {

    initialize: function(form, fieldName, errorMessage, focus) {
        this.form = form;
        this.fieldName = fieldName;
        this.errorMessage = errorMessage;

        if ( focus == true || focus == false ) {
            this.focus = focus;
        } else {
            this.focus = false;
            this.redirect = focus;
        }
    },

    check: function () {
        var ele = this.form[this.fieldName];
        if ( typeof(ele[0]) != "undefined" ) {
            for (var idxe = 0 ; idxe < ele.length ; idxe++) {
                if (ele[idxe].checked == true) {
                    return true;
                }
            }
            return false;
        } else {
            return ele.checked == true;
        }
    }

});

