/** 
 * x.js compiled from X 4.0 with XC 0.27b. 
 * Distributed by GNU LGPL. For copyrights, license, documentation and more visit Cross-Browser.com 
 * Copyright 2001-2005 Michael Foster (Cross-Browser.com)
 **/

var xOp7Up,xOp6Dn,xIE4Up,xIE4,xIE5,xIE6,xNN4,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
  var i=xUA.indexOf('opera');
  if(i!=-1){
    var v=parseInt(xUA.charAt(i+6));
    xOp7Up=v>=7;
    xOp6Dn=v<7;
  }
}
else if(navigator.vendor!='KDE' && document.all && xUA.indexOf('msie')!=-1){
  xIE4Up=parseFloat(navigator.appVersion)>=4;
  xIE4=xUA.indexOf('msie 4')!=-1;
  xIE5=xUA.indexOf('msie 5')!=-1;
  xIE6=xUA.indexOf('msie 6')!=-1;
}
else if(document.layers){xNN4=true;}
var xMac=xUA.indexOf('mac')!=-1;
var xFF=xUA.indexOf('firefox')!=-1;

// (element, event(without 'on'), event listener(function name)[, caption])
function xAddEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xPCW=xClientWidth(); window.xPCH=xClientHeight(); window.xREL=eL; xResizeEvent(); return; }
    if(eT=='scroll') { window.xPSL=xScrollLeft(); window.xPST=xScrollTop(); window.xSEL=eL; xScrollEvent(); return; }
  }
  var eh='e.on'+eT+'=eL';
  if(e.addEventListener) e.addEventListener(eT,eL,cap);
  else if(e.attachEvent) e.attachEvent('on'+eT,eL);
  else eval(eh);
}
// called only from the above
function xResizeEvent()
{
  if (window.xREL) setTimeout('xResizeEvent()', 250);
  var cw = xClientWidth(), ch = xClientHeight();
  if (window.xPCW != cw || window.xPCH != ch) { window.xPCW = cw; window.xPCH = ch; if (window.xREL) window.xREL(); }
}

function xScrollEvent()
{
  if (window.xSEL) setTimeout('xScrollEvent()', 250);
  var sl = xScrollLeft(), st = xScrollTop();
  if (window.xPSL != sl || window.xPST != st) { window.xPSL = sl; window.xPST = st; if (window.xSEL) window.xSEL(); }
}

function xAppendChild(oParent, oChild)
{
  if (oParent.appendChild) return oParent.appendChild(oChild);
  else return null;
}

function xClientHeight()
{
  var h=0;
  if(xOp6Dn) h=window.innerHeight;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientHeight)
    h=document.documentElement.clientHeight;
  else if(document.body && document.body.clientHeight)
    h=document.body.clientHeight;
  else if(xDef(window.innerWidth,window.innerHeight,document.width)) {
    h=window.innerHeight;
    if(document.width>window.innerWidth) h-=16;
  }
  return h;
}

function xClientWidth()
{
  var w=0;
  if(xOp6Dn) w=window.innerWidth;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientWidth)
    w=document.documentElement.clientWidth;
  else if(document.body && document.body.clientWidth)
    w=document.body.clientWidth;
  else if(xDef(window.innerWidth,window.innerHeight,document.height)) {
    w=window.innerWidth;
    if(document.height>window.innerHeight) w-=16;
  }
  return w;
}

function xCreateElement(sTag)
{
  if (document.createElement) return document.createElement(sTag);
  else return null;
}

function xDef()
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
  return true;
}

function xDeleteCookie(name, path)
{
  if (xGetCookie(name)) {
    document.cookie = name + "=" +
                    "; path=" + ((!path) ? "/" : path) +
                    "; expires=" + new Date(0).toGMTString();
  }
}

function xDisplay(e,s)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.display)) {
    if (xStr(s)) e.style.display = s;
    return e.style.display;
  }
  return null;
}

function xEvent(evt) // object prototype
{
  var e = evt || window.event;
  if(!e) return;
  if(e.type) this.type = e.type;
  if(e.target) this.target = e.target;
  else if(e.srcElement) this.target = e.srcElement;

  // Section B
  if (e.relatedTarget) this.relatedTarget = e.relatedTarget;
  else if (e.type == 'mouseover' && e.fromElement) this.relatedTarget = e.fromElement;
  else if (e.type == 'mouseout') this.relatedTarget = e.toElement;
  // End Section B

  if(xOp6Dn) { this.pageX = e.clientX; this.pageY = e.clientY; }
  else if(xDef(e.pageX,e.pageY)) { this.pageX = e.pageX; this.pageY = e.pageY; }
  else if(xDef(e.clientX,e.clientY)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); }

  // Section A
  if (xDef(e.offsetX,e.offsetY)) {
    this.offsetX = e.offsetX;
    this.offsetY = e.offsetY;
  }
  else if (xDef(e.layerX,e.layerY)) {
    this.offsetX = e.layerX;
    this.offsetY = e.layerY;
  }
  else {
    this.offsetX = this.pageX - xPageX(this.target);
    this.offsetY = this.pageY - xPageY(this.target);
  }
  // End Section A
  
  if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
  else if (xDef(e.which) && e.type.indexOf('key')!=-1) { this.keyCode = e.which; }

  this.shiftKey = e.shiftKey;
  this.ctrlKey = e.ctrlKey;
  this.altKey = e.altKey;
}

function xFirstChild(e, t)
{
  var c = e ? e.firstChild : null;
  if (t) while (c && c.nodeName != t) { c = c.nextSibling; }
  else while (c && c.nodeType != 1) { c = c.nextSibling; }
  return c;
}

function xGetBodyWidth() {
  var cw = xClientWidth();
  var sw = window.document.body.scrollWidth;
  return cw>sw?cw:sw;
}

function xGetBodyHeight() {
  var cw = xClientHeight();
  var sw = window.document.body.scrollHeight;
  return cw>sw?cw:sw;
}

function xGetComputedStyle(oEle, sProp, bInt)
{
  var s, p = 'undefined';
  var dv = document.defaultView;
  if(dv && dv.getComputedStyle){
    s = dv.getComputedStyle(oEle,'');
    if (s) p = s.getPropertyValue(sProp);
  }
  else if(oEle.currentStyle) {
    // convert css property name to object property name for IE
    var a = sProp.split('-');
    sProp = a[0];
    for (var i=1; i<a.length; ++i) {
      c = a[i].charAt(0);
      sProp += a[i].replace(c, c.toUpperCase());
    }   
    p = oEle.currentStyle[sProp];
  }
  else return null;
  return bInt ? (parseInt(p) || 0) : p;
}

function xGetCookie(name)
{
  var value=null, search=name+"=";
  if (document.cookie.length > 0) {
    var offset = document.cookie.indexOf(search);
    if (offset != -1) {
      offset += search.length;
      var end = document.cookie.indexOf(";", offset);
      if (end == -1) end = document.cookie.length;
      value = unescape(document.cookie.substring(offset, end));
    }
  }
  return value;
}

function xGetElementById(e)
{
  if(typeof(e)!='string') return e;
  if(document.getElementById) e=document.getElementById(e);
  else if(document.all) e=document.all[e];
  else e=null;
  return e;
}

function xGetElementsByAttribute(sTag, sAtt, sRE, fn)
{
  var a, list, found = new Array(), re = new RegExp(sRE, 'i');
  list = xGetElementsByTagName(sTag);
  for (var i = 0; i < list.length; ++i) {
    a = list[i].getAttribute(sAtt);
    if (!a) {a = list[i][sAtt];}
    if (typeof(a)=='string' && a.search(re) != -1) {
      found[found.length] = list[i];
      if (fn) fn(list[i]);
    }
  }
  return found;
}

function xGetElementsByClassName(c,p,t,f)
{
  var found = new Array();
  var re = new RegExp('\\b'+c+'\\b', 'i');
  var list = xGetElementsByTagName(t, p);
  for (var i = 0; i < list.length; ++i) {
    if (list[i].className && list[i].className.search(re) != -1) {
      found[found.length] = list[i];
      if (f) f(list[i]);
    }
  }
  return found;
}

function xGetElementsByTagName(t,p)
{
  var list = null;
  t = t || '*';
  p = p || document;
  if (xIE4 || xIE5) {
    if (t == '*') list = p.all;
    else list = p.all.tags(t);
  }
  else if (p.getElementsByTagName) list = p.getElementsByTagName(t);
  return list || new Array();
}

function xGetURLArguments()
{
  var idx = location.href.indexOf('?');
  var params = new Array();
  if (idx != -1) {
    var pairs = location.href.substring(idx+1, location.href.length).split('&');
    for (var i=0; i<pairs.length; i++) {
      nameVal = pairs[i].split('=');
      params[i] = nameVal[1];
      params[nameVal[0]] = nameVal[1];
    }
  }
  return params;
}

function xHeight(e,h)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(h)) {
    if (h<0) h = 0;
    else h=Math.round(h);
  }
  else h=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    h = xClientHeight();
  }
  else if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
    if(h>=0) {
      var pt=0,pb=0,bt=0,bb=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pt=gcs(e,'padding-top',1);
        if (pt !== null) {
          pb=gcs(e,'padding-bottom',1);
          bt=gcs(e,'border-top-width',1);
          bb=gcs(e,'border-bottom-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetHeight,e.style.height)){
          e.style.height=h+'px';
          pt=e.offsetHeight-h;
        }
      }
      h-=(pt+pb+bt+bb);
      if(isNaN(h)||h<0) return null;
      else e.style.height=h+'px';
    }
    h=e.offsetHeight;
  }
  else if(css && xDef(e.style.pixelHeight)) {
    if(h>=0) e.style.pixelHeight=h;
    h=e.style.pixelHeight;
  }
  return h;
}

function xHex(sn, digits, prefix)
{
  var p = '';
  var n = Math.ceil(sn);
  if (prefix) p = prefix;
  n = n.toString(16);
  for (var i=0; i < digits - n.length; ++i) {
    p += '0';
  }
  return p + n;
}

function xHide(e){return xVisibility(e,0);}

function xInnerHtml(e,h)
{
  if(!(e=xGetElementById(e)) || !xStr(e.innerHTML)) return null;
  var s = e.innerHTML;
  if (xStr(h)) {e.innerHTML = h;}
  return s;
}

function xLeft(e, iX)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if (css && xStr(e.style.left)) {
    if(xNum(iX)) e.style.left=iX+'px';
    else {
      iX=parseInt(e.style.left);
      if(isNaN(iX)) iX=0;
    }
  }
  else if(css && xDef(e.style.pixelLeft)) {
    if(xNum(iX)) e.style.pixelLeft=iX;
    else iX=e.style.pixelLeft;
  }
  return iX;
}

function xMoveTo(e,x,y)
{
  xLeft(e,x);
  xTop(e,y);
}

function xName(e)
{
  if (!e) return e;
  else if (e.id && e.id != "") return e.id;
  else if (e.name && e.name != "") return e.name;
  else if (e.nodeName && e.nodeName != "") return e.nodeName;
  else if (e.tagName && e.tagName != "") return e.tagName;
  else return e;
}

function xNextSib(e,t)
{
  var s = e ? e.nextSibling : null;
  if (t) while (s && s.nodeName != t) { s = s.nextSibling; }
  else while (s && s.nodeType != 1) { s = s.nextSibling; }
  return s;
}

function xNum()
{
  for(var i=0; i<arguments.length; ++i){if(isNaN(arguments[i]) || typeof(arguments[i])!='number') return false;}
  return true;
}

function xOffsetLeft(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetLeft)) return e.offsetLeft;
  else return 0;
}

function xOffsetTop(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetTop)) return e.offsetTop;
  else return 0;
}

function xPad(s,len,c,left)
{
  if(typeof s != 'string') s=s+'';
  if(left) {for(var i=s.length; i<len; ++i) s=c+s;}
  else {for (i=s.length; i<len; ++i) s+=c;}
  return s;
}

function xPageX(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var x = 0;
  while (e) {
    if (xDef(e.offsetLeft)) x += e.offsetLeft;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
  return x;
}

function xPageY(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var y = 0;
  while (e) {
    if (xDef(e.offsetTop)) y += e.offsetTop;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
//  if (xOp7Up) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324 (reported 1nov03)
  return y;
}

function xParent(e, bNode)
{
  if (!(e=xGetElementById(e))) return null;
  var p=null;
  if (!bNode && xDef(e.offsetParent)) p=e.offsetParent;
  else if (xDef(e.parentNode)) p=e.parentNode;
  else if (xDef(e.parentElement)) p=e.parentElement;
  return p;
}

function xPreventDefault(e)
{
  if (e && e.preventDefault) e.preventDefault()
  else if (window.event) window.event.returnValue = false;
}

function xPrevSib(e,t)
{
  var s = e ? e.previousSibling : null;
  if (t) while(s && s.nodeName != t) {s=s.previousSibling;}
  else while(s && s.nodeType != 1) {s=s.previousSibling;}
  return s;
}

function xRemoveEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xREL=null; return; }
    if(eT=='scroll') { window.xSEL=null; return; }
  }
  var eh='e.on'+eT+'=null';
  if(e.removeEventListener) e.removeEventListener(eT,eL,cap);
  else if(e.detachEvent) e.detachEvent('on'+eT,eL);
  else eval(eh);
}

function xResizeTo(e,w,h)
{
  xWidth(e,w);
  xHeight(e,h);
}

function xScrollLeft(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollLeft) offset=w.document.documentElement.scrollLeft;
    else if(w.document.body && xDef(w.document.body.scrollLeft)) offset=w.document.body.scrollLeft;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollLeft)) offset = e.scrollLeft;
  }
  return offset;
}

function xScrollTop(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollTop) offset=w.document.documentElement.scrollTop;
    else if(w.document.body && xDef(w.document.body.scrollTop)) offset=w.document.body.scrollTop;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollTop)) offset = e.scrollTop;
  }
  return offset;
}

function xSetCookie(name, value, expire, path)
{
  document.cookie = name + "=" + escape(value) +
                    ((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
                    "; path=" + ((!path) ? "/" : path);
}

function xShow(e) {return xVisibility(e,1);}


function xStr(s)
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
  return true;
}

function xTop(e, iY)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if(css && xStr(e.style.top)) {
    if(xNum(iY)) e.style.top=iY+'px';
    else {
      iY=parseInt(e.style.top);
      if(isNaN(iY)) iY=0;
    }
  }
  else if(css && xDef(e.style.pixelTop)) {
    if(xNum(iY)) e.style.pixelTop=iY;
    else iY=e.style.pixelTop;
  }
  return iY;
}

