/** 
 * 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 (zero@nzeo.com)
 * @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 encodeURI(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 = '';
    }
}

/* jQuery의 extend. */
/* TODO:jQuery 등 자바스크립트 프레임웍 차용시 대체 가능하면 제거 대상 */
objectExtend = function() {
    // copy reference to target object
    var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;

    // Handle a deep copy situation
    if ( target.constructor == Boolean ) {
        deep = target;
        target = arguments[1] || {};
        // skip the boolean and the target
        i = 2;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if ( typeof target != "object" && typeof target != "function" )
        target = {};

    // extend jQuery itself if only one argument is passed
    if ( length == i ) {
        target = this;
        --i;
    }

    for ( ; i < length; i++ )
        // Only deal with non-null/undefined values
        if ( (options = arguments[ i ]) != null )
            // Extend the base object
            for ( var name in options ) {
                var src = target[ name ], copy = options[ name ];

                // Prevent never-ending loop
                if ( target === copy )
                    continue;

                // Recurse if we're merging object values
                if ( deep && copy && typeof copy == "object" && !copy.nodeType )
                    target[ name ] = objectExtend( deep, 
                        // Never move original objects, clone them
                        src || ( copy.length != null ? [ ] : { } )
                    , copy );

                // Don't bring in undefined values
                else if ( copy !== undefined )
                    target[ name ] = copy;

            }

    // Return the modified object
    return target;
};

/**
 * @brief 멀티미디어 출력용 (IE에서 플래쉬/동영상 주변에 점선 생김 방지용)
 **/
function displayMultimedia(src, width, height, options) {
    if(src.indexOf('files') == 0) src = request_uri + src;

    var defaults = {
        wmode : 'transparent',
        allowScriptAccess : 'sameDomain',
        quality : 'high',
        flashvars : ''
    };

    if(options) {
        var autostart = (options.autostart) ? 'true' : 'false';
        delete(options.autostart);
    }

    var params = objectExtend(defaults, options || {});

    var clsid = "";
    var codebase = "";
    var html = "";

    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="'+params.flashvars+'">';
        html += '<param name="movie" value="'+src+'" />';
        for(var name in params) {
            if(params[name] != 'undefined' && params[name] != '') {
                html += '<param name="'+name+'" value="'+params[name]+'" />';
            }
        }
        html += ''
            + '<embed src="'+src+'" autostart="'+autostart+'"  width="'+width+'" height="'+height+'" flashvars="'+params.flashvars+'" wmode="'+params.wmode+'"></embed>'
            + '</object>';
    } else if(/\.flv/i.test(src)) {
        html = '<embed src="'+request_uri+'common/tpl/images/flvplayer.swf" allowfullscreen="true" autostart="'+autostart+'" width="'+width+'" height="'+height+'" flashvars="&file='+src+'&width='+width+'&height='+height+'&autostart='+autostart+'" />';
    } else {
        html = '<embed src="'+src+'" autostart="'+autostart+'" 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';
    area.style.zIndex = 9999;
    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.nodeName != 'A') obj = obj.parentNode;
    if(!obj || (obj.nodeName != 'DIV' && obj.nodeName != 'SPAN' && obj.nodeName != 'A')) 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]+)$/;


    for(var i=0,c=class_name_list.length;i<c;i++) {
        if(menu_id_regx.test(class_name_list[i])) {
            menu_id = class_name_list[i];
        }
    }


    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 >0 ? e.pageX : GetObjLeft(obj);
    params["page_y"] = e.pageY >0 ? e.pageY : GetObjTop(obj)+ xHeight(obj);

    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 GetObjTop(obj) { 
    if(obj.offsetParent == document.body) return xOffsetTop(obj); 
    else return xOffsetTop(obj) + GetObjTop(obj.offsetParent); 
} 
function GetObjLeft(obj) { 
    if(obj.offsetParent == document.body) return xOffsetLeft(obj); 
    else return xOffsetLeft(obj) + GetObjLeft(obj.offsetParent); 
} 

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(typeof(item.length)=='undefined' || 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 = "";
                    var click_str = "";
                    if(icon) styleText = " style=\"background-image:url('"+icon+"')\" ";
                    switch(target) {
                        case "popup" :
                                click_str = " onclick=\"popopen(this.href,'"+target+"'); return false;\"";
                            break;
                        case "self" :
                                //click_str = " onclick=\"location.href='"+url+"' return false;\"";
                            break;
                        case "javascript" :
                                click_str = " onclick=\""+url+"; return false; \"";
                                url="#";
                            break;
                        default :
                                click_str = " onclick=\"window.open(this.href); return false;\"";
                            break;
                    }

                    html += '<li '+styleText+'><a href="'+url+'"'+click_str+'>'+str+'</a></li> ';
                }
            }
        }
        loaded_popup_menus[menu_id] =  html;
    }

    // 레이어 출력
    if(html) {
        var area = xGetElementById("popup_menu_area");
        xInnerHtml(area, '<ul>'+html+'</ul>');
        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();
}

