// {{{ [utils] ÃÖ¼Ò´ÜÀ§ ¸Þ¼Òµå
/**
 * ÃÖ¼Ò´ÜÀ§ÀÇ À¯¿ëÇÑ ¸Þ¼Òµåµé¸¸ Á¤¸®
 *
 * @package   jquery.fn
 * @author    ¿Á¿ë¼ö <okyongsu@unitel.co.kr>
 * @copyright 2008 ´Ù¿ì±â¼ú À¯´ÏÅÚ»ç¾÷º»ºÎ
 */
(function($) {

    $.extend($.fn, {
        /**
         * INPUT[type=hidden]¿¡ °ªÀÌ º¯°æµÉ ¶§ ¹ß»ýÇÏ´Â ÀÌº¥Æ®
         * http://www.quirksmode.org/dom/events/
         */
        watch: function(fn) {
            if ($(this).attr('type') !== 'hidden') {
                throw 'INPUT[type=hidden]¿¡¸¸ »ç¿ëÇÒ °Í';
            }
            if ($.browser.msie) {
                return fn ? this.bind('propertychange', fn) : this.trigger('propertychange');
            } else if ($.browser.mozilla || $.browser.opera) {
                return fn ? this.bind('DOMAttrModified', fn) : this.trigger('DOMAttrModified');
            } else {
                // safari´Â ¾ÆÁ÷....
            }
        }
    });


    $.extend($.fn, {

        /**
         * INPUT¿¡ ¹®ÀÚ°¡ maxlength¸¸Å­ ÀÔ·ÂµÇ¾úÀ»½Ã,
         * Ä¿¼­ÀÇ À§Ä¡¸¦ ÀÚµ¿À¸·Î ÀÌµ¿ÇÏµµ·Ï ÇÕ´Ï´Ù.
         *
         * @example
         * // < input type='text' id='first' maxlength='5' / >
         * // < input type='text' id='second' / >
         *
         * $("#first").autoTab("#second");
         * $("#first", form).autoTab("#second", form);
         *
         * @param {selector} elem ÀÌº¥Æ®¸¦ µî·ÏÇÒ °´Ã¼ÁöÁ¤
         * @param {element} context »óÀ§°´Ã¼
         *
         * @return {jQuery} chainable jQuery class
         * @exception Error INPUTÅÂ±×¿¡ maxlength ¼Ó¼º ÇÊ¼ö
         * @see Daou.Form.methods.tab jQuery.validate È°¿ë½Ã¿¡´Â Daou.Form.methods¸¦ ÂüÁ¶ÇÒ °Í.
         */
        autoTab: function(elem, context) {

            // [Tip]
            // form°´Ã¼ ¾ÈÀÇ input°´Ã¼¸¦ ÁöÁ¤ÇÒ¶§,
            // form°´Ã¼¸¦ context¿¡ ÁöÁ¤ÇÏ°Ô µÇ¸é select¼Óµµ°¡ Çâ»óµÊ.
            context = context || document;

            var maxlength = $(this).attr('maxlength');

            // maxlength ±âº»°ª
            // IE : 2147483647
            // FF, Opera : -1
            // safari : 524288
            if ((new String(maxlength)).match(/-1|2147483647|524288/)) {
                throw new Error('[jQuery: autoTab] maxlength°¡ ÇÊ¿äÇÕ´Ï´Ù.');
            }

            return $(this).keyup(function(){
                if ($(this).attr('maxlength') == $(this).val().length) {
                    $(elem, context).focus();
                }
            });
        },


        /**
         * EnterÀÌº¥Æ®°¡ ¹ß»ýÇÏ¿´À»½Ã,
         * callbackÇÔ¼ö¸¦ ½ÇÇà½ÃÅµ´Ï´Ù.
         *
         * @example
         *  $("#input").enter(function() {
         *    alert('ÇÔ¼ö ½ÇÇà');
         *  });
         *
         * @param {function} callback ½ÇÇàÇÒ ÇÔ¼ö
         *
         * @return {jQuery} chainable jQuery class
         */
        enter: function(callback) {
            return $(this).each(function() {
                $(this).keypress(function(e) {
                    var event = $.event.fix(e);
                    if (event.which === 13) {
                        callback.call(this);
                    }
                });
            });
        },

        /**
         * Çã¿ëµÈ ¹®ÀÚ¿­¸¸ ÀÔ·Â°¡´ÉÇÏµµ·Ï ÇÔ.
         *
         * @example
         * $(':text[name=num]').allowInputString("0123456789");
         * $(':text[name=phone]').allowInputString("0123456789-");
         *
         * @param {string}   str      Çã¿ë°¡´ÉÇÑ ¹®ÀÚ¿­
         * @param {function} callback ½ÇÇàÇÒ ÇÔ¼ö
         */
        allowInputString: function(str, calback) {
            var limitStrings = new RegExp("([^"+str+"]+)", "mg");
            
            return $(this).each(function() {
                $(this)
                    .keypress(function(e) {
                        var event = $.event.fix(e);
                        if (!String.fromCharCode(event.which).match(limitStrings)) {
                            return true;
                        } else {
                            if (calback) {
                                calback.call(this);
                            }
                            return false;
                        }
                    })
                    .keyup(function(e) {
                        var num = $(this).val().replace(limitStrings, '');
                        $(this).val(num);
                    });
            });
        },


        /**
         * INPUT[type=text]¿¡ ±âº» ¾È³» ¹®±¸¸¦ ³Ö¾î¼­,<br>
         * »ç¿ëÀÚ°¡ °ªÀ» ÀÔ·ÂÇÏ¸é, ÀÔ·ÂÇÑ °ªÀÌ
         * °ªÀ» ÀÔ·ÂÇÏÁö ¾ÊÀ¸¸é, ±âº» ¾È³» ¹®±¸¸¦ º¸¿©ÁÖµµ·Ï ÇÔ.
         *
         * @example
         * $("input[name=rcv_mobile]").inputInit('¾È³»¸Þ½ÃÁö');
         *
         * @param {string} defaultValue µðÆúÆ® ¾È³»¸Þ½ÃÁö
         *
         * @return {jQuery} chainable jQuery class
         */
        inputInit: function(defaultValue) {

            if ($(this).val() === '') {
                $(this).val(defaultValue);
            }

            return $(this).focus(function() {
                var changedValue = $(this).val();
                if (defaultValue === changedValue) {
                    $(this).val('');
                }
            }).blur(function() {
                if ($(this).val() === '') {
                    $(this).val(defaultValue);
                }
            });
        },


        /**
         * Å¬¸¯ ÀÌº¥Æ®¿¡ ´ëÇÑ ÆË¾÷Ã¢ ¶ç¿ì±â
         *
         * @example
         * $("a").clickOpenWindow({url:'index.html', width:100, height:100});
         *
         * @param {object} option {scrollbars, status, top, left, width, height}¸¦ ÁöÁ¤
         *
         * @return {jQuery} chainable jQuery class
         */
        clickOpenWindow: function(option) {

            var opt = $.extend({
                    name:'',
                    scrollbars:'no',
                    status:'no',
                    top:(window.screen.height - option.height)/2,
                    left:(window.screen.width - option.width)/2
                }, option);

            var attrs = 'scrollbars=' + opt.scrollbars;
            attrs += ',status=' + opt.status;
            attrs += ',width=' + opt.width;
            attrs += ',height=' + opt.height;
            attrs += ',top=' + opt.top;
            attrs += ',left=' + opt.left;

            return $(this).click(function() {

                window.open(opt.url, opt.name, attrs);
                return false;
            });
        },


        /**
         * Å¬¸¯ ÀÌº¥Æ®¿¡ ´ëÇÑ °æ°íÃ¢ ¶ç¿ì±â
         *
         * @example
         * $("a").clickAlert(message);
         *
         * @param {object} message°¡ ÀÖÀ»½Ã message Ãâ·Â, ¾øÀ»¶© title Ãâ·Â
         *
         * @return {jQuery} chainable jQuery class
         */
        clickAlert: function(message) {
            return  $(this).click(function() {

                if (!message) {
                    message = $(this).attr('title');
                }

                alert(message);
                return false;
            });
        },


        /**
         * Å¬¸¯ ÀÌº¥Æ®¿¡ ´ëÇÑ ÆË¾÷Ã¢ Á×ÀÌ±â
         *
         * @example
         * $("a").clickClose();
         *
         * @return {jQuery} chainable jQuery class
         */
        clickClose: function() {
            return $(this).click(function() {
                self.close();
                return false;
            });
        },


        /**
         * click¹ß»ý½Ã url·Î ÀÌµ¿
         * URL¿¡ ÀÏ¹ÝÀûÀÎ ¹®ÀÚ¿­ »Ó¸¸ ¾Æ´Ï¶ó, ÅÛÇÃ¸´À» Àû¿ëÇÏ¿© Àü´ÞÇÒ ¼ö ÀÖÀ½.
         *
         * @example
         * [ÀÏ¹Ý ¹®ÀÚ¿­ url]
         * // PPLoginMgr.qri?act=id_form ÁÖ¼Ò·Î ÀÌµ¿
         * $('#findPasswd').clickForward('PPLoginMgr.qri?act=id_form');
         *
         * [ÅÛÇÃ¸´ ¹®ÀÚ¿­ url]
         * // radio INPUTÀÇ value°ªÀÌ act°ª¿¡ ÇØ´çµÈ´Ù¸é 
         * $(':radio[name=rd]').clickForward('PPLoginMgr.qri?act=<%=action%>');
         *
         * @param {string} url ÁÖ¼Ò
         *
         * @return {jQuery} chainable jQuery class
         */
        clickForward: function(url) {
            return $(this).click(function() {
                url = $.template(url, {'action':$(this).val()}, true);
                $.forward(url);
                return false;
            });
        },


        /**
         * º»¹®ÀÇ JSON ¹®ÀÚ¿­À» JSON°´Ã¼·Î º¯È¯
         *
         * @example
         * <textarea id="formRules">{name:'json'}</textarea>
         * $("#formRules").toJSON();
         *
         * @return {object} JSON object
         */
        toJSON: function() {
            var str = $(this).val();
            return eval("(" + str + ")");
        },


        /**
         */
        embedFlash: function(opt) {

            var option = $.extend({
                'src': '',
                'width': '320',
                'height': '240',
                'classid': 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
                'codebase': 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0',
                'type': 'application/x-shockwave-flash',
                'pluginspage': 'http://www.macromedia.com/go/getflashplayer',
                'quality': 'high'
            }, opt);

            if (option.src == '') {
                alert('src¸¦ ÁöÁ¤ÇÏ¼Å¾ß ÇÕ´Ï´Ù.');
                return false;
            }

            $(this).html($.template('<object'
                     + ' classid="<%=classid%>"'
                     + ' codebase="<%=codebase%>"'
                     + ' width="<%=width%>"'
                     + ' height="<%=height%>">'
                     + '<param name="movie" value="<%=src%>">'
                     + '<param name="quality" value="<%=quality%>">'
                     + '<embed src="<%=src%>" quality="<%=quality%>"'
                     + ' pluginspage="<%=pluginspage%>"'
                     + ' type="<%=type%>"'
                     + ' width="<%=width%>"'
                     + ' height="<%=height%>">'
                     + '</embed>'
                     + '</object>', option, true));
        }

    });


    // }}}
    // {{{ [utils] ÃÖ¼Ò´ÜÀ§ ÇÔ¼ö
    /**
     * ÃÖ¼Ò´ÜÀ§ÀÇ À¯¿ëÇÑ ÇÔ¼öµé¸¸ Á¤¸®
     *
     * @package   jquery
     * @author    ¿Á¿ë¼ö <okyongsu@unitel.co.kr>
     * @copyright 2008 ´Ù¿ì±â¼ú À¯´ÏÅÚ»ç¾÷º»ºÎ
     */
    var __openedWindow = [];
    var template_cache = {};

    $.extend({

        openWindow: function(option) {
            var opt = $.extend({
                    name:'',
                    scrollbars:'no',
                    resizable:'no',
                    status:'no',
                    top:(window.screen.height - option.height)/2,
                    left:(window.screen.width - option.width)/2
                }, option);

            var attrs = 'scrollbars=' + opt.scrollbars;
            attrs += ',status=' + opt.status;
            attrs += ',width=' + opt.width;
            attrs += ',height=' + opt.height;
            attrs += ',top=' + opt.top;
            attrs += ',left=' + opt.left;

            __openedWindow.push(window.open(opt.url, opt.name, attrs));
        },

        closeWindow: function() {
            for (var i in __openedWindow) {
                if (__openedWindow[i]) {
                    __openedWindow[i].close();
                }
            }
        },

        /**
         * ÇØ´ç½ºÆ®¸µÀÇ ¹ÙÀÌÆ®´ÜÀ§ ±æÀÌ¸¦ ¸®ÅÏÇÕ´Ï´Ù. 
         * (±âÁ¸ÀÇ length ¼Ó¼ºÀº 2¹ÙÀÌÆ® ¹®ÀÚ¸¦ ÇÑ±ÛÀÚ·Î °£ÁÖÇÕ´Ï´Ù)
         *
         * @example
         * jQuery.strlen("ÇÑ±Ûaa"); // OUTFUT : 6
         * $.strlen("ÇÑ±Ûaa"); // OUTFUT : 6
         *
         * @param {string} str ¹®ÀÚ¿­
         *
         * @return {integer}
         */
        strlen: function(str) {
            var l = 0;
            for (var i=0; i<str.length; i++) l += (str.charCodeAt(i) > 128) ? 2 : 1;
            return l;
        },


        /**
         * ÁÖ¼Ò¸¦ ÀÌµ¿ÇÕ´Ï´Ù.
         *
         * @example
         * jQuery.redirect('index.qri');
         * $.redirect('index.qri');
         *
         * @param {string} url
         *
         * @return void
         */
        redirect: function(url) {
            location.href = url;
        },


        /**
         * ÁÖ¼Ò¸¦ º¯°æÇÕ´Ï´Ù.
         *
         * @example
         * jQuery.forward('index.qri');
         * $.forward('index.qri');
         *
         * @param {string} url
         *
         * @return void
         */
        forward: function(url) {
            location.replace(url);
        },

       
        /**
         * parseUri 1.2.1
         *
         * @author Steven Levithan <stevenlevithan.com>
         * @license MIT License
         * @see http://blog.stevenlevithan.com/archives/parseuri
         */
        parseUri: function(str, options) {
            var o = $.extend({
                    strictMode: false,
                    key: ["source", "protocol", "authority", "userInfo", "user",
                          "password", "host", "port", "relative", "path",
                          "directory", "file", "query", "anchor"],
                    q:   {
                        name:   "queryKey",
                        parser: /(?:^|&)([^&=]*)=?([^&]*)/g
                    },
                    parser: {
                        strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
                        loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
                    }
                }, options);
            m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
            uri = {},
            i   = 14;

            while (i--) uri[o.key[i]] = m[i] || "";

            uri[o.q.name] = {};
            uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
                if ($1) uri[o.q.name][$1] = $2;
            });

            return uri;
        },

        
        /**
         * ÁöÁ¤ÇÑ ÀÚ¹Ù½ºÅ©¸³Æ® ÆÄÀÏÀ» ¸Å¹ø ÀÎÅ¬·çµå [µ¿Àû+Á¤Àû]
         *
         * ÁÖÀÇ»çÇ× [1]
         * È£Ãâ½Ã cacheÇÏÁö ¾Êµµ·Ï ¼³Á¤µÇ¾î ÀÖÀ¸¹Ç·Î
         * Á¤ÀûÀÎ ½ºÅ©¸³Æ® È£Ãâ½Ã ÁÖÀÇÇÒ °Í
         *
         * ÁÖÀÇ»çÇ× [2]
         * µ¿±â½Ä È£ÃâÀÌ¹Ç·Î, ´ë¿ë·®ÀÇ ÆÄÀÏ ÀÎÅ¬·çµå½Ã ÁÖÀÇÇÒ °Í.
         *
         * @example
         * $.include('jquery.dump.js');
         * $.dump($);
         *
         * @param {string}   js      ÀÚ¹Ù½ºÅ©¸³Æ® ÆÄÀÏ °æ·Î
         * @param {function} success ¼º°øÇßÀ»½Ã ½ÇÇàµÉ callbackÇÔ¼ö
         *
         * return {void}
         */
        include: function(js, success) {
            var func = success || function() {};

            $.ajax({
                type:'GET',
                url:js,
                async:false,
                dataType:'script',
                success:func,
                cache:false,
                error:function() {
                    throw new Error('[jQuery] '+js+'ÆÄÀÏÀ» includeÇÏÁö ¸øÇß½À´Ï´Ù.');
                }
            });
        },

        
        /**
         * ÁöÁ¤ÇÑ ÀÚ¹Ù½ºÅ©¸³Æ® ÆÄÀÏÀ» ÇÑ¹ø¸¸ ÀÎÅ¬·çµåÇÔ [Á¤Àû]
         *
         * ÁÖÀÇ»çÇ×
         * µ¿±â½Ä È£ÃâÀÌ¹Ç·Î, ´ë¿ë·®ÀÇ ÆÄÀÏ ÀÎÅ¬·çµå½Ã ÁÖÀÇÇÒ °Í.
         */
        include_once: function(js, success) {

            this.include_once_cache = this.include_once_cache || {};
            if (this.include_once_cache[js]) return false;

            var func = success || function() {};

            $.ajax({
                type:'GET',
                url:js,
                async:false,
                dataType:'script',
                success:func,
                complete:function() {
                    $.include_once_cache[js] = true;
                },
                cache:true,
                error:function() {
                    throw new Error('[jQuery] '+js+'ÆÄÀÏÀ» includeÇÏÁö ¸øÇß½À´Ï´Ù.');
                }
            });
        },

        
        /**
         * JavaScript Micro-Templating
         * ÅÛÇÃ¸´ ¹®ÀÚ¿­·Î ¹ÞÀº ³»¿ëÀ» ÀÌ¸§¾ø´Â ÇÔ¼ö·Î º¯È¯ÇÏ¿©
         * jsonµ¥ÀÌÅÍ¿Í Á¶ÇÕÇÏ¿© °á°ú¸¦ Ãâ·ÂÇÏ´Â ¹æ½ÄÀÓ.
         *
         * @example
         * <div id="result1"></div>
         * <div id="result2"></div>
         * 
         * <script type="text/html" id="tmpl_1">
         * <div>
         *   <%=(i % 2 == 1 ? "È¦¼ö" : "Â¦¼ö")%>¹øÈ£ :  <%=id%> = <%=name%>
         * </div>
         * </script> 
         * 
         * <script type="text/html" id="tmpl_2">
         * <% for ( var i = 0; i < data2.length; i++ ) { %>
         *     <li><%=data2[i].name%>ÀÇ ÁÖ¼Ò´Â <%=data2[i].address%>ÀÔ´Ï´Ù.</li>
         * <% } %>
         * </script> 
         * <script>
         * var data1 = {
         *     "i":2,
         *     "id":"honggildong",
         *     "name":"È«±æµ¿"
         * };
         * 
         * var data2 = [
         *     {"name":"È«±æµ¿", "address":"¼­¿ï"},
         *     {"name":"ÀÓ²©Á¤", "address":"°æ±â"}
         * ];
         * 
         * $('#result1').html($.template("tmpl_1", data1));
         * 
         * var list = $.template("tmpl_2");
         * $('#result2').html(list(data2));
         *
         * // ¹®ÀÚ¿­¹æ½ÄÀÇ »ç¿ë¿¹Á¦
         * alert($.template('<h1><%=title%></h1>', {title:'Á¦¸ñ'}, true));
         * </script>
         *
         * @author  John Resig
         * @license http://ejohn.org/ - MIT Licensed
         *
         * @param {string}  str      ÅÛÇÃ¸´ SCRIPT{id}¸¦ ÁöÁ¤
         * @param {object}  data     ÅÛÇÃ¸´µ¥ÀÌÅÍ
         * @param {boolean} isString ÀÏ¹Ý¹®ÀÚ¿­ Çü½ÄÀ» str¸Å°³º¯¼ö¿¡ ÁöÁ¤ÇÒ ¶§
         *
         * @return {string}
         * @see http://ejohn.org/blog/javascript-micro-templating/
         */
        template: function (str, data, isString){
            isString = isString || false;

            var fn = !/\W/.test(str) ?
            template_cache[str] = template_cache[str] ||
                ((isString)? str : this.template(document.getElementById(str).innerHTML)) :
            
            // ÀÌ¸§ ¾ø´Â ÇÔ¼ö »ý¼º
            new Function("obj",
                "var p=[],print=function(){p.push.apply(p,arguments);};" +

                "with(obj){p.push('" +

                // ÅÛÇÃ¸´À» ¼ø¼ö ÀÚ¹Ù½ºÅ©¸³Æ®·Î º¯È¯
                str
                    .replace(/[\r\t\n]/g, " ")
                    .split("<%").join("\t")
                    .replace(/((^|%>)[^\t]*)'/g, "$1\r")
                    .replace(/\t=(.*?)%>/g, "',$1,'")
                    .split("\t").join("');")
                    .split("%>").join("p.push('")
                    .split("\r").join("\\'")
                + "');}return p.join('');");

            // jsonµ¥ÀÌÅÍ¸¦ ¹Þ¾ÒÀ¸¸é ¹Ù·Î ÇÔ¼ö¸¦ ½ÇÇàÇÏÁö¸¸, 
            // µ¥ÀÌÅÍ°¡ ¾øÀ»½Ã¿¡´Â ¹Ì¸® ÄÄÆÄÀÏµÈ Çü½ÄÀÇ ÇÔ¼ö¸¦ ¹ÝÈ¯ÇÏ¿©,
            // °è¼Ó »ç¿ëÇÒ ¼ö ÀÖÀ½.
            return data ? fn( data ) : fn;
        }
    });

})(jQuery);
// }}}