﻿/**
*  2か月分同時表示用ポップアップ カレンダー
*  Yahoo Calendar とそれをラップしたYahhoカレンダーを2か月表示バージョンにカスタマイズ
*  休日取得は、祝日XMLファイルから引いてきた内容を利用
**/
//祝日取得用js
/**
*  休日取得処理
*  DBから引いてきた内容を利用(同一サーバ上のXMLファイルを読み込む)
*/
// jquery.jsをload
if (window.jQuery == undefined) {
  script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "/common/dg/js/jquery.js";
  document.getElementsByTagName("head")[0].appendChild(script);
}
var IkyuHolidays = {
  holidays: {}
};
/**
 *  祝日を取得する
 *  @param  Function  callback  データ取得時に呼び出されるfunction
 *  @param  Number  year    (optional) 年
 *  @param  Number  month   (optional) 月
 */
IkyuHolidays.get = function(callback, year, month) {
  //日付範囲
  var padZero = function(value) { return ("0" + value).slice(-2); };
  var y = year;
  var start = [y, padZero(month), "01"].join("-");
  var m = month;
  var end = [y, padZero(m), padZero(new Date(y, m, 0).getDate())].join("-");
  
  //取得済みの場合はそれを使う
  var cache = this.holidays[year + "/" + month];
  if (cache) {
    callback(cache);
    return;
  }
  this.userCallback = callback;
  readHolidays(year, month);
};
// 祝日データXMLファイルを読み込み、祝日データを返す
function readHolidays(year, month) {
  var padZero = function(value) { return ("0" + value).slice(-2); };
  //read xml data
  jQuery.ajax({
    //path the xml file
    url: "/common/file/holiday/IkyuHolidays" + year + padZero(month) + ".xml",
    type: "GET",
    dataType: "xml",
    timeout: 2000,
    cache: false,
    async: false,
    success: IkyuHolidays.decode
  });
}
/**
*  AJAXでXMLを読み込み成功後呼び出されるfunction
*  @param  Object  xml   読み込んだ祝日XMLデータ
*/
IkyuHolidays.decode = function(xml) {
  var hdays = [];
  //read data
  var i = 0;
  jQuery(xml).find("Holiday").each(function() {
    var y = jQuery(this).find("Year").text();
    var m = jQuery(this).find("Month").text();
    var d = jQuery(this).find("Day").text();
    var t = jQuery(this).find("Name").text();
    hdays[i] = { year: y, month: m, date: d, title: t };
    i = i + 1;
  });
  //sort by date
  hdays.sort(function(a, b) {
    return (a.year > b.year) ? 1 : -1;
    return (a.month > b.month) ? 1 : -1;
    return (a.date >= b.date) ? 1 : -1;
  });
  if (hdays.length > 0) {
    IkyuHolidays.holidays[hdays[0].year + "/" + hdays[0].month] = hdays;  //cache
    IkyuHolidays.userCallback(hdays);  //callback
  }
};
/* 以降はYahooCal.jsの2か月表示カスタマイズ版 */
/**
*  Yahho Calendar - Japanized Popup Calendar
*  @see   http://0-oo.net/sbox/javascript/yahho-calendar
*  @version   0.4.0 beta 2
*  @copyright 2008-2009 dgbadmin@gmail.com
*  @license   http://0-oo.net/pryn/MIT_license.txt (The MIT license)
*  See also
*  @see http://developer.yahoo.com/yui/calendar/
*  @see http://developer.yahoo.com/yui/docs/YAHOO.widget.Calendar.html
*/
var IkyuYuiCal = {
  /**
  *  loadYUI()で読み込むYUIのURL
  *  @see http://developer.yahoo.com/yui/articles/hosting/
  *  @see http://code.google.com/intl/ja/apis/ajaxlibs/documentation/#yui
  */
  YUI_URL: {
    SERVER: location.protocol + "//ajax.googleapis.com/ajax/libs/yui/",
    VERSION: "2.7.0",
    DIR: "/build/"
  },
  /** カレンダーの見た目の設定 */
  CAL_STYLE: {
    //inlineを他のcssで指定されていると表示が崩れるので、カレンダー内はblockで固定化
    "div": "display: block",
    //幅（IE6で縮まるのを防ぐ）
    "": "width: 13em",
    //日曜日
    "td.wd0 a.selector": "background-color: #fcf",
    //土曜日
    "td.wd6 a.selector": "background-color: #cff",
    //祝日
    "td.holiday a.selector": "background-color: #f9f",
    //今日
    "td.today a.selector": "",
    //選択された日
    "td.selected a.selector": "background-color: #0f0",
    //選択可能な日付の範囲外の日（今日が黒くなるのを防ぐ）
    "td.previous": "background-color: #fff",
    //ヘッダ年月文字色
    "div.calheader": "color: #336699",
    //ヘッダ週文字色
    "th.calweekdaycell": "color: #666666"
    //プレビューボタンリンクがIEで少し見切れている件の対策
    //"a.calnavright": "margin-right: 0.8em",
    //"a.calnavleft": "margin-left: 0.8em"
  },
  /** 地域（YUI_CAL_CONFIGのどれを使うかの指定） */
  locale: "ja",
  /** YUIカレンダー設定 */
  YUI_CAL_CONFIG: {
    //英語
    en: {},
    //日本語
    ja: {
      my_label_year_position: 1,
      my_label_year_suffix: "年 ",
      my_label_month_suffix: "月",
      months_long: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
      weekdays_short: ["日", "月", "火", "水", "木", "金", "土"],
      // START_WEEKDAY: 1,
      PAGES: 2
    },
    //韓国語
    ko: {
      my_label_year_position: 1,
      my_label_year_suffix: "&#xb144; ",
      my_label_month_suffix: "&#xc6d4;",
      months_long: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
      weekdays_short: [
      "&#xc77c;", "&#xc6d4;", "&#xd654;", "&#xc218;", "&#xbaa9;",
      "&#xae08;", "&#xd1a0;"
      ]
    },
    //中国語
    zh: {
      my_label_year_position: 1,
      my_label_year_suffix: "年 ",
      my_label_month_suffix: "月",
      months_long: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
      weekdays_short: ["日", "一", "二", "三", "四", "五", "六"]
    }
  },
  //入力要素をラップするアダプタ
  adapters: {}
};
var getLargestZIndex = function() {
  var largestZIndex = 0;
  var defaultView = document.defaultView;
  var func = function(tagname) {
    var elems = document.getElementsByTagName(tagname), len = elems.length;
    for (var i = 0; i < len; i++) {
      var elem = elems[i];
      var zIndex = elem.style.zIndex;
      if (!zIndex) {
      var css = elem.currentStyle || defaultView.getComputedStyle(elem, null);
      zIndex = css ? css.zIndex : 0;
      }
      zIndex -= 0;
      if (largestZIndex < zIndex) largestZIndex = zIndex;
    }
  };
  if (arguments.length == 0) func('*');
  else for (var i = 0; i < arguments.length; i++) func(arguments[i]);
  return largestZIndex;
};
/**
*  カレンダーを表示する
*  @param  String  inputId 入力要素のid or 年の入力要素のid
*  @param  String  monthId (optional) 月の入力要素のid
*  @param  String  dateId  (optional) 日の入力要素のid
*  @return Boolean カレンダーの表示ができたかどうか
*/
IkyuYuiCal.render = function(inputId, monthId, dateId) {
  //  if (!window.YAHOO || !YAHOO.widget.Calendar) {  //YUIを読み込んでいない場合
  if (!window.YAHOO || !YAHOO.widget.CalendarGroup) {  //YUIを読み込んでいない場合
    return false;
  }
  var currentId = (this.currentId = dateId || inputId);   //入力要素を特定するID
  //アダプタを取得
  if (!this.adapters[currentId]) {
    this.adapters[currentId] = this.createAdapter(inputId, monthId, dateId);
  }
  var adapter = this.adapters[currentId];
  var cal = this.cal;
  if (cal) {  //再表示の場合
    cal.hide();
    IkyuYuiCal.removeDummyIframe(); // IE6のcssバグ対策
    var el = document.getElementById(currentId)
    var xp = YAHOO.util.Dom.getX(el) + el.offsetWidth;
    var yp = YAHOO.util.Dom.getY(el) + el.offsetHeight;
    cal.show();
    YAHOO.util.Dom.setXY(this.place, [xp, yp]); // showした後に変更しないと位置が変わらないので
    IkyuYuiCal.insertDummyIframe(); // IE6のcssバグ対策
    //YAHOO.util.Dom.insertAfter(this.place, currentId);
  } else {  //初めて表示する場合
    this.setStyle();
    cal = (this.cal = this.createCalendar(currentId));
  }
  //入力済みの日付を取得
  var val = adapter.getDate();
  var y = val[0], m = val[1], d = val[2];
  var shown = new Date(y, m - 1, d);
  //表示設定
  var pagedate = "", selected = "";
  if ((shown.getFullYear() == y && shown.getMonth() + 1 == m && shown.getDate() == d)) {
    //日付として正しい場合
    pagedate = m + "/" + y;
    selected = m + "/" + d + "/" + y;
  } else {
    shown = new Date();
  }
  cal.cfg.setProperty("pagedate", pagedate);  //表示する年月
  cal.cfg.setProperty("selected", selected);  //選択状態の日付
  cal.render();
  //複数月対応
  //for (var i in cal.pages) {
  for (var i = 0; i < cal.pages.length; i++) {
    this.showHolidays(shown);
    shown = new Date(shown.getFullYear(), shown.getMonth() + 1, shown.getDate())
  }
  //カレンダーの表示が終わってからクリックイベントの捕捉を始める
  setTimeout(function() {
    YAHOO.util.Event.addListener(document, "click", IkyuYuiCal.clickListener);
  }, 1);
  return true;
};
/**
*  入力要素とカレンダーとのポリモフィズムなアダプタを生成する
*/
IkyuYuiCal.createAdapter = function(inputId, monthId, dateId) {
  var adapter = {};

  if (!monthId) {   //テキストボックス1つの場合（YYYY/M/D）
    var ymd = document.getElementById(inputId);
    adapter.getDate = function() { return ymd.value.split("/"); };
    adapter.setDate = function(y, m, d) { ymd.value = ("0000" + y).substr(("0000" + y).length - 4, 4) + "/" + ("00" + m).substr(("00" + m).length - 2, 2) + "/" + ("00" + d).substr(("00" + d).length - 2, 2); };
    return adapter;
  }
  //年・月・日が分かれている場合
  var ey = document.getElementById(inputId);
  var em = document.getElementById(monthId);
  var ed = document.getElementById(dateId);
  if (ey.tagName == "INPUT") {  //テキストボックスの場合
    adapter.getDate = function() { return [ey.value, em.value, ed.value]; };
    adapter.setDate = function(y, m, d) { ed.value = ("00" + d).substr(("00" + d).length - 2, 2); em.value = ("00" + m).substr(("00" + m).length - 2, 2); ey.value = ("0000" + y).substr(("0000" + y).length - 4, 4); };
    return adapter;
  }
  //選択リストの場合
  var getNumber = function(opt) { return (opt.value || opt.text).replace(/^0+/, ""); };
  var get = function(sel) { return getNumber(sel.options[sel.selectedIndex]); };
  var set = function(sel, value) {
    for (var i = 0, len = sel.length; i < len; i++) {
      if (getNumber(sel.options[i]) == value) {
      sel.options[i].selected = true;
      sel.selectedIndex = i;
      return;
      }
    }
  };
  var change = function(sel) { try { sel.onchange(); } catch (e) { } return; };
  adapter.getDate = function() {
    var ey = document.getElementById(inputId);
    var em = document.getElementById(monthId);
    var ed = document.getElementById(dateId);
    return [get(ey), get(em), get(ed)];
  };
  adapter.setDate = function(y, m, d) {
    // DropDownListDateSelectionでは年月の変更イベントで日リストを変更する処理があるため、最後に日をセットしなくてはならない
    // また、ユーザ系でFromToの年月日リストがペアである場合は連動処理があり、年月日が全てかたまった後に変更イベントを走らせる必要があるため
    // 年月日設定⇒年変更イベント⇒月変更イベント⇒年、月、日設定⇒日変更イベントの順で処理を行う。
    // また性能対策としてgetElementByIdの回数、変更イベントを必要な分だけにして減らす
    var ey = document.getElementById(inputId);
    var em = document.getElementById(monthId);
    var ed = document.getElementById(dateId);
    var oldy = get(ey);
    var oldm = get(em);
    var oldd = get(ed);
    if (oldd != d) { set(ed, d); };
    if (oldm != m) { set(em, m); };
    if (oldy != y) { set(ey, y); };
    if (oldy != y) { change(ey, y); };
    if (oldm != m) { change(em, m); };
    if (oldy != y) { set(ey, y); };
    if (oldm != m) { set(em, m); };
    if (oldd != d) { set(ed, d); };
    if (oldd != d || oldm != m || oldy != y) { change(ed, d); };
  };
  return adapter;
};
/**
*  styleを設定する
*/
IkyuYuiCal.setStyle = function() {
  var css = "";
  for (var target in this.CAL_STYLE) {
    css += ".yui-skin-sam .yui-calcontainer .yui-calendar " + target;
    css += "{" + this.CAL_STYLE[target] + "}";
  }
  var tmp = document.createElement("div");
  tmp.innerHTML = 'dummy<style type="text/css">' + css + "</style>";
  document.getElementsByTagName("head")[0].appendChild(tmp.lastChild);
};
/**
*  カレンダーを生成する
*/
IkyuYuiCal.createCalendar = function(insertId) {
  var yDom = YAHOO.util.Dom;
  //YUI skinを適用
  yDom.addClass(document.body, "yui-skin-sam");
  //カレンダーの場所を作る
  var place = (this.place = document.createElement("div"));
  place.id = insertId + "Calender";
  yDom.setStyle(place, "position", "absolute");
  yDom.setStyle(place, "z-index", getLargestZIndex() + 1);
  yDom.setStyle(place, "width", "335px");   // 狭い場所に配置された場合、縦で2か月分表示されてしまうため、横幅を固定化
  yDom.setStyle(place, "font-size", "12px");  // 狭い場所に配置された場合、縦で2か月分表示されてしまうため、Font-sizeを固定化
  yDom.setStyle(place, "line-height", "100%");  // line-heightを変えられるとはみ出してしまうため、Font-sizeを固定化
  var el = document.getElementById(insertId)
  var x = yDom.getX(el) + el.offsetWidth;
  var y = yDom.getY(el) + el.offsetHeight;
  document.getElementsByTagName("form")[0].appendChild(place);
  yDom.setXY(place, [x, y]);
  IkyuYuiCal.insertDummyIframe(); // IE6のcssバグ対策
  //カレンダー生成
  var config = this.YUI_CAL_CONFIG[this.locale];
  config.close = true;
  config.hide_blank_weeks = true;
  var cal = new YAHOO.widget.CalendarGroup(place, config);
  // イベント設定
  IkyuYuiCal.setEvent(cal);
  return cal;
};
/**
*  イベントを設定する
*/
IkyuYuiCal.setEvent = function(cal) {
  //日付を選択された時のイベント
  cal.selectEvent.subscribe(function(eventName, selectedDate) {
    var date = selectedDate[0][0];
    IkyuYuiCal.adapters[IkyuYuiCal.currentId].setDate(date[0], date[1], date[2]);
    cal.hide();
    IkyuYuiCal.removeDummyIframe(); // IEのcssバグ対策
  });
  //月を移動した時のイベント
  //複数月対応
  cal.pages[0].changePageEvent.subscribe(function() {
    IkyuYuiCal.showHolidays(cal.pages[0].cfg.getProperty("pagedate"));
  });
  cal.pages[1].changePageEvent.subscribe(function() {
    IkyuYuiCal.showHolidays(cal.pages[1].cfg.getProperty("pagedate"));
  });
  //閉じた時のイベント
  cal.hideEvent.subscribe(function() {
    YAHOO.util.Event.removeListener(document, "click", IkyuYuiCal.clickListener);
    IkyuYuiCal.removeDummyIframe(); // IEのcssバグ対策
  });
  return cal;
};
/**
*  祝日を表示する
*/
IkyuYuiCal.showHolidays = function(target) {
  if (!window.IkyuHolidays) {   //IkyuHolidays.jsを読み込んでいない場合
    return;
  }
  IkyuHolidays.get(this.setHolidays, target.getFullYear(), target.getMonth() + 1);
};
/**
*  祝日表示を設定する
*/
IkyuYuiCal.setHolidays = function(holidays) {
  if (holidays.length == 0) {
    return;
  }
  var yDom = YAHOO.util.Dom;
  //取得した年月をまだ表示しているかチェック
  var first = holidays[0];
  var tbodys = yDom.getElementsByClassName("m" + first.month + " calbody", "tbody", this.place);
  if (!tbodys) {
    return;
  }
  //祝日設定
  // 2か月分対応
  //for (var i in tbodys) {
  for (var i = 0;  i < tbodys.length; i++) {
    var tbody = tbodys[i];
    //for (var j in holidays) {
    for (var j = 0; j < holidays.length; j++) {
      var h = holidays[j];
      var td = yDom.getElementsByClassName("d" + h.date, "td", tbody)[0];
      yDom.addClass(td, "holiday");
      td.title = h.title;   //マウスオーバーで祝日名を表示
    }
  }
};
/**
*  カレンダーの外をクリックされたらカレンダーを閉じる
*/
IkyuYuiCal.clickListener = function(clickedPoint) {
  var xy = YAHOO.util.Event.getXY(clickedPoint);
  var x = xy[0], y = xy[1];
  var r = YAHOO.util.Dom.getRegion(IkyuYuiCal.cal.containerId);
  if (x < r.left || x > r.right || y < r.top || y > r.bottom) {
    IkyuYuiCal.cal.hide();
    IkyuYuiCal.removeDummyIframe(); // IEのcssバグ対策
  }
};
/**
*  必要なYUIのJavaScriptとCSSを読み込む
*  @param  String  yuiBase (optional) YUIのベースとなるURL
*/
IkyuYuiCal.loadYUI = function(yuiBase) {
  if (!yuiBase) {
    yuiBase = this.YUI_URL.SERVER + this.YUI_URL.VERSION + this.YUI_URL.DIR;
  }
  //YUI Loaderをload
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.src = yuiBase + "yuiloader-dom-event/yuiloader-dom-event.js";
  document.getElementsByTagName("head")[0].appendChild(script);

  //YUI Loaderがloadされるまで待つ
  var limit = 5000, interval = 50, time = 0;
  var loadedId = setInterval(function() {
    if (window.YAHOO) {
      clearInterval(loadedId);
      //YUI Calendarをload
      (new YAHOO.util.YUILoader({ base: yuiBase, require: ["calendar"] })).insert();
    } else if ((time += interval) > limit) {  //タイムアウト
      clearInterval(loadedId);
    }
  }, interval);
};
/**
*  週の初めを月曜日にする
*/
IkyuYuiCal.setMondayAs1st = function() {
  this.YUI_CAL_CONFIG[this.locale].start_weekday = 1;
};
/**
*  選択可能な最初の日を指定する
*  @param  integer y   西暦4桁
*  @param  integer m   1～12月
*  @param  integer d
*/
IkyuYuiCal.setMinDate = function(y, m, d) {
  var date = m + "/" + d + "/" + y;
  if (this.cal) {
    //this.cal.configMinDate(null, [date]);
    //this.cal.cfg.config.mindate = date
    this.YUI_CAL_CONFIG[this.locale].mindate = date;
    this.cal.init(this.cal.id, this.cal.containerId, this.YUI_CAL_CONFIG[this.locale]);
    // イベント再設定
    IkyuYuiCal.setEvent(this.cal);
  } else {
    this.YUI_CAL_CONFIG[this.locale].mindate = date;
  }
};
/**
*  選択可能な最後の日を指定する
*  @param  integer y   西暦4桁
*  @param  integer m   1～12月
*  @param  integer d
*/
IkyuYuiCal.setMaxDate = function(y, m, d) {
  var date = m + "/" + d + "/" + y;
  if (this.cal) {
    //this.cal.configMaxDate(null, [date]);
    //this.cal.cfg.config.maxdate = date
    this.YUI_CAL_CONFIG[this.locale].maxdate = date;
    this.cal.init(this.cal.id, this.cal.containerId, this.YUI_CAL_CONFIG[this.locale]);
    // イベント再設定
    IkyuYuiCal.setEvent(this.cal);
  } else {
    this.YUI_CAL_CONFIG[this.locale].maxdate = date;
  }
};
// IE6のCSSバグ対策（z-indexプロパティが効かないので、Ifreamを挟む処理）
IkyuYuiCal.insertDummyIframe = function() {
  var isMSIE = /*@cc_on!@*/false;
  if (isMSIE) {
     if (typeof document.documentElement.style.msInterpolationMode == "undefined") { //IE6以下判定
      var placeIf = document.createElement("iframe");
      placeIf.id = "IkyuYuiCalMaskSelect";
      YAHOO.util.Dom.setAttribute(placeIf, "src", "javascript:false;");
      YAHOO.util.Dom.setStyle(placeIf, "margin", "0px");
      YAHOO.util.Dom.setStyle(placeIf, "padding", "0px");
      YAHOO.util.Dom.setStyle(placeIf, "position", "absolute");
      YAHOO.util.Dom.setStyle(placeIf, "display", "block");
      YAHOO.util.Dom.setStyle(placeIf, "z-index", YAHOO.util.Dom.getStyle(this.place, "z-index") - 1);
      YAHOO.util.Dom.setStyle(placeIf, "width", YAHOO.util.Dom.getStyle(this.place, "width"));
      YAHOO.util.Dom.setStyle(placeIf, "height", YAHOO.util.Dom.getStyle(this.place, "height"));
      YAHOO.util.Dom.insertAfter(placeIf, this.place.id);
      // タグを書き出した後出ないと座標設定効かないみたいなので、タグ書いた後に座標を設定
      YAHOO.util.Dom.setXY(placeIf, [YAHOO.util.Dom.getX(this.place), YAHOO.util.Dom.getY(this.place)]);
    }
  }
};

// IE6のCSSバグ対策（z-indexプロパティが効かないので、Ifreamを挟む対策の後始末処理）
IkyuYuiCal.removeDummyIframe = function() {
  var isMSIE = /*@cc_on!@*/false;
  if (isMSIE) {
    if (typeof document.documentElement.style.msInterpolationMode == "undefined") { //IE6以下判定
      var dom_obj = document.getElementById("IkyuYuiCalMaskSelect");
      if (dom_obj) {
      var dom_obj_parent = dom_obj.parentNode;
      dom_obj_parent.removeChild(dom_obj);
      }
    }
  }
};
// ここから 参照時にそのまま実行される処理
var d = new Date();

//今日以降のみを選択可能にする
var min = (d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getFullYear();
//6か月後までを選択可能にする
var max = (d.getMonth() + 7) + "/" + d.getDate() + "/" + d.getFullYear();

//common配下固定でYUIライブラリロード
IkyuYuiCal.loadYUI("/common/js/yui/build/");

IkyuYuiCal.YUI_CAL_CONFIG["ja"].mindate = min;
IkyuYuiCal.YUI_CAL_CONFIG["ja"].maxdate = max;