function completeMessage(ret_obj) {
    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.addResponseItem("document_srl");
    oFilter.proc();

    editorRelKeys[editor_sequence]['content'].value = prev_content;
    return false;
}

function completeDocumentSave(ret_obj) {
    xGetElementsByAttribute('input', 'name', 'document_srl')[0].value = ret_obj['document_srl'];
    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).setQuery('act', 'dispBoardWrite');
    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();
    }
}

/* 관리자가 문서를 관리하기 위해서 선택시 세션에 넣음 */
var addedDocument = new Array();
function doAddDocumentCart(obj) {
    var srl = obj.value;
    addedDocument[addedDocument.length] = srl;
    setTimeout(function() { callAddDocumentCart(addedDocument.length); }, 100);
}

function callAddDocumentCart(document_length) {
    if(addedDocument.length<1 || document_length != addedDocument.length) return;
    var params = new Array();
    params["srls"] = addedDocument.join(",");
    exec_xml("document","procDocumentAdminAddCart", params, null);
    addedDocument = new Array();
}

/* 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;
            var first_enable = new Array();
            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;
                }else{
                    first_enable[i] = first_enable[i]>-1? first_enable[i] : j;
                }
            }

            if(!disabled_exists) continue;
            
            sels[i].oldonchange = sels[i].onchange;
            sels[i].onchange = function() {  
                if(this.options[this.selectedIndex].disabled) {

                    this.selectedIndex = first_enable[i];
/*
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() {}
}

function reloadDocument() {
    location.reload();
}

/**
 * @file   common/js/xml_handler.js
 * @author zero <zero@nzeo.com>
 * @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();
    if(typeof(params)!='undefined') {
        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.objXmlHttp = 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.objXmlHttp = 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.objXmlHttp.readyState!=0) {
        this.objXmlHttp.abort();
        this.objXmlHttp = this.getXmlHttp();
    }
    this.objXmlHttp.onreadystatechange = function () {callBackFunc(xmlObj, callBackFunc2, response_tags, callback_func_arg, fo_obj)};

    // 모든 xml데이터는 POST방식으로 전송. try-cacht문으로 오류 발생시 대처
    try {

        this.objXmlHttp.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.objXmlHttp.send(rd);
}

function xml_handlerSetPath(path) {
    this.xml_path = "./"+path;
}


function xml_handlerReset() {
    this.objXmlHttp = this.getXmlHttp();
    this.params = new Array();
}

function xml_handlerAddParam(key, val) {
    this.params[key] = val;
}

function xml_handlerGetResponseXML() {
    if(this.objXmlHttp && this.objXmlHttp.readyState == 4 && isDef(this.objXmlHttp.responseXML)) {
        var xmlDoc = this.objXmlHttp.responseXML;
        this.reset();
        return xmlDoc;
    }
    return null;
}


function xml_parseXmlDoc(dom) {

    if(!dom) return;

    var jsonStr = xml2json(dom,false,false);
    var jsonObj = eval("("+ jsonStr +");");
    return jsonObj.response;
/*

    var ret_obj = new Array();

    var obj = dom.firstChild;
    var preObj;
    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;
}



/*  This work is licensed under Creative Commons GNU LGPL License.

    License: http://creativecommons.org/licenses/LGPL/2.1/
   Version: 0.9
    Author:  Stefan Goessner/2006
    Web:     http://goessner.net/
*/
function xml2json(xml, tab, ignoreAttrib) {
   var X = {
      toObj: function(xml) {
         var o = {};
         if (xml.nodeType==1) {   // element node ..
            if (ignoreAttrib && xml.attributes.length)   // element with attributes  ..
               for (var i=0; i<xml.attributes.length; i++)
                  o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString();
            if (xml.firstChild) { // element has child nodes ..
               var textChild=0, cdataChild=0, hasElementChild=false;
               for (var n=xml.firstChild; n; n=n.nextSibling) {
                  if (n.nodeType==1) hasElementChild = true;
                  else if (n.nodeType==3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) textChild++; // non-whitespace text
                  else if (n.nodeType==4) cdataChild++; // cdata section node
               }
               if (hasElementChild) {
                  if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node ..
                     X.removeWhite(xml);
                     for (var n=xml.firstChild; n; n=n.nextSibling) {
                        if (n.nodeType == 3)  // text node
                           o = X.escape(n.nodeValue);
                        else if (n.nodeType == 4)  // cdata node
//                           o["#cdata"] = X.escape(n.nodeValue);
                            o = X.escape(n.nodeValue);
                        else if (o[n.nodeName]) {  // multiple occurence of element ..
                           if (o[n.nodeName] instanceof Array)
                              o[n.nodeName][o[n.nodeName].length] = X.toObj(n);
                           else
                              o[n.nodeName] = [o[n.nodeName], X.toObj(n)];
                        }
                        else  // first occurence of element..
                           o[n.nodeName] = X.toObj(n);
                     }
                  }
                  else { // mixed content
                     if (!xml.attributes.length)
                        o = X.escape(X.innerXml(xml));
                     else
                        o["#text"] = X.escape(X.innerXml(xml));
                  }
               }
               else if (textChild) { // pure text
                  if (!xml.attributes.length)
                     o = X.escape(X.innerXml(xml));
                  else
                     o["#text"] = X.escape(X.innerXml(xml));
               }
               else if (cdataChild) { // cdata
                  if (cdataChild > 1)
                     o = X.escape(X.innerXml(xml));
                  else
                     for (var n=xml.firstChild; n; n=n.nextSibling){
                        //o["#cdata"] = X.escape(n.nodeValue);
                        o = X.escape(n.nodeValue);
                  }
               }
            }
            if (!xml.attributes.length && !xml.firstChild) o = null;
         }
         else if (xml.nodeType==9) { // document.node
            o = X.toObj(xml.documentElement);
         }
         else
            alert("unhandled node type: " + xml.nodeType);
         return o;
      },
      toJson: function(o, name, ind) {
         var json = name ? ("\""+name+"\"") : "";
         if (o instanceof Array) {
            for (var i=0,n=o.length; i<n; i++)
               o[i] = X.toJson(o[i], "", ind+"\t");
            json += (name?":[":"[") + (o.length > 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]";
         }
         else if (o == null)
            json += (name&&":") + "null";
         else if (typeof(o) == "object") {
            var arr = [];
            for (var m in o)
               arr[arr.length] = X.toJson(o[m], m, ind+"\t");
            json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}";
         }
         else if (typeof(o) == "string")
            json += (name&&":") + "\"" + o.toString() + "\"";
         else
            json += (name&&":") + o.toString();
         return json;
      },
      innerXml: function(node) {
         var s = ""
         if ("innerHTML" in node)
            s = node.innerHTML;
         else {
            var asXml = function(n) {
               var s = "";
               if (n.nodeType == 1) {
                  s += "<" + n.nodeName;
                  for (var i=0; i<n.attributes.length;i++)
                     s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\"";
                  if (n.firstChild) {
                     s += ">";
                     for (var c=n.firstChild; c; c=c.nextSibling)
                        s += asXml(c);
                     s += "</"+n.nodeName+">";
                  }
                  else
                     s += "/>";
               }
               else if (n.nodeType == 3)
                  s += n.nodeValue;
               else if (n.nodeType == 4)
                  s += "<![CDATA[" + n.nodeValue + "]]>";
               return s;
            };
            for (var c=node.firstChild; c; c=c.nextSibling)
               s += asXml(c);
         }
         return s;
      },
      escape: function(txt) {
         return txt.replace(/[\\]/g, "\\\\")
                   .replace(/[\"]/g, '\\"')
                   .replace(/[\n]/g, '\\n')
                   .replace(/[\r]/g, '\\r');
      },
      removeWhite: function(e) {
         e.normalize();
         for (var n = e.firstChild; n; ) {
            if (n.nodeType == 3) {  // text node
               if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
                  var nxt = n.nextSibling;
                  e.removeChild(n);
                  n = nxt;
               }
               else
                  n = n.nextSibling;
            }
            else if (n.nodeType == 1) {  // element node
               X.removeWhite(n);
               n = n.nextSibling;
            }
            else                      // any other node
               n = n.nextSibling;
         }
         return e;
      }
   };
   if (xml.nodeType == 9) // document node
      xml = xml.documentElement;
   var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "");
   return "{" + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "}";
}

