Util = (function () {
    var exports = {};

    /* */
    exports.deserializeForm = function ($form, data, callback) {
        $('[name]', $form).each(function (index) {

            var $this = $(this);
            var name = $this.attr("name");

            if (_.isEmpty(name)) {
                /* continue */
                return true;
            }

            var patterns = {
                validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i,
                key: /[a-z0-9_]+|(?=\[\])/gi
            };

            /* */
            var elements = [];
            var keys = name.match(patterns.key), k;
            while ((k = keys.pop()) !== undefined) {
                elements.push(k);
            }
            elements.reverse();

            /* */
            var next = data;
            elements.forEach(function (k) {
                if (_.isNull(next[k]) || _.isUndefined(next[k]) || _.isNaN(next[k])) {
                    next = '';
                } else {
                    next = next[k];
                }
            });

            var value = next;
            if (value === data || _.isNull(value) || _.isUndefined(value) || _.isNaN(value)) {
                /* continue */
                return true;
            }

            /* */
            if (_.isFunction(callback)) {
                value = callback(name, value);
            }

            var tagName = this.tagName.toUpperCase();
            if (tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA") {

                if ($this.attr("type") === "radio" || $this.attr("type") === "checkbox") {
                    var checked = (("" + value) == this.value || value === true) ? true : false;

                    $this.attr("checked", checked);
                } else {
                    $this.val(value);
                }
            } else {
                if (_.isBoolean(value)) {
                    // value가 boolean인 경우 문자열로 변환
                    value += '';
                }

                $this.html(value);
            }
        });
    };

    /* */
    exports.clearForm = function ($form) {
        $form[0].reset();
    };

    /*
     * url과 query string을 생성
     * url: 호출 URL (string)
     * parameters: 서버에 전달할 parameter (object)
     */
    exports.buildQueryString = function (url, parameters) {
        var qs = '';

        for (var key in parameters) {
            var value = parameters[key];
            qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
        }

        if (qs.length > 0) {
            qs = qs.substring(0, qs.length - 1); //chop off last "&"
            url = url + "?" + qs;
        }

        return url;
    };

    exports.getParameterByName = function(name) {
        var url = window.location.href;
        name = name.replace(/[\[\]]/g, '\\$&');
        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, ' '));
    }


    return exports;
})();
