  // Type Define
  var Type = {
    Object    : typeof new Object,
    Number    : typeof 0,
    String    : typeof "string",
    Boolean   : typeof true,
    Function  : typeof Object,
    Undefined : typeof _UNDEFINED
  }

  var Validate = {

    // 인자의 갯수가 1~2개가 아니면 경고메시지를 출력하고 null을 반환한다.
    // 인자의 갯수가 1개이고 첫번째 인자의 값이 null 이거나 값없는 문자열인 경우 true를 반환, 그렇지 않은 경우 false를 반환한다.
    // 인자의 갯수가 2개이고 첫번째 인자의 값이 null 이거나 값없는 문자열인 경우 두번째인자를 반환, 두번째 인자가 null 이면 값없는 문자열을 반환한다.
    // 인자의 갯수가 2개이고 첫번째 인자의 값이 null 이 아니고 값없는 문자열도 아닐 경우 첫번째 인자를 반환한다.
    isNull : function() {
      var retValue = null;
      switch(arguments.length) {
        case 1 :
          if(arguments[0] == null || typeof arguments[0] == Type.Undefined || (typeof arguments[0] == Type.String && arguments[0].length <= 0)) retValue = true;
          else retValue = false;
          break;
        case 2 :
          arguments[1] = this.isNull(arguments[1]) ? "" : arguments[1];
          retValue = this.isNull(arguments[0]) ? arguments[1] : arguments[0];
          break;
        default :
          alert("isNull 메소드 인자의 갯수는 1 또는 2개 이어야 합니다.");
      }
      return retValue;
    }
  }

  // 브라우저 정보
  
  var Browser = {
    isMsie      : !Validate.isNull(navigator.userAgent.match(/MSIE/gi)),
    isMozes     : !Validate.isNull(navigator.userAgent.match(/Gecko/gi)),
    isOpera     : !Validate.isNull(navigator.userAgent.match(/Opera/gi)),
    isKhtml     : !Validate.isNull(navigator.userAgent.match(/KHTML/gi)),
    isSafari    : !Validate.isNull(navigator.userAgent.match(/AppleWebKit/gi)),
    isFirefox   : !Validate.isNull(navigator.userAgent.match(/Firefox/gi)),
    isNetscape  : !Validate.isNull(navigator.userAgent.match(/Netscape/gi)),
    name        : navigator.userAgent.match(/(MSIE)|(Opera)|(Safari)|(Firefox)|(Netscape)/gi).toString(),
    version     : navigator.userAgent.match(/(MSIE [\d\.]*)|(Opera\/[\d\.]*)|(Firefox\/[\d\.]*)|(Netscape\/[\d\.]*)/gi).toString().replace(/[^\d\.]*/gi,"")
    
  }
  
  // object 에 명시된 객체(id 속성이 object 이거나  object 가 객체 자신일 경우 object 객체)를 반환한다.
  function GetObjectById(object) {
    if((typeof object) == Type.String) return document.getElementById(object);
    else return object;
  }

  // 날짜 관련 객체
  function Calendar() {
    this.calendar = new Date();
    
    if(!Validate.isNull(arguments[5])) {
      this.calendar.setSeconds(arguments[5]);
    }
    if(!Validate.isNull(arguments[4])) {
      this.calendar.setMinute(arguments[4]);
    }
    if(!Validate.isNull(arguments[3])) {
      this.calendar.setHours(arguments[3]);
    }
    if(!Validate.isNull(arguments[2])) {
      this.calendar.setDate(arguments[2]);
    }
    if(!Validate.isNull(arguments[1])) {
      this.calendar.setMonth(arguments[1] - 1);
    }
    if(!Validate.isNull(arguments[0])) {
      this.calendar.setFullYear(arguments[0]);
    }
  
    this.getYear = function() { // 년도를 반환 한다.
      return this.calendar.getFullYear();
    };
  
    this.setYear = function() { // 년도를 설정 한다.
      return this.calendar.setFullYear(arguments[0]);
    };
  
    this.getMonth = function() { // 월을 반환 한다.
      return this.calendar.getMonth() + 1;
    };
  
    this.setMonth = function() { // 월을 설정 한다.
      return this.calendar.setMonth(arguments[0]-1);
    };
  
    this.getDate = function() { // 날짜를 반환 한다.
      return this.calendar.getDate();
    };
  
    this.setDate = function() { // 날짜를 설정 한다.
      return this.calendar.setDate(arguments[0]);
    };
  
    this.getHours = function() { // 시를 반환 한다.
      return this.calendar.getHours();
    };
  
    this.setHours = function() { // 시를 설정 한다.
      return this.calendar.setHours(arguments[0]);
    };
  
    this.getMinute = function() { // 분을 반환 한다.
      return this.calendar.getMinute();
    };
  
    this.setMinute = function() { // 분을 설정 한다.
      return this.calendar.setMinute(arguments[0]);
    };
  
    this.getSeconds = function() { // 초를 반환 한다.
      return this.calendar.getSeconds();
    };
  
    this.setSeconds = function() { // 초를 설정 한다.
      return this.calendar.setSeconds(arguments[0]);
    };
  
    this.getMilliseconds = function() { // 1/1000초를 반환 한다.
      return this.calendar.getMilliseconds();
    };
  
    this.setMilliseconds = function() { // 1/1000초를 설정 한다.
      return this.calendar.setMilliseconds(arguments[0]);
    };
  
    this.getFirstDay = function() { // 첫째날 요일을 반환 한다.
      var tempDate = new Date(this.calendar.getFullYear(), this.calendar.getMonth(), 1);
      return tempDate.getDay();
    };
    
    this.getLastDate = function() { // 마지막 날짜를 반환 한다.
      var tempDate = new Date(this.calendar.getFullYear(), this.calendar.getMonth()+1, 0);
      return tempDate.getDate();
    };
    
    this.getWeeks = function() { // 주의 갯수를 반환 한다.
      var lastPosition = this.getFirstDay() + this.getLastDate();
      return parseInt((lastPosition / 7) + (lastPosition % 7 != 0 ? 1 : 0));
    };
  }

  // 날짜 선택기
  function DateSelector() {
    try{
      var event = arguments[0] || window.event;
      var target = event.srcElement;
      var instance = document.getElementById("_dateSelector");
      if(!Validate.isNull(instance)) { document.body.removeChild(instance); }
      var calendar = null;
      if(!Validate.isNull(arguments[1])){
        target = GetObjectById(arguments[1]);
             
        var date = GetObjectById(arguments[1]).value.split("-");
        if(!Validate.isNull(GetObjectById(arguments[1]).value) && date.length == 3){
          calendar = new Calendar(date[0],date[1],date[2],null,null,null);
        }else{
          calendar = new Calendar();
        }
      }
      var getController = function(newYear, newMonth) {
        if(!Validate.isNull(newYear) && !Validate.isNull(newMonth)) {
          calendar.setDate(1);
          calendar.setMonth(newMonth);
          calendar.setYear(newYear);
        }
        var year = calendar.getYear();
        var month = calendar.getMonth();
        var table = document.createElement("table");
        var tbody = document.createElement("tbody");
        var tr = document.createElement("tr");
        var td = document.createElement("td");
        var img_left = document.createElement("img");
        var img_right = document.createElement("img");
        var img_close = document.createElement("img");
        table.style.borderCollapse = "collapse";
        table.style.border = "solid #DBDBDB 1px";
        table.setAttribute("style", "rcalendar")
        table.setAttribute("border", "1px");
        table.setAttribute("width", "100%");
        table.setAttribute("height", "20px");
        table.setAttribute("cellpadding", "0px");
        table.setAttribute("cellspacing", "0px");
        td.style.color = "#0066CC";
        td.style.fontSize = "12px";
        td.style.fontWeight = "bold";
        td.style.backgroundColor = "#FFFFFF";
        td.setAttribute("align", "center");
        img_left.style.cursor = "pointer";
        img_left.style.marginRight = "5px";
        img_left.setAttribute("align","absmiddle");
        img_left.setAttribute("src","/images/common/icon_arrow_left_01.gif");
        img_left.setAttribute("alt","<");
        img_right.style.cursor = "pointer";
        img_right.style.marginLeft = "5px";
        img_right.setAttribute("align","absmiddle");
        img_right.setAttribute("src","/images/common/icon_arrow_right_01.gif");
        img_right.setAttribute("alt",">");
        img_close.style.cursor = "pointer";
        img_close.style.marginLeft = "5px";
        img_close.setAttribute("align","absmiddle");
        img_close.setAttribute("src","/images/common/icon_close.gif");
        img_close.setAttribute("alt","닫기");
        img_left.onclick = function() {
          if(--month == 0) {
            month = 12;
            --year;
          }
          var _new_controller = getController(year, month);
          var _new_calendar = getCalendar(year, month);
          div.replaceChild(_new_controller,_controller);
          div.replaceChild(_new_calendar,_calendar);
          _controller = _new_controller;
          _calendar = _new_calendar;
        };
        img_right.onclick = function() {
          if(++month == 13) {
            month = 1;
            ++year;
          }
          var _new_controller = getController(year, month);
          var _new_calendar = getCalendar(year, month);
          div.replaceChild(_new_controller,_controller);
          div.replaceChild(_new_calendar,_calendar);
          _controller = _new_controller;
          _calendar = _new_calendar;
        };
        img_close.onclick = function () {
          document.body.removeChild(document.getElementById("_dateSelector"));
        };
        td.appendChild(img_left);
        td.appendChild(document.createTextNode(year + "년 " + (month <= 9 ? "0" : "") + month + " 월"));
        td.appendChild(img_right);
        td.appendChild(img_close);
        tr.appendChild(td);
        tbody.appendChild(tr);
        table.appendChild(tbody);
        return table;
      };
  
      var getCalendar = function(newYear, newMonth) {
        var holiday = null; // 공휴일 리스트
        var day = new Array(
                    new Array("일","#CC0000"), 
                    new Array("월","#666666"), 
                    new Array("화","#666666"), 
                    new Array("수","#666666"), 
                    new Array("목","#666666"), 
                    new Array("금","#666666"), 
                    new Array("토","#3399CC"));
        if(!Validate.isNull(newYear) && !Validate.isNull(newMonth)) {
          calendar.setDate(1);
          calendar.setMonth(newMonth);
          calendar.setYear(newYear);
        }
        var year = calendar.getYear();
        var month = calendar.getMonth();
        var weeks = calendar.getWeeks();
        var firstDay = calendar.getFirstDay();
        var lastDate = calendar.getLastDate();
        var lastPosition = firstDay + lastDate;
        var table = document.createElement("table");
        table.style.borderCollapse = "collapse";
        table.style.border = "solid #DBDBDB 1px";
        table.setAttribute("border", "1px");
        table.setAttribute("width", "100%");
        table.setAttribute("cellpadding", "0px");
        table.setAttribute("cellspacing", "0px");
        var tbody = document.createElement("tbody");
        var tr_day = document.createElement("tr");
        for(var idx_td = 0; idx_td < 7; idx_td++) {
          var td = document.createElement("td");
          td.appendChild(document.createTextNode(day[idx_td][0]));
          td.style.width = "20px";
          td.style.color = day[idx_td][1];
          td.style.fontSize = "11px";
          td.style.backgroundColor = "#FFFFFF";
          td.setAttribute("align", "center");
          tr_day.appendChild(td);
        }
        tbody.appendChild(tr_day);
        for(var idx_tr = 0; idx_tr < weeks; idx_tr++) {
          var tr = document.createElement("tr");
          for(var idx_td = 0; idx_td < 7; idx_td++) {
            var td = document.createElement("td");
            var currentPosition = (idx_tr) * 7 + idx_td + 1;
            var currentDate = currentPosition - firstDay;
            td.style.color = day[idx_td][1];
            td.style.fontSize = "11px";
            td.style.backgroundColor = "#FFFFFF";
            td.setAttribute("align", "center");
            if(currentPosition > firstDay && currentPosition <= lastPosition) {
              var today = new Date();
              if(today.getFullYear() == year && today.getMonth() == month - 1 && today.getDate() == currentDate) td.style.fontWeight = "bold";
              td.appendChild(document.createTextNode(currentDate));
              td.onclick = function() {
                var date = this.firstChild.nodeValue;
                target.value = year + "-" + (month <= 9 ? "0" : "") + month + "-" + (date <= 9 ? "0" : "") + date;
                document.body.removeChild(document.getElementById("_dateSelector"));
                target.focus();
              };
              td.onmouseover = function() {
                this.style.backgroundColor = "yellow";
              };
              td.onmouseout = function() {
                this.style.backgroundColor = "#FFFFFF";
              };
            }
            tr.appendChild(td);
          }
          tbody.appendChild(tr);
        }
        table.appendChild(tbody);
        return table;
      };
      
      var weeks = calendar.getWeeks();
      var div = document.createElement("div");
      var offset = 10;
      var width = Browser.isMozes ? 147 : 148;
      var height = new Array(116, 135, 154);
      var top = event.clientY;
      var left = event.clientX;
      var innerWidth = window.innerWidth ? window.innerWidth : document.body.clientWidth;
      var innerHeight = window.innerHeight ? window.innerHeight : document.body.clientHeight;
      div.style.top =  ((innerHeight > top + height[weeks-4] + offset) ? top : (innerHeight - height[weeks-4] - offset)) + document.documentElement.scrollTop + "px";
      div.style.left = ((innerWidth > left + width + offset) ? left : (innerWidth - width - offset)) + document.documentElement.scrollLeft + "px";
      div.style.width = width + "px";
      div.style.cursor = "default";
      div.style.position = "absolute";window.scr
      div.style.backgroundColor = "#FFFFFF";
      div.setAttribute("align", "center");
      div.setAttribute("id", "_dateSelector");
      //div.onclick = function() {document.body.removeChild(document.getElementById("_dateSelector")); };
    
      var _controller = getController();
      var _calendar = getCalendar();
      div.appendChild(_controller);
      div.appendChild(_calendar);
      document.body.appendChild(div);
    }catch(e){alert(e.message);}
  }