function xVisibility(e, bShow)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.visibility)) {
    if (xDef(bShow)) e.style.visibility = bShow ? 'visible' : 'hidden';
    return e.style.visibility;
  }
  return null;
}

function xWidth(e,w)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(w)) {
    if (w<0) w = 0;
    else w=Math.round(w);
  }
  else w=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    w = xClientWidth();
  }
  else if(css && xDef(e.offsetWidth) && xStr(e.style.width)) {
    if(w>=0) {
      var pl=0,pr=0,bl=0,br=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pl=gcs(e,'padding-left',1);
        if (pl !== null) {
          pr=gcs(e,'padding-right',1);
          bl=gcs(e,'border-left-width',1);
          br=gcs(e,'border-right-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetWidth,e.style.width)){
          e.style.width=w+'px';
          pl=e.offsetWidth-w;
        }
      }
      w-=(pl+pr+bl+br);
      if(isNaN(w)||w<0) return null;
      else e.style.width=w+'px';
    }
    w=e.offsetWidth;
  }
  else if(css && xDef(e.style.pixelWidth)) {
    if(w>=0) e.style.pixelWidth=w;
    w=e.style.pixelWidth;
  }
  return w;
}

function xZIndex(e,uZ)
{
  if(!(e=xGetElementById(e))) return 0;
  if(e.style && xDef(e.style.zIndex)) {
    if(xNum(uZ)) e.style.zIndex=uZ;
    uZ=parseInt(e.style.zIndex);
  }
  return uZ;
}

function xStopPropagation(evt)
{
  if (evt && evt.stopPropagation) evt.stopPropagation();
  else if (window.event) window.event.cancelBubble = true;
}


/**
 * @file common.js
 * @author zero (info@hotit.co.jp)
 * @brief 몇가지 유용한 & 기본적으로 자주 사용되는 자바스크립트 함수들 모음
 **/

/**
 * @brief location.href에서 특정 key의 값을 return
 **/
String.prototype.getQuery = function(key) {
    var idx = this.indexOf('?');
    if(idx == -1) return null;
    var query_string = this.substr(idx+1, this.length);
    var args = {}
    query_string.replace(/([^=]+)=([^&]*)(&|$)/g, function() { args[arguments[1]] = arguments[2]; });

    var q = args[key];
    if(typeof(q)=="undefined") q = "";

    return q;
}

/**
 * @brief location.href에서 특정 key의 값을 return
 **/
