// ================================================================
//                       CHEditor 4.3.6
// ----------------------------------------------------------------
// Author: Na Chang-Ho (chna@chcode.com)
// Homepage: http://www.chcode.com
// Copyright (c) 1997-2009 CHSOFT
// ================================================================
var userAgent = navigator.userAgent.toLowerCase();
var GB = {
    colors : ["#ffffff", "#000000", "#eeece1", "#1f497d", "#4f81bd", "#c0504d", "#9bbb59", "#8064a2", "#4bacc6", "#f79646",
              "#f2f2f2", "#7f7f7f", "#ddd9c3", "#c6d9f0", "#dbe5f1", "#f2dcdb", "#ebf1dd", "#e5e0ec", "#dbeef3", "#fdeada",
              "#d8d8d8", "#595959", "#c4bd97", "#8db3e2", "#b8cce4", "#e5b9b7", "#d7e3bc", "#ccc1d9", "#b7dde8", "#fbd5b5",
              "#bfbfbf", "#3f3f3f", "#938953", "#548dd4", "#95b3d7", "#d99694", "#c3d69b", "#b2a2c7", "#92cddc", "#fac08f",
              "#a5a5a5", "#262626", "#494429", "#17365d", "#366092", "#953734", "#76923c", "#5f497a", "#31859b", "#e36c09",
              "#7f7f7f", "#0c0c0c", "#1d1b10", "#0f243e", "#244061", "#632423", "#4f6128", "#3f3151", "#205867", "#974806",
              "#c00000", "#ff0000", "#ffc000", "#ffff00", "#92d050", "#00b050", "#00b0f0", "#0070c0", "#002060", "#7030a0"],

    htmlKey : ["!doctype", "a", "abbr", "acronym", "address", "applet", "area", "b", "base", "basefont", "bgsound", "bdo",
               "big", "blink", "dl", "body", "br", "button", "caption", "center", "cite", "code", "col", "colgroup",
               "comment", "dd", "del", "dfn", "dir", "div", "font", "dt", "em", "embed", "fieldset", "blockquote",
               "form", "frame", "frameset", "h", "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr",
               "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "label", "legend", "li", "link",
               "listing", "map", "marquee", "menu", "meta", "multicol", "nextid", "nobr", "noframes", "noscript", "object", "ol",
               "optgroup", "option", "p", "param", "plaintext","pre", "q", "s", "samp", "script", "select", "server",
               "small", "sound", "spacer", "span", "strike", "strong", "style", "sub", "sup", "table", "tbody", "td",
               "textarea", "title", "tfoot", "th", "thead", "textflow", "tr", "tt", "u", "ul", "var", "wbr", "xmp"],


    xhtmlNlBefore   : '|div|p|table|tbody|tr|td|th|title|head|body|script|comment|li|meta|h1|h2|h3|h4|h5|h6|hr|ul|ol|option|link|',
    xhtmlNlAfter    : '|html|head|body|p|th|style|',
    xhtmlInsSpace   : '|font|strong|strike|em|u|sub|sup|span|div|',
    xhtmlInsChild   : '|style|title|script|textarea|a|iframe|embed|',
    xhtmlComment    : new RegExp("^<!--(([a]|[^a])*)-->$"),
    xhtmlHyphen     : new RegExp("-$"),
    xhtmlEnts : {8364:"euro",402:"fnof",8240:"permil",352:"Scaron",338:"OElig",381:"#381",8482:"trade",353:"scaron",
                 339:"oelig",382:"#382",376:"Yuml",162:"cent",163:"pound",164:"curren",165:"yen",166:"brvbar",167:"sect",
                 168:"uml",169:"copy",170:"ordf",171:"laquo",172:"not",173:"shy",174:"reg",175:"macr",176:"deg",177:"plusmn",
                 178:"sup2",179:"sup3",180:"acute",181:"micro",182:"para",183:"middot",184:"cedil",185:"sup1",186:"ordm",
                 187:"raquo",188:"frac14",189:"frac12",190:"frac34",191:"iquest",192:"Agrave",193:"Aacute",194:"Acirc",
                 195:"Atilde",196:"Auml",197:"Aring",198:"AElig",199:"Ccedil",200:"Egrave",201:"Eacute",202:"Ecirc",
                 203:"Euml",204:"Igrave",205:"Iacute",206:"Icirc",207:"Iuml",208:"ETH",209:"Ntilde",210:"Ograve",211:"Oacute",
                 212:"Ocirc",213:"Otilde",214:"Ouml",215:"times",216:"Oslash",217:"Ugrave",218:"Uacute",219:"Ucirc",220:"Uuml",
                 221:"Yacute",222:"THORN",223:"szlig",224:"agrave",225:"aacute",226:"acirc",227:"atilde",228:"auml",229:"aring",
                 230:"aelig",231:"ccedil",232:"egrave",233:"eacute",234:"ecirc",235:"euml",236:"igrave",237:"iacute",
                 238:"icirc",239:"iuml",240:"eth",241:"ntilde",242:"ograve",243:"oacute",244:"ocirc",245:"otilde",246:"ouml",
                 247:"divide",248:"oslash",249:"ugrave",250:"uacute",251:"ucirc",252:"uuml",253:"yacute",254:"thorn",255:"yuml",
                 913:"Alpha",914:"Beta",915:"Gamma",916:"Delta",917:"Epsilon",918:"Zeta",919:"Eta",920:"Theta",921:"Iota",
                 922:"Kappa",923:"Lambda",924:"Mu",925:"Nu",926:"Xi",927:"Omicron",928:"Pi",929:"Rho",931:"Sigma",932:"Tau",
                 933:"Upsilon",934:"Phi",935:"Chi",936:"Psi",937:"Omega",8756:"there4",8869:"perp",945:"alpha",946:"beta",
                 947:"gamma",948:"delta",949:"epsilon",950:"zeta",951:"eta",952:"theta",953:"iota",954:"kappa",955:"lambda",
                 956:"mu",957:"nu",968:"xi",969:"omicron",960:"pi",961:"rho",962:"sigmaf",963:"sigma",964:"tau",965:"upsilon",966:"phi",
                 967:"chi",968:"psi",969:"omega",8254:"oline",8804:"le",8260:"frasl",8734:"infin",8747:"int",9827:"clubs",9830:"diams",
                 9829:"hearts",9824:"spades",8596:"harr",8592:"larr",8594:"rarr",8593:"uarr",8595:"darr",8220:"ldquo",8221:"rdquo",
                 8222:"bdquo",8805:"ge",8733:"prop",8706:"part",8226:"bull",8800:"ne",8801:"equiv",8776:"asymp",8230:"hellip",
                 8212:"mdash",8745:"cap",8746:"cup",8835:"sup",8839:"supe",8834:"sub",8838:"sube",8712:"isin",8715:"ni",8736:"ang",
                 8711:"nabla",8719:"prod",8730:"radic",8743:"and",8744:"or",8660:"hArr",8658:"rArr",9674:"loz",8721:"sum",
                 8704:"forall",8707:"exist",8216:"lsquo",8217:"rsquo",161:"iexcl",977:"thetasym",978:"upsih",982:"piv",8242:"prime",
                 8243:"Prime",8472:"weierp",8465:"image",8476:"real",8501:"alefsym",8629:"crarr",8656:"lArr",8657:"uArr",8659:"dArr",
                 8709:"empty",8713:"notin",8727:"lowast",8764:"sim",8773:"cong",8836:"nsub",8853:"oplus",8855:"otimes",8901:"sdot",
                 8968:"lceil",8969:"rceil",8970:"lfloor",8971:"rfloor",9001:"lang",9002:"rang",710:"circ",732:"tilde",8194:"ensp",
                 8195:"emsp",8201:"thinsp",8204:"zwnj",8205:"zwj",8206:"lrm",8207:"rlm",8211:"ndash",8218:"sbquo",8224:"dagger",
                 8225:"Dagger",8249:"lsaquo",8250:"rsaquo"},

    editorMode  : 'rich',
    imageBorder : '#ccc solid',
    currentRS   : new Object(),
    browser     : { msie    : /msie/.test(userAgent) && !/opera/.test(userAgent),
                    ver     : (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
                    gecko   : /gecko/.test(userAgent),
                    opera   : /opera/.test(userAgent),
                    safari  : /webkit/.test(userAgent),
                    mozilla : /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
    },

    popupIFrame : ['fontType', 'fontSize', 'Paragraph', 'boxStyle', 'foreColor', 'backColor', 'BgColor'],
    popup       : {imageUpload :{ tmpl : 'popup_imageUpload.html', boxW : 700, title : '사진 첨부' },
                   imageUrl :   { tmpl : 'popup_image.html', boxW : 354, title : '이미지 URL' },
                   media :      { tmpl : 'popup_media.html', boxW : 430, title : '미디어' },
                   bgimage :    { tmpl : 'popup_bgimage.html', boxW : 379, title : '배경 이미지' },
                   table :      { tmpl : 'popup_table.html', boxW : 430, title : '테이블 만들기' },
                   hyperLink :  { tmpl : 'popup_hlink.html', boxW : 420, title : '하이퍼링크' },
                   emotion :    { tmpl : 'popup_emicon.html',boxW : 350, title : '표정아이콘' },
                   schar :      { tmpl : 'popup_schar.html', boxW : 450, title : '특수 문자' },
                   google_map : { tmpl : 'popup_maps.html',  boxW : 525, title : '지도' },
                   flash :      { tmpl : 'popup_flash.html', boxW : 500, title : '플래쉬 무비' },
                   highlight :  { tmpl : 'popup_highlight.html', boxW : 500, title : '소스코드 하이라이트' }}
}

function URI (uri) {
    this.scheme    = null;
    this.authority = null;
    this.path      = '';
    this.query     = null;
    this.fragment  = null;

    this.parse = function (uri) {
        var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
        this.scheme    = m[3] ? m[2] : null;
        this.authority = m[5] ? m[6] : null;
        this.path      = m[7];
        this.query     = m[9] ? m[10] : null;
        this.fragment  = m[12]? m[13] : null;
        return this;
    }

    this.toString = function () {
        var result = '';
        if(this.scheme    != null) result = result +      this.scheme + ':';
        if(this.authority != null) result = result +'//'+ this.authority;
        if(this.path      != null) result = result +      this.path;
        if(this.query     != null) result = result + '?'+ this.query;
        if(this.fragment  != null) result = result + '#'+ this.fragment;
        return result;
    }

    this.toAbsolute = function (base) {
        var base = new URI(base);
        var r = this;
        var t = new URI;

        if (base.scheme == null) return false;

        if (r.scheme != null && r.scheme.toLowerCase() == base.scheme.toLowerCase()) {
            r.scheme = null;
        }

        if (r.scheme != null) {
            t.scheme    = r.scheme;
            t.authority = r.authority;
            t.path      = removeDotSegments(r.path);
            t.query     = r.query;
        }
        else {
            if (r.authority != null) {
                t.authority = r.authority;
                t.path      = removeDotSegments(r.path);
                t.query     = r.query;
            }
            else {
                if (r.path == '') {
                    t.path = base.path;
                    t.query = r.query || base.query;
                }
                else {
                    if (r.path.substr(0,1) == '/') {
                        t.path = removeDotSegments(r.path);
                    }
                    else {
                        if (base.authority != null && base.path == '') {
                            t.path = '/'+r.path;
                        }
                        else {
                            t.path = base.path.replace(/[^\/]+$/,'')+r.path;
                        }
                        t.path = removeDotSegments(t.path);
                    }
                    t.query = r.query;
                }
                t.authority = base.authority;
            }
            t.scheme = base.scheme;
        }

        t.fragment = r.fragment;
        return t;
    }

    function removeDotSegments (path) {
        var out = '';
        while (path) {
            if (path.substr(0,3)=='../' || path.substr(0,2)=='./') {
                path = path.replace(/^\.+/,'').substr(1);
            }
            else if (path.substr(0,3)=='/./' || path=='/.') {
                path = '/'+path.substr(3);
            }
            else if (path.substr(0,4)=='/../' || path=='/..') {
                path = '/'+path.substr(4);
                out = out.replace(/\/?[^\/]*$/, '');
            }
            else if (path=='.' || path=='..') {
                path = '';
            }
            else {
                var rm = path.match(/^\/?[^\/]*/)[0];
                path = path.substr(rm.length);
                out = out + rm;
            }
        }
        return out;
    }

    if (uri) this.parse(uri);
}

function setConfig (oname) {
    this.config = {
            editorWidth     : '100%',
            editorHeight    : '300px',
            editorFontSize  : '9pt',
            editorFontFace  : '굴림',
            editorFontColor : '#000',
            editorBgColor   : '#fff',
            lineHeight      : 1.4,
            editAreaMargin  : '7px',
            tabIndex        : 0,
            editorPath      : null,
            fullHTMLSource  : false,
            outputXhtml     : true,
            xhtmlLang       : 'ko',
            xhtmlEncoding   : 'euc-kr',
            hrefTarget      : '_blank',
            showTagPath     : false,
            toolBarSplit    : true,
            imgMaxWidth     : 640,
            imgBlockMargin  : '5px 0px',
            imgReSize       : true,
            includeHostname : false,
            ieEnterMode     : 'css', // [css, div, br, default]
            useSource       : true,
            usePreview      : true,
            usePrint        : true,
            useUndo         : true,
            useCopy         : true,
            useCut          : true,
            usePaste        : true,
            usePasteFromWord: true,
            useSelectAll    : true,
            useBold         : true,
            useUnderline    : true,
            useStrike       : true,
            useItalic       : true,
            useSuperscript  : true,
            useSubscript    : true,
            useJustifyLeft  : true,
            useJustifyCenter: true,
            useJustifyRight : true,
            useJustifyFull  : true,
            useOrderedList  : true,
            useUnOrderedList: true,
            useOutdent      : true,
            useIndent       : true,
            useFontType     : true,
            useParagraph    : true,
            useFontSize     : true,
            useBackColor    : true,
            useForeColor    : true,
            useBGColor      : true,
            useSChar        : true,
            useHyperLink    : true,
            useUnLink       : true,
            useFlash        : true,
            useMedia        : true,
            useUploadImage  : true,
            useImageLink    : true,
            useBGImage      : true,
            useEmotion      : true,
            useHR           : true,
            autoHeight      : false,
            useTable        : true,
            useBoxStyle     : true,
            useFullScreen   : true,
            usePageBreak    : true,
            useBodyAttribute: false
    };

    if (this.config.editorPath == null) {
        var base = location.href;
        var e = document.getElementsByTagName('base')
        for (var i=0; i<e.length; i++) {
            if (e[i].href)
                base = e[i].href;
        }

        var e = document.getElementsByTagName('script');
        for (var i=0; i<e.length; i++) {
            if (e[i].src) {
                var src = new URI(e[i].src);
                if(/\/cheditor\.js$/.test(src.path)) {
                    var srcAbs = src.toAbsolute(base).toString();
                    delete srcAbs.query;
                    delete srcAbs.fragment;
                    this.config.editorPath = srcAbs.replace(/[^\/]+$/, '');
                }
            }
        }
    }

    this.oname              = oname;
    this.editorId           = 'id_'+this.oname;
    this.editArea           = null;
    this.doc                = null;
    this.editAreaWrapper    = null;
    this.tmpObject          = null;
    this.inputForm          = null;
    this.range              = null;
    this.selectionType      = null;
    this.szTmp              = '';
    this.images             = new Array();
    this.currentMode        = 'rich';
    this.setFullScreenMode  = false;
    this.iconPath           = this.config.editorPath + 'icons/';
    this.cssPath            = this.config.editorPath + 'css/';
    this.popupPath          = this.config.editorPath + 'popup/';
    this.editorElem         = new Object();
    this._modalReSize       = null;
};

function cheditor () {
    var argv = arguments;
    try {
        if (argv.length < 1) {
            throw "CHEditor의 개체 이름을 설정하여 주십시오.";
        }
        if (typeof(document.execCommand) == 'undefined') {
            throw "현재 브라우저가 execCommand를 지원하지 않습니다.";
        }
        if (GB.browser.msie && GB.browser.ver < 6) {
            throw "CHEditor는 MSIE 6.0 이하 버전은 지원하지 않습니다.";
        }
        else if (GB.browser.gecko) {
            if (navigator.productSub < 20030107)
                throw "CHEditor는 현재 사용 중인 브라우저를 지원하지 않습니다.";
        }
    }
    catch (e) {
        alert(e);
        return null;
    }

    setConfig.apply(this, argv);

    if (this.config.editorPath == null) {
        alert('CHEditor 경로가 바르지 않습니다.\nmyeditor.config.editorPath를 설정하여 주십시오.');
        return null;
    }
};

cheditor.prototype = {
//----------------------------------------------------------------

resetData : function () {
    this.resetEditArea();
    if (GB.browser.msie) {
        try { this.doc.execCommand('BackgroundImageCache', false, true); }
        catch (e) {}
    }
},

appendContents : function (contents) {
    this.editArea.focus();
    var div = this.doc.createElement('div');
    div.innerHTML = '' + this.trimSpace(contents);

    while (div.hasChildNodes())
        this.doc.body.appendChild(div.firstChild);

    this.editArea.focus();
},

insertContents : function (contents) {
    this.editArea.focus();
    this.setSelection();
    this.doCmdPaste(''+this.trimSpace(contents));
},

replaceContents : function (contents) {
    this.editArea.focus();
    this.doc.body.innerHTML = '';
    this.loadContents(contents);
    this.editArea.focus();
},

loadContents : function (contents) {
    this.editAreaWrapper.style.visibility = 'hidden';

    if (typeof(contents) === 'string') {
        this.doc.body.innerHTML = this.trimSpace(contents);
    }

    this.editAreaWrapper.style.visibility = 'visible';
},

loadScript : function (path) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = path;
    var head = document.getElementsByTagName("head")[0] || document.documentElement;
    var done = false;

    script.onload = script.onreadystatechange = function() {
        if (!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete"))
        {
            done = true;
            head.removeChild(script);
        }
    };

    head.appendChild(script);
},

setDesignMode : function (designMode) {
    if (GB.browser.msie) {
        this.doc.body.contentEditable = designMode;
    }
    else {
        this.doc.designMode = designMode ? "On" : "Off";
    }
},

openDoc : function (doc, contents) {
    doc.open("text/html", "replace");
    doc.close();

    if (typeof(contents) === 'string')
        doc.body.innerHTML = contents;
},

resetDoc : function () {
    this.editArea = this.editAreaWrapper.contentWindow;
    this.doc = this.editArea.document;
},

resetEditArea : function () {
    this.resetDoc();
    this.openDoc(this.doc);
    this.setDesignMode(true);
    this.editArea.focus();

    if (this.inputForm != null && typeof(this.$(this.inputForm)) != 'undefined') {
        this.setDesignMode(false);
        this.loadContents(this.trimSpace(this.$(this.inputForm).value));
        this.setDesignMode(true);
    }

    this.doc.body.style.fontSize        = this.config.editorFontSize;
    this.doc.body.style.fontFamily      = this.config.editorFontFace;
    this.doc.body.style.color           = this.config.editorFontColor;
    this.doc.body.style.margin          = this.config.editAreaMargin;
    this.doc.body.style.lineHeight      = this.config.lineHeight;
    this.doc.body.style.backgroundColor = this.config.editorBgColor;
    this.editAreaWrapper.style.padding  = '0px';
    this.editAreaWrapper.style.margin   = '0px';
    this.editAreaWrapper.style.fontSize = '9pt';
},

resizeCancelEvent : function (event) {
    if (event.preventDefault) {
        event.preventDefault();
    }
    else {
        event.cancelBubble = true;
        event.returnValue = false;
    }
},

resizeStart : function (event) {
    GB.currentRS.elNode = this.editAreaWrapper;
    var y = GB.browser.msie ? window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop :
        event.clientY + window.pageYOffset;

    GB.currentRS.cursorStartY = y;
    GB.currentRS.elStartTop = parseInt(GB.currentRS.elNode.style.height);
    if (isNaN(GB.currentRS.elStartTop)) GB.currentRS.elStartTop = 0;

    var self = this;
    var ev = event || window.event;
    self._dragStopFunc = function () { self.resizeStop.call(self, ev); };
    self._dragMoveFunc = self.resizeMove;

    self.setSelection();
    GB.currentRS.elNode.style.visibility = 'hidden';

    if (GB.browser.msie) {
        document.attachEvent("onmousemove", self._dragMoveFunc );
        document.attachEvent("onmouseup", self._dragStopFunc);
    }
    else {
        document.addEventListener("mousemove", self._dragMoveFunc, true);
        document.addEventListener("mouseup", self._dragStopFunc, true);
    }

    self.resizeCancelEvent(ev);
},

resizeMove : function (event) {
    var y = (GB.browser.msie) ? window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop :
        event.clientY + window.pageYOffset;

    var h = (GB.currentRS.elStartTop + y - GB.currentRS.cursorStartY);
    GB.currentRS.elNode.style.height  = (h < 1 ? 1 : h) + 'px';

    if (event.preventDefault) {
        event.preventDefault();
    }
    else {
        event.cancelBubble = true;
        event.returnValue = false;
    }
},

resizeStop : function (event) {
    if (GB.browser.msie) {
        document.detachEvent("onmousemove", this._dragMoveFunc);
        document.detachEvent("onmouseup", this._dragStopFunc);
    }
    else {
        document.removeEventListener("mousemove", this._dragMoveFunc, true);
        document.removeEventListener("mouseup", this._dragStopFunc, true);
    }

    this.resizeCancelEvent(event);

    GB.currentRS.elNode.style.visibility = 'visible';
    this.editArea.focus();
    this.restoreRange();
},

switchEditorMode : function (selectedMode) {
    this.editArea.focus();
    if (this.currentMode == selectedMode) return;

    switch (selectedMode) {
        case 'rich' :
            if (this.currentMode == 'preview')
                this.previewMode();
            else if (this.currentMode == 'code')
                this.editMode();

            this.$(this.oname+'_tabEditModeRich').src = this.iconPath + 'edit_mode_rich_a.gif';
            if (this.config.useSource) {
                this.$(this.oname+'_tabEditModeCode').src = this.iconPath + 'edit_mode_code_b.gif';
            }
			if (this.config.usePreview) {
	            this.$(this.oname+'_tabEditModePreview').src = this.iconPath + 'edit_mode_view_b.gif';
			}
            break;
        case 'code' :
            this.$(this.oname+'_tabEditModeRich').src = this.iconPath + 'edit_mode_rich_b.gif';
            this.$(this.oname+'_tabEditModeCode').src = this.iconPath + 'edit_mode_code_a.gif';
			if (this.config.usePreview) {
	            this.$(this.oname+'_tabEditModePreview').src = this.iconPath + 'edit_mode_view_b.gif';
			}
            this.editMode();
            break;
        case 'preview' :
            this.previewMode();
            this.$(this.oname+'_tabEditModeRich').src = this.iconPath + 'edit_mode_rich_b.gif';
            if (this.config.useSource) {
                this.$(this.oname+'_tabEditModeCode').src = this.iconPath + 'edit_mode_code_b.gif';
            }
            this.$(this.oname+'_tabEditModePreview').src = this.iconPath + 'edit_mode_view_a.gif';
            break;
    }
    this.currentMode = selectedMode;
},

run : function () {
    var self = this;
    self.setDefaultCss({cssName: 'default.css', doc: window.document});

    var container = document.createElement('div');
    container.style.textAlign = 'left';
    container.style.position = 'relative';
    container.style.width = self.config.editorWidth;
    self.editorElem.container = container;

    var toolbar = document.createElement('div');
    self.editorElem.toolbar = toolbar;
    toolbar.className = 'cheditor_toolbar';
    self.drawToolbar(toolbar);
    container.appendChild(toolbar);

    var editorWrapper = document.createElement('div');
    editorWrapper.className = 'cheditor_editarea';
    container.appendChild(editorWrapper);
    self.editorElem.editorWrapper = editorWrapper;

    var editorFrame = document.createElement('iframe');
    editorFrame.setAttribute('frameBorder', 0);
    editorFrame.style.border = '0px';
    editorFrame.style.width = '100%';
    editorFrame.style.height = self.config.editorHeight;
    editorFrame.style.overflow = 'auto';

    if (isNaN(self.config.tagIndex) == false)
        editorFrame.setAttribute('tabIndex', this.config.tabIndex);

    self.editAreaWrapper = editorFrame;
    editorWrapper.appendChild(editorFrame);

    var editBlock = document.createElement('div');
    editBlock.className = 'cheditor_modify_block';
    editBlock.appendChild(document.createTextNode('\u00a0'));
    container.appendChild(editBlock);
    self.editorElem.editBlock = editBlock;

    if (self.config.showTagPath) {
        var tagPath = document.createElement('div');
        tagPath.className = 'cheditor_tag_path';
        var span = document.createElement('span');
        span.className = 'cheditor_status_bar';
        span.appendChild(document.createTextNode('<html> <body>'));
        self.editorElem.tagPath = span;
        tagPath.appendChild(span);
        container.appendChild(tagPath);
    }

    var resizeBar = document.createElement('div');
    resizeBar.onmousedown = function(event) { self.resizeStart(event); };
    resizeBar.className = 'cheditor_splitter';
    self.editorElem.resizeBar = resizeBar;

    var resizeIco = new Image();
    resizeIco.src = self.iconPath + 'splitter.gif';
    resizeIco.style.verticalAlign = 'top';
    resizeIco.setAttribute('alt', '');
    resizeBar.appendChild(resizeIco);
    container.appendChild(resizeBar);

    var viewMode = document.createElement('div');
    viewMode.style.paddingLeft = '4px';
    viewMode.style.height = '16px';
    viewMode.style.background = 'url(' + self.iconPath + 'statusbar_bgline.gif) 0 0 repeat-x';
    self.editorElem.viewMode = viewMode;

    var imgRich = new Image();
    imgRich.id = self.oname + '_tabEditModeRich';
    imgRich.src = self.iconPath + 'edit_mode_rich_a.gif';
    imgRich.setAttribute('title', '입력모드');
    imgRich.setAttribute('alt', '');
    imgRich.style.cursor = 'pointer';
    imgRich.onclick = function() {self.switchEditorMode('rich');};
    viewMode.appendChild(imgRich);

    if (this.config.useSource) {
        var imgSource = new Image();
        imgSource.id = self.oname + '_tabEditModeCode';
        imgSource.src = self.iconPath + 'edit_mode_code_b.gif';
        imgSource.setAttribute('title', 'HTML 편집');
        imgSource.setAttribute('alt', '');
        imgSource.style.cursor = 'pointer';
        imgSource.onclick = function() {self.switchEditorMode('code');};
        viewMode.appendChild(imgSource);
    }

	if (this.config.usePreview) {
		var imgPreview = new Image();
		imgPreview.id = self.oname + '_tabEditModePreview';
		imgPreview.src = self.iconPath + 'edit_mode_view_b.gif';
		imgPreview.setAttribute('title', '미리보기');
		imgPreview.setAttribute('alt', '');
		imgPreview.style.cursor = 'pointer';
		imgPreview.onclick = function() {self.switchEditorMode('preview');};
		viewMode.appendChild(imgPreview);
	}

    var statusBlock = document.createElement('div');
    statusBlock.appendChild(resizeBar);
    statusBlock.appendChild(viewMode);
    container.appendChild(statusBlock);

    var popupWindow = document.createElement('div');
    popupWindow.className = 'cheditor_popup_window';
    popupWindow.setAttribute('onselectstart', 'return false');
    self.editorElem.popupElem = popupWindow;

    var dragHandle = document.createElement('div');
    dragHandle.className = 'cheditor_popup_drag_handle';
    dragHandle.style.background = '#6b90c0 url(' + self.iconPath + '/title_bar_bg.gif)';
    self.editorElem.dragHandle = dragHandle;

    var titleBar = document.createElement('div');
    titleBar.className = 'cheditor_popup_title_bar';
    var label = document.createElement('label');
    label.className = 'cheditor_popup_title';
    self.editorElem.popupTitle = label;
    titleBar.appendChild(label);
    dragHandle.appendChild(titleBar);
    popupWindow.appendChild(dragHandle);

    var popupFrameWrapper = document.createElement('div');
    popupFrameWrapper.className = 'cheditor_popup_cframe';
    popupWindow.appendChild(popupFrameWrapper);
    container.appendChild(popupWindow);
    self.editorElem.popupFrameWrapper = popupFrameWrapper;

    if (self.inputForm != null) {
        var textarea = self.$(self.inputForm);
        if (textarea != 'undefined') {
            textarea.style.display = 'none';
            var pNode = textarea.parentNode,
                nNode = textarea.nextSibling;

            if (nNode == null) {
                pNode.appendChild(container);
            }
            else {
                pNode.insertBefore(container, nNode);
            }
        }
        self.editorElem.textarea = textarea;
    }

    var modalBackground = document.createElement('div');
    modalBackground.className = 'cheditor_modalPopupTransparent';
    self.editorElem.modalBackground = modalBackground;
    container.parentNode.insertBefore(modalBackground, container);

    var tmpframe = document.createElement('iframe');
    tmpframe.setAttribute('contentEditable', true);
    tmpframe.style.visibility = 'hidden';
    tmpframe.style.height = tmpframe.style.width = '0px';
    tmpframe.setAttribute('frameBorder', 0);
    container.appendChild(tmpframe);

    var tmpdoc = tmpframe.contentWindow.document;
    tmpdoc.designMode = 'On';
    tmpdoc.open("text/html","replace");
    tmpdoc.write("<html><body></body></html>");
    tmpdoc.close();
    self.editorElem.tmpdoc = tmpdoc;

    self.resetData();
    self.editArea.focus();
    self.setEditorEvent();
    self.setDefaultCss();

},

fullScreenMode : function () {
    var self = this;
    self.editArea.focus();
    self.boxHideAll();

    var container = self.editorElem.container,
        tmpFlagId = 'CHEditorTmpFlag_' + self.oname,
        docElement = self.doc.documentElement;

    container.style.visibility = 'hidden';
    var openDoc = function(content) {
        self.doc.open("text/html", "replace");
        self.doc.write(content);
        self.doc.close();
    };

    if (self.setFullScreenMode == false) {
        var margin = 2,
            tmpFlag = document.createElement('div');

        tmpFlag.id = tmpFlagId;
        tmpFlag.style.display = 'none';
        container.parentNode.insertBefore(tmpFlag, container);
        document.body.insertBefore(container, document.body.firstChild);

        container.style.position = 'absolute';
        container.style.top = container.style.left = 0;
        container.style.width = '100%';
        container.style.zIndex = 99;

        var s = self.editorElem.toolbar.offsetHeight + self.editorElem.resizeBar.offsetHeight +
                self.editorElem.viewMode.offsetHeight + 2;

        var containerReSize = function() {
            var winSize = self.getWindowSize();
            container.style.height = winSize.height + 'px';
            self.editAreaWrapper.style.height = winSize.height - s + 'px';
        };

        containerReSize();
        window.onresize = containerReSize;

        self.resetDoc();
        openDoc(GB.browser.msie ? docElement.outerHTML : docElement.innerHTML);
    }
    else {
        window.onresize = null;
        self.$(tmpFlagId).parentNode.replaceChild(container, self.$(tmpFlagId));
        self.resetDoc();
        openDoc(GB.browser.msie ? docElement.outerHTML : docElement.innerHTML);

        container.removeAttribute('style');
        container.style.position = 'relative';
        container.style.width = self.config.editorWidth;
        container.style.textAlign = 'left';
        self.editAreaWrapper.style.height = self.config.editorHeight;
    }

    self.setFullScreenMode = !(self.setFullScreenMode);
    container.style.visibility = 'visible';

    self.setDesignMode(true);
    self.setEditorEvent();
    self.setDefaultCss();
    self.editArea.focus();
},

showColorMenu : function (idImg, menu) {
    var boxName = menu + '_' + this.oname;

    if (this.$(boxName) == null) {
        var output = this.setColorTable(menu);
        this.createWindow(180, output);
        this.createPulldownFrame(output, boxName);
    }

    this.windowPos(idImg, boxName);
    this.displayWindow(boxName);
},

showFontTypeMenu : function (idImg) {
    var self = this;
    var boxName = 'fontType_' + self.oname;

    if (!self.$(boxName)) {
        var outputHtml = document.createElement('div');
        var fontFace = ['굴림', '바탕', '돋움', '궁서', '맑은 고딕',
                        'Arial', 'Arial Black', 'Arial Narrow', 'Courier New', 'Tahoma', 'Times New Roman', 'Verdana'];

        for (var i=0; i < fontFace.length; i++) {
            var div = document.createElement('div');
            var label = document.createElement('label');
            div.el = fontFace[i];
            div.onclick = function() { self.doCmdPopup("FontName", this.el); };
            div.onmouseover = function() { self.mouseOver(this); };
            div.onmouseout = function() { self.mouseOut(this); };
            div.style.padding = '2px';
            div.style.lineHeight = 1.1;
            div.style.margin = '1px';
            div.style.fontSize = '9pt';
            label.style.fontFamily = fontFace[i];
            label.appendChild(document.createTextNode(fontFace[i]));
            div.appendChild(label);
            outputHtml.appendChild(div);
        }
        self.createWindow(150, outputHtml);
        self.createPulldownFrame(outputHtml, boxName);
    }

    self.windowPos(idImg, boxName);
    self.displayWindow(boxName);
},

showParagraphMenu : function (idImg) {
    var self = this;
    var boxName = 'Paragraph_' + self.oname;

    if (!self.$(boxName)) {
        var outputHtml = document.createElement('div');
        var para = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'PRE', 'ADDRESS', 'DIV', 'P'];
        var text = ['제목 1', '제목 2', '제목 3', '제목 4', '제목 5', '제목 6', 'Preformatted (PRE)', '주소 (ADDRESS)', '보통 (DIV)', '보통 (P)'];

        for (var i=0; i < para.length; i++) {
            var div = document.createElement('div');
            div.el = para[i];
            div.onclick = function() { self.doCmdPopup("FormatBlock", '<' + this.el + '>'); };
            div.onmouseover = function() { self.mouseOver(this); };
            div.onmouseout = function() { self.mouseOut(this); };
            div.style.padding = '2px';
            div.style.margin = '1px';
            div.style.cursor = 'default';
            div.style.lineHeight = 1.1;

            if (para[i].match(/H[123456]/)) {
                var H = document.createElement(para[i]);
                H.style.margin = '0px';
                H.appendChild(document.createTextNode(text[i]));
                div.appendChild(H);
            }
            else {
                var span = document.createElement('span');
                span.style.fontSize = '9pt';
                span.style.margin = '0px';
                if (para[i] == 'ADDRESS') span.style.fontStyle = 'italic';
                span.appendChild(document.createTextNode(text[i]));
                div.appendChild(span);
            }
            outputHtml.appendChild(div);
        }

        self.createWindow(150, outputHtml);
        self.createPulldownFrame(outputHtml, boxName);
    }

    self.windowPos(idImg, boxName);
    self.displayWindow(boxName);
},

showFontSizeMenu : function (idImg) {
    var self = this;
    var boxName = 'fontSize_' + self.oname;

    if (!self.$(boxName)) {
        var outputHtml = document.createElement('div');
        var fontSize = [1, 2, 3, 4, 5, 6, 7];
        var showFont = [8, 10, 12, 14, 18, 24, 32];

        for (var i=0; i < fontSize.length; i++) {
            var div = document.createElement('div');
            var label = document.createElement('label');
            var text = showFont[i] == 32 ? '가나다' : '가나다라';
            div.el = fontSize[i];
            div.onclick = function() { self.doCmdPopup("FontSize", this.el); };
            div.onmouseover = function() { self.mouseOver(this); };
            div.onmouseout = function() { self.mouseOut(this); };
            div.style.padding = '2px';
            div.style.margin = '1px';
            div.style.lineHeight = 1.1;
            div.style.fontSize = showFont[i] + 'pt';
            label.style.fontFamily = this.config.editorFontFace;
            label.appendChild(document.createTextNode(text+'('+showFont[i]+'pt)'));
            div.appendChild(label);
            outputHtml.appendChild(div);
        }

        this.createWindow(280, outputHtml);
        this.createPulldownFrame(outputHtml, boxName);
    }

    this.windowPos(idImg, boxName);
    this.displayWindow(boxName);
},

showBoxStyleMenu : function (idImg) {
    var self = this;
    var boxName = 'boxStyle_' + self.oname;

    if (!self.$(boxName)) {
        var outputHtml = document.createElement('div');
        var quote = [['1px #dedfdf solid','#f7f7f7'],
                     ['1px #aee8e8 solid','#bfffff'],
                     ['1px #d3bceb solid','#e6ccff'],
                     ['1px #e8e88b solid','#ffff99'],
                     ['1px #c3e89e solid','#d6ffad'],
                     ['1px #e8c8b7 solid','#ffdcc9'],
                     ['1px #666666 dashed','#ffffff'],
                     ['1px #d4d4d4 solid','#ffffff'],
                     ['1px #cccccc inset','#f7f7f7']];

        for (var i=0; i < quote.length; i++) {
            var wrapper = document.createElement('div');
            var div = document.createElement('div');
            div.onclick = function() { self.boxStyle(this); };
            wrapper.onmouseover = function() { this.style.border = "1px #316ac5 solid"; };
            wrapper.onmouseout = function() { this.style.border = "1px #fff solid"; };
            wrapper.style.border = '1px #fff solid';
            wrapper.style.padding = '1px';
            wrapper.style.margin = '1px';
            div.style.textAlign = 'center';
            div.style.lineHeight = '18px';
            div.style.fontSize = '9pt';
            div.style.border = quote[i][0];
            div.style.backgroundColor = quote[i][1];
            div.style.cursor = 'default';
            div.style.fontFamily = self.config.editorFontFace;
            div.appendChild(document.createTextNode('가나다라 ABC'));
            wrapper.appendChild(div);
            outputHtml.appendChild(wrapper);
        }

        self.createWindow(100, outputHtml);
        self.createPulldownFrame(outputHtml, boxName);
    }

    self.windowPos(idImg, boxName);
    self.displayWindow(boxName);
},

createPulldownFrame : function (contents, id) {
    var div = document.createElement('div');
    div.id = id;
    div.className = 'cheditor_pulldown_frame';
    div.appendChild(contents);
    this.editorElem.container.firstChild.appendChild(div);
},

setDefaultCss : function (ar) {
    if (arguments.length == 0) {
        ar = {cssName: 'default.css', doc: this.doc};
        if (GB.browser.msie) {
            ar = {cssName: 'p.css', doc: this.doc};
        }
    }

    var cssFile = this.cssPath + ar.cssName,
        head = ar.doc.getElementsByTagName('head')[0],
        found = false;

    if (typeof head == 'undefined')
        return;

    if (head.hasChildNodes()) {
        var child = head.childNodes;
        for (var i = 0; i < child.length; i++) {
            if (child[i].tagName == 'LINK') {
                var href = child[i].getAttribute('href');
                if (href != null && href == cssFile) {
                    found = true;
                    break;
                }
            }
        }
    }

    if (found == false) {
        var css = head.appendChild(ar.doc.createElement('link'));
        css.setAttribute('type', 'text/css');
        css.setAttribute('rel', 'stylesheet');
        css.setAttribute('media', 'all');
        css.setAttribute('href', this.cssPath + ar.cssName);
    }
},

setEditorEvent : function () {
    var self = this;

    if (GB.browser.msie && self.config.ieEnterMode == 'br') {
        self.doc.onkeydown = function() { self.doOnKeyPress(); };
    }

    var func = function() { self.doEditorEvent(); };
    self.addEvent(self.doc, "mouseup", func);

    var hideBox = function() { self.boxHideAll(); };
    self.addEvent(self.doc, "mousedown", hideBox);
},

addEvent : function (doc, ev, func) {
    this.removeEvent(doc, ev, func);

    if (GB.browser.msie)
        doc.attachEvent("on"+ev, func);
    else
        doc.addEventListener(ev, func, false);
},

removeEvent : function (doc, ev, func) {
    if (GB.browser.msie)
        doc.detachEvent("on"+ev, func);
    else
        doc.removeEventListener(ev, func, false);
},

toolbarButtonOut : function (elemButton, nTop) {
    elemButton.style.top = -nTop + 'px';
},

toolbarButtonOver : function (elemButton) {
    var nTop = elemButton.style.top.substring(0, elemButton.style.top.length - 2);
    elemButton.style.top = nTop - 22 + 'px';
},

showToolbar : function (tb, td) {
    for (var i in tb) {
        if (typeof tb[i].use === "boolean" && tb[i].use == true) {
            var icon = this.drawToolbarIcon(tb[i]);
            td.appendChild(icon);
        }
    }
},

drawToolbarIcon : function (icon) {
    var self = this;
    var iconWidth = icon.icon[2];
    var toolTip = icon.title;
    var iconBlock = icon.icon[0];
    var cmd = icon.exec;
    var top = icon.icon[1];
    var rect = (GB.browser.msie && GB.browser.ver < 8) ? '0px,'+iconWidth+'px,22px,0px' : '0px '+iconWidth+'px 22px 0px';
    var div = document.createElement('div');
    div.style.width = iconWidth + 'px';
    div.className = 'cheditor_toolbar_icon_wrapper';

    var span = document.createElement('span');
    span.setAttribute('unselectable', 'on');
    span.style.cursor = 'pointer';
    span.style.position = 'absolute';
    span.style.height = '24px';
    span.style.width = iconWidth + 'px';
    span.style.clip = 'rect(' + rect + ')';
    div.appendChild(span);

    var img = new Image();
    img.id = 'cheditor_toolbar_' + iconBlock + '_' + top;
    img.setAttribute('title', toolTip);
    img.src = self.iconPath + 'toolbar_icon_' + iconBlock + '.gif';
    img.style.position = 'absolute';
    img.style.top = -top + 'px';
    img.style.width = iconWidth + 'px';
    img.onmouseover = function() { self.toolbarButtonOver(this); };
    img.onmouseout  = function() { self.toolbarButtonOut(this, top); };
    img.onclick = function() {
        if (img.id == 'cheditor_toolbar_7_44') self.toolbarButtonOut(this, top);
        cmd.call(self, this.id);
    };

    img.setAttribute('alt', '');
    span.appendChild(img);

    return div;
},

drawToolbar : function (wrapper) {
    var toolbarRow1 = {
        btnPrint : { use : this.config.usePrint, icon : [1,0,22], title : '인쇄', exec : function() { this.doCmd('print', false); }},
        btnUndo : { use : this.config.useUndo, icon : [1,44,22], title : '실행취소', exec : function() { this.doCmd('Undo', false); }},
        btnRedo : { use : this.config.useUndo, title : '되돌리기', icon : [1,88,22], exec :function() { this.doCmd('Redo', false); }},
        btnCopy : { use : this.config.useCopy, icon : [1,132,22], title : '복사', exec : function() { this.doCmd('Copy', false); }},
        btnCut : { use : this.config.useCut, icon : [2,0,22], title : '잘라내기', exec : function() { this.doCmd('Cut', false); }},
        btnPaste : { use : this.config.usePaste, icon : [2,44,22], title : '붙이기', exec : function() { this.doCmd('Paste', false); }},
        btnPasteFromWord : { use : this.config.usePasteFromWord, icon : [10,88,22], title : 'MS워드 붙이기', exec : function() { this.doCmd('PasteFromWord', false); }},
        btnSelectAll : { use : this.config.useSelectAll, icon : [2,88,22], title : '전체 선택', exec : function() { this.doCmd('SelectAll', false); }},
        btnBold : { use : this.config.useBold, icon : [2,132,22], title : '진하게', exec : function() { this.doCmd('Bold', false); }},
        btnUnderline : { use : this.config.useUnderline, icon : [3,0,22], title : '밑줄', exec : function() { this.doCmd('Underline', false); }},
        btnStrike : { use : this.config.useStrike, icon : [3,44,22], title : '취소선', exec : function() { this.doCmd('Strikethrough', false); }},
        btnItalic : { use : this.config.useItalic, icon : [3,88,22], title : '기울임', exec : function() { this.doCmd('Italic', false); }},
        btnSuperscript : { use : this.config.useSuperscript, icon : [3,132,22], title : '위첨자', exec : function() { this.doCmd('Superscript', false); }},
        btnSubscript : { use : this.config.useSubscript, icon : [4,0,22], title : '아래첨자', exec : function() { this.doCmd('Subscript', false); }},
        btnJustifyLeft : { use : this.config.useJustifyLeft, icon : [4,44,22], title : '왼쪽 정렬', exec : function() { this.doCmd('JustifyLeft', false); }},
        btnJustifyCenter : { use : this.config.useJustifyCenter, icon : [4,88,22], title : '가운데 정렬', exec : function() { this.doCmd('JustifyCenter', false); }},
        btnJustifyRight : { use : this.config.useJustifyRight, icon : [4,132,22], title : '오른쪽 정렬', exec : function() { this.doCmd('JustifyRight', false); }},
        btnJustifyFull : { use : this.config.useJustifyFull, icon : [5,0,22], title : '양쪽 정렬', exec : function() { this.doCmd('JustifyFull', false); }},
        btnOrderedList : { use : this.config.useOrderedList, icon : [5,44,22], title : '문단 번호', exec : function() { this.doCmd('InsertOrderedList', false); }},
        btnUnOrderedList : { use : this.config.useUnOrderedList, icon : [5,88,22], title : '글 머리표', exec : function() { this.doCmd('InsertUnOrderedList', false); }},
        btnOutdent : { use : this.config.useOutdent, icon : [5,132,22], title : '왼쪽 여백 줄이기', exec : function() { this.doCmd('Outdent', false); }},
        btnIndent : { use : this.config.useIndent, icon : [6,0,22], title : '왼쪽 여백 늘이기', exec : function() { this.doCmd('Indent', false); }}
    };

    var toolbarRow2 = {
        btnFontType : { use : this.config.useFontType, icon : [8,0,30], title : '글꼴', exec : function(id) { this.showFontTypeMenu(id); }},
        btnParagraph : { use : this.config.useParagraph, icon : [8,44,30], title : '단락', exec : function(id) { this.showParagraphMenu(id); }},
        btnFontSize : { use : this.config.useFontSize, icon : [8,88,30], title : '글꼴 크기', exec : function(id) { this.showFontSizeMenu(id); }},
        btnBoxStyle : { use : this.config.useBoxStyle, icon : [11,0,22], title : '박스', exec : function(id) { this.showBoxStyleMenu(id); }},
        btnBackColor : { use : this.config.useBackColor, icon : [9,88,22], title : '형광펜', exec : function(id) { this.showColorMenu(id, 'backColor'); }},
        btnForeColor : { use : this.config.useForeColor, icon : [9,132,22], title : '글자색', exec : function(id) { this.showColorMenu(id, 'foreColor'); }},
        btnBGColor : { use : this.config.useBGColor, icon : [9,44,22], title : '배경색', exec : function(id) { this.showColorMenu(id, 'BgColor'); }},
        btnSChar : { use : this.config.useSChar, icon : [7,132,22], title : '특수문자', exec : function() { this.windowOpen('schar'); }},
        btnHyperLink : { use : this.config.useHyperLink, icon : [6,44,22], title : '하이퍼링크', exec : function() { this.windowOpen('hyperLink'); }},
        btnUnLink : { use : this.config.useUnLink, icon : [6,88,22], title : '하이퍼링크 취소', exec :function() { this.doCmd('UnLink', false); }},
        btnFlash : { use : this.config.useFlash, icon : [9,0,22], title : '플래쉬', exec : function() { this.windowOpen('flash'); }},
        btnMedia : { use : this.config.useMedia, icon : [6,132,22], title : '미디어', exec : function() { this.windowOpen('media'); }},
        btnUploadImage : { use : this.config.useUploadImage, icon : [7,0,22], title : '사진 넣기', exec : function() { this.windowOpen('imageUpload'); }},
        btnImageLink : { use : this.config.useImageLink, icon : [12,0,22], title : '외부 사진', exec : function() { this.windowOpen('imageUrl'); }},
        btnBGImage : { use : this.config.useBGImage, icon : [11,88,22], title : '배경 패턴', exec : function() { this.windowOpen('bgimage'); }},
        btnEmotion : { use : this.config.useEmotion, icon : [7,88,22], title : '이모티콘', exec : function() { this.windowOpen('emotion'); }},
        btnHR : { use : this.config.useHR, icon : [10,0,22], title : '가로선', exec : function() { this.doCmd('InsertHorizontalRule'); }},
        btnTable : { use : this.config.useTable, icon : [10,44,22], title : '테이블', exec : function() { this.windowOpen('table'); }},
        btnPageBreak : { use : this.config.usePageBreak, icon : [10,132,22], title : '인쇄 페이지 나눔', exec : function() { this.printPageBreak(); }},
        btnMap : { use : this.config.useMap, icon : [11,132,22], title : '지도', exec : function() { this.windowOpen('google_map'); }},
        btnHighLight : { use : this.config.useHighlight, icon : [11,44,22], title : '코드 하일라이트', exec : function() { this.windowOpen('highlight'); }},
        btnFullScreen : { use : this.config.useFullScreen, icon : [7,44,22], title : '전체화면', exec : function() { this.fullScreenMode(); }}
    };

    var table = document.createElement('table');
    table.border = table.cellPadding = table.cellSpacing = 0;
    var cell_1 = table.insertRow(0).insertCell(0);
    cell_1.align = 'left';
    this.showToolbar(toolbarRow1, cell_1);

    if (this.config.toolBarSplit) {
        var cell_2 = table.insertRow(1).insertCell(0);
        cell_2.align = 'left';
        this.showToolbar(toolbarRow2, cell_2);
    }
    else {
        this.showToolbar(toolbarRow2, cell_1);
    }

    wrapper.appendChild(table);
},

changeBodyColor : function (val) { this.setBodyColor(val); },

changeFontColor : function (color, type) {
    if (type == 'back') {
        this.doCmdPopup(GB.browser.msie ? 'BackColor' : 'HiliteColor', color);
    }
    else {
        this.doCmdPopup('ForeColor', color);
    }
},

setBodyColor : function (color) {
    this.doc.body.style.backgroundColor = color;

    if (GB.browser.msie && this.range)
        this.range.select();

    this.boxHideAll();
    this.editArea.focus();
},

getElement : function (elm, tag) {
    while (elm != null && elm.tagName != tag) {
        if (elm.id == this.editorId) return null;
        elm = elm.parentElement;
    }
    return elm;
},

hyperLink: function (href, target, title) {
    var rng = this.range;
    var selType = this.selectionType;
    var linked = '';

    if (GB.browser.msie) {
        if (rng.text == '' || selType == "None")
            return;
        else
            rng.select();

        rng.execCommand("UnLink", false);
        rng.execCommand("CreateLink", false, href);
        linked = rng.parentElement ? rng.parentElement() : this.getElement(rng.item(0), "A");
    }
    else {
        var sel = this.getSelection();
        var rng = this.getRange();
        this.$(this.editorId).contentDocument.execCommand("CreateLink", false, href);
        linked = rng.startContainer;
    }

    if (linked) {
        if (target) try { linked.setAttribute("target", target); } catch(e) {};
        if (title)  try { linked.setAttribute("title",  title); } catch(e) {};
    }
},

boxStyle: function (el) {
    var range = this.range || this.getRange();
    var quote = this.doc.createElement("blockquote");

    if (el.currentStyle) {
        quote.style.backgroundColor = el.currentStyle.backgroundColor;
        quote.style.border = el.style.border;
    }
    else if (window.getComputedStyle) {
        var compStyle = document.defaultView.getComputedStyle(el, null);
        var style = compStyle.getPropertyValue('border-top-style');
        var width = compStyle.getPropertyValue('border-top-width');
        var color = compStyle.getPropertyValue('border-top-color');
        quote.style.border = width + ' ' + color + ' ' + style;
        quote.style.backgroundColor = compStyle.getPropertyValue("background-color");
    }
    else {
        alert('현재 브라우저는 이 기능을 지원하지 않습니다.');
        return;
    }

    quote.style.padding = "2px";
    quote.style.margin = "5px";

    if (GB.browser.msie) {
        var ctx = range.htmlText;
        quote.innerHTML = ctx ? ctx: '&nbsp;';
        range.select();
        this.insertHTML(quote.outerHTML);
    }
    else {
        var pDiv = this.doc.createElement('div');
        quote.appendChild(range != '' ? range.extractContents() : this.doc.createElement('br'));
        pDiv.appendChild(quote);
        this.insertNodeAtSelection(pDiv);
    }

    this.boxHideAll();
},

insertBgImage: function (img) {
    this.editArea.focus();

    if (img) {
        this.doc.body.style.backgroundImage = "url("+img+")";
    }
    else {
        var s = this.doc.body.style;
        GB.browser.msie ? s.removeAttribute("backgroundImage") : s.backgroundImage = "none";
    }
},

insertFlash: function (elem) {
    this.editArea.focus();

    if (typeof elem === 'string') {
        var embed = null;
        var div = this.doc.createElement('DIV');
        elem = this.trimSpace(elem);

        var pos = elem.toLowerCase().indexOf("embed");
        if (pos != -1) {
            var str = elem.substr(pos);
            pos = str.indexOf(">");
            div.innerHTML = "<" + str.substr(0, pos) + ">";
            embed = div.firstChild;
        }
        else {
            div.innerHTML = elem;
            var object = div.getElementsByTagName('OBJECT')[0];
            if (object && object.hasChildNodes()) {
                var child = object.firstChild;
                var movieHeight, movieWidth;
                movieWidth  = (isNaN(object.width) != true) ? object.width : 320;
                movieHeight = (isNaN(object.height)!= true) ? object.height: 240;
                var params = new Array();

                do {
                    if ((child.nodeName == 'PARAM') &&  (typeof child.name != 'undefined') && (typeof child.value != 'undefined'))
                    {
                        params.push({key: (child.name == 'movie') ? 'src' : child.name, val: child.value});
                    }
                    child = child.nextSibling;
                }
                while (child);

                if (params.length > 0) {
                    embed = this.doc.createElement('embed');
                    embed.setAttribute("width", movieWidth);
                    embed.setAttribute("height", movieHeight);

                    for (var i=0; i<params.length; i++)
                        embed.setAttribute(params[i].key, params[i].val);

                    embed.setAttribute("type", "application/x-shockwave-flash");
                }
            }
        }

        if (embed != null) {
            if (GB.browser.msie) {
                this.doCmdPaste(embed.outerHTML);
            }
            else {
                this.insertNodeAtSelection(embed);
            }
        }
    }

    this.editArea.focus();
},

insertHtmlPopup: function (elem) {
    this.editArea.focus();
    if (GB.browser.msie) {
        if (typeof elem === 'string') {
            this.doCmdPaste(elem);
        }
        else {
            this.doCmdPaste(elem.outerHTML);
        }
    }
    else {
        if (typeof elem === 'string') {
            var div = this.doc.createElement('DIV');
            div.innerHTML = elem;
            this.insertNodeAtSelection(div.firstChild);
        }
        else {
            this.insertNodeAtSelection(elem);
        }
    }
    this.editArea.focus();
},

insertHTML: function (html) {
    if (GB.browser.msie) {
        this.getRange().pasteHTML(html);
    }
    else {
        var div = this.doc.createElement('DIV');
        div.innerHTML = html;
        this.insertNodeAtSelection(div.firstChild);
    }
},

insertNodeAtSelection: function (insertNode) {
    var sel = this.getSelection();
    var rng = this.getRange();

    sel.removeAllRanges();
    rng.deleteContents();

    var container = rng.startContainer;
    var pos = rng.startOffset;

    rng = document.createRange();

    if (container.nodeType==3 && insertNode.nodeType==3) {
        container.insertData(pos, insertNode.nodeValue);
        try {
            rng.setEnd(container, pos+insertNode.length);
            rng.setStart(container, pos+insertNode.length);
        }
        catch (e) {};
    }
    else {
        var afterNode, beforeNode;
        if (container.nodeType == 3) {
            var textNode    = container;
            var text        = textNode.nodeValue;
            var textBefore  = text.substr(0, pos);
            var textAfter   = text.substr(pos);

            container   = textNode.parentNode;
            beforeNode  = document.createTextNode(textBefore);
            afterNode   = document.createTextNode(textAfter);

            container.insertBefore(afterNode, textNode);
            container.insertBefore(insertNode, afterNode);
            container.insertBefore(beforeNode, insertNode);
            container.removeChild(textNode);
        }
        else {
            afterNode = container.childNodes[pos];
            container.insertBefore(insertNode, afterNode);
        }

        try {
            rng.setEnd(afterNode, 0);
            rng.setStart(afterNode, 0);
        }
        catch (e) { };
    }

    sel.addRange(rng);
},

doInsertImage : function (images) {
    var div = document.createElement('div');
    for (var i=0; i<images.length; i++) {
        var img = new Image();
        img.src = images[i]['src'];
        img.width = images[i]['width'];
        img.height = images[i]['height'];
        img.alt = images[i]['alt'] ? images[i]['alt'] : '';
        img.border = 0;
        if (images[i]['align']) img.align = images[i]['align'];

        if (typeof images[i]['info'] != 'undefined') {
            this.images.push(images[i]['info']);
        }

        div.appendChild(this.insertImage(img));
    }

    this.insertHtmlPopup(div);
    var br = document.createElement('br');

    if (GB.browser.msie) {
        this.insertHtmlPopup(br);
        return;
    }

    var nNode = div.nextSibling;
    var pNode = div.parentNode;

    if (nNode)
        pNode.insertBefore(br, nNode);
    else
        pNode.appendChild(br);
},

insertImage : function (img) {
    var linebreak = false;
    var reSize = false;

    if (this.config.imgReSize) {
        reSize = this.resizeImageComplete(img);
    }

    if (img.alt == 'break') {
        linebreak = true;
        img.removeAttribute("align");
        img.alt = '';
    }

    if (reSize) {
        var szRandom = Math.random();
        var imgId = 'image_'+szRandom;
        imgId = imgId.replace(/\./,'');
        img.id = imgId;
        img.className = 'chimg_photo';
    }

    if (linebreak) {
        var p = document.createElement('p');
        p.style.margin = this.config.imgBlockMargin;
        p.setAttribute("align", "center");
        p.appendChild(img);
        return p;
    }
    else {
        return img;
    }
},

resizeImageComplete : function (img) {
    var maxWidth = isNaN(this.config.imgMaxWidth) ? 600 : this.config.imgMaxWidth;
    if (img.width <= maxWidth) return false;

    img.style.width  = maxWidth + 'px';
    img.style.height = Math.round((img.height * maxWidth) / img.width) + 'px';
    img.removeAttribute("width");
    img.removeAttribute("height");

    return true;
},

showTagSelector : function (on) {
    if (!this.config.showTagPath) return;
    this.editorElem.tagPath.style.display = on ? '' : 'none';
},

showTags : function (doc) {
    var retDoc = '';
    if (doc.hasChildNodes()) {
        var child = doc.firstChild;
        do {
            child = child.nextSibling;

        } while (child);
        var children = doc.childNodes;
        for (var i=0; i < children.length; i++) {
            this.showTags(children[i]);
        }
    }
},

editMode: function () {
    this.range = null;
    this.popupWinClose();
    this.resetStatusBar();
    this.editAreaWrapper.style.visibility = 'hidden';
    this.setDesignMode(true);

    if (this.currentMode == 'rich' || this.currentMode == 'preview') {
        var tmpBody = this.getContents();
        this.szTmp = this.doc.body.style.cssText;
        var content = this.config.fullHTMLSource ? tmpBody : this.docSplit(tmpBody);
        var key = GB.htmlKey.join ("|");
        var reg1 = new RegExp ("(&lt;\/?)("+key+")( ?\/?)(&gt;)", "ig");
        var reg2 = new RegExp ("(&lt;)("+key+") +([a-zA-Z]+)=(.+?)(\/?)(&gt;)", "ig");

        content = content.replace(/</g,'&lt;').replace(/>/g,'&gt;');
        content = content.replace(/&nbsp;/g, '&amp;nbsp;');
        content = content.replace(reg2, "<font color=\"#0000c8\">$1$2</font> <font color=\"#b40000\">$3</font>=<font color=\"#248f00\">$4</font><font color=\"#0000c8\">$5$6</font>");
        content = content.replace(reg1, "<font color=\"#0000cc\">$1$2$3$4</font>");
        content = content.replace(/\n/g, '<br />');

        this.doc.body.innerHTML = content;
        this.doc.body.clearAttributes;
        this.doc.body.style.fontFamily = 'courier new,courier';
        this.doc.body.style.fontSize = '9pt';
        this.doc.body.style.color = '#000';
        this.doc.body.style.lineHeight = this.config.lineHeight;
        this.doc.body.style.background = '#fff';

        var tmpHeight = this.editAreaWrapper.offsetHeight + this.editorElem.toolbar.offsetHeight;
        this.editorElem.toolbar.style.display = "none";
        this.editAreaWrapper.style.height = parseInt(tmpHeight) + 'px';
        this.showTagSelector(false);
    }
    else {
        this.setDesignMode(false);
        this.putContents(this.makeHtmlContent());
        this.editorElem.toolbar.style.display = '';

        var tmpHeight = this.editAreaWrapper.offsetHeight - this.editorElem.toolbar.offsetHeight;
        this.editAreaWrapper.style.height = tmpHeight + 'px';

        if (!this.config.fullHTMLSource)
            this.doc.body.style.cssText = this.szTmp;

        this.setDesignMode(true);
        this.showTagSelector(true);
        this.setEditorEvent();
    }

    this.editAreaWrapper.style.visibility = 'visible';
    this.editArea.focus();
    this.setDefaultCss();
},

makeHtmlContent : function () {
    if (GB.browser.msie) return this.doc.body.innerText;

    var html = this.doc.createRange();
    html.selectNodeContents(this.doc.body);

    return html.toString();
},

resetStatusBar : function () {
    if (this.config.showTagPath)
        this.editorElem.tagPath.innerHTML = '&lt;html&gt; &lt;body&gt; ';
},

previewMode : function () {
    this.range = null;
    this.popupWinClose();
    this.resetStatusBar();

    if (this.config.useSource) {
        if (this.currentMode == 'code') {
            this.setDesignMode(false);
            this.putContents(this.makeHtmlContent());
            this.currentMode = 'rich';
        }
    }

    this.editAreaWrapper.style.visibility = 'hidden';

    if (this.currentMode == 'rich') {
        this.setDesignMode(false);
        this.editorElem.editBlock.style.display = 'none';
        this.showTagSelector(false);

        var tmpHeight = this.editAreaWrapper.offsetHeight + this.editorElem.toolbar.offsetHeight;
        this.editorElem.toolbar.style.display = "none";
        this.editAreaWrapper.style.height =  tmpHeight+'px';
    }
    else {
        this.setDesignMode(true);
        this.editorElem.toolbar.style.display = '';
        var tmpHeight = this.editAreaWrapper.offsetHeight - this.editorElem.toolbar.offsetHeight;

        this.editAreaWrapper.style.height = tmpHeight + 'px';
        this.showTagSelector(true);
        this.setEditorEvent();
    }

    this.editAreaWrapper.style.visibility = 'visible';
    this.editArea.focus();
    this.setDefaultCss();
},

putContents : function (sContent) {
    sContent = (this.config.fullHTMLSource == false) ? sContent : this.docSplit(sContent);
    if (GB.browser.msie) {
        this.openDoc(this.doc, sContent);
        this.setDesignMode(true);
        this.doc.execCommand("2D-Position", true, true);
        this.doc.execCommand("MultipleSelection", true, true);
        this.doc.execCommand("LiveResize", true, true);
    }
    else {
        this.doc.body.innerHTML = sContent;
    }

    this.doc.body.style.cssText = this.szTmp;
},

getImages : function () {
    var img = this.doc.body.getElementsByTagName('img');
    var imgNumber = this.images.length;
    var imgArr = new Array();

    for (i=0; i<img.length; i++) {
        if (img[i].src) {
            var imgid = img[i].src;
            imgid = imgid.slice(imgid.lastIndexOf("/") + 1);
            for (var j=0; j<imgNumber; j++) {
                if (this.images[j]['fileName'] == imgid) {
                    imgArr.push(this.images[j]);
                    break;
                }
            }
        }
    }

    return imgArr.length > 0 ? imgArr : null;
},

getXhtml : function (node, needNewLine, insidePre) {
    var text = '';
    var children = node.childNodes;
    var childLength = children.length;
    var sTagName;
    var doNewLine = needNewLine ? true : false;
    var mediaAlign = '';
    var reParsedVal = new Date().getTime();
    var ieEnterModeDiv = (this.config.ieEnterMode == 'div');

    for (var i=0; i < childLength; i++) {
        var child = children[i];
        if (GB.browser.msie) {
            if (child.getAttribute && child.getAttribute('parsed_timestamp') == reParsedVal) {
                continue;
            }
            if (child.setAttribute) {
                child.setAttribute('parsed_timestamp', reParsedVal);
            }
        }

        if (child.parentNode &&
            String(node.tagName).toLowerCase() != String(child.parentNode.tagName).toLowerCase())
        {
            continue;
        }

        switch (child.nodeType) {
        case 1: {
            var sTagName = String(child.tagName).toLowerCase();

            if (GB.browser.msie && sTagName == 'embed') {
                var parameter = /align=("[^\"]*"|'[^\']*'|[^\"\'\s]*)(\s|\>)/i;
                var alignCode = String(child.outerHTML).match(parameter);

                if (alignCode) {
                    alignCode = alignCode[1];
                    mediaAlign = alignCode.replace(/("|')/g,"");
                }
            }

            if (sTagName == '/embed') continue;
            if (sTagName == '') break;

            if (sTagName == 'meta') {
                var metaName = String(child.name).toLowerCase();
                if (metaName == 'generator') break;
            }

            if (GB.browser.msie && sTagName == 'object' && !(child.canHaveChildren || child.hasChildNodes())) {
                text += this.fixedObjectCode(child.outerHTML);
                continue;
            }

            if (sTagName == '!') {
                var parts = GB.xhtmlComment.exec(child.text);

                if (parts) {
                    var innerText = parts[1];
                    text += this.fixedComment(innerText);
                }
            }
            else {
                if (sTagName == 'html') {
                    text = '<?xml version="1.0" encoding="'+this.config.xhtmlEncoding+'"?>\n';
                    text += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n';
                }

                if (GB.xhtmlNlBefore.indexOf('|' + sTagName + '|') != -1) {
                    if ((doNewLine || text != '') && !insidePre)
                        text += "\n";
                    else
                        doNewLine = true;
                }

                if (GB.browser.msie && (sTagName == 'p' || ieEnterModeDiv) && !child.hasChildNodes()) {
                    text += "<br />";
                    continue;
                }
                else
                    text += '<' + sTagName;

                var attr = child.attributes;
                var attrLength = attr.length;
                var attrValue;
                var attrLang = false;
                var attrXmlLang = false;
                var attrXmlNs = false;
                var isAltAttr = false;

                for (j=0; j < attrLength; j++) {
                    var attrName = attr[j].nodeName.toLowerCase();

                    if (attrName == 'parsed_timestamp')
                        continue;

                    if (!attr[j].specified &&
                        attrName != 'selected' &&
                        attrName != 'style' &&
                        attrName != 'value' &&
                        attrName != 'shape' &&
                        attrName != 'coords')
                    {
                        continue;
                    }

                    if ((attrName == 'shape' || attrName == 'coords') && sTagName != 'area')
                        continue;

                    if (attrName == 'selected' &&
                        !child.selected ||
                        attrName == 'style' &&
                        child.style.cssText == '')
                    {
                        continue;
                    }

                    if (attrName == '_moz_dirty' ||
                        attrName == '_moz_resizing' ||
                        attrName == '_moz-userdefined' ||
                        sTagName == 'br' && attrName == 'type' &&
                        child.getAttribute('type') == '_moz')
                    {
                        continue;
                    }

                    var valid_attr = true;

                    switch (attrName) {
                    case "style" :
                        attrValue = child.style.cssText.toLowerCase();
                        break;
                    case "class" :
                        attrValue = child.className;
                        break;
                    case "http-equiv":
                        attrValue = child.httpEquiv;
                        break;
                    case "noshade":
                    case "checked":
                    case "selected":
                    case "multiple":
                    case "nowrap":
                    case "disabled":
                        attrValue = attrName;
                        break;
                    case "name":
                        attrValue = child.name ? child.name : child.getAttribute('name');
                        break;
                    case "for":
                        attrValue = child.htmlFor;
                        break;
                    default:
                        try {
                            attrValue = child.getAttribute(attrName, 2);
                        }
                        catch (e) {
                            valid_attr = false;
                        }
                    }

                    if (sTagName == 'embed') {
                        switch (attrName) {
                        case 'align':
                            if (mediaAlign)
                                attrValue = mediaAlign ? mediaAlign : eval('child.'+attrName);
                            break;
                        case 'showstatusbar':
                        case 'showcontrols':
                        case 'autostart':
                        case 'type':
                        case 'flashvars':
                            attrValue = attr[j].nodeValue;
                            break;
                        default:
                            break;
                        }
                    }

                    if (sTagName == 'html' && attrName == 'lang') {
                        attrLang = true;
                        attrValue = attrValue || this.config.xhtmlLang;
                    }

                    if (attrName == 'xml:lang') {
                        attrXmlLang = true;
                        attrValue = attrValue || this.config.xhtmlLang;
                    }

                    if (attrName == 'xmlns') attrXmlNs = true;

                    if (sTagName == 'object' && attrName == 'src' && GB.browser.msie) {
                        attrValue = this.fixedObjectSrc(child.outerHTML);
                    }

                    if (valid_attr) {
                        if (!(sTagName == 'li' && attrName == 'value')) {
                            text += ' ' + attrName + '="' + this.fixedAttribute(attrValue) + '"';
                        }
                    }

                    if (attrName == 'alt')
                        isAltAttr = true;
                }

                if (sTagName == 'img' && !isAltAttr) {
                    text += ' alt=""';
                }

                if (sTagName == 'html') {
                    if (!attrLang) text += ' lang="' + this.config.xhtmlLang + '"';
                    if (!attrXmlLang) text += ' xml:lang="' + this.config.xhtmlLang + '"';
                    if (!attrXmlNs) text += ' xmlns="http://www.w3.org/1999/xhtml"';
                }

                if (child.hasChildNodes() || child.nodeName == 'BODY') {
                    text += '>';
                    text += this.getXhtml(child, true, insidePre || ((sTagName == 'pre') ? true : false));
                    text += '</'+sTagName+'>';
                }
                else {
                    if (GB.xhtmlInsChild.indexOf('|' + sTagName + '|') != -1) {
                        text += '>';
                        var innerText = (sTagName == 'script') ? child.text : child.innerHTML;

                        if (sTagName == 'style') {
                            innerText = String(innerText).replace(/[\n]+/g,'\n');
                        }

                        text += innerText+'</'+sTagName+'>';
                    }
                    else if (GB.xhtmlInsSpace.indexOf('|' + sTagName + '|') != -1) {
                        text += '></'+sTagName+'>';
                        if (!child.nextSibling) text += '&nbsp;';
                    }
                    else {
                        text += ' />';
                    }
                }
            }
            break;
        }
        case 3: {
            if (!insidePre) {
                if (child.nodeValue != '\n') {
                    text += this.fixedEntities(this.fixedText(child.nodeValue));
                }
            }
            else
                text += child.nodeValue;
            break;
        }
        case 8: {
            text += this.fixedComment(child.nodeValue);
            break;
        }
        default:
            break;
        }
    }

    return text;
},

fixedComment : function (text) {
    text = text.replace(/--/g, "__");
    if (GB.xhtmlHyphen.exec(text)) text += " ";
    return "<!--"+text+"-->";
},

fixedText : function (text) {
    var str = String(text).replace(/\&lt;/g, "__lt__").replace(/\&gt;/g, "__gt__");
    str = str.replace(/\n{2,}/g, "\n").replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\u00A0/g, "&nbsp;");
    return str.replace(/__lt__/g, "&lt;").replace(/__gt__/g, "&gt;");
},

fixedAttribute : function (text) {
    var str = String(text).replace(/\&lt;/g, "__lt__").replace(/\&gt;/g, "__gt__");
    str = str.replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;");
    return str.replace(/__lt__/g, "&lt;").replace(/__gt__/g, "&gt;");
},

fixedObjectSrc : function (text) {
    var obj = text.match(/<object ([^>]+)>/i);
    if (obj) {
        var value = obj[1].match(/src="([^"]+)"/i)
        if (!value) {
            value = obj[1].match(/src='([^']+)'/i);
            if (!value)
                value = obj[1].match(/src=([^ ]+)/i);
        }

        if (value)
            return value[1];
    }

    return '';
},

fixedObjectCode : function (text) {
    var str = String(text);
    str = str.replace(/ style=/gi, ' style=');
    str = str.replace(/ codeBase=/gi, ' codebase=');
    str = str.replace(/ height=/gi, ' height=');
    str = str.replace(/ width=/gi, ' width=');
    str = str.replace(/ align=/gi, ' align=');
    str = str.replace(/ classid=/gi, ' classid=');
    str = str.replace(/ src=/gi, ' src=');
    str = str.replace(/ name=/gi, ' name=');
    str = str.replace(/ value=/gi, ' value=');
    str = str.replace(/ quality=/gi, ' quality=');
    str = str.replace(/ type=/gi, ' type=');
    str = str.replace(/ pluginspage=/gi, ' pluginspage=');
    str = str.replace(/<object /gi, '<object ');
    str = str.replace(/<\/object>/gi, '</object>');
    str = str.replace(/<param /gi, '<param ');
    str = str.replace(/<\/param>/gi, '</param>');
    str = str.replace(/<embed /gi, '<embed ');
    str = str.replace(/<\/embed>/gi, '</embed>');

    return str;
},

fixedEntities : function (text) {
    var rData = '';
    var temp = new RegExp("[a]|[^a]", "g");
    var parts = text.match(temp);

    if (!parts) return text;

    for (var i=0; i<parts.length; i++) {
        var c_code = parseInt(parts[i].charCodeAt());
        if (GB.xhtmlEnts[c_code]) {
            rData += "&" + GB.xhtmlEnts[c_code]+";";
        }
        else {
            rData += parts[i];
        }
    }

    return rData;
},

getContents : function () {
    if (this.config.hrefTarget != '' || this.config.hrefTarget != null) {
        for (var i=0; i < this.doc.links.length; i++) {
            if (!this.doc.links[i].target) {
                this.doc.links[i].target = this.config.hrefTarget;
            }
        }
    }

    this.szTmp = this.doc.body.style.cssText;

    if (GB.browser.msie && (this.config.ieEnterMode == 'css' || this.config.ieEnterMode == 'div')) {
        var p = this.doc.body.getElementsByTagName('P');
        var remove = new Array();

        for (var i=0; i < p.length; i++) {
            if (this.config.ieEnterMode == 'css') {
                if (p[i].style.cssText.toLowerCase().indexOf("margin") == -1) {
                    p[i].style.margin = '0px';
                }
                continue;
            }

            if (this.config.ieEnterMode == 'div') {
                var div = this.doc.createElement('div');

                p[i].parentElement.insertBefore(div, p[i]);

                var attr = p[i].getAttribute('name');
                if (attr) div.setAttribute('name', attr);

                attr = p[i].getAttribute('id');
                if (attr) div.setAttribute('id', attr);

                attr = p[i].getAttribute('style');
                if (attr) {
                    if (typeof attr === 'string') {
                        if (attr != '') {
                            div.setAttribute('style', attr);
                        }
                    }
                    else if (typeof attr == 'object') {
                        var css = attr.cssText.split(';');
                        for (var j=0; j < css.length; j++) {
                            var s = css[j].split(':');
                            if (s[0] && typeof s[1] != 'undefined') {
                                div.style.setAttribute(s[0], s[1]);
                            }
                        }
                    }
                }

                div.innerHTML = p[i].innerHTML;
                remove.push(p[i]);
            }
        }

        for (i=0; i<remove.length; i++) {
            this.doc.body.removeChild(remove[i]);
        }
    }

    if (this.config.includeHostname == false) {
        var img = this.doc.images;
        var hostname = location.hostname;
        for (var i=0; i<img.length; i++) {
            if (img[i].src) {
                if (img[i].src.indexOf(hostname) != -1) {
                    img[i].src = img[i].src.substring(img[i].src.indexOf(hostname) + hostname.length);
                }
            }
        }
    }

    this.doc.body.removeAttribute('contentEditable');
    var mydoc   = new String('');
    var content = this.config.outputXhtml ? this.doc : this.doc.documentElement;
    var removeTags = ['LINK', 'TITLE', 'META', 'HEAD'];

    for (var i=0; i<removeTags.length; i++) {
        var tags = content.getElementsByTagName(removeTags[i]);
        for (var j=0; j < tags.length; j++) {
            if (tags[j]) tags[j].parentNode.removeChild(tags[j]);
        }
    }

    if (this.config.outputXhtml) {
        mydoc = this.getXhtml(content);
    }
    else {
        if (GB.browser.msie) {
            mydoc = content.outerHTML;
            mydoc = mydoc.replace(/<(\/?)strong>/ig, "<$1B>");
            mydoc = mydoc.replace(/<(\/?)em>/ig, "<$1I>");
        }
        else {
            mydoc = '<html>'+content.innerHTML+'</html>';
        }
    }

    mydoc = mydoc.replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g, '&amp;gt;');
    this.setDesignMode(true);

    return mydoc;
},

docSplit : function (mydoc) {
    mydoc = mydoc.substr(mydoc.search(/<body/ig) + 1);
    mydoc = mydoc.substr(mydoc.indexOf('>') + 1);
    mydoc = mydoc.slice(0, mydoc.search(/<\/body/ig));
    mydoc = this.trimSpace(mydoc);
    return mydoc;
},

returnContents : function (mydoc) {
    this.setDesignMode(true);
    if (this.inputForm && this.$(this.inputForm))
        this.$(this.inputForm).value = mydoc;
    return mydoc;
},

outputHTML : function () {
    this.resetViewHTML();
    var mydoc = this.getContents();
    mydoc = mydoc.replace (/&amp;lt;/g, '&lt;').replace(/&amp;gt;/g,'&gt;');
    return this.returnContents(mydoc);
},

outputBodyHTML : function () {
    var mydoc = this.docSplit(this.outputHTML());

    if (this.config.useBodyAttribute) {
        var szCss = this.doc.body.style.cssText;

        if (typeof szCss !== 'string')
            szCss = this.doc.body.getAttribute('style');

        szCss = szCss.replace(/ margin:(.+?);/ig, "");
        mydoc = '<div style="'+szCss+'">'+mydoc+'</div>';
    }

    return this.returnContents(mydoc);
},

outputBodyText : function () {
    this.resetViewHTML();
    return (GB.browser.msie) ? this.doc.body.innerText :
        this.outputBodyHTML().replace(/<br>/ig, "\n").replace(/<[^>]+>/g, "");
},

returnFalse : function () {
    this.editArea.focus();
    var img = this.doc.images;
    for (i=0; i<img.length; i++) {
        if (img[i].src) {
            if (img[i].getAttribute("onload")) {
                img[i].onload = 'true';
            }
        }
        else {
            img[i].removeAttribute("onload", "", 0);
            img[i].removeAttribute("className", "", 0);
        }
    }
    this.setEditorEvent();
    return false;
},

trimSpace : function (str) {
    str = str ? '' + str : '';
    return str.replace(/^\s+|\s+$/g, '');
},

strLength : function (str) {
    var len = str.length;
    var mbytes = 0;
    var i = 0;

    for (; i<len; i++) {
        var c = str.charCodeAt(i);
        if (c > 128) mbytes++;
    }

    return (len-mbytes) + (mbytes*2);
},

resetViewHTML : function () {
    if (this.currentMode == 'code') {
        this.switchEditorMode('rich');
    }
},

contentsLengthAll : function () {
    this.resetViewHTML();
    return this.outputHTML().length;
},

contentsLength : function () {
    this.resetViewHTML();
    var content = this.outputBodyHTML();
    content = this.trimSpace(content);

    if (!content || content == "")
        return 0;

    return this.strLength(content);
},

inputLength : function () {
    this.resetViewHTML();
    var content = this.trimSpace(this.outputBodyText());

    if (!content || content == "")
        return 0;

    return this.strLength(content);
},

displayWindow : function (boxName) {
    this.editArea.focus();
    this.boxHideAll();
    this.setSelection();

    var pullDown = this.$(boxName);
    pullDown.style.visibility = "visible";
    pullDown.style.zIndex = 1002;
},

mouseOver : function (el) { el.className = "cheditor_pulldown_mouseover"; },
mouseOut  : function (el) { el.className = "cheditor_pulldown_mouseout"; },

windowPos : function (idImg, boxName) {
    var boxEl = this.$(boxName);
    var pNode = this.$(idImg);
    boxEl.style.left = pNode.parentNode.parentNode.offsetLeft + 3 + 'px';
    boxEl.style.top  = pNode.parentNode.parentNode.parentNode.offsetTop + 26 + 'px';
},

boxHideAll : function () {
    for (i=0; i < GB.popupIFrame.length; i++) {
        if (this.$(GB.popupIFrame[i]+'_'+this.oname)) {
            this.$(GB.popupIFrame[i]+'_'+this.oname).style.visibility = 'hidden';
        }
    }
},

createWindow : function (width, div) {
    div.className = 'cheditor_pulldown_container';
    div.style.width = width+'px';
},

setColorTable : function (menu) {
    var title = {
            'foreColor' : '글자색',
            'backColor' : '형광펜',
            'BgColor' : '바탕색'
    };

    var pulldown = document.createElement('div');
    pulldown.className = 'cheditor_pulldown_background';

    var dragHandle = document.createElement('div');
    dragHandle.style.background = '#6b90c0 url('+this.iconPath+'/title_bar_bg.gif)';
    dragHandle.className = 'cheditor_popup_drag_handle';

    var titleBar = document.createElement('div');
    titleBar.className = 'cheditor_popup_title_bar';
	titleBar.style.lineHeight = "1.3em";

    var label = document.createElement('label');
    label.className = 'cheditor_popup_title';
    label.appendChild(document.createTextNode(title[menu]));

    titleBar.appendChild(label);
    dragHandle.appendChild(titleBar);
    pulldown.appendChild(dragHandle);

    var table = document.createElement('table');
    table.className = 'cheditor_pulldown_color_table';
    table.cellPadding = 1;
    table.cellSpacing = 2;
    var tr = table.insertRow(0);
    var td = tr.insertCell(0);
    td.setAttribute('colSpan', 10);
    td.align = 'center';
    td.className = 'cheditor_pulldown_color_selected';
    td.appendChild(document.createTextNode('\u00a0'));

    var k = 0, w = 7, h = 10;
    var self = this;

    for (var i = 0; i < w; i++) {
        var tr2 = table.insertRow(i+1);
        for (var j = 0; j < h; j++) {
            var td2 = tr2.insertCell(j);
            td2.bgColor = GB.colors[k++];
            td2.className = 'cheditor_pulldown_color_cell';
            td2.appendChild(document.createTextNode('\u00a0'));
            td2.onmouseover = function() {
                td.bgColor = this.bgColor;
                if (td.firstChild) td.removeChild(td.firstChild);
                td.appendChild(document.createTextNode(this.bgColor.toUpperCase()));
            };
            td2.onclick = function() {
                switch (menu) {
                case 'backColor' :
                    self.changeFontColor(this.bgColor, 'back');
                    break;
                case 'foreColor' :
                    self.changeFontColor(this.bgColor, 'fore');
                    break;
                case 'BgColor' :
                    self.changeBodyColor(this.bgColor);
                    break;
                }
            };
        }
    }

    pulldown.appendChild(table);
    return pulldown;
},

doOnKeyPress : function () {
    var oEditor = this.editArea;
    var key = oEditor.event.keyCode;

    if (key) {
        if (key == 13) {
            if (oEditor.event.shiftKey == false) {
                var rng = this.getRange();
                oEditor.event.returnValue = false;
                oEditor.event.cancelBubble = true;
                rng.pasteHTML('<br />');
                rng.select();
                rng.moveEnd("character", 1);
                rng.moveStart("character", 1);
                rng.collapse(false);
                return false;
            }
            else
                return oEditor.event.keyCode = 13;
        }
    }
},

setWinPosition : function (oWin, oWinWidth) {
    var obj = this.editorElem.container;
    var container = obj;
    var L = 0;
    var T = 0;

    if (obj.offsetParent) {
        do {
            T += obj.offsetTop;
        } while (obj = obj.offsetParent);
    }

    if (GB.browser.msie) L /= 2;
    L = (this.getWindowSize().width / 2) - (oWinWidth / 2);
    oWin.style.left = L + 'px';
    oWin.style.top = T + 'px';
    oWin.style.width = oWinWidth + 'px';
},

getWindowSize : function () {
    var w = 0, h = 0;

    if (document.documentElement.clientWidth) {
        w = document.documentElement.clientWidth;
        h = document.documentElement.clientHeight;

    }
    else if (typeof window.innerWidth == 'number'){
        w = window.innerWidth;
        h = window.innerHeight;

    }
    else {
        w = document.body.clientWidth;
        h = document.body.clientHeight;
    }

    return { width: w, height: h };
},

modalReSize : function () {
    var modalSize = this.getWindowSize();
    this.editorElem.modalBackground.style.width = modalSize.width + 'px';
    this.editorElem.modalBackground.style.height = modalSize.height + 'px';
},

popupWinLoad : function (popupInfo) {
    var self = this;
    if (self.editorElem.popupTitle.hasChildNodes())
        self.editorElem.popupTitle.removeChild(self.editorElem.popupTitle.firstChild);

    self.editorElem.popupTitle.appendChild(document.createTextNode(popupInfo['title']));
    self.editorElem.popupElem.style.zIndex = 1001;
    self.setWinPosition(self.editorElem.popupElem, popupInfo['boxW']);

    var iframe = document.createElement("iframe");
    iframe.setAttribute('frameBorder', 0);
    iframe.style.width  = '100%';
    iframe.style.border = "0px";

    iframe.setAttribute('src', self.popupPath + popupInfo['tmpl']);
    iframe.style.visibility = 'hidden';
    iframe.id = popupInfo['tmpl'];

    if (self.editorElem.popupFrameWrapper.hasChildNodes())
        self.editorElem.popupFrameWrapper.removeChild(self.editorElem.popupFrameWrapper.firstChild);

    self.editorElem.popupFrameWrapper.appendChild(iframe);

    var popWinResizeHeight = function () {
        iframe.style.visibility = 'visible';
        iframe.contentWindow.focus();
        iframe.contentWindow.init.call(self, iframe);
    };

    self._modalReSize = function() {
        modalSize = self.getWindowSize.call(self);
        self.editorElem.modalBackground.style.width = modalSize.width + 'px';
        self.editorElem.modalBackground.style.height = modalSize.height + 'px';
    };

    if (GB.browser.msie) {
        iframe.contentWindow.attachEvent("onload", popWinResizeHeight);
        window.attachEvent("onresize", self._modalReSize);
    }
    else {
        iframe.onload = popWinResizeHeight;
        window.addEventListener("resize", self._modalReSize, false);
    }

    self.editorElem.popupElem.style.display = 'block';
    self._modalReSize();
    self.editorElem.modalBackground.style.zIndex = 1000;

    if (GB.browser.msie) self.editorElem.modalBackground.style.filter = 'alpha(opacity=50)';
    else self.editorElem.modalBackground.style.opacity = .5;

    document.body.insertBefore(self.editorElem.modalBackground, document.body.firstChild);
    self.editorElem.modalBackground.style.display = 'block';
    document.body.insertBefore(self.editorElem.popupElem, document.body.firstChild);

    DragWindow.init(self.editorElem.dragHandle, self.editorElem.popupElem);
},

popupWinClose : function () {
    if (this.editorElem.popupElem == null)
        return;

    this.editorElem.popupElem.style.display = 'none';
    this.editorElem.popupElem.style.zIndex = -1;
    this.editorElem.popupFrameWrapper.src = "";
    this.editorElem.modalBackground.style.display = 'none';
    this.editorElem.modalBackground.style.zIndex = -1;

    if (this.modalReSize != null) {
        if (GB.browser.msie) window.detachEvent("onresize", this._modalReSize);
        else window.removeEventListener("resize", self._modaReSize, false);

        this.modalReSize = null;
    }

    this.editArea.focus();
    this.restoreRange();
},

restoreRange : function () {
    if (GB.browser.msie) {
        var rng = this.range || this.getRange();
        if (rng) {
            rng.select();
            this.selectionType = this.range = null;
        }
    }
},

windowOpen : function (popupName) {
    this.editArea.focus();
    this.boxHideAll();

    if (GB.browser.msie) this.setSelection();

    if (popupName == 'hyperLink') {
        if (GB.browser.msie) {
            if (this.selectionType == 'None') {
                alert('문자열을 선택하여 주십시오.');
                return;
            }
        }
    }

    if (typeof GB.popup[popupName] != 'undefined')
        this.popupWinLoad(GB.popup[popupName]);
    else
        alert('사용할 수 없는 명령입니다.');
},

getSelection : function () {
    return (GB.browser.msie) ? this.doc.selection : this.editArea.getSelection();
},

getRange : function () {
    var self = this;
    var sel = self.getSelection(), rng = null;

    try {
        if (sel) {
            rng = GB.browser.msie ? (sel.createRange ? sel.createRange() : self.doc.createRange()) : sel.getRangeAt(0);
        }
    }
    catch (e) {}

    if (!rng) {
        rng = GB.browser.msie ? self.doc.body.createTextRange() : self.doc.createRange();
    }

    return rng;
},

setSelection : function () {
    this.range = this.getRange();
    this.selectionType = this.getSelectionType(this.range);
},

setRange : function (rng) {
    if (GB.browser.msie) {
        try {
            rng.select();
        }
        catch(e) {}
    }
    else {
        var sel = this.getSelection();
        if (sel) {
            sel.removeAllRanges();
            sel.addRange(rng);
        }
    }
},

getSelectionType : function (rng) {
    return rng ? (GB.browser.msie ? this.doc.selection.type : rng.startContainer.nodeType) : null;
},

doCmd : function (cmd, opt) {
    var self = this;
    var rng;
    self.popupWinClose();
    self.boxHideAll();
    self.range = null;

    if (GB.browser.msie) {
        rng =  self.getRange();
        if (self.getSelectionType(rng) == 'None') rng = self.doc;
    }
    else {
        rng = self.doc;
    }

    if (cmd == 'Print') {
        self.editArea.print();
        return;
    }

    if (!GB.browser.msie && ((cmd == 'Cut') || (cmd == 'Copy') || (cmd == 'Paste'))) {
        if (cmd == 'PasteFromWord') {
            cmd = 'Paste';
        }

        try {
            rng.execCommand(cmd, false, opt);
        }
        catch (e) {
            var keyboard = '';
            var command = '';
            switch (cmd) {
                case 'Cut'  : keyboard = 'x'; command = '자르기'; break;
                case 'Copy' : keyboard = 'c'; command = '복사'; break;
                case 'Paste': keyboard = 'v'; command = '붙이기'; break;
            }

            alert('사용하고 계신 브라우저에서는 \'' + command + '\' 명령을 사용하실 수 없습니다. \n' +
            '키보드 단축키를 이용하여 주세요. \(윈도 사용자: Ctrl + ' + keyboard + ', 맥킨토시 사용자: Apple + ' + keyboard + '\)')
        }

        self.editArea.focus();
        return;
    }

    try {
        if (cmd == 'PasteFromWord') {
            var rng = self.getRange();
            var tmpDoc = self.editorElem.tmpdoc;
            tmpDoc.execCommand("SelectAll");
            tmpDoc.execCommand("Paste");

            rng.pasteHTML(self.cleanFromWord(tmpDoc));
            rng.select();
        }
        else {
            rng.execCommand(cmd, false, opt);
        }
    }
    catch (e) {
        alert(cmd + ": 지원되지 않는 명령입니다.");
    }

    self.setEditorEvent();
},

cleanFromWord : function (tmpDoc) {
    for (var i=0; i < tmpDoc.body.all.length; i++) {
        tmpDoc.body.all[i].removeAttribute("className", "", 0);
    }

    var doc = tmpDoc.body.innerHTML;
    doc = doc.replace(/MsoNormal/g, "");
    doc = doc.replace(/<\\?\?xml[^>]*>/g, "");
    doc = doc.replace(/<\/?o:p[^>]*>/g, "");
    doc = doc.replace(/<\/?v:[^>]*>/g, "");
    doc = doc.replace(/<\/?o:[^>]*>/g, "");
    doc = doc.replace(/<\/?st1:[^>]*>/g, "");
    doc = doc.replace(/<!--(.*)-->/g, "");
    doc = doc.replace(/<!--(.*)>/g, "");
    doc = doc.replace(/<!(.*)-->/g, "");
    doc = doc.replace(/<\\?\?xml[^>]*>/g, "");
    doc = doc.replace(/<\/?o:p[^>]*>/g, "");
    doc = doc.replace(/<\/?v:[^>]*>/g, "");
    doc = doc.replace(/<\/?o:[^>]*>/g, "");
    doc = doc.replace(/<\/?st1:[^>]*>/g, "");
    doc = doc.replace(/lang=.?[^" >]*/ig, "");
    doc = doc.replace(/type=.?[^" >]*/g, "");
    doc = doc.replace(/href=\'#[^\"]*\'/g, "");
    doc = doc.replace(/href=\"#[^\"]*\"/g, "");
    doc = doc.replace(/name=.?[^\" >]*/g, "");
    doc = doc.replace(/ clear=\"all\"/g, "");
    doc = doc.replace(/id=\"[^\"]*\"/g, "");
    doc = doc.replace(/title=\"[^\"]*\"/g, "");
    doc = doc.replace(/\n/g, "");
    doc = doc.replace(/\r/g, "");
    doc = doc.replace(/mso\-[^">;]*/g, "");
    doc = doc.replace(/<p[^>]*/ig, "<p");
    doc = doc.replace(/<span[^>]*<\/span>/ig, "");
    return doc;
},

printPageBreak : function () {
    this.editArea.focus();
    var html = '<div style="page-break-after: always;line-height: 0px;padding: 0px;border-top: 1px #f45000 dotted;';
    html += 'border-bottom: 1px #f45000 dotted;height: 3px;font-size: 1px;margin: 5px 0px 10px 0px;"></div>';
    this.insertHTML(html);
},

doCmdPaste : function (str) {
    this.editArea.focus();
    if (GB.browser.msie) {
        if (this.selectionType == "Control") return;
        this.range.pasteHTML(str);
        this.range.collapse(false);
        this.range.select();
    }
    else {
        this.insertNodeAtSelection(str);
    }
},

doCmdPopup : function (cmd, opt) {
    this.editArea.focus();
    var rng, oRange;

    if (GB.browser.msie) {
        oRange = this.range || this.getRange();
        oRange.select();
        rng = (this.selectionType == 'None') ? this.doc : oRange;
    }
    else {
        rng = this.doc;
    }

    try {
        rng.execCommand(cmd, false, opt);
    }
    catch(e) {
        alert(cmd + ": 지원되지 않는 명령입니다.");
    }

    this.setEditorEvent();
    this.boxHideAll();
},

modifyImage : function (img) {
    var self = this;
    var a_align = new Array("baseline","top","middle","bottom","texttop","absmiddle","absbottom","left","right");
    var a_text = new Array("기준선","위쪽","가운데","아래쪽","문자열 위쪽","선택 영역의 가운데","선택 영역의 아래쪽","왼쪽","오른쪽");
    if (img.hspace < 0) img.hspace = 0;
    if (img.vspace < 0) img.vspace = 0;
    if (img.border < 0 || img.border == '') img.border = 0;
    var htmlOutput = '<table cellpadding="0" cellspacing="0" border="0"><tr>' +
        '<td width="110"><font style="font-size:9pt">가로 픽셀: <input type="text" size="3" style="font-size:9pt" value="'+img.width+'" id="n_width" />&#160;</font>\n</td>' +
        '<td width="110"><font style="font-size:9pt">가로 여백: <input type="text" size="3" style="font-size:9pt" value="'+img.hspace+'" id="n_hspace" />&#160;</font>\n</td>' +
        '<td width="200"><font style="font-size:9pt">정렬: <select id="n_alignment" name="n_alignment" style="font-size:9pt">' +
        '<option value="">없음</option>';
        for (var i=0; i<a_align.length; i++) {
            htmlOutput += '<option value='+a_align[i];
            if (img.align == a_align[i].toLowerCase()) htmlOutput += ' selected';
            htmlOutput += '>'+a_text[i]+'</option>';
        }

     htmlOutput += '</select><select id="n_alignment_caption" name="n_alignment_caption" style="display:none;font-size:9pt">'+
        '<option value="left">왼쪽</option><option value="right">오른쪽</option></select></font></td>' +
        '<td>&#160;<font style="font-size:9pt">괘선 두께: <input type="text" size="1" style="font-size:9pt" value="'+img.border+'" id="n_border" />&#160;</font>\n</td></tr>' +
        '<tr><td><font style="font-size:9pt">세로 픽셀: <input type="text" size="3" style="font-size:9pt" value="'+img.height+'" id="n_height" />&#160;</font>\n</td>' +
        '<td><font style="font-size:9pt">세로 여백: <input type="text" size="3" style="font-size:9pt" value="'+img.vspace+'" id="n_vspace" />&#160;</font>\n</td>' +
        '<td colspan="2"><font style="font-size:9pt">설명: <input type="text" size="25" id="n_alt" style="font-size:9pt" value="'+img.alt+'" />' +
        '&#160;<button style="height:21px;font-size:9pt;" id="editimg">수정</button>' +
        '&#160;<input type="checkbox" id="isCaption" style="background-color:#a3d260" />캡션</font>\n</td></tr></table>';

    self.editorElem.editBlock.innerHTML = htmlOutput;
    self.$("isCaption").onclick = function () {
        if (self.$("isCaption").checked) {
            self.$("n_alignment_caption").style.display = '';
            self.$("n_alignment").style.display = 'none';
        }
        else {
            self.$("n_alignment_caption").style.display = 'none';
            self.$("n_alignment").style.display = '';
        }
    };
    self.$("editimg").onclick = function () {
        var n_width  = self.$("n_width");
        var n_height = self.$("n_height");
        var n_hspace = self.$("n_hspace");
        var n_vspace = self.$("n_vspace");
        var n_border = self.$("n_border");
        var n_alt    = self.$("n_alt");

        if (n_width.value == '' || n_width.value == null || n_width.value < 1) {
            alert("가로 픽셀 크기를 입력하여 주십시오");
            return;
        }
        else if (n_height.value == '' || n_height.value == null || n_height.value < 1) {
            alert("세로 픽셀 크기를 입력하여 주십시오");
            return;
        }
        else {
            var n_align  = '';
            if (self.$("n_alignment").style.display != 'none') {
                n_align = self.$("n_alignment");
            }
            else {
                n_align = self.$("n_alignment_caption");
            }

            img.width  = parseInt(n_width.value);
            img.height = parseInt(n_height.value);

            if (parseInt(n_hspace.value) > 0) img.hspace = parseInt(n_hspace.value);
            else img.removeAttribute("hspace", "", 0);
            if (parseInt(n_vspace.value) > 0) img.vspace = parseInt(n_vspace.value);
            else img.removeAttribute("vspace", "", 0);
            if (parseInt(n_border.value) > 0) {
                img.style.border = n_border.value+'px ' + GB.imageBorder;
                img.removeAttribute("border", "", 0);
            }
            else img.removeAttribute("style", "", 0);
            if (n_align.value != '')  img.align  = n_align.value ;
            else img.removeAttribute("align", "", 0);
            if (n_alt.value != '') img.alt = n_alt.value;
            else img.alt = '';
        }
    }
},

modifyCell : function (cell) {
    while (cell != null && cell.tagName.toLowerCase() != "td")
        cell = cell.parentNode;

    var self = this;
    var tbl = cell;
    var row = tbl;
    var editorPath = self.config.editorPath;

    while (tbl != null && tbl.tagName.toLowerCase() != "table") tbl = tbl.parentNode;
    while (row != null && row.tagName.toLowerCase() != "tr") row = row.parentNode;

    var t_width  = tbl.style.width  ? tbl.style.width  : tbl.width;
    var t_height = tbl.style.height ? tbl.style.height : tbl.getAttribute("height");
    var t_cellpadding = tbl.cellPadding;
    var t_cellspacing = tbl.cellSpacing;
    var t_bgcolor = tbl.getAttribute("bgcolor") ? tbl.bgColor : '';
    var t_bordercolor = tbl.getAttribute("bordercolor") ? tbl.getAttribute("bordercolor") : '';
    var t_border = tbl.getAttribute("border") ? tbl.border : '';
    var c_width = cell.getAttribute("width") ? cell.getAttribute("width") : '';
    var c_height = cell.getAttribute("height") ? cell.getAttribute("height") : '';
    var c_align = cell.getAttribute("align") ? cell.align : '';
    var c_bgcolor = cell.getAttribute("bgcolor") ? cell.bgColor : '';
    var is_ie = navigator.userAgent.toLowerCase().indexOf("msie") != -1;

    if (t_height == null) t_height = '';
    t_width = t_width.replace(/px/ig, '');
    t_height = t_height.replace(/px/ig, '');

    var html_output = '<table cellpadding="0" cellspacing="0" style="margin-top:5px;">' +
                      '<tr><td><span style="font-size:9pt;">가로 폭: <input type="text" size="4" value="'+t_width+'" id="n_width" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">셀 패딩: <input type="text" size="1" value="'+t_cellpadding+'" id="n_cellpadding" /></span>\n</td>' +
                      '<td align="right"><span style="font-size:9pt;">테이블 배경 색: <input type="text" size="6" value="'+t_bgcolor+'" id="n_bgcolor" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">테이블 정렬: <select id="alignment" style="font-size:9pt">' +
                      '<option value="">없음</option>' +
                      '<option value="left">왼쪽</option>' +
                      '<option value="center">가운데</option>' +
                      '<option value="right">오른쪽</option>' +
                      '</select></span></td>' +
                      '</tr><tr>' +
                      '<td><span style="font-size:9pt;">세로 폭: <input type="text" size="4" value="'+t_height+'" id="n_height" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">셀 간격: <input type="text" size="1" value="'+t_cellspacing+'" id="n_cellspacing" /></span>\n</td>' +
                      '<td align="right"><span style="font-size:9pt;">테이블 테두리 색: <input type="text" size="6" value="'+t_bordercolor+'" id="n_bordercolor" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">테두리 두께: <input type="text" size="1" value="'+t_border+'" id="n_border" /></span>\n</td>' +
                      '</tr><tr>' +
                      '<td><span style="font-size:9pt;">셀 가로: <input type="text" size="4" value="'+c_width+'" id="c_width" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">가로 정렬: <select id="c_alignment" style="font-size:9pt;">' +
                      '<option value="">없음</option>' +
                      '<option value="left">왼쪽</option>' +
                      '<option value="center">가운데</option>' +
                      '<option value="right">오른쪽</option>' +
                      '<option value="justify">양쪽</option>' +
                      '</select></span></td>' +
                      '<td align="right"><span style="font-size:9pt;">셀 배경 색: <input type="text" size="6" value="'+c_bgcolor+'" id="c_bgcolor" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">No Wrap:<input type="checkbox" value="'+t_bgcolor+'" id="nowrap" />&#160;</span>\n' +
                      '<button style="width:54px;height:21px;font-size:9pt;padding-top:2px" id="editcell">수정</button></td>' +
                      '</tr><tr>' +
                      '<td><span style="font-size:9pt;">셀 세로: <input type="text" size="4" value="'+c_height+'" id="c_height" />&#160;</span>\n</td>' +
                      '<td>&#160;<span style="font-size:9pt;">세로 정렬: <select id="c_valignment" style="font-size:9pt;">' +
                      '<option value="">없음</option>' +
                      '<option value=top>위쪽</option>' +
                      '<option value=middle>가운데</option>' +
                      '<option value=bottom>아래</option>' +
                      '<option value=baseline>기준선</option>' +
                      '</select></span></td>' +
                      '<td style=padding-left:12px colspan=2>' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/increasecolspan.gif" id="increasecolspan" title="ColSpan 증가" />' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/decreasecolspan.gif" id="decreasecolspan" title="ColSpan 감소" />' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/increaserowspan.gif" id="increaserowspan" title="RowSpan 증가" />' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/decreaserowspan.gif" id="decreaserowspan" title="RowSpan 감소" />&#160;&#160;&#160;&#160;' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/addcol.gif" id="addcol" title="행 삽입" />&#160;' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/addcols.gif" id="addcols" title="셀 삽입" />&#160;' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/removecol.gif" id="removecol" title="행 삭제" />&#160;' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/removecols.gif" id="removecols" title="셀 삭제" />&#160;' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/addrow.gif" id="addrows" title="열 삽입" />&#160;' +
                      '<img style="vertical-align:middle;width:20px;height:20px;cursor:pointer;" src="'+editorPath+'icons/removerow.gif" id="removerow" title="열 삭제" />' +
                      '</td></tr></table>';

    self.editorElem.editBlock.innerHTML = html_output;
    self.$("nowrap").checked = cell.getAttribute("nowrap") ? true : false;

    if (tbl.getAttribute("align")) { self.$("alignment").value = tbl.getAttribute("align"); }
    if (cell.getAttribute("align")) { self.$("c_alignment").value  = cell.getAttribute("align"); }
    if (cell.getAttribute("valign")) { self.$("c_valignment").value    = cell.getAttribute("valign"); }

    self.$("editcell").onclick = function () {
        var n_width = self.$("n_width");
        var n_height = self.$("n_height");
        var n_align = self.$("alignment");
        var n_cellpadding = self.$("n_cellpadding");
        var n_cellspacing = self.$("n_cellspacing");
        var n_bgcolor = self.$("n_bgcolor");
        var n_border = self.$("n_border");
        var n_bordercolor = self.$("n_bordercolor");
        var c_width = self.$("c_width");
        var c_height = self.$("c_height");
        var c_bgcolor = self.$("c_bgcolor");
        var c_align = self.$("c_alignment");
        var c_valign = self.$("c_valignment");

        tbl.border = parseInt(n_border.value);
        tbl.removeAttribute("width", 0);
        tbl.removeAttribute("height", 0);

        if (n_width.value) tbl.style.width = n_width.value;
        if (n_height.value > 0) tbl.style.height = n_height.value;

        tbl.cellPadding = n_cellpadding.value;
        tbl.cellSpacing = n_cellspacing.value;

        if (n_align.value != "") tbl.align = n_align.value;
        else if (tbl.getAttribute("align")) tbl.removeAttribute("align", 0);

        if (n_bgcolor.value) tbl.bgColor = n_bgcolor.value;
        else tbl.removeAttribute("bgcolor", 0);

        if (n_bordercolor.value) tbl.setAttribute("borderColor", n_bordercolor.value);
        else tbl.removeAttribute("borderColor", 0);

        if (c_width.value > 0) cell.width = c_width.value;
        if (c_height.value > 0) cell.height = c_height.value;

        cell.noWrap = self.$("nowrap").checked ? true : false;

        if (c_align.value != "") cell.align = c_align.value;
        else cell.removeAttribute("align", 0);

        if (c_valign.value != "") cell.vAlign = c_valign.value;
        else cell.removeAttribute("valign", 0);

        if (c_bgcolor.value) cell.bgColor = c_bgcolor.value;
        else cell.removeAttribute("bgcolor", 0);
    }

    self.$("increasecolspan").onclick = function () {
        cell.colSpan++;
        if (cell.nextSibling)
        cell.parentNode.deleteCell(cell.cellIndex + 1);
    }
    self.$("decreasecolspan").onclick = function () {
        if (cell.colSpan == 1) cell.removeAttribute("colspan", 0);
        else cell.colSpan = cell.colSpan - 1;
    }
    self.$("increaserowspan").onclick = function () { cell.rowSpan++; }
    self.$("decreaserowspan").onclick = function () {
        if (cell.rowSpan == 1) cell.removeAttribute("rowspan", 0);
        else cell.rowSpan = cell.rowSpan - 1;
    }
    self.$("addcol").onclick = function () {
        for (var i=0; i<tbl.rows.length; i++) {
            var trow = tbl.rows.item(i);
            var col = trow.insertCell(cell.cellIndex);
            if (!GB.browser.msie) {
                var br = document.createElement("br");
                col.appendChild(br);
            }
        }
    }
    self.$("addcols").onclick = function () {
        var col = row.insertCell(cell.cellIndex);
        if (!GB.browser.msie) {
            var br = document.createElement("br");
            col.appendChild(br);
        }
    }
    self.$("removecol").onclick = function () {
        for (var i=0; i<tbl.rows.length; i++) {
            var trow = tbl.rows.item(i);
            trow.deleteCell(cell.cellIndex);
        }
    }
    self.$("removecols").onclick = function () { row.deleteCell(cell.cellIndex); }
    self.$("addrows").onclick = function () {
        var nrow = tbl.insertRow(row.rowIndex);
        var len = row.cells.length;
        for (var i=0; i<len; i++) {
            var td = nrow.insertCell(i);
            if (!GB.browser.msie) {
                var br = document.createElement("br");
                td.appendChild(br);
            }
        }
    }
    self.$("removerow").onclick = function () { tbl.deleteRow(row.rowIndex); }
},

doEditorEvent : function () {
    var self        = this;
    var statusBar   = self.editorElem.tagPath;
    var modifyBlock = self.editorElem.editBlock;
    var oEditor     = self.editArea;
    var cmd = null, el, pNode, ancestors = new Array();

    oEditor.focus();
    var rng = self.getRange();
    var nodeType = self.getSelectionType(rng);
    if (GB.browser.msie) {
        switch (nodeType) {
        case 'Text' :
        case 'None' :
            pNode = rng.parentElement();
            break;
        case 'Control' :
            pNode = rng.item(0);
            break;
        default :
            pNode = oEditor.document.body;
        }
    }
    else {
        try {
            pNode = rng.commonAncestorContainer;
            if (!rng.collapsed &&
                rng.startContainer == rng.endContainer &&
                rng.startOffset - rng.endOffset < 2 &&
                rng.startContainer.hasChildNodes())
            {
                pNode = rng.startContainer.childNodes[rng.startOffset];
            }

            while (pNode.nodeType == 3) {
                pNode = pNode.parentNode;
            }
        }
        catch (e) { pNode= null; }
    }

    while (pNode && (pNode.nodeType == 1) && (pNode.tagName.toLowerCase() != 'body')) {
        ancestors.push(pNode);
        if (pNode.tagName.toLowerCase() == 'img' && (pNode.src.indexOf('/icons/em/') == -1)) {
            cmd = 'img';
            break;
        }
        else if (pNode.tagName.toLowerCase() == 'td') {
            cmd = 'td';
            break;
        }
        pNode = pNode.parentNode;
    }

    ancestors.push(oEditor.document.body);

    if (cmd != null) {
        switch (cmd) {
        case "img" :
            modifyBlock.style.display = "block";
            self.modifyImage(pNode);
            break;
        case "td" :
            modifyBlock.style.display = "block";
            self.modifyCell(pNode);
            break;
        }
    }
    else {
        modifyBlock.style.display = "none";
        modifyBlock.innerHTML = '';
    }

    if (self.config.showTagPath) {
        statusBar.innerHTML = '';
        statusBar.appendChild(document.createTextNode('<html> <body> '));

        while (el = ancestors.pop()) {
            if (!el || el.tagName.toLowerCase() == 'html' || el.tagName.toLowerCase() == 'body')
                continue;

            var tag = el.tagName.toUpperCase();
            var a = document.createElement("a");
            a.el = el;
            a.href = "javascript:void%200";
            a.className = 'cheditor_tag_path_elem';
            a.title = el.style.cssText;
            a.onclick  = function () { self.$('removeSelected').style.display = 'inline'; self.tagSelector(this.el); };
            a.appendChild(document.createTextNode(tag.toLowerCase()));
            statusBar.appendChild(document.createTextNode('<'));
            statusBar.appendChild(a);
            statusBar.appendChild(document.createTextNode('> '));
        }

        var remove = document.createElement("a");
        remove.href = "javascript:void%200";
        remove.id = "removeSelected";
        remove.style.display = 'none';
        remove.className = 'cheditor_tag_path_elem';
        remove.style.color = '#cc3300';
        remove.appendChild(document.createTextNode('remove'));
        remove.onclick = function () {  oEditor.document.execCommand("RemoveFormat", false, null);
                                        remove.style.display = 'none';
                                        oEditor.focus();
                                        self.doEditorEvent(); };

        var span = document.createElement('span');
        span.style.marginTop = '2px';
        span.appendChild(remove);
        self.editorElem.tagPath.appendChild(span);
    }
},

tagSelector : function (node) {
    this.editArea.focus();
    var rng;

    if (GB.browser.msie) {
        rng = this.doc.body.createTextRange();
        if (rng) {
            rng.moveToElementText(node);
            rng.select();
        }
    }
    else {
        var sel = this.editArea.getSelection();
        if (typeof sel == 'undefined')
            return;
        try {
            rng = sel.getRangeAt(0);
        }
        catch(e) { return; }

        rng.selectNodeContents(node);
        sel.removeAllRanges();
        sel.addRange(rng);
    }
},

$ : function (id) {
    return document.getElementById(id);
}

//----------------------------------------------------------------
};

var DragWindow = {
    obj : null,
    init : function (o, oRoot, minX, maxX, minY, maxY) {
        o.onmousedown = DragWindow.start;
        o.onmouseover = function () { this.style.cursor = 'move'; };
        o.hmode = true ;
        o.vmode = true ;
        o.root = oRoot && oRoot != null ? oRoot : o;
        o.transId = oRoot.id + '_Trans';

        if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
        if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
        if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
        if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

        o.minX = typeof minX != 'undefined' ? minX : null;
        o.minY = typeof minY != 'undefined' ? minY : null;
        o.maxX = typeof maxX != 'undefined' ? maxX : null;
        o.maxY = typeof maxY != 'undefined' ? maxY : null;

        o.root.onDragStart  = new Function();
        o.root.onDragEnd    = new Function();
        o.root.onDrag       = new Function();
    },

    start : function (e) {
        var o = DragWindow.obj = this;
        e = DragWindow.fixE(e);
        var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
        var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
        o.root.onDragStart(x, y);

        o.lastMouseX = e.clientX;
        o.lastMouseY = e.clientY;

        document.onmousemove = DragWindow.drag;
        document.onmouseup   = DragWindow.end;

        if (o.root.lastChild.id == o.transId) return false;

        var dragTransBg = document.createElement('div');
        dragTransBg.className = 'cheditor_dragWindowTransparent';

        if (GB.browser.msie) dragTransBg.style.filter = 'alpha(opacity=0)';
        else dragTransBg.style.opacity = 0;

        dragTransBg.id = o.transId;
        dragTransBg.style.width = o.root.lastChild.firstChild.style.width;
        dragTransBg.style.height = o.root.lastChild.firstChild.style.height;
        o.root.appendChild(dragTransBg);

        return false;
    },

    drag : function (e) {
        e = DragWindow.fixE(e);
        var o = DragWindow.obj;
        var ey = e.clientY;
        var ex = e.clientX;
        var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
        var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
        var nx, ny;

        nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
        ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

        DragWindow.obj.root.style.left = nx + "px";
        DragWindow.obj.root.style.top = ny + "px";
        DragWindow.obj.lastMouseX  = ex;
        DragWindow.obj.lastMouseY  = ey;
        DragWindow.obj.root.onDrag(nx, ny);

        return false;
    },

    end : function () {
        document.onmousemove = null;
        document.onmouseup   = null;
        DragWindow.obj.root.onDragEnd(parseInt(DragWindow.obj.root.style[DragWindow.obj.hmode ? "left" : "right"]),
                parseInt(DragWindow.obj.root.style[DragWindow.obj.vmode ? "top" : "bottom"]));

        if (DragWindow.obj.root.lastChild.id == DragWindow.obj.transId)
            DragWindow.obj.root.removeChild(DragWindow.obj.root.lastChild);
        DragWindow.obj = null;
    },

    fixE : function (e) {
        if (typeof e == 'undefined') e = window.event;
        if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
        if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
        return e;
    }
};