/**
 * @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 regx.test(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 false;
}

// 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') { 
        var content = editorGetContent(editor_sequence);

        var dummy = xCreateElement("div");
        xInnerHtml(dummy, content);

        // IE에서 컨텐츠 전체를 P태그로 감싸는 경우가 있어서 이 의미없는 P태그를 제거
        if(dummy.firstChild && dummy.firstChild.nodeName == 'P' && dummy.firstChild == dummy.lastChild) {
            var content = xInnerHtml(dummy.firstChild);
            xInnerHtml(dummy,content);
        }

        // img/a 태그의 대상에 대해 경로 재설정 (IE브라우저에서 위지윅 에디터내의 경로를 절대 경로로 바꾸는 버그때문ㅇ)
        var imgTags = xGetElementsByTagName('IMG', dummy);
        for(var i=0;i<imgTags.length;i++) {
            if(imgTags[i].src.indexOf(request_uri)!=-1) {
                imgTags[i].src = imgTags[i].src.replace(/(.*)files\/(.*)/i,'files/$2');
            }
        }
        var aTags = xGetElementsByTagName('A', dummy);
        for(var i=0;i<aTags.length;i++) {
            if(aTags[i].href.indexOf(request_uri)!=-1) {
                aTags[i].href = aTags[i].href.replace(/(.*)\?module=file&(.*)/i,'./?module=file&$2');
            }
        }
        var content = xInnerHtml(dummy);
        editorRelKeys[editor_sequence]['content'].value = content;
    }

    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;
}

var url_regx = /((http|https|ftp|news|telnet|irc):\/\/(([0-9a-z\-._~!$&'\(\)*+,;=:]|(%[0-9a-f]{2}))*\@)?((\[(((([0-9a-f]{1,4}:){6}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|(::([0-9a-f]{1,4}:){5}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|(([0-9a-f]{1,4})?::([0-9a-f]{1,4}:){4}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){3}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){2}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4})|((([0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::))|(v[0-9a-f]+.[0-9a-z\-._~!$&'\(\)*+,;=:]+))\])|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))|(([0-9a-z\-._~!$&'\(\)*+,;=]|(%[0-9a-f]{2}))+))(:[0-9]*)?(\/([0-9a-z\-._~!$&'\(\)*+,;=:@]|(%[0-9a-f]{2}))*)*(\?([0-9a-z\-._~!$&'\(\)*+,;=:@\/\?]|(%[0-9a-f]{2}))*)?(#([0-9a-z\-._~!$&'\(\)*+,;=:@\/\?]|(%[0-9a-f]{2}))*)?)/i;
function replaceHrefLink(target_obj)
{
    var obj_list = new Array();
    var obj = target_obj;
    while(obj) {
        obj_list[obj_list.length] = obj;
        obj = obj.nextSibling;
    }
    
    for(var i=0;i<obj_list.length;i++) {
        var obj = obj_list[i];
        var pObj = obj.parentNode;
        if(!pObj) continue;

        var pN = pObj.nodeName.toLowerCase();
        if(pN == 'a' || pN == 'pre' || pN == 'xml' || pN == 'textarea' || pN == 'input')
            continue;
        
        if(obj.nodeType == 3 && obj.data && url_regx.test(obj.data) ) {
            var html = obj.nodeValue.split('<');
            for(var i=0;i<html.length;i++) {
                var html2 = html[i].split('>');
                for(var j=0;j<html2.length;j++)
                    html2[j] = html2[j].replace(url_regx,"<a href=\"$1\" onclick=\"window.open(this.href); return false;\">$1<\/a>");
                html[i] = html2.join('&gt;');
            }
            var output = html.join('&lt;');
            var dummy = xCreateElement('span');
            xInnerHtml(dummy, output);
            pObj.insertBefore(dummy, obj);
            pObj.removeChild(obj);
        }
        else if(obj.nodeType == 1 && obj.firstChild)
            replaceHrefLink(obj.firstChild);
    }
}

function addUrlLink() {
    var objs = xGetElementsByClassName('xe_content');
    if(objs.length<1) return;
    for(var i=0;i<objs.length;i++) {
        if(url_regx.test(xInnerHtml(objs[i]))) replaceHrefLink(objs[i].firstChild);
    }
}

xAddEventListener(window,'load', addUrlLink);

/**
 * @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 = decodeURI(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의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
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의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
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);
}

// 롤오버 2차메뉴 만들기   
// Brower   
var browserType='';    
if(navigator.userAgent.indexOf("MSIE") >-1) {   
   browserType = 'IE';    
} else if(navigator.userAgent.indexOf("Firefox") >-1) {   
   browserType = 'FF';    
} else {   
   browserType = 'OTHER';    
}   
function gnbinToggle(id, gnbblock) {   
 if(browserType == 'FF') {   
  gnbinToggleFF(id, gnbblock);   
 } else {   
  gnbinToggleIE(id, gnbblock);   
 }   
}   
// Local Navigation Toggle   
function gnbinToggleIE(id, gnbblock) {   
 for(num=0; num<gnb_count; num++) {   
  document.getElementById('gnb'+num).style.display='none';              // 2차 메뉴   
  document.getElementById('gnbli'+num).setAttribute('className', 'off');  // 1차 메뉴   
 }   
 var sub_1 = document.getElementById('gnbli'+id);     // 1 차메뉴    
 var sub_2 = document.getElementById('gnb'+id);     // 2 차메뉴   
 document.getElementById('gnb'+id).style.display = 'block';   
 gnbblock.className = "on";   
 var sub_2_left =sub_1.offsetWidth * (id+0.5) - sub_2.offsetWidth /2;   
 // 2차메뉴 크기에 따른 위치 조절   
 if (sub_2_left < 0)   
  sub_2_left = 0;   
 else if( (sub_2_left + sub_2.offsetWidth) > 700 )   
  sub_2_left=(700 - sub_2.offsetWidth);         
}   
// Local Navigation Toggle   
function gnbinToggleFF(id, gnbblock) {   
 for(var num=0; num<gnb_count; num++) {   
  document.getElementById('gnb'+num).style.display='none'; // 2차 메뉴   
  document.getElementById('gnbli'+num).className = null;  // 1차 메뉴   
 }   
 var sub_1 = document.getElementById('gnbli'+id);     // 1 차메뉴    
 var sub_2 = document.getElementById('gnb'+id);     // 2 차메뉴   
 document.getElementById('gnb'+id).style.display = '';   
 gnbblock.className = "on";   
 var sub_2_left =sub_1.offsetWidth * (id+0.5) - sub_2.offsetWidth /2;   
 // 2차메뉴 크기에 따른 위치 조절   
 if (sub_2_left < 0)   
  sub_2_left = 0;   
 else if( (sub_2_left + sub_2.offsetWidth) > 700 )   
  sub_2_left=(700 - sub_2.offsetWidth);        
}   
function reset_menu()   
{   
      
     var sub_1 = document.getElementById('gnbli'+gnb_count_now);     // 1 차메뉴    
  var sub_2 = document.getElementById('gnb'+gnb_count_now);     // 2 차메뉴   
  var sub_2_left =sub_1.offsetWidth * (gnb_count_now+0.5) - sub_2.offsetWidth /2;   
 // 넓이가 0미만일경우 0   
 if (sub_2_left < 0)   
  sub_2_left = 0;   
 else if( (sub_2_left + sub_2.offsetWidth) > 700 )   
  sub_2_left=(700 - sub_2.offsetWidth);       
}  

//flash
function flash(url,w,h,id,bg,win){
	document.write("\
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0' width="+w+" height="+h+" id="+id+" align='middle'>\
<param name='allowScriptAccess' value='sameDomain' />\
<param name='movie' value="+url+" />\
<param name='quality' value='high' />\
<param name='bgcolor' value="+bg+" />\
<param name='wmode' value="+win+" />\
<embed src="+url+" quality='high' bgcolor="+bg+" width="+w+" wmode="+win+" height="+h+" name="+id+" align='middle' allowScriptAccess='sameDomain' type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/go/getflashplayer' />\
</object>\
	"); 
}

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의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
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의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
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) {
    if(fo_obj.remember_user_id && fo_obj.remember_user_id.checked) {
        var expire = new Date();
        expire.setTime(expire.getTime()+ (7000 * 24 * 3600000));
        xSetCookie('user_id', fo_obj.user_id.value, expire);
    }

    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;
    }
}