String.prototype.setQuery = function(key, val) {
    var idx = this.indexOf('?');
    var uri = this;
    uri = uri.replace(/#$/,'');

    if(idx != -1) {
        uri = this.substr(0, idx);
        var query_string = this.substr(idx+1, this.length);
        var args = new Array();
        query_string.replace(/([^=]+)=([^&]*)(&|$)/g, function() { args[arguments[1]] = arguments[2]; });

        args[key] = val;

        var q_list = new Array();
        for(var i in args) {
        if( !args.hasOwnProperty(i) ) continue;
            var arg = args[i];
            if(!arg.toString().trim()) continue;

            q_list[q_list.length] = i+'='+arg;
        }
        uri = uri+"?"+q_list.join("&");
    } else {
        if(val.toString().trim()) uri = uri+"?"+key+"="+val;
    }

    uri = uri.replace(/^https:\/\//i,'http://');
    if(typeof(ssl_actions)!='undefined' && typeof(ssl_actions.length)!='undefined' && uri.getQuery('act')) {
        var act = uri.getQuery('act');
        for(i=0;i<ssl_actions.length;i++) {
            if(ssl_actions[i]==act) {
                uri = uri.replace(/^http:\/\//i,'https://');
                break;
            }
        }
    }
    return uri;
}

/**
 * @breif replace outerHTML
 **/
function replaceOuterHTML(obj, html) {
    if(obj.outerHTML) {
        obj.outerHTML = html;
    } else {
        var dummy = xCreateElement("div"); 
        xInnerHtml(dummy, html);
        var parent = obj.parentNode;
        while(dummy.firstChild) {
            parent.insertBefore(dummy.firstChild, obj);
        }
        parent.removeChild(obj);
    }
}

/**
 * @breif get outerHTML
 **/
function getOuterHTML(obj) {
    if(obj.outerHTML) return obj.outerHTML;
    var dummy = xCreateElement("div");
    dummy.insertBefore(obj, dummy.lastChild);
    return xInnerHtml(dummy);
}

/**
 * @brief xSleep(micro time) 
 **/
function xSleep(sec) {
    sec = sec / 1000;
    var now = new Date();
    var sleep = new Date();
    while( sleep.getTime() - now.getTime() < sec) {
        sleep = new Date();
    }      
}


/**
 * @brief string prototype으로 trim 함수 추가
 **/
String.prototype.trim = function() {
    return this.replace(/(^\s*)|(\s*$)/g, "");
}

/**
 * @brief 주어진 인자가 하나라도 defined되어 있지 않으면 false return
 **/
function isDef() {
    for(var i=0; i<arguments.length; ++i) {
        if(typeof(arguments[i])=="undefined") return false;
    }
    return true;
}

/**
 * @brief 윈도우 오픈
 * 열려진 윈도우의 관리를 통해 window.focus()등을 FF에서도 비슷하게 구현함
 **/
var winopen_list = new Array();
function winopen(url, target, attribute) {
    try {
        if(target != "_blank" && winopen_list[target]) {
            winopen_list[target].close();
            winopen_list[target] = null;
        }
    } catch(e) {
    }

    if(typeof(target)=='undefined') target = '_blank';
    if(typeof(attribute)=='undefined') attribute = '';
    var win = window.open(url, target, attribute);
    win.focus();
    if(target != "_blank") winopen_list[target] = win;
}

/**
 * @brief 팝업으로만 띄우기 
 * common/tpl/popup_layout.html이 요청되는 제로보드 XE내의 팝업일 경우에 사용
 **/
function popopen(url, target) {
    if(typeof(target)=="undefined") target = "_blank";
    winopen(url, target, "left=10,top=10,width=10,height=10,scrollbars=no,resizable=yes,toolbars=no");
}

/**
 * @brief 메일 보내기용
 **/
function sendMailTo(to) {
    location.href="mailto:"+to;
}

/**
 * @brief url이동 (open_window 값이 N 가 아니면 새창으로 띄움)
 **/
function move_url(url, open_wnidow) {
    if(!url) return false;
    if(typeof(open_wnidow)=='undefined') open_wnidow = 'N';
    if(open_wnidow=='N') open_wnidow = false;
    else open_wnidow = true;

    if(/^\./.test(url)) url = request_uri+url;

    if(open_wnidow) {
        winopen(url);
    } else {
        location.href=url;
    }
    return false;
}

/**
 * @brief 특정 Element의 display 옵션 토글
 **/
function toggleDisplay(obj, display_type) {
    var obj = xGetElementById(obj);
    if(!obj) return;
    if(!obj.style.display || obj.style.display != 'none') {
        obj.style.display = 'none';
    } else {
        if(display_type) obj.style.display = display_type;
        else obj.style.display = '';
    }
}

/**
 * @brief 멀티미디어 출력용 (IE에서 플래쉬/동영상 주변에 점선 생김 방지용)
 **/
function displayMultimedia(src, width, height, auto_start, flashvars) {
    if(src.indexOf('files')==0) src = request_uri+src;
    if(auto_start) auto_start = "true";
    else auto_start = "false";

    var clsid = "";
    var codebase = "";
    var html = "";

    if(typeof(flashvars)=="undefined") flashvars = "";

    if(/\.swf/i.test(src)) {
        clsid = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"; 
        codebase = "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0";
        html = ""+
            "<object classid=\""+clsid+"\" codebase=\""+codebase+"\" width=\""+width+"\" height=\""+height+"\" flashvars=\""+flashvars+"\">"+
            "<param name=\"wmode\" value=\"transparent\" />"+
            "<param name=\"allowScriptAccess\" value=\"sameDomain\" />"+
            "<param name=\"movie\" value=\""+src+"\" />"+
            "<param name=\"quality\" value=\"high\" />"+
            "<param name=\"flashvars\" value=\""+flashvars+"\" />"+
            "<embed src=\""+src+"\" autostart=\""+auto_start+"\"  width=\""+width+"\" height=\""+height+"\" flashvars=\""+flashvars+"\" wmode=\"transparent\"></embed>"+
            "<\/object>";
    } else if(/\.flv/i.test(src)) {
        html = "<embed src=\""+request_uri+"common/tpl/images/flvplayer.swf\" allowfullscreen=\"true\" autostart=\""+auto_start+"\" width=\""+width+"\" height=\""+height+"\" flashvars=\"&file="+src+"&width="+width+"&height="+height+"&autostart="+auto_start+"\" />";
    } else {
        html = "<embed src=\""+src+"\" autostart=\""+auto_start+"\" width=\""+width+"\" height=\""+height+"\"></embed>";
    }
    document.writeln(html);
}

/**
 * @brief 에디터에서 사용되는 내용 여닫는 코드 (고정, zbxe용)
 **/
function zbxe_folder_open(id) {
    var open_text_obj = xGetElementById("folder_open_"+id);
    var close_text_obj = xGetElementById("folder_close_"+id);
    var folder_obj = xGetElementById("folder_"+id);
    open_text_obj.style.display = "none";
    close_text_obj.style.display = "block";
    folder_obj.style.display = "block";
}

function zbxe_folder_close(id) {
    var open_text_obj = xGetElementById("folder_open_"+id);
    var close_text_obj = xGetElementById("folder_close_"+id);
    var folder_obj = xGetElementById("folder_"+id);
    open_text_obj.style.display = "block";
    close_text_obj.style.display = "none";
    folder_obj.style.display = "none";
}


/**
 * @brief 에디터에서 사용하되 내용 여닫는 코드 (zb5beta beta 호환용으로 남겨 놓음)
 **/
function svc_folder_open(id) {
    var open_text_obj = xGetElementById("_folder_open_"+id);
    var close_text_obj = xGetElementById("_folder_close_"+id);
    var folder_obj = xGetElementById("_folder_"+id);
    open_text_obj.style.display = "none";
    close_text_obj.style.display = "block";
    folder_obj.style.display = "block";
}

function svc_folder_close(id) {
    var open_text_obj = xGetElementById("_folder_open_"+id);
    var close_text_obj = xGetElementById("_folder_close_"+id);
    var folder_obj = xGetElementById("_folder_"+id);
    open_text_obj.style.display = "block";
    close_text_obj.style.display = "none";
    folder_obj.style.display = "none";
}

/**
 * @brief 팝업의 경우 내용에 맞춰 현 윈도우의 크기를 조절해줌 
 * 팝업의 내용에 맞게 크기를 늘리는 것은... 쉽게 되지는 않음.. ㅡ.ㅜ
 * popup_layout 에서 window.onload 시 자동 요청됨.
 **/
function setFixedPopupSize() {

    if(xGetElementById('popBody')) {
        if(xHeight('popBody')>500) {
            xGetElementById('popBody').style.overflowY = 'scroll';
            xGetElementById('popBody').style.overflowX = 'hidden';
            xHeight('popBody', 500);
        }
    }

    var w = xWidth("popup_content");
    var h = xHeight("popup_content");

    var obj_list = xGetElementsByTagName('div');
    for(i=0;i<obj_list.length;i++) {
        var ww = xWidth(obj_list[i]);
        var id = obj_list[i].id;
        if(id == 'waitingforserverresponse' || id == 'fororiginalimagearea' || id == 'fororiginalimageareabg') continue;
        if(ww>w) w = ww;
    }

    // 윈도우에서는 브라우저 상관없이 가로 픽셀이 조금 더 늘어나야 한다.
    if(xUA.indexOf('windows')>0) {
        if(xOp7Up) w += 10;
        else if(xIE4Up) w += 10;
        else w += 6;
    }
    window.resizeTo(w,h);
   
    var h1 = xHeight(window.document.body);
    window.resizeBy(0,h-h1);

    window.scrollTo(0,0);
}

/**
 * @brief 이름, 게시글등을 클릭하였을 경우 팝업 메뉴를 보여주는 함수
 **/
xAddEventListener(window, 'load', createPopupMenu);
xAddEventListener(document, 'click', chkPopupMenu);

var loaded_popup_menus = new Array();

/* 멤버 팝업 메뉴 레이어를 생성하는 함수 (문서 출력이 완료되었을때 동작) */
function createPopupMenu(evt) {
    var area = xGetElementById("popup_menu_area");
    if(area) return;
    area = xCreateElement("div");
    area.id = "popup_menu_area";
    area.style.visibility = 'hidden';
    document.body.appendChild(area);
}

/* 클릭 이벤트 발생시 이벤트가 일어난 대상을 검사하여 적절한 규칙에 맞으면 처리 */
function chkPopupMenu(evt) {
    // 이전에 호출되었을지 모르는 팝업메뉴 숨김
    var area = xGetElementById("popup_menu_area");
    if(!area) return;

    if(area.style.visibility!="hidden") area.style.visibility="hidden";

    // 이벤트 대상이 없으면 무시
    var e = new xEvent(evt);
    if(!e) return;

    // 대상의 객체 구함
    var obj = e.target;
    if(!obj) return;

    // obj의 nodeName이 div나 span이 아니면 나올대까지 상위를 찾음
    if(obj && obj.nodeName != 'DIV' && obj.nodeName != 'SPAN') obj = obj.parentNode;
    if(!obj || (obj.nodeName != 'DIV' && obj.nodeName != 'SPAN')) return;

    // 객체의 className값을 구함
    var class_name = obj.className;
    if(!class_name) return;

    // className을 분리
    var class_name_list = class_name.split(' ');
    var menu_id = '';
    var menu_id_regx = /^([a-zA-Z]+)_([0-9]+)$/ig;
    for(var i in class_name_list) {
        if(menu_id_regx.test(class_name_list[i])) {
            menu_id = class_name_list[i];
            break;
        }
    }
    if(!menu_id) return;

    // module명과 대상 번호가 없으면 return
    var tmp_arr = menu_id.split('_');
    var module_name = tmp_arr[0];
    var target_srl = tmp_arr[1];
    if(!module_name || !target_srl || target_srl < 1) return;

    // action이름을 규칙에 맞게 작성
    var action_name = "get" + module_name.substr(0,1).toUpperCase() + module_name.substr(1,module_name.length-1) + "Menu";

    // 서버에 메뉴를 요청
    var params = new Array();
    params["target_srl"] = target_srl;
    params["cur_mid"] = current_mid;
    params["cur_act"] = current_url.getQuery('act');
    params["menu_id"] = menu_id;
    params["page_x"] = e.pageX;
    params["page_y"] = e.pageY;

    var response_tags = new Array("error","message","menus");

    if(loaded_popup_menus[menu_id]) {
        displayPopupMenu(params, response_tags, params);
        return;
    }

    show_waiting_message = false;
    exec_xml(module_name, action_name, params, displayPopupMenu, response_tags, params);
    show_waiting_message = true;
}

function displayPopupMenu(ret_obj, response_tags, params) {
    var target_srl = params["target_srl"];
    var menu_id = params["menu_id"];
    var menus = ret_obj['menus'];
    var html = "";

    if(loaded_popup_menus[menu_id]) {
        html = loaded_popup_menus[menu_id];
    } else {
        if(menus) {
            var item = menus['item'];
            if(item.length<1) item = new Array(item);
            if(item.length) {
                for(var i=0;i<item.length;i++) {
                    var url = item[i].url;
                    var str = item[i].str;
                    var icon = item[i].icon;
                    var target = item[i].target;

                    var styleText = "";

                    if(icon) styleText = " style=\"background:url('"+icon+"') no-repeat left center; padding-left:18px; \"";
                    switch(target) {
                        case "popup" :
                                click_str = " onclick=\"popopen('"+url+"','"+target+"')\"; return false;";
                            break;
                        case "self" :
                                click_str = " onclick=\"location.href='"+url+"'\"; return false;";
                            break;
                        case "javascript" :
                                click_str = " onclick=\""+url+"\"; return false;";
                            break;
                        default :
                                click_str = " onclick=\"window.open('"+url+"')\"; return false;";
                            break;
                    }

                    html += '<div class="item" onmouseover="this.className=\'item_on\'" onmouseout="this.className=\'item\'"'+styleText+click_str+'>'+str+'</div> ';
                }
            }
        }
        loaded_popup_menus[menu_id] =  html;
    }

    // 레이어 출력
    if(html) {
        var area = xGetElementById("popup_menu_area");
        xInnerHtml(area, "<div class=\"box\">"+html+"</div>");
        xLeft(area, params["page_x"]);
        xTop(area, params["page_y"]);
        if(xWidth(area)+xLeft(area)>xClientWidth()+xScrollLeft()) xLeft(area, xClientWidth()-xWidth(area)+xScrollLeft());
        if(xHeight(area)+xTop(area)>xClientHeight()+xScrollTop()) xTop(area, xClientHeight()-xHeight(area)+xScrollTop());
        area.style.visibility = "visible";
    }
}

/**
 * @brief 추천/비추천,스크랩,신고기능등 특정 srl에 대한 특정 module/action을 호출하는 함수
 **/
function doCallModuleAction(module, action, target_srl) {
    var params = new Array();
    params['target_srl'] = target_srl;
    params['cur_mid'] = current_mid;
    exec_xml(module, action, params, completeCallModuleAction);
}

function completeCallModuleAction(ret_obj, response_tags) {
    if(ret_obj['message']!='success') alert(ret_obj['message']);
    location.reload();
}

/**
 * @brief 날짜 선택 (달력 열기) 
 **/
function open_calendar(fo_id, day_str, callback_func) {
    if(typeof(day_str)=="undefined") day_str = "";

    var url = "./common/tpl/calendar.php?";
    if(fo_id) url+="fo_id="+fo_id;
    if(day_str) url+="&day_str="+day_str;
    if(callback_func) url+="&callback_func="+callback_func;

    popopen(url, 'Calendar');
}

/* 언어코드 (lang_type) 쿠키값 변경 */
function doChangeLangType(obj) {
    if(typeof(obj)=="string") {
        setLangType(obj);
    } else {
        var val = obj.options[obj.selectedIndex].value;
        setLangType(val);
    }
    location.reload();
}
function setLangType(lang_type) {
    var expire = new Date();
    expire.setTime(expire.getTime()+ (7000 * 24 * 3600000));
    xSetCookie('lang_type', lang_type, expire);
}

/* 미리보기 */
function doDocumentPreview(obj) {
    var fo_obj = obj;
    while(fo_obj.nodeName != "FORM") {
        fo_obj = fo_obj.parentNode;
    }
    if(fo_obj.nodeName != "FORM") return;
    var editor_sequence = fo_obj.getAttribute('editor_sequence');

    var content = editorGetContent(editor_sequence);

    var win = window.open("","previewDocument","toolbars=no,width=700px;height=800px,scrollbars=yes,resizable=yes");

    var dummy_obj = xGetElementById("previewDocument");

    if(!dummy_obj) {
        var fo_code = '<form id="previewDocument" target="previewDocument" method="post" action="'+request_uri+'">'+
                      '<input type="hidden" name="module" value="document" />'+
                      '<input type="hidden" name="act" value="dispDocumentPreview" />'+
                      '<input type="hidden" name="content" />'+
                      '</form>';
        var dummy = xCreateElement("DIV");
        xInnerHtml(dummy, fo_code);
        window.document.body.insertBefore(dummy,window.document.body.lastChild);
        dummy_obj = xGetElementById("previewDocument");
    }

    if(dummy_obj) {
        dummy_obj.content.value = content;
        dummy_obj.submit();
    }
}

/* 게시글 저장 */
function doDocumentSave(obj) {
    var editor_sequence = obj.form.getAttribute('editor_sequence');
    var prev_content = editorRelKeys[editor_sequence]['content'].value;
    if(typeof(editor_sequence)!='undefined' && editor_sequence && typeof(editorRelKeys)!='undefined' && typeof(editorGetContent)=='function') {
        var content = editorGetContent(editor_sequence);
        editorRelKeys[editor_sequence]['content'].value = content;
    }

    var oFilter = new XmlJsFilter(obj.form, "member", "procMemberSaveDocument", completeDocumentSave);
    oFilter.addResponseItem("error");
    oFilter.addResponseItem("message");
    oFilter.proc();

    editorRelKeys[editor_sequence]['content'].value = prev_content;
    return false;
}

function completeDocumentSave(ret_obj) {
    alert(ret_obj['message']);
}

/* 저장된 게시글 불러오기 */
var objForSavedDoc = null;
function doDocumentLoad(obj) {
    // 저장된 게시글 목록 불러오기
    objForSavedDoc = obj.form;
    popopen(request_uri.setQuery('module','member').setQuery('act','dispSavedDocumentList'));
}

/* 저장된 게시글의 선택 */
function doDocumentSelect(document_srl) {
    if(!opener || !opener.objForSavedDoc) {
        window.close();
        return;
    }

    // 게시글을 가져와서 등록하기
    opener.location.href = opener.current_url.setQuery('document_srl', document_srl);
    window.close();
}


/* 스킨 정보 */
function viewSkinInfo(module, skin) {
    popopen("./?module=module&act=dispModuleSkinInfo&selected_module="+module+"&skin="+skin, 'SkinInfo');
}

/* 체크박스 선택 */
function checkboxSelectAll(form, name, option){ 
    var value;
    var fo_obj = xGetElementById(form);
    for ( var i = 0 ; i < fo_obj.length ; i++ ){
        if(typeof(option) == "undefined") {
            var select_mode = fo_obj[i].checked;
            if ( select_mode == 0 ){
                value = true;
                select_mode = 1;
            }else{
                value = false;
                select_mode = 0;
            }
        }
        else if(option == true) value = true
        else if(option == false) value = false

        if(fo_obj[i].name == name) fo_obj[i].checked = value;
    }
}

/* 체크박스를 실행 */
function clickCheckBoxAll(form, name) {
    var fo_obj = xGetElementById(form);
    for ( var i = 0 ; i < fo_obj.length ; i++ ){
        if(fo_obj[i].name == name) fo_obj[i].click();
    }
}

/* 관리자가 문서를 관리하기 위해서 선택시 세션에 넣음 */
function doAddDocumentCart(obj) {
    var srl = obj.value;
    var params = new Array();
    params["srl"] = srl;
    exec_xml("document","procDocumentAdminAddCart", params, null);
}

/* ff의 rgb(a,b,c)를 #... 로 변경 */
function transRGB2Hex(value) {
    if(!value) return value;
    if(value.indexOf('#') > -1) return value.replace(/^#/, '');

    if(value.toLowerCase().indexOf('rgb') < 0) return value;
    value = value.replace(/^rgb\(/i, '').replace(/\)$/, '');
    value_list = value.split(',');

    var hex = '';
    for(var i = 0; i < value_list.length; i++) {
        var color = parseInt(value_list[i], 10).toString(16);
        if(color.length == 1) color = '0'+color;
        hex += color;
    }
    return hex;
}

/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}

/* select - option의 disabled=disabled 속성을 IE에서도 체크하기 위한 함수 */
if(xIE4Up) {
    xAddEventListener(window, 'load', activateOptionDisabled);

    function activateOptionDisabled(evt) {
        var sels = xGetElementsByTagName('select');
        for(var i=0; i < sels.length; i++){
            var disabled_exists = false;
            for(var j=0; j < sels[i].options.length; j++) {
                if(sels[i].options[j].disabled) {
                    sels[i].options[j].style.color = '#CCCCCC';
                    disabled_exists = true;
                }
            }

            if(!disabled_exists) continue;
            
            sels[i].oldonchange = sels[i].onchange;
            sels[i].onchange = function() {  
                if(this.options[this.selectedIndex].disabled) {
                    if(this.options.length<=1) this.selectedIndex = -1;
                    else if(this.selectedIndex < this.options.length - 1) this.selectedIndex++;
                    else this.selectedIndex--;
                } else {
                    if(this.oldonchange) this.oldonchange();
                }
            }

            if(sels[i].selectedIndex >= 0 && sels[i].options[ sels[i].selectedIndex ].disabled) sels[i].onchange();

        }
    }
}


/* 보안 로그인 모드로 전환 */
function toggleSecuritySignIn() {
    var href = location.href;
    if(/https:\/\//i.test(href)) location.href = href.replace(/^https/i,'http');
    else location.href = href.replace(/^http/i,'https');
}   

/* 하위호환성 문제 */
if(typeof(resizeImageContents) == 'undefined')
{
    function resizeImageContents() {}
}

/**
 * @file   common/js/xml_handler.js
 * @author zero <info@hotit.co.jp>
 * @brief  zbxe내에서 ajax기능을 이용함에 있어 module, act를 잘 사용하기 위한 자바스크립트
 **/

// xml handler을 이용하는 user function
var show_waiting_message = true;
function exec_xml(module, act, params, callback_func, response_tags, callback_func_arg, fo_obj) {
    var oXml = new xml_handler();
    oXml.reset();
    for(var key in params) {
	if(!params.hasOwnProperty(key)) continue;
        var val = params[key];
        oXml.addParam(key, val);
    }
    oXml.addParam("module", module);
    oXml.addParam("act", act);

    if(typeof(response_tags)=="undefined" || response_tags.length<1) response_tags = new Array('error','message');

    oXml.request(xml_response_filter, oXml, callback_func, response_tags, callback_func_arg, fo_obj);
}

// 결과 처리 후 callback_func에 넘겨줌
function xml_response_filter(oXml, callback_func, response_tags, callback_func_arg, fo_obj) {
    var xmlDoc = oXml.getResponseXml();
    if(!xmlDoc) return null;

    var waiting_obj = xGetElementById("waitingforserverresponse");
    if(waiting_obj) waiting_obj.style.visibility = "hidden";

    var ret_obj = oXml.toZMsgObject(xmlDoc, response_tags);
    if(ret_obj["error"]!=0) {
        alert(ret_obj["message"]);
        return null;
    }

    if(ret_obj["redirect_url"]) {
        location.href=ret_obj["redirect_url"];
        return null;
    }

    if(!callback_func) return null;

    callback_func(ret_obj, response_tags, callback_func_arg, fo_obj);

    return null;
}

// xml handler
function xml_handler() {
    this.obj_xmlHttp = null;
    this.method_name = null;
    this.xml_path = request_uri+"index.php";

    this.params = new Array();

    this.reset = xml_handlerReset;
    this.getXmlHttp = zGetXmlHttp;
    this.request = xml_handlerRequest;
    this.setPath = xml_handlerSetPath;
    this.addParam = xml_handlerAddParam;
    this.getResponseXml = xml_handlerGetResponseXML;
    this.toZMsgObject = xml_handlerToZMsgObject;
    this.parseXMLDoc = xml_parseXmlDoc;

    this.obj_xmlHttp = this.getXmlHttp();
}

function zGetXmlHttp() {
    if (window.XMLHttpRequest) return new XMLHttpRequest();
    else if (window.ActiveXObject) {
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }       
    return null;
}

function xml_handlerRequest(callBackFunc, xmlObj, callBackFunc2, response_tags, callback_func_arg, fo_obj) {
    var rd = "";
    rd += "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
    +  "<methodCall>\n"
    +  "<params>\n"

    for (var key in this.params) {
        if(!this.params.hasOwnProperty(key)) continue;
        var val = this.params[key];
        rd += "<"+key+"><![CDATA["+val+"]]></"+key+">\n";
    }

    rd += "</params>\n"
    +  "</methodCall>\n";

    // ssl action
    if(typeof(ssl_actions)!='undefined' && typeof(ssl_actions.length)!='undefined' && typeof(this.params['act'])!='undefined' && /^https:\/\//i.test(location.href) ) {
        var action = this.params['act'];
        for(i=0;i<ssl_actions.length;i++) {
            if(ssl_actions[i]==action) {
                this.xml_path = this.xml_path.replace(/^http:\/\//i,'https://');
                break;
            }
        }
    }

    if(this.obj_xmlHttp.readyState!=0) {
        this.obj_xmlHttp.abort();
        this.obj_xmlHttp = this.getXmlHttp();
    }
    this.obj_xmlHttp.onreadystatechange = function () {callBackFunc(xmlObj, callBackFunc2, response_tags, callback_func_arg, fo_obj)};

    // 모든 xml데이터는 POST방식으로 전송. try-cacht문으로 오류 발생시 대처
    try {

        this.obj_xmlHttp.open("POST", this.xml_path, true);

    } catch(e) {
        alert(e);
        return;
    }

    // ajax 통신중 대기 메세지 출력 (show_waiting_message값을 false로 세팅시 보이지 않음)
    var waiting_obj = xGetElementById("waitingforserverresponse");
    if(show_waiting_message && waiting_obj) {
        xInnerHtml(waiting_obj, waiting_message);

        xTop(waiting_obj, xScrollTop()+20);
        xLeft(waiting_obj, xScrollLeft()+20);
        waiting_obj.style.visibility = "visible";
    }

    this.obj_xmlHttp.send(rd);
}

function xml_handlerSetPath(path) {
    this.xml_path = "./"+path;
}


function xml_handlerReset() {
    this.obj_xmlHttp = this.getXmlHttp();
    this.params = new Array();
}

function xml_handlerAddParam(key, val) {
    this.params[key] = val;
}

function xml_handlerGetResponseXML() {
    if(this.obj_xmlHttp && this.obj_xmlHttp.readyState == 4 && isDef(this.obj_xmlHttp.responseXML)) {
        var xmlDoc = this.obj_xmlHttp.responseXML;
        this.reset();
        return xmlDoc;
    }
    return null;
}

function xml_parseXmlDoc(dom) {
    if(!dom) return;

    var ret_obj = new Array();

    var obj = dom.firstChild;
    if(!obj) return;

    while(obj) {
        if(obj.nodeType == 1) {

            var name = obj.nodeName;
            var value = null;

            if(obj.childNodes.length==1 && obj.firstChild.nodeType != 1) {
                value = obj.firstChild.nodeValue;
            } else {
                value = this.parseXMLDoc(obj);
            }

            if(typeof(ret_obj[name])=='undefined') {
                ret_obj[name] = value;
            } else {
                if(ret_obj[name].length>0) {
                    ret_obj[name][ret_obj[name].length] = value;
                } else {
                    var tmp_value = ret_obj[name];
                    ret_obj[name] = new Array();
                    ret_obj[name][ret_obj[name].length] = tmp_value;
                    ret_obj[name][ret_obj[name].length] = value;
                }
            }

        }
        obj = obj.nextSibling;
    }
    return ret_obj;
}

function xml_handlerToZMsgObject(xmlDoc, tags) {
    if(!xmlDoc) return null;
    if(!tags) tags = new Array("error","message");
    tags[tags.length] = "redirect_url";
    tags[tags.length] = "act";

    var parsed_array = this.parseXMLDoc(xmlDoc.getElementsByTagName('response')[0]);

    var obj_ret = new Array();
    for(var i=0; i<tags.length; i++) {
        var key = tags[i];
        if(parsed_array[key]) obj_ret[key] = parsed_array[key];
        else obj_ret[key] = null;
    }
    return obj_ret;
}

/**
 * @file   common/js/xml_js_filter.js
 * @author zero (zero@nzeo.com)
 * @brief  xml filter에서 사용될 js
 *
 * zbxe 에서 form의 동작시 필수입력 여부등을 선처리하고 xml_handler.js의 exec_xml()을 통해서
 * 특정 모듈과의 ajax 통신을 통해 process를 진행시킴
 **/

var alertMsg = new Array();
var target_type_list = new Array();
var notnull_list = new Array();
var extra_vars = new Array();

/**
 * @function filterAlertMessage
 * @brief ajax로 서버에 요청후 결과를 처리할 callback_function을 지정하지 않았을 시 호출되는 기본 함수
 **/
function filterAlertMessage(ret_obj) {
    var error = ret_obj["error"];
    var message = ret_obj["message"];
    var act = ret_obj["act"];
    var redirect_url = ret_obj["redirect_url"];
    var url = location.href;

    if(typeof(message)!="undefined"&&message&&message!="success") alert(message);

    if(typeof(act)!="undefined" && act) url = current_url.setQuery("act", act);
    else if(typeof(redirect_url)!="undefined" && redirect_url) url = redirect_url;

    if(url == location.href) url = url.replace(/#(.+)$/,'');

    location.href = url;
}

/**
 * @class XmlJsFilter
 * @authro zero (zero@nzeo.com)
 * @brief form elements, module/act, callback_user_func을 이용하여 서버에 ajax로 form 데이터를 넘기고 결과를 받아오는 js class
 **/
function XmlJsFilter(form_object, module, act, callback_user_func) {
    this.field = new Array();
    this.parameter = new Array();
    this.response = new Array();

    this.fo_obj = form_object;
    this.module = module;
    this.act = act;
    this.user_func = callback_user_func;
    this.setFocus = XmlJsFilterSetFocus;
    this.addFieldItem = XmlJsFilterAddFieldItem;
    this.addParameterItem = XmlJsFilterAddParameterItem;
    this.addResponseItem = XmlJsFilterAddResponseItem;
    this.getValue = XmlJsFilterGetValue;
    this.executeFilter = XmlJsFilterExecuteFilter;
    this.checkFieldItem = XmlJsFilterCheckFieldItem;
    this.getParameterParam = XmlJsFilterGetParameterParam;
    this.alertMsg = XmlJsFilterAlertMsg;
    this.proc = XmlJsFilterProc;
}

function XmlJsFilterSetFocus(target_name) {
    var obj = this.fo_obj[target_name];
    if(typeof(obj)=='undefined' || !obj) return;

    var length = obj.length;
    try {
        if(typeof(length)!='undefined') {
            obj[0].focus();
        } else {
            obj.focus();
        }
    } catch(e) {
    }
}

function XmlJsFilterAddFieldItem(target, required, minlength, maxlength, equalto, filter) {
    var obj = new Array(target, required, minlength, maxlength, equalto, filter);
    this.field[this.field.length] = obj;
}

function XmlJsFilterAddParameterItem(param, target) {
    var obj = new Array(param, target);
    this.parameter[this.parameter.length] = obj;
}

function XmlJsFilterAddResponseItem(name) {
    this.response[this.response.length] = name;
}

function XmlJsFilterGetValue(target_name) {
    var obj = this.fo_obj[target_name];
    if(typeof(obj)=='undefined' || !obj) return '';
    var value = '';
    var length = obj.length;
    var type = obj.type;
    if((typeof(type)=='undefined'||!type) && typeof(length)!='undefined' && typeof(obj[0])!='undefined' && length>0) type = obj[0].type;
    else length = 0;

    switch(type) {
        case 'checkbox' :
                if(length>0) {
                    var value_list = new Array();
                    for(var i=0;i<length;i++) {
                        if(obj[i].checked) value_list[value_list.length] = obj[i].value;
                    }
                    value = value_list.join('|@|');
                } else {
                    if(obj.checked) value = obj.value;
                    else value = '';
                }
            break;
        case 'radio' :
                if(length>0) {
                    for(var i=0;i<length;i++) {
                        if(obj[i].checked) value = obj[i].value;
                    }
                } else {
                    if(obj.checked) value = obj.value;
                    else value = '';
                }
            break;
        case 'select' :
        case 'select-one' :
                if(obj.selectedIndex>=0) value = obj.options[obj.selectedIndex].value;
            break;
        default :
                if(length>0 && target_type_list[target_name]) {
                    switch(target_type_list[target_name]) {
                        case 'kr_zip' :
                                var val1 = obj[0].value;
                                var val2 = obj[1].value;
                                if(val1&&val2) {
                                    value = val1+'|@|'+val2;
                                }
                            break;
                        case 'tel' :
                                var val1 = obj[0].value;
                                var val2 = obj[1].value;
                                var val3 = obj[2].value;
                                if(val1&&val2&&val3) {
                                    value = val1+'|@|'+val2+'|@|'+val3;
                                }
                            break;
                    }

                } else {
                    value = obj.value;
                }
            break;
    }

    if(typeof(value)=='undefined'||!value) return '';
    return value.trim();
}

function XmlJsFilterExecuteFilter(filter, value) {
    switch(filter) {
        case "email" :
        case "email_address" :
                var regx = /^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$/;
                return regx.test(value);
            break;
        case "userid" :
        case "user_id" :
                var regx = /^[a-zA-Z]+([_0-9a-zA-Z]+)*$/;
                return value;
            break;
        case "homepage" :
                var regx = /^(http|https|ftp|mms):\/\/[0-9a-z-]+(\.[_0-9a-z-\/\~]+)+(:[0-9]{2,4})*$/;
                return regx.test(value);
            break;
        case "korean" :
                var regx = /^[가-힣]*$/;
                return regx.test(value);
            break;
        case "korean_number" :
                var regx = /^[가-힣0-9]*$/;
                return regx.test(value);
            break;
        case "alpha" :
                var regx = /^[a-zA-Z]*$/;
                return regx.test(value);
            break;
        case "alpha_number" :
                var regx = /^[a-zA-Z][a-zA-Z0-9\_]*$/;
                return regx.test(value);
            break;
        case "number" :
            return !isNaN(value);
        break;
    }

    return null;
}

function XmlJsFilterAlertMsg(target, msg_code, minlength, maxlength) {
    var target_msg = "";

    if(alertMsg[target]!='undefined') target_msg = alertMsg[target];
    else target_msg = target;

    var msg = "";
    if(typeof(alertMsg[msg_code])!='undefined') {
        if(alertMsg[msg_code].indexOf('%s')>=0) msg = alertMsg[msg_code].replace('%s',target_msg);
        else msg = target_msg+alertMsg[msg_code];
    } else {
        msg = msg_code;
    }

    if(typeof(minlength)!='undefined' && typeof(maxlength)!='undefined') msg += "("+minlength+"~"+maxlength+")";

    alert(msg);
    this.setFocus(target);

    return false;
}

function XmlJsFilterCheckFieldItem() {
    for(var i=0; i<extra_vars.length;i++) {
        var name = extra_vars[i];
        this.addFieldItem(name, false, 0, 0, "", "");
    }

    for(var i=0; i<this.field.length;i++) {
        var item = this.field[i];
        var target = item[0];
        var required = item[1];
        var minlength = item[2];
        var maxlength = item[3];
        var equalto = item[4];
        var filter = item[5].split(",");

        if(typeof(this.fo_obj[target])=='undefined') continue;

        for(var j=0; j<notnull_list.length; j++) {
            if(notnull_list[j]==target) required = true;
        }

        var value = this.getValue(target);
        if(!required && !value) continue;
        if(required && !value && this.fo_obj[target]) return this.alertMsg(target,'isnull');

        if(minlength>0 && maxlength>0 && (value.length < minlength || value.length > maxlength)) return this.alertMsg(target, 'outofrange', minlength, maxlength);

        if(equalto) {
            var equalto_value = this.getValue(equalto);
            if(equalto_value != value) return this.alertMsg(target, 'equalto');
        }

        if(filter.length && filter[0]) {
            for(var j=0;j<filter.length;j++) {
                var filter_item = filter[j];
                if(!this.executeFilter(filter_item, value)) return this.alertMsg(target, "invalid_"+filter_item);
            }
        }
    }
    return true;
}

function XmlJsFilterGetParameterParam() {
    if(!this.fo_obj) return new Array();

    var prev_name = '';
    if(this.parameter.length<1) {
        for(var i=0;i<this.fo_obj.length;i++) {
            var name = this.fo_obj[i].name;
            if(typeof(name)=='undefined'||!name||name==prev_name) continue;
            this.addParameterItem(name, name);
            prev_name = name;
        }
    }

    var params = new Array();
    for(var i=0; i<this.parameter.length;i++) {
        var item = this.parameter[i];
        var param = item[0];
        var target = item[1];
        var value = this.getValue(target);
        params[param] = value;
    }
    return params;
}

function XmlJsFilterProc(confirm_msg) {
    var result = this.checkFieldItem();
    if(!result) return false;

    if(typeof(confirm_msg)=='undefined') confirm_msg = '';

    var params = this.getParameterParam();
    var response = this.response;
    if(confirm_msg && !confirm(confirm_msg)) return false;
    if(!this.act) {
        this.user_func(this.fo_obj, params);
        return true;
    }
    exec_xml(this.module, this.act, params, this.user_func, response, params, this.fo_obj);

    return null;
}

// form proc
function procFilter(fo_obj, filter_func) {
    // form문 안에 위지윅 에디터가 세팅되어 있을 경우 에디터의 값과 지정된 content field를 sync
    var editor_sequence = fo_obj.getAttribute('editor_sequence');
    if(typeof(editor_sequence)!='undefined' && editor_sequence && typeof(editorRelKeys)!='undefined') {
        editorRelKeys[editor_sequence]['content'].value = editorGetContent(editor_sequence);
    }

    filter_func(fo_obj);
    return false;
}

/**
 * @brief 카운터 정보 수집 javascript
 * window.onload 이벤트 후에 counter 모듈을 호출한다.
 **/

// 이벤트 등록
xAddEventListener(window,'load',doCallCounter);

// counter 모듈을 호출하는 함수
function doCallCounter() {
    show_waiting_message = false;
    exec_xml('counter','procCounterExecute');
    show_waiting_message = true;
}

	toggle=0;  document.ondblclick = function(event) {	if(window.event) EventStatus = window.event.srcElement.tagName;else EventStatus = event.target.tagName;   if(EventStatus!='INPUT'&&EventStatus!='TEXTAREA'){ if(toggle==0) { var sc=99999; toggle=1; }else{ var sc=0; toggle=0;} window.scrollTo(0,sc)}}

/**
 * @brief 화면내에서 상위 영역보다 이미지가 크면 리사이즈를 하고 클릭시 원본을 보여줄수 있도록 변경
 **/
var imageGalleryIndex = new Array();
function resizeImageContents() {
    // 이미지 태그 정규 표현식
    var img_regx = new RegExp("<img","im");
    var site_regx = new RegExp("^"+request_uri,"im");
    
    // xe_content 내의 이미지 요소들에 대한 체크
    var xe_objs = xGetElementsByClassName("xe_content");
    for(var j=0;j<xe_objs.length;j++) {

        imageGalleryIndex[j] = new Array();

        var html = xInnerHtml(xe_objs[j]);
        if(!img_regx.test(html)) continue;

        // 모든 이미지에 대한 체크를 시작
        var objs = xGetElementsByTagName("IMG", xe_objs[j]);

        for(var i=0;i<objs.length;i++) {
            var obj = objs[i];

            // zbXE내부 프로그램 또는 스킨의 이미지라면 이미지 리사이즈를 하지 않음
            if(!/\/(modules|addons|classes|common|layouts|libs|widgets)\//i.test(obj.src)) {
                var parent = obj.parentNode;
                while(parent) {
                    if(/(document|comment)_([0-9]*)_([0-9]*)/i.test(parent.className) ) break;
                    parent = parent.parentNode;
                }
                if(!parent) continue;

                var dummy = xCreateElement("div");
                dummy.style.visibility = "hidden";
                dummy.style.border = "1px solid red";
                parent.parentNode.insertBefore(dummy, parent);

                var parent_width = xWidth(dummy);
                parent.parentNode.removeChild(dummy);
                dummy = null;

                var obj_width = xWidth(obj);
                var obj_height = xHeight(obj);

                // 만약 선택된 이미지의 가로 크기가 부모의 가로크기보다 크면 리사이즈 (이때 부모의 가로크기 - 2 정도로 지정해줌)
                if(obj_width > parent_width - 2) {
                    obj.style.cursor = "pointer";
                    var new_w = parent_width - 2;
                    var new_h = Math.round(obj_height * new_w/obj_width);
                    xWidth(obj, new_w);
                    xHeight(obj, new_h);
                } 

                obj.style.cursor = "pointer";

                // 만약 대상 이미지에 링크가 설정되어 있거나 onclick 이벤트가 부여되어 있으면 원본 보기를 하지 않음
                if(obj.parentNode.nodeName.toLowerCase()!='a' && !obj.getAttribute('onclick')) xAddEventListener(obj,"click", showOriginalImage);

                imageGalleryIndex[j][i] = obj.src;
                obj.setAttribute("rel", j+','+i);
            }
        }
    }
}
xAddEventListener(window, "load", resizeImageContents);

/**
 * @brief 본문내에서 컨텐츠 영역보다 큰 이미지의 경우 원본 크기를 보여줌
 **/
function showOriginalImage(evt) {
    var e = new xEvent(evt);
    var obj = e.target;
    var src = obj.src;
    var rel = obj.getAttribute('rel');
    displayOriginalImage(src, rel);
}

function displayOriginalImage(src, rel) {
    // 투명 배경을 지정
    var bgObj = xGetElementById("forOriginalImageBGArea");
    if(!bgObj) {
        bgObj = xCreateElement("div");
        bgObj.id = "forOriginalImageBGArea";
        bgObj.style.visibility = "hidden";
        bgObj.style.backgroundColor = "#000000";
        bgObj.style.zIndex = 500;
        bgObj.style.position = "absolute";
        document.body.appendChild(bgObj);
    }
    xWidth(bgObj, xClientWidth());
    xHeight(bgObj, xClientHeight());
    xLeft(bgObj, xScrollLeft());
    xTop(bgObj, xScrollTop());
    bgObj.style.opacity = .5;
    bgObj.style.filter = "alpha(opacity=50);";
    bgObj.style.visibility = "visible";

    // 원본 이미지 노출을 위한 준비
    var foreObj = xGetElementById("forOriginalImageArea");
    if(!foreObj) {
        foreObj = xCreateElement("div");
        foreObj.id = "forOriginalImageArea";
        foreObj.style.visibility = "hidden";
        foreObj.style.overflow = "hidden";
        foreObj.style.position = "absolute";
        foreObj.style.zIndex = 510;
        document.body.appendChild(foreObj);
    }
    xWidth(foreObj, xClientWidth());
    xHeight(foreObj, xClientHeight());
    xLeft(foreObj, xScrollLeft());
    xTop(foreObj, xScrollTop());
    foreObj.style.visibility = "visible";

    var foreWidth = xWidth(foreObj);
    var foreHeight = xHeight(foreObj);

    // 버튼
    var iconClose = xGetElementById("forOriginalImageIconClose");
    if(!iconClose) {
        iconClose = xCreateElement("img");
        iconClose.id = "forOriginalImageIconClose";
        iconClose.style.position = "absolute";
        iconClose.src = request_uri+"addons/resize_image/iconClose.png";
        iconClose.style.width = iconClose.style.height = "60px";
        iconClose.className = 'iePngFix';
        iconClose.style.zIndex = 530;
        iconClose.style.cursor = "pointer";
        foreObj.appendChild(iconClose);
    }
    iconClose.style.visibility = 'visible';
    xLeft(iconClose, (foreWidth-60)/2);
    xTop(iconClose, 10);

    var iconLeft = xGetElementById("forOriginalImageIconLeft");
    if(!iconLeft) {
        iconLeft = xCreateElement("img");
        iconLeft.id = "forOriginalImageIconLeft";
        iconLeft.style.position = "absolute";
        iconLeft.src = request_uri+"addons/resize_image/iconLeft.png";
        iconLeft.style.width = iconLeft.style.height = "60px";
        iconLeft.style.zIndex = 530;
        iconLeft.className = 'iePngFix';
        iconLeft.style.cursor = "pointer";
        foreObj.appendChild(iconLeft);
    }
    iconLeft.onclick = null;
    xLeft(iconLeft, 10);
    xTop(iconLeft, (foreHeight-60)/2);
    iconLeft.style.visibility = 'hidden';

    var iconRight = xGetElementById("forOriginalImageIconRight");
    if(!iconRight) {
        iconRight = xCreateElement("img");
        iconRight.id = "forOriginalImageIconRight";
        iconRight.style.position = "absolute";
        iconRight.src = request_uri+"addons/resize_image/iconRight.png";
        iconRight.style.width = iconRight.style.height = "60px";
        iconRight.className = 'iePngFix';
        iconRight.style.zIndex = 530;
        iconRight.style.cursor = "pointer";
        foreObj.appendChild(iconRight);
    }
    iconRight.onclick = null;
    xLeft(iconRight, foreWidth - 10 - 60);
    xTop(iconRight, (foreHeight-60)/2);
    iconRight.style.visibility = 'hidden';


    if(rel) {
        var tmp = rel.split(',');
        var j = parseInt(tmp[0],10);
        var i = parseInt(tmp[1],10);
        var length = imageGalleryIndex[j].length;

        if(length>1) {

            var prev = i-1;
            var next = i+1;
            if(prev>=0) {
                iconLeft.style.visibility = 'visible';
                iconLeft.onclick = function() { displayOriginalImage(imageGalleryIndex[j][prev], j+','+prev); }
            } else {
                iconLeft.style.visibility = 'hidden';
            }

            if(next<length) {
                iconRight.style.visibility = 'visible';
                iconRight.onclick = function() { displayOriginalImage(imageGalleryIndex[j][next], j+','+next); }
            } else {
                iconRight.style.visibility = 'hidden';
            }

        }

    }

    // 원본 이미지를 추가
    var origObj = xGetElementById("forOriginalImage");
    if(origObj) foreObj.removeChild(origObj);

    origObj = null;
    origObj = xCreateElement("img");
    origObj.id = "forOriginalImage";
    origObj.style.border = "7px solid #ffffff";
    origObj.style.visibility = "hidden";
    origObj.style.cursor = "move";
    origObj.style.zIndex = 520;
    foreObj.appendChild(origObj);

    origObj.style.position = "relative";
    origObj.src = src;

    var objWidth = xWidth(origObj);
    var objHeight = xHeight(origObj);

    var posX = 0;
    var posY = 0;

    if(objWidth < foreWidth) posX = parseInt( (foreWidth - objWidth) / 2, 10);
    if(objHeight < foreHeight) posY = parseInt( (foreHeight - objHeight) / 2, 10);

    xLeft(origObj, posX);
    xTop(origObj, posY);

    origObj.style.visibility = "visible";

    var sel_list = xGetElementsByTagName("select");
    for (var i = 0; i < sel_list.length; ++i) sel_list[i].style.visibility = "hidden";

    xAddEventListener(origObj, "mousedown", origImageDragEnable);
    xAddEventListener(origObj, "dblclick", closeOriginalImage);
    xAddEventListener(iconClose, "mousedown", closeOriginalImage);
    xAddEventListener(window, "scroll", closeOriginalImage);
    xAddEventListener(window, "resize", closeOriginalImage);
    xAddEventListener(document, 'keydown',closeOriginalImage);
}

/**
 * @brief 원본 이미지 보여준 후 닫는 함수
 **/
function closeOriginalImage(evt) {
    var bgObj = xGetElementById("forOriginalImageBGArea");
    var foreObj = xGetElementById("forOriginalImageArea");
    var origObj = xGetElementById("forOriginalImage");
    var iconClose = xGetElementById("forOriginalImageIconClose");
    var iconLeft = xGetElementById("forOriginalImageIconLeft");
    var iconRight = xGetElementById("forOriginalImageIconRight");

    var sel_list = xGetElementsByTagName("select");
    for (var i = 0; i < sel_list.length; ++i) sel_list[i].style.visibility = "visible";

    xRemoveEventListener(origObj, "mousedown", origImageDragEnable);
    xRemoveEventListener(origObj, "dblclick", closeOriginalImage);
    xRemoveEventListener(iconClose, "mousedown", closeOriginalImage);
    xRemoveEventListener(window, "scroll", closeOriginalImage);
    xRemoveEventListener(window, "resize", closeOriginalImage);
    xRemoveEventListener(document, 'keydown',closeOriginalImage);

    bgObj.style.visibility = "hidden";
    foreObj.style.visibility = "hidden";
    origObj.style.visibility = "hidden";
    iconClose.style.visibility = 'hidden';
    iconLeft.style.visibility = 'hidden';
    iconRight.style.visibility = 'hidden';
}

/**
 * @brief 원본 이미지 드래그
 **/
var origDragManager = {obj:null, isDrag:false}
function origImageDragEnable(evt) {
    var e = new xEvent(evt);
    var obj = e.target;
    if(obj.id != "forOriginalImage") return;

    obj.draggable = true;
    obj.startX = e.pageX;
    obj.startY = e.pageY;

    if(!origDragManager.isDrag) {
        origDragManager.isDrag = true;
        xAddEventListener(document, "mousemove", origImageDragMouseMove, false);
    }

    xAddEventListener(document, "mousedown", origImageDragMouseDown, false);
}

function origImageDrag(obj, px, py) {
    var x = px - obj.startX;
    var y = py - obj.startY;

    var origObj = xGetElementById("forOriginalImage");
    xLeft(origObj, xLeft(origObj)+x);
    xTop(origObj, xTop(origObj)+y);

    obj.startX = px;
    obj.startY = py;
}

function origImageDragMouseDown(evt) {
    var e = new xEvent(evt);
    var obj = e.target;
    if(obj.id != "forOriginalImage" || !obj.draggable) return;

    if(obj) {
        xPreventDefault(evt);
        obj.startX = e.pageX;
        obj.startY = e.pageY;
        origDragManager.obj = obj;
        xAddEventListener(document, 'mouseup', origImageDragMouseUp, false);
        origImageDrag(obj, e.pageX, e.pageY);
    }
}

function origImageDragMouseUp(evt) {
    if(origDragManager.obj) {
        xPreventDefault(evt);
        xRemoveEventListener(document, 'mouseup', origImageDragMouseUp, false);
        xRemoveEventListener(document, 'mousemove', origImageDragMouseMove, false);
        xRemoveEventListener(document, 'mousemdown', origImageDragMouseDown, false);
        origDragManager.obj.draggable  = false;
        origDragManager.obj = null;
        origDragManager.isDrag = false;
    }
}

function origImageDragMouseMove(evt) {
    var e = new xEvent(evt);
    var obj = e.target;
    if(!obj) return;
    if(obj.id != "forOriginalImage") {
        xPreventDefault(evt);
        xRemoveEventListener(document, 'mouseup', origImageDragMouseUp, false);
        xRemoveEventListener(document, 'mousemove', origImageDragMouseMove, false);
        xRemoveEventListener(document, 'mousemdown', origImageDragMouseDown, false);
        origDragManager.obj.draggable  = false;
        origDragManager.obj = null;
        origDragManager.isDrag = false;
        return;
    }

    xPreventDefault(evt);
    origDragManager.obj = obj;
    xAddEventListener(document, 'mouseup', origImageDragMouseUp, false);
    origImageDrag(obj, e.pageX, e.pageY);
}


/**
 * @file   modules/board/js/board.js
 * @author zero (zero@nzeo.com)
 * @brief  board 모듈의 javascript
 **/

/* 글쓰기 작성후 */
function completeDocumentInserted(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var mid = ret_obj['mid'];
    var document_srl = ret_obj['document_srl'];
    var category_srl = ret_obj['category_srl'];

    //alert(message);

    var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act','');
    if(category_srl) url = url.setQuery('category',category_srl);
    location.href = url;
}

/* 글 삭제 */
function completeDeleteDocument(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var mid = ret_obj['mid'];
    var page = ret_obj['page'];

    var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl','');
    if(page) url = url.setQuery('page',page);

    //alert(message);

    location.href = url;
}

/* 검색 실행 */
function completeSearch(fo_obj, params) {
    fo_obj.submit();
}

function completeVote(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    alert(message);
    location.href = location.href;
}

// 현재 페이지 reload
function completeReload(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];

    location.href = location.href;
}

/* 댓글 글쓰기 작성후 */
function completeInsertComment(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var mid = ret_obj['mid'];
    var document_srl = ret_obj['document_srl'];
    var comment_srl = ret_obj['comment_srl'];

    var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act','');
    if(comment_srl) url = url.setQuery('rnd',comment_srl)+"#comment_"+comment_srl;

    //alert(message);

    location.href = url;
}

/* 댓글 삭제 */
function completeDeleteComment(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var mid = ret_obj['mid'];
    var document_srl = ret_obj['document_srl'];
    var page = ret_obj['page'];

    var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act','');
    if(page) url = url.setQuery('page',page);

    //alert(message);

    location.href = url;
}

/* 트랙백 삭제 */
function completeDeleteTrackback(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var mid = ret_obj['mid'];
    var document_srl = ret_obj['document_srl'];
    var page = ret_obj['page'];

    var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act','');
    if(page) url = url.setQuery('page',page);

    //alert(message);

    location.href = url;
}

/* 카테고리 이동 */
function doChangeCategory() {
    var sel_obj = xGetElementById("board_category");
    var sel_idx = sel_obj.selectedIndex;
    var category_srl = sel_obj.options[sel_idx].value;
    location.href = current_url.setQuery('category',category_srl);
}

/* 스크랩 */
function doScrap(document_srl) {
    var params = new Array();
    params["document_srl"] = document_srl;
    exec_xml("member","procMemberScrapDocument", params, null);
}

function search(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "board", "", completeSearch);
	oFilter.addFieldItem("search_target",true,0,0,"","");
	oFilter.addFieldItem("search_keyword",true,0,40,"","");
	oFilter.addParameterItem("mid","mid");
	oFilter.addParameterItem("search_target","search_target");
	oFilter.addParameterItem("search_keyword","search_keyword");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	return oFilter.proc();
}
alertMsg["search_target"] = "検索対象";
alertMsg["search_keyword"] = "キーワード";
alertMsg["mid"] = "モジュール名";
target_type_list["search_target"] = "";
target_type_list["search_keyword"] = "";
alertMsg["isnull"] = "%sを入力してください";
alertMsg["outofrange"] = "%sの文字の長さを合わせてください";
alertMsg["equalto"] = "%sが正しくありません";
alertMsg["invalid_email"] = "%sのパターンが正しくありません (例: info@hotit.co.jp)";
alertMsg["invalid_homepage"] = "%sの形式が正しくありません (例: http://www.hotit.co.jp)";
alertMsg["invalid_korean"] = "%sの形式が正しくありません。ハングルのみ入力してください。";
alertMsg["invalid_korean_number"] = "%sの形式が正しくありません。ハングルと半角数字で入力してください。";
alertMsg["invalid_alpha"] = "%sの形式が正しくありません。半角英文字のみ入力してください。";
alertMsg["invalid_alpha_number"] = "%sの形式が正しくありません。半角英数で入力してください。";
alertMsg["invalid_number"] = "%sの形式が正しくありません。半角数字で入力してください。";

function insert_comment(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "board", "procBoardInsertComment", completeInsertComment);
	oFilter.addFieldItem("document_srl",true,0,0,"","");
	oFilter.addFieldItem("nick_name",true,0,0,"","");
	oFilter.addFieldItem("password",true,0,0,"","");
	oFilter.addFieldItem("email_address",false,0,250,"","");
	oFilter.addFieldItem("homepage",false,0,250,"","");
	oFilter.addFieldItem("content",true,1,0,"","");
	oFilter.addParameterItem("mid","mid");
	oFilter.addParameterItem("document_srl","document_srl");
	oFilter.addParameterItem("comment_srl","comment_srl");
	oFilter.addParameterItem("parent_srl","parent_srl");
	oFilter.addParameterItem("nick_name","nick_name");
	oFilter.addParameterItem("password","password");
	oFilter.addParameterItem("email_address","email_address");
	oFilter.addParameterItem("homepage","homepage");
	oFilter.addParameterItem("content","content");
	oFilter.addParameterItem("is_secret","is_secret");
	oFilter.addParameterItem("notify_message","notify_message");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	oFilter.addResponseItem("mid");
	oFilter.addResponseItem("document_srl");
	oFilter.addResponseItem("comment_srl");
	return oFilter.proc("登録しますか？");
}
alertMsg["document_srl"] = "書き込み番号";
alertMsg["nick_name"] = "ニックネーム";
alertMsg["password"] = "パスワード";
alertMsg["email_address"] = "メールアドレス";
alertMsg["homepage"] = "ホームページ";
alertMsg["content"] = "内容";
alertMsg["mid"] = "モジュール名";
alertMsg["comment_srl"] = "comment_srl";
alertMsg["parent_srl"] = "parent_srl";
alertMsg["is_secret"] = "is_secret";
alertMsg["notify_message"] = "notify_message";
target_type_list["document_srl"] = "";
target_type_list["nick_name"] = "";
target_type_list["password"] = "";
target_type_list["email_address"] = "";
target_type_list["homepage"] = "";
target_type_list["content"] = "";
alertMsg["isnull"] = "%sを入力してください";
alertMsg["outofrange"] = "%sの文字の長さを合わせてください";
alertMsg["equalto"] = "%sが正しくありません";
alertMsg["invalid_email"] = "%sのパターンが正しくありません (例: info@hotit.co.jp)";
alertMsg["invalid_homepage"] = "%sの形式が正しくありません (例: http://www.hotit.co.jp)";
alertMsg["invalid_korean"] = "%sの形式が正しくありません。ハングルのみ入力してください。";
alertMsg["invalid_korean_number"] = "%sの形式が正しくありません。ハングルと半角数字で入力してください。";
alertMsg["invalid_alpha"] = "%sの形式が正しくありません。半角英文字のみ入力してください。";
alertMsg["invalid_alpha_number"] = "%sの形式が正しくありません。半角英数で入力してください。";
alertMsg["invalid_number"] = "%sの形式が正しくありません。半角数字で入力してください。";

/**
 * 에디터에서 사용하기 위한 변수
 **/
var editorMode = new Array(); ///<< 에디터의 html편집 모드 flag 세팅 변수 (html or null)
var editorAutoSaveObj = {fo_obj:null, editor_sequence:0, title:'', content:'', locked:false} ///< 자동저장을 위한 정보를 가진 object
var editorRelKeys = new Array(); ///< 에디터와 각 모듈과의 연동을 위한 key 값을 보관하는 변수
var editorDragObj = {isDrag:false, y:0, obj:null, id:'', det:0, source_height:0}

/**
 * 에디터 사용시 사용되는 이벤트 연결 함수 호출
 **/
xAddEventListener(document, 'click', editorEventCheck);
xAddEventListener(document, 'mousedown', editorDragStart);
xAddEventListener(document, 'mouseup', editorDragStop);

function editorGetContent(editor_sequence) {
    // 입력된 내용을 받아옴
    var content = editorRelKeys[editor_sequence]["func"](editor_sequence);

    // 첨부파일 링크시 url을 변경
    var reg_pattern = new RegExp( request_uri.replace(/\//g,'\\/')+"(files|common|modules|layouts|widgets)", 'ig' );
    return content.replace(reg_pattern, "$1");
}

// 에디터에 포커스를 줌
function editorFocus(editor_sequence) {
    var iframe_obj = editorGetIFrame(editor_sequence);
    iframe_obj.contentWindow.focus();
}

/**
 * 자동 저장 기능
 **/
// 자동 저장 활성화 시키는 함수 (10초마다 자동저장)
function editorEnableAutoSave(fo_obj, editor_sequence) {
    var title = fo_obj.title.value;
    var content = editorRelKeys[editor_sequence]['content'].value;
    editorAutoSaveObj = {"fo_obj":fo_obj, "editor_sequence":editor_sequence, "title":title, "content":content, locked:false};
    setTimeout(_editorAutoSave, 10000);
}

// ajax를 이용하여 editor.procEditorSaveDoc 호출하여 자동 저장시킴
function _editorAutoSave() {
    var fo_obj = editorAutoSaveObj.fo_obj;
    var editor_sequence = editorAutoSaveObj.editor_sequence;

    // 현재 자동저장중이면 중지
    if(editorAutoSaveObj.locked == true) return;

    // 대상이 없으면 자동저장 시키는 기능 자체를 중지
    if(!fo_obj || typeof(fo_obj.title)=='undefined' || !editor_sequence) return;

    // 자동저장을 위한 준비
    var title = fo_obj.title.value;
    var content = editorGetContent(editor_sequence);

    // 내용이 이전에 저장하였던 것과 다르면 자동 저장을 함
    if(title != editorAutoSaveObj.title || content != editorAutoSaveObj.content ) {
        var params = new Array();

        params["title"] = title;
        params["content"] = content;
        params["document_srl"] = editorRelKeys[editor_sequence]['primary'].value;

        editorAutoSaveObj.title = title;
        editorAutoSaveObj.content = content;

        var obj = xGetElementById("editor_autosaved_message_"+editor_sequence);
        obj.style.display = 'block';
        var oDate = new Date();
        html = oDate.getHours()+':'+oDate.getMinutes()+' '+auto_saved_msg;
        xInnerHtml(obj, html);
        obj.style.display = "block";

        // 현재 자동저장중임을 설정
        editorAutoSaveObj.locked = true;

        // 서버 호출 (서버와 교신중이라는 메세지를 보이지 않도록 함)
        show_waiting_message = false;
        exec_xml("editor","procEditorSaveDoc", params, function() { editorAutoSaveObj.locked = false; } );
        show_waiting_message = true;
    }

    // 10초마다 동기화를 시킴
    setTimeout(_editorAutoSave, 10000);
}

// 자동저장된 모든 메세지를 삭제하는 루틴
function editorRemoveSavedDoc() {
    exec_xml("editor","procEditorRemoveSavedDoc");
}

/**
 * 에디터의 상태나 객체를 구하기 위한 함수
 **/

// editor_sequence값에 해당하는 iframe의 object를 return
function editorGetIFrame(editor_sequence) {
    if(editorRelKeys != undefined && editorRelKeys[editor_sequence] != undefined && editorRelKeys[editor_sequence]['editor'] != undefined)
    return editorRelKeys[editor_sequence]['editor'].getFrame();
    return xGetElementById( 'editor_iframe_'+ editor_sequence );
}
function editorGetTextarea(editor_sequence) {
    return xGetElementById( 'editor_textarea_'+ editor_sequence );
}
/**
 * iframe 세로 크기 조절 드래그 관련
 **/
function editorDragStart(evt) {
    var e = new xEvent(evt);
    var obj = e.target;
    if(typeof(obj.id)=='undefined'||!obj.id) return;

    var id = obj.id;
    if(id.indexOf('editor_drag_bar_')!=0) return;

    editorDragObj.isDrag = true;
    editorDragObj.y = e.pageY;
    editorDragObj.obj = e.target;
    editorDragObj.id = id.substr('editor_drag_bar_'.length);

    var iframe_obj = editorGetIFrame(editorDragObj.id);
    var textarea_obj = editorGetTextarea(editorDragObj.id);
    var preview_obj = xGetElementById('editor_preview_'+editorDragObj.id);
    editorDragObj.source_height = xHeight(iframe_obj) || xHeight(preview_obj);
    xGetElementById('xeEditorMask_' + editorDragObj.id).style.display='block';

    xAddEventListener(document, 'mousemove', editorDragMove, true);
//    xAddEventListener(editorDragObj.obj, 'mousemove', editorDragMove, false);
}

function editorDragMove(evt) {

    if(!editorDragObj.isDrag){
        if(editorDragObj.id) xGetElementById('xeEditorMask_' + editorDragObj.id).style.display='none';
        return;
    }

    var e = new xEvent(evt);
    var h = e.pageY - editorDragObj.y;

    editorDragObj.isDrag = true;
    editorDragObj.y = e.pageY;
    editorDragObj.obj = e.target;


    var iframe_obj = editorGetIFrame(editorDragObj.id);
    var textarea_obj = editorGetTextarea(editorDragObj.id);
    var preview_obj = xGetElementById('editor_preview_'+editorDragObj.id);
    var height = xHeight(iframe_obj) || xHeight(textarea_obj) || xHeight(preview_obj);
    height += h;
    xHeight(iframe_obj, height);
    xHeight(textarea_obj, height);
    xHeight(preview_obj, height);
//    xHeight(iframe_obj.parentNode, height+200);
}

function editorDragStop(evt) {
    if(editorDragObj.id) xGetElementById('xeEditorMask_'+editorDragObj.id).style.display='none';
    if(!editorDragObj.isDrag){
        return;
    }


    xRemoveEventListener(document, 'mousemove', editorDragMove, false);
//    xRemoveEventListener(editorDragObj.obj, 'mousemove', editorDragMove, false);

    var iframe_obj = editorGetIFrame(editorDragObj.id);
    var textarea_obj = editorGetTextarea(editorDragObj.id);
    if(typeof(fixAdminLayoutFooter)=='function') fixAdminLayoutFooter(xHeight(iframe_obj)-editorDragObj.source_height);


    editorDragObj.isDrag = false;
    editorDragObj.y = 0;
    editorDragObj.obj = null;
    editorDragObj.id = '';
}

// Editor Option Button
function eOptionOver(obj) {
    obj.style.marginTop='-21px';
    obj.style.zIndex='99';
}
function eOptionOut(obj) {
    obj.style.marginTop='0';
    obj.style.zIndex='1';
}
function eOptionClick(obj) {
    obj.style.marginTop='-42px';
    obj.style.zIndex='99';
}

/**
 * 에디터 컴포넌트 구현 부분
 **/

// 에디터 상단의 컴포넌트 버튼 클릭시 action 처리 (마우스다운 이벤트 발생시마다 요청이 됨)
var editorPrevSrl = null;
function editorEventCheck(evt) {
    editorPrevNode = null;

    // 이벤트가 발생한 object의 ID를 구함
    var e = new xEvent(evt);
    var target_id = e.target.id;
    if(!target_id) return;

    // editor_sequence와 component name을 구함 (id가 포맷과 다르면 return)
    var info = target_id.split('_');
    if(info[0]!="component") return;
    var editor_sequence = info[1];
    var component_name = target_id.replace(/^component_([0-9]+)_/,'');
    if(!editor_sequence || !component_name) return;

    if(editorMode[editor_sequence]=='html') return;

    switch(component_name) {

        // 기본 기능에 대한 동작 (바로 실행)
        case 'Bold' :
        case 'Italic' :
        case 'Underline' :
        case 'StrikeThrough' :
        case 'undo' :
        case 'redo' :
        case 'JustifyLeft' :
        case 'JustifyCenter' :
        case 'JustifyRight' :
        case 'JustifyFull' :
        case 'Indent' :
        case 'Outdent' :
        case 'InsertOrderedList' :
        case 'InsertUnorderedList' :
        case 'SaveAs' :
        case 'Print' :
        case 'Copy' :
        case 'Cut' :
        case 'Paste' :
        case 'RemoveFormat' :
        case 'Subscript' :
        case 'Superscript' :
                editorDo(component_name, '', editor_sequence);
            break;

        // 추가 컴포넌트의 경우 서버에 요청을 시도
        default :
                openComponent(component_name, editor_sequence);
            break;
    }

    return;
}

// 컴포넌트 팝업 열기
function openComponent(component_name, editor_sequence, manual_url) {
    editorPrevSrl = editor_sequence;
    if(editorMode[editor_sequence]=='html') return;

    var popup_url = request_uri+"?module=editor&act=dispEditorPopup&editor_sequence="+editor_sequence+"&component="+component_name;
    if(typeof(manual_url)!="undefined" && manual_url) popup_url += "&manual_url="+escape(manual_url);

    popopen(popup_url, 'editorComponent');
}

// 더블클릭 이벤트 발생시에 본문내에 포함된 컴포넌트를 찾는 함수
var editorPrevNode = null;
function editorSearchComponent(evt) {
    var e = new xEvent(evt);

    editorPrevNode = null;
    var obj = e.target;

    // 위젯인지 일단 체크
    if(obj.getAttribute("widget")) {
        // editor_sequence을 찾음
        var tobj = obj;
        while(tobj && tobj.nodeName != "BODY") {
            tobj = xParent(tobj);
        }
        if(!tobj || tobj.nodeName != "BODY" || !tobj.getAttribute("editor_sequence")) {
            editorPrevNode = null;
            return;
        }
        var editor_sequence = tobj.getAttribute("editor_sequence");
        var widget = obj.getAttribute("widget");
        editorPrevNode = obj;

        if(editorMode[editor_sequence]=='html') return;
        popopen(request_uri+"?module=widget&act=dispWidgetGenerateCodeInPage&selected_widget="+widget+"&module_srl="+editor_sequence,'GenerateCodeInPage');
        return;
    }

    // 선택되어진 object부터 상단으로 이동하면서 editor_component attribute가 있는지 검사
    if(!obj.getAttribute("editor_component")) {
        while(obj && !obj.getAttribute("editor_component")) {
            if(obj.parentElement) obj = obj.parentElement;
            else obj = xParent(obj);
        }
    }

    if(!obj) obj = e.target;

    var editor_component = obj.getAttribute("editor_component");

    // editor_component를 찾지 못했을 경우에 이미지/텍스트/링크의 경우 기본 컴포넌트와 연결
    if(!editor_component) {
        // 이미지일 경우
        if(obj.nodeName == "IMG") {
            editor_component = "image_link";
            editorPrevNode = obj;

        // 테이블의 td일 경우
        } else if(obj.nodeName == "TD") {
            editor_component = "table_maker";
            editorPrevNode = obj;

        // 링크거나 텍스트인 경우
        } else if(obj.nodeName == "A" || obj.nodeName == "BODY" || obj.nodeName.indexOf("H")==0 || obj.nodeName == "LI" || obj.nodeName == "P") {
            editor_component = "url_link";
            editorPrevNode = obj;
        }
    } else {
        editorPrevNode = obj;
    }

    // 아무런 editor_component가 없다면 return
    if(!editor_component) {
        editorPrevNode = null;
        return;
    }

    // editor_sequence을 찾음
    var tobj = obj;
    while(tobj && tobj.nodeName != "BODY") {
        tobj = xParent(tobj);
    }
    if(!tobj || tobj.nodeName != "BODY" || !tobj.getAttribute("editor_sequence")) {
        editorPrevNode = null;
        return;
    }
    var editor_sequence = tobj.getAttribute("editor_sequence");

    // 해당 컴포넌트를 찾아서 실행
    openComponent(editor_component, editor_sequence);
}

// 에디터 내의 선택된 부분의 html코드를 변경
function editorReplaceHTML(iframe_obj, html) {
    // 에디터가 활성화 되어 있는지 확인 후 비활성화시 활성화
    var editor_sequence = iframe_obj.contentWindow.document.body.getAttribute("editor_sequence");

    // iframe 에디터에 포커스를 둠
    iframe_obj.contentWindow.focus();

    if(xIE4Up) {
        var range = iframe_obj.contentWindow.document.selection.createRange();
        if(range.pasteHTML) {
            range.pasteHTML(html);
        } else if(editorPrevNode) {
            editorPrevNode.outerHTML = html;
        }

    } else {

        try {
            if(iframe_obj.contentWindow.getSelection().focusNode.tagName == "HTML") {
                var range = iframe_obj.contentDocument.createRange();
                range.setStart(iframe_obj.contentDocument.body,0);
                range.setEnd(iframe_obj.contentDocument.body,0);
                range.insertNode(range.createContextualFragment(html));
            } else {
                var range = iframe_obj.contentWindow.getSelection().getRangeAt(0);
                range.deleteContents();
                range.insertNode(range.createContextualFragment(html));
            }
        } catch(e) {
            xInnerHtml(iframe_obj.contentWindow.document.body, html+xInnerHtml(iframe_obj.contentWindow.document.body));
        }

    }
}

// 에디터 내의 선택된 부분의 html 코드를 return
function editorGetSelectedHtml(editor_sequence) {
    var iframe_obj = editorGetIFrame(editor_sequence);
    if(xIE4Up) {
        var range = iframe_obj.contentWindow.document.selection.createRange();
        var html = range.htmlText;
        return html;
    } else {
        var range = iframe_obj.contentWindow.getSelection().getRangeAt(0);
        var dummy = xCreateElement('div');
        dummy.appendChild(range.cloneContents());
        var html = xInnerHtml(dummy);
        return html;
    }
}

/**
 * @author zero (zero@nzeo.com)
 * @version 0.1
 * @brief 에디터 관련 스크립트
 */

/**
 * 에디터 사용시 사용되는 이벤트 연결 함수 호출
 **/

/**
 * 에디터의 상태나 객체를 구하기 위한 함수
 **/

// editor_sequence값에 해당하는 textarea object를 return
function editorGetTextArea(editor_sequence) {
    return xGetElementById( 'editor_textarea_' + editor_sequence );
}

function editorGetPreviewArea(editor_sequence) {
    return xGetElementById( 'editor_preview_' + editor_sequence );
}

// editor_sequence에 해당하는 form문 구함
function editorGetForm(editor_sequence) {
    var iframe_obj = editorGetIFrame(editor_sequence);
    if(!iframe_obj) return;

    var fo_obj = iframe_obj.parentNode;
    while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; }
    if(fo_obj.nodeName == 'FORM') return fo_obj;
    return;
}

// 에디터의 전체 내용 return
function editorGetContent_xe(editor_sequence) {
    var html = "";
    if(editorMode[editor_sequence]=='html') {
        var textarea_obj = editorGetTextArea(editor_sequence);
        if(!textarea_obj) return "";
        html = textarea_obj.value;
    } else {
        var iframe_obj = editorGetIFrame(editor_sequence);
        if(!iframe_obj) return "";
        html = xInnerHtml(iframe_obj.contentWindow.document.body).replace(/^<br([^>]*)>$/i,'');
    }
    return html;
}

// 에디터 내의 선택된 부분의 NODE를 return
function editorGetSelectedNode(editor_sequence) {
    var iframe_obj = editorGetIFrame(editor_sequence);
    if(xIE4Up) {
        var range = iframe_obj.contentWindow.document.selection.createRange();
        var div = xCreateElement('div');
        xInnerHtml(div, range.htmlText);
        var node = div.firstChild;
        return node;
    } else {
        var range = iframe_obj.contentWindow.getSelection().getRangeAt(0);
        var node = xCreateElement('div');
        node.appendChild(range.cloneContents());
        return node.firstChild;
    }
}

/**
 * editor 시작 (editor_sequence로 iframe객체를 얻어서 쓰기 모드로 전환)
 **/
var _editorFontColor = new Array();
function editorStart(editor_sequence, primary_key, content_key, editor_height, font_color) {

    if(typeof(font_color)=='undefined') font_color = '#000';
    _editorFontColor[editor_sequence] = font_color;

    // iframe obj를 찾음
    var iframe_obj = editorGetIFrame(editor_sequence);
    if(!iframe_obj) return;
    xWidth(iframe_obj.parentNode, '100%');
    iframe_obj.style.width = '100%';

    // 현 에디터를 감싸고 있는 form문을 찾음
    var fo_obj = editorGetForm(editor_sequence);
    if(!fo_obj) return;

    // fo_obj에 editor_sequence 값 지정
    fo_obj.setAttribute('editor_sequence', editor_sequence);

    // 모듈 연관 키 값을 세팅
    editorRelKeys[editor_sequence] = new Array();
    editorRelKeys[editor_sequence]["primary"] = fo_obj[primary_key];
    editorRelKeys[editor_sequence]["content"] = fo_obj[content_key];
    editorRelKeys[editor_sequence]["func"] = editorGetContent_xe;

    // saved document(자동저장 문서)에 대한 확인
    if(typeof(fo_obj._saved_doc_title)!="undefined" ) { ///<< _saved_doc_title field가 없으면 자동저장 하지 않음

        var saved_title = fo_obj._saved_doc_title.value;
        var saved_content = fo_obj._saved_doc_content.value;

        if(saved_title || saved_content) {
            // 자동저장된 문서 활용여부를 물은 후 사용하지 않는다면 자동저장된 문서 삭제
            if(confirm(fo_obj._saved_doc_message.value)) {
                if(typeof(fo_obj.title)!='undefined') fo_obj.title.value = saved_title;
                editorRelKeys[editor_sequence]['content'].value = saved_content;
            } else {
                editorRemoveSavedDoc();
            }
        }
    }

    // 대상 form의 content element에서 데이터를 구함
    var content = editorRelKeys[editor_sequence]['content'].value;

    // IE가 아니고 내용이 없으면 <br /> 추가 (FF등에서 iframe 선택시 focus를 주기 위한 꽁수)
    if(!content && !xIE4Up) content = "<br />";

    // IE일 경우 ctrl-Enter 안내 문구를 노출
    var ieHelpObj = xGetElementById("for_ie_help_"+editor_sequence);
    if(xIE4Up && ieHelpObj) {
        ieHelpObj.style.display = "block";
    }

    // content 생성
    editor_path = editor_path.replace(/^\.\//ig, '');
    var contentHtml = ''+
        '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'+
        '<html xmlns="http://www.w3.org/1999/xhtml><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/>'+
        '<style type="text/css">'+
        'body {font-size:.75em; line-height:1.6; font-family:Sans-serif; height:'+editor_height+'px; padding:0; margin:0; background-color:transparent; color:'+font_color+';}'+
        '</style>'+
        '</head><body editor_sequence="'+editor_sequence+'">'+
        content+
        '</body></html>'+
        '';
    iframe_obj.contentWindow.document.open("text/html","replace");
    iframe_obj.contentWindow.document.write(contentHtml);
    iframe_obj.contentWindow.document.close();

    // editorMode를 기본으로 설정
    editorMode[editor_sequence] = null;

    // 에디터를 시작 시킴
    try {
        iframe_obj.contentWindow.document.designMode = 'On';
    } catch(e) {
    }

    try {
        iframe_obj.contentWindow.document.execCommand("undo", false, null);
        iframe_obj.contentWindow.document.execCommand("useCSS", false, true);
    }  catch (e) {
    }

    /**
     * 더블클릭이나 키눌림등의 각종 이벤트에 대해 listener 추가
     * 작성시 필요한 이벤트 체크
     * 이 이벤트의 경우 윈도우 sp1 (NT or xp sp1) 에서 iframe_obj.contentWindow.document에 대한 권한이 없기에 try 문으로 감싸서
     * 에러를 무시하도록 해야 함.
     **/

    // 위젯 감시를 위한 더블클릭 이벤트 걸기
    try {
        xAddEventListener(iframe_obj.contentWindow.document,'dblclick',editorSearchComponent);
    } catch(e) {
    }

    // 에디터에서 키가 눌러질때마다 이벤트를 체크함 (enter키의 처리나 FF에서 alt-s등을 처리)
    try {
        if(xIE4Up) xAddEventListener(iframe_obj.contentWindow.document, 'keydown',editorKeyPress);
        else xAddEventListener(iframe_obj.contentWindow.document, 'keypress',editorKeyPress);
    } catch(e) {
    }

    // 자동저장 필드가 있다면 자동 저장 기능 활성화
    if(typeof(fo_obj._saved_doc_title)!="undefined" ) editorEnableAutoSave(fo_obj, editor_sequence);
}


/**
 * 에디터의 세부 설정과 데이터 핸들링을 정의한 함수들
 **/



/**
 * 키 또는 마우스 이벤트 핸들링 정의 함수
 **/

// 입력 키에 대한 이벤트 체크
function editorKeyPress(evt) {
    var e = new xEvent(evt);

    // 대상을 구함
    var obj = e.target;
    var body_obj = null;
    if(obj.nodeName == "BODY") body_obj = obj;
    else body_obj = obj.firstChild.nextSibling;
    if(!body_obj) return;

    // editor_sequence는 에디터의 body에 attribute로 정의되어 있음
    var editor_sequence = body_obj.getAttribute("editor_sequence");
    if(!editor_sequence) return;

    // IE에서 enter키를 눌렀을때 P 태그 대신 BR 태그 입력
    if (xIE4Up && !e.ctrlKey && !e.shiftKey && e.keyCode == 13 && !editorMode[editor_sequence]) {
        var iframe_obj = editorGetIFrame(editor_sequence);
        if(!iframe_obj) return;

        var contentDocument = iframe_obj.contentWindow.document;

        var obj = contentDocument.selection.createRange();

        var pTag = obj.parentElement().tagName.toLowerCase();

        switch(pTag) {
            case 'li' :
                    return;
                break;
            default :
                    obj.pasteHTML("<br />");
                break;
        }
        obj.select();
        evt.cancelBubble = true;
        evt.returnValue = false;
        return;
    }

    // ctrl-S, alt-S 클릭시 submit하기
    if( e.keyCode == 115 && (e.altKey || e.ctrlKey) ) {
        // iframe 에디터를 찾음
        var iframe_obj = editorGetIFrame(editor_sequence);
        if(!iframe_obj) return;

        // 대상 form을 찾음
        var fo_obj = editorGetForm(editor_sequence);
        if(!fo_obj) return;

        // 데이터 동기화
        editorRelKeys[editor_sequence]['content'].value = editorGetContent(editor_sequence);

        // form문 전송
        if(fo_obj.onsubmit) fo_obj.onsubmit();

        // 이벤트 중단
        evt.cancelBubble = true;
        evt.returnValue = false;
        xPreventDefault(evt);
        xStopPropagation(evt);
        return;
    }

    // ctrl-b, i, u, s 키에 대한 처리 (파이어폭스에서도 에디터 상태에서 단축키 쓰도록)
    if (e.ctrlKey) {
        // iframe 에디터를 찾음
        var iframe_obj = editorGetIFrame(editor_sequence);
        if(!iframe_obj) return;

        // html 에디터 모드일 경우 이벤트 취소 시킴
        if(editorMode[editor_sequence]) {
            evt.cancelBubble = true;
            evt.returnValue = false;
            xPreventDefault(evt);
            xStopPropagation(evt);
            return;
        }

        switch(e.keyCode) {
            // ctrl+1~6
            case 49 :
            case 50 :
            case 51 :
            case 52 :
            case 53 :
            case 54 :
                    editorDo('formatblock',"<H"+(e.keyCode-48)+">",e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;
            // ctrl+7
            case 55 :
                    editorDo('formatblock',"<P>",e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;
            // ie에서 ctrlKey + enter일 경우 P 태그 입력
            case 13 :
                    if(xIE4Up) {
                        if(e.target.parentElement.document.designMode!="On") return;
                        var obj = e.target.parentElement.document.selection.createRange();
                        obj.pasteHTML('<P>');
                        obj.select();
                        evt.cancelBubble = true;
                        evt.returnValue = false;
                        return;
                    }
            // bold
            case 98 :
                    editorDo('Bold',null,e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;
            // italic
            case 105 :
                    editorDo('Italic',null,e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;
            // underline
            case 117 :
                    editorDo('Underline',null,e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;
            //RemoveFormat
            case 100 :
                    editorDo('RemoveFormat',null,e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;


            // strike
            /*
            case 83 :
            case 115 :
                    editorDo('StrikeThrough',null,e.target);
                    xPreventDefault(evt);
                    xStopPropagation(evt);
                break;
            */
        }
    }
}

// 편집 기능 실행
function editorDo(command, value, target) {

    var doc = null;

    // target이 object인지 editor_sequence인지에 따라 document를 구함
    if(typeof(target)=="object") {
        if(xIE4Up) doc = target.parentElement.document;
        else doc = target.parentNode;
    } else {
        var iframe_obj = editorGetIFrame(target);
        doc = iframe_obj.contentWindow.document;
    }

    var editor_sequence = doc.body.getAttribute('editor_sequence');
    if(editorMode[editor_sequence]) return;

    // 포커스
    if(typeof(target)=="object") target.focus();
    else editorFocus(target);

    // 실행
    doc.execCommand(command, false, value);

    // 포커스
    if(typeof(target)=="object") target.focus();
    else editorFocus(target);
}

// 폰트를 변경
function editorChangeFontName(obj,srl) {
    var value = obj.options[obj.selectedIndex].value;
    if(!value) return;
    editorDo('FontName',value,srl);
    obj.selectedIndex = 0;
}

function editorChangeFontSize(obj,srl) {
    var value = obj.options[obj.selectedIndex].value;
    if(!value) return;
    editorDo('FontSize',value,srl);
    obj.selectedIndex = 0;
}

function editorUnDo(obj,srl) {
    editorDo('undo','',srl);
    obj.selectedIndex = 0;
}

function editorReDo(obj,srl) {
    editorDo('redo','',srl);
    obj.selectedIndex = 0;
}

function editorChangeHeader(obj,srl) {
    var value = obj.options[obj.selectedIndex].value;
    if(!value) return;
    value = "<"+value+">";
    editorDo('formatblock',value,srl);
    obj.selectedIndex = 0;
}

/**
 * HTML 편집 기능 활성/비활성
 **/

function editorChangeMode(mode, editor_sequence) {
    var iframe_obj = editorGetIFrame(editor_sequence);
    if(!iframe_obj) return;

    var textarea_obj = editorGetTextArea(editor_sequence);
    var preview_obj = editorGetPreviewArea(editor_sequence);
    var contentDocument = iframe_obj.contentWindow.document;

    var html = null;
    if(editorMode[editor_sequence]=='html') {
        html = textarea_obj.value;
        contentDocument.body.innerHTML = textarea_obj.value;
    } else if (editorMode[editor_sequence]=='preview') {
//        html = xInnerHtml(preview_obj);
        html = textarea_obj.value;
        preview_obj.contentWindow.document.body.innerHTML = '';
//        xAddEventListener(xGetElementById('editor_preview_'+editor_sequence), 'load', function(){setPreviewHeight(editor_sequence)});
    } else {
        html = contentDocument.body.innerHTML;
        textarea_obj.value = html
        html = html.replace(/<br>/ig,"<br />\n");
        html = html.replace(/<br \/>\n\n/ig,"<br />\n");
    }

    // html 편집 사용시
    if(mode == 'html' && textarea_obj) {
        preview_obj.style.display='none';
        if(xGetElementById('fileUploader_'+editor_sequence)) xGetElementById('fileUploader_'+editor_sequence).style.display='block';
        textarea_obj.value = html;
        xWidth(textarea_obj, xWidth(iframe_obj.parentNode));
        xHeight(textarea_obj, xHeight(iframe_obj.parentNode));
        editorMode[editor_sequence] = 'html';

        if(xGetElementById('xeEditor_'+editor_sequence)) {
            xGetElementById('xeEditor_'+editor_sequence).className = 'xeEditor html';
            xGetElementById('use_rich_'+editor_sequence).className = '';
            xGetElementById('preview_html_'+editor_sequence).className = '';
            xGetElementById('use_html_'+editor_sequence).className = 'active';
        }
    // 미리보기
    } else if(mode == 'preview' && preview_obj) {
        preview_obj.style.display='';
        if(xGetElementById('fileUploader_'+editor_sequence)) xGetElementById('fileUploader_'+editor_sequence).style.display='none';

        var fo_obj = xGetElementById("preview_form");
        if(!fo_obj) {
            fo_obj = xCreateElement('form');
            fo_obj.id = "preview_form";
            fo_obj.action = request_uri;
            fo_obj.target = "editor_preview_"+editor_sequence;
            xInnerHtml(fo_obj,'<input type="hidden" name="module" value="editor" /><input type="hidden" name="editor_sequence" value="'+editor_sequence+'" /><input type="hidden" name="act" value="dispEditorPreview" /><input type="hidden" name="content" />');
            document.body.appendChild(fo_obj);
        }
        fo_obj.content.value = html;
        fo_obj.submit();

        xWidth(preview_obj, xWidth(iframe_obj.parentNode));
        editorMode[editor_sequence] = 'preview';

        if(xGetElementById('xeEditor_'+editor_sequence)) {
            xGetElementById('xeEditor_'+editor_sequence).className = 'xeEditor preview';
            xGetElementById('use_rich_'+editor_sequence).className = '';
            xGetElementById('preview_html_'+editor_sequence).className = 'active';
            if(xGetElementById('use_html_'+editor_sequence)) xGetElementById('use_html_'+editor_sequence).className = '';
        }
    // 위지윅 모드 사용시
    } else {
        preview_obj.style.display='none';
        if(xGetElementById('fileUploader_'+editor_sequence)) xGetElementById('fileUploader_'+editor_sequence).style.display='block';
        contentDocument.body.innerHTML = html;
        editorMode[editor_sequence] = null;

        if(xGetElementById('xeEditor_'+editor_sequence)) {
            xGetElementById('xeEditor_'+editor_sequence).className = 'xeEditor rich';
            xGetElementById('use_rich_'+editor_sequence).className = 'active';
            xGetElementById('preview_html_'+editor_sequence).className = '';
            if(xGetElementById('use_html_'+editor_sequence)) xGetElementById('use_html_'+editor_sequence).className = '';
        }
    }

}

// Editor Info Close
function closeEditorInfo(editor_sequence) {
    xGetElementById('editorInfo_'+editor_sequence).style.display='none';
    var expire = new Date();
    expire.setTime(expire.getTime()+ (7000 * 24 * 3600000));
    xSetCookie('EditorInfo', '1', expire);
}


function showEditorHelp(e,editor_sequence){
    var oid = 'helpList_'+editor_sequence;

    if(xGetElementById(oid).className =='helpList'){

        xGetElementById(oid).className = 'helpList open';
    }else{
        xGetElementById(oid).className = 'helpList';
    }
}

function showEditorExtension(evt,editor_sequence){
    var oid = 'editorExtension_'+editor_sequence;
    var e = new xEvent(evt);
    if(xGetElementById(oid).className =='extension2'){
        xGetElementById(oid).className = 'extension2 open';

        if(e.pageX <= xWidth('editor_component_'+editor_sequence)){
            xGetElementById('editor_component_'+editor_sequence).style.right='auto';
            xGetElementById('editor_component_'+editor_sequence).style.left='0px';
        }else{
            xGetElementById('editor_component_'+editor_sequence).style.right='0px';
            xGetElementById('editor_component_'+editor_sequence).style.left='auto';
        }

    }else{
        xGetElementById(oid).className = 'extension2';
    }
}

function showPreviewContent(editor_sequence) {
    if(typeof(editor_sequence)=='undefined') return;
    if(typeof(_editorFontColor[editor_sequence])=='undefined') return;
    var preview_obj = editorGetPreviewArea(editor_sequence);
    preview_obj.contentWindow.document.body.style.color = _editorFontColor[editor_sequence];
}

function setPreviewHeight(editor_sequence){
    var h = xGetElementById('editor_preview_'+editor_sequence).contentWindow.document.body.scrollHeight;
    if(h < 400) h=400;
    xHeight('editor_preview_'+editor_sequence,h+20);
}

// Hide And Show Toggle
var cc=0
function hideShow(id) {
    if (cc==0) {
        cc=1
        document.getElementById(id).style.display="none";
    } else {
        cc=0
        document.getElementById(id).style.display="block";
    }
}

// Show And Hide Toggle
var cc=0
function showHide(id) {
    if (cc==0) {
        cc=1
        document.getElementById(id).style.display="block";
    } else {
        cc=0
        document.getElementById(id).style.display="none";
    }
}

// Local Navigation Toggle
function lnbToggle(id) {
	for(num=1; num<=3; num++) document.getElementById('D3MG'+num).style.display='none'; //D4MG1~D4MG3 까지 숨긴 다음
	document.getElementById(id).style.display='block'; //해당 ID만 보임
}

// IS
function chkIsKind(key, value) {
    showHide('selectOrder');
    xGetElementById('search_target'+key).checked = true;
    xInnerHtml('search_target_label', value);
}
function widget_login(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "member", "procMemberLogin", completeLogin);
	oFilter.addFieldItem("user_id",true,0,0,"","user_id");
	oFilter.addFieldItem("password",true,0,0,"","");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	return oFilter.proc();
}
alertMsg["user_id"] = "ユーザＩＤ";
alertMsg["password"] = "パスワード";
target_type_list["user_id"] = "user_id";
target_type_list["password"] = "";
alertMsg["isnull"] = "%sを入力してください";
alertMsg["outofrange"] = "%sの文字の長さを合わせてください";
alertMsg["equalto"] = "%sが正しくありません";
alertMsg["invalid_email"] = "%sのパターンが正しくありません (例: info@hotit.co.jp)";
alertMsg["invalid_homepage"] = "%sの形式が正しくありません (例: http://www.hotit.co.jp)";
alertMsg["invalid_korean"] = "%sの形式が正しくありません。ハングルのみ入力してください。";
alertMsg["invalid_korean_number"] = "%sの形式が正しくありません。ハングルと半角数字で入力してください。";
alertMsg["invalid_alpha"] = "%sの形式が正しくありません。半角英文字のみ入力してください。";
alertMsg["invalid_alpha_number"] = "%sの形式が正しくありません。半角英数で入力してください。";
alertMsg["invalid_number"] = "%sの形式が正しくありません。半角数字で入力してください。";

function openid_login(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "member", "procMemberOpenIDLogin", completeOpenIDLogin);
	oFilter.addFieldItem("user_id",true,0,0,"","");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	return oFilter.proc();
}
alertMsg["user_id"] = "ユーザＩＤ";
target_type_list["user_id"] = "";
alertMsg["isnull"] = "%sを入力してください";
alertMsg["outofrange"] = "%sの文字の長さを合わせてください";
alertMsg["equalto"] = "%sが正しくありません";
alertMsg["invalid_email"] = "%sのパターンが正しくありません (例: info@hotit.co.jp)";
alertMsg["invalid_homepage"] = "%sの形式が正しくありません (例: http://www.hotit.co.jp)";
alertMsg["invalid_korean"] = "%sの形式が正しくありません。ハングルのみ入力してください。";
alertMsg["invalid_korean_number"] = "%sの形式が正しくありません。ハングルと半角数字で入力してください。";
alertMsg["invalid_alpha"] = "%sの形式が正しくありません。半角英文字のみ入力してください。";
alertMsg["invalid_alpha_number"] = "%sの形式が正しくありません。半角英数で入力してください。";
alertMsg["invalid_number"] = "%sの形式が正しくありません。半角数字で入力してください。";

/* 로그인 영역에 포커스 */
function doFocusUserId(fo_id) {
    if(xScrollTop()) return;
    var fo_obj = xGetElementById(fo_id);
    if(fo_obj.user_id) {
        try{
            fo_obj.user_id.focus();
        } catch(e) {};
    }
}

/* 로그인 후 */
function completeLogin(ret_obj, response_tags, params, fo_obj) {
    var url =  current_url.setQuery('act','');
    location.href = url;
}

/* 오픈아이디 로그인 후 */
function completeOpenIDLogin(ret_obj, response_tags) {
    var redirect_url =  ret_obj['redirect_url'];
    location.href = redirect_url;
}

/* 오픈 아이디 폼 변환 */
function toggleLoginForm(obj) {
    if(xGetElementById('login').style.display != "none") {
        xGetElementById('login').style.display = "none";
        xGetElementById('openid_login').style.display = "block";
        xGetElementById('use_open_id_2').checked = true;
    } else {
        xGetElementById('openid_login').style.display = "none";
        xGetElementById('login').style.display = "block";
        xGetElementById('use_open_id').checked = false;
        xGetElementById('use_open_id_2').checked = false;
    }
}

