﻿/**
*  2か月分同時表示用ポップアップ カレンダー（英語用）
*  Yahoo Calendar とそれをラップしたYahhoカレンダーを2か月表示バージョンにカスタマイズ
*  休日取得は、祝日XMLファイルから引いてきた内容を利用
**/

/* 以降は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 IkyuYuiCalML = {
	/**
	*  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"

		//"": "background-color: transparent none"

		//プレビューボタンリンクがIEで少し見切れている件の対策
		//"a.calnavright": "margin-right: 0.8em",
		//"a.calnavleft": "margin-left: 0.8em"
	},

	/** 地域（YUI_CAL_CONFIGのどれを使うかの指定） */
	locale: "en",

	/** 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 カレンダーの表示ができたかどうか
*/
IkyuYuiCalML.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();
		IkyuYuiCalML.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した後に変更しないと位置が変わらないので
		IkyuYuiCalML.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) {
		shown = new Date(shown.getFullYear(), shown.getMonth() + 1, shown.getDate())
	}

	//カレンダーの表示が終わってからクリックイベントの捕捉を始める
	setTimeout(function() {
		YAHOO.util.Event.addListener(document, "click", IkyuYuiCalML.clickListener);
	}, 1);

};
/**
*  入力要素とカレンダーとのポリモフィズムなアダプタを生成する
*/
IkyuYuiCalML.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 eyId = inputId;
	var emId = monthId;
	var edId = dateId;

	if (document.getElementById(eyId).tagName == "INPUT") {    //テキストボックスの場合
		adapter.getDate = function() { return [document.getElementById(eyId).value, document.getElementById(emId).value, document.getElementById(edId).value]; };
		adapter.setDate = function(y, m, d) {
			document.getElementById(edId).value = ("00" + d).substr(("00" + d).length - 2, 2);
			document.getElementById(emId).value = ("00" + m).substr(("00" + m).length - 2, 2);
			document.getElementById(eyId).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(eyId);
		var em = document.getElementById(emId);
		var ed = document.getElementById(edId);
		return [get(ey), get(em), get(ed)];
	};
	adapter.setDate = function(y, m, d) {
		// DropDownListDateSelectionでは年月の変更イベントで日リストを変更する処理があるため、最後に日をセットしなくてはならない
		// また、ユーザ系でFromToの年月日リストがペアである場合は連動処理があり、年月日が全てかたまった後に変更イベントを走らせる必要があるため
		// 年月日設定⇒年変更イベント⇒月変更イベント⇒年、月、日設定⇒日変更イベントの順で処理を行う。
		// また性能対策としてgetElementByIdの回数、変更イベントを必要な分だけにして減らす
		var ey = document.getElementById(eyId);
		var em = document.getElementById(emId);
		var ed = document.getElementById(edId);
		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を設定する
*/
IkyuYuiCalML.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);
};
/**
*  カレンダーを生成する
*/
IkyuYuiCalML.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", "357px");     // 狭い場所に配置された場合、縦で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]);
	//yDom.insertAfter(place, insertId);
	IkyuYuiCalML.insertDummyIframe(); // IE6のcssバグ対策

	//カレンダー生成
	var config = this.YUI_CAL_CONFIG[this.locale];
	config.close = true;
	config.hide_blank_weeks = true;
	//var cal = new YAHOO.widget.Calendar(place, config);
	//var cal = new YAHOO.widget.CalendarGroup(insertId, place.id, config);
	var cal = new YAHOO.widget.CalendarGroup(place, config);

	// イベント設定
	IkyuYuiCalML.setEvent(cal);

	return cal;
};

/**
*  イベントを設定する
*/
IkyuYuiCalML.setEvent = function(cal) {

	//日付を選択された時のイベント
	cal.selectEvent.subscribe(function(eventName, selectedDate) {
		var date = selectedDate[0][0];
		IkyuYuiCalML.adapters[IkyuYuiCalML.currentId].setDate(date[0], date[1], date[2]);
		cal.hide();
		IkyuYuiCalML.removeDummyIframe(); // IEのcssバグ対策
	});

	//月を移動した時のイベント
	//cal.changePageEvent.subscribe(function() {

	//閉じた時のイベント
	cal.hideEvent.subscribe(function() {
		YAHOO.util.Event.removeListener(document, "click", IkyuYuiCalML.clickListener);
		IkyuYuiCalML.removeDummyIframe(); // IEのcssバグ対策
	});

	return cal;
};

/**
*  カレンダーの外をクリックされたらカレンダーを閉じる
*/
IkyuYuiCalML.clickListener = function(clickedPoint) {
	var xy = YAHOO.util.Event.getXY(clickedPoint);
	var x = xy[0], y = xy[1];
	var r = YAHOO.util.Dom.getRegion(IkyuYuiCalML.cal.containerId);
	if (x < r.left || x > r.right || y < r.top || y > r.bottom) {
		IkyuYuiCalML.cal.hide();
		IkyuYuiCalML.removeDummyIframe(); // IEのcssバグ対策
	}

};

/**
*  必要なYUIのJavaScriptとCSSを読み込む
*  @param  String  yuiBase (optional) YUIのベースとなるURL
*/
IkyuYuiCalML.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);
};
/**
*  週の初めを月曜日にする
*/
IkyuYuiCalML.setMondayAs1st = function() {
	this.YUI_CAL_CONFIG[this.locale].start_weekday = 1;
};
/**
*  選択可能な最初の日を指定する
*  @param  integer y   西暦4桁
*  @param  integer m   1～12月
*  @param  integer d
*/
IkyuYuiCalML.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]);
		// イベント再設定
		IkyuYuiCalML.setEvent(this.cal);
	} else {
		this.YUI_CAL_CONFIG[this.locale].mindate = date;
	}
};
/**
*  選択可能な最後の日を指定する
*  @param  integer y   西暦4桁
*  @param  integer m   1～12月
*  @param  integer d
*/
IkyuYuiCalML.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]);
		// イベント再設定
		IkyuYuiCalML.setEvent(this.cal);
	} else {
		this.YUI_CAL_CONFIG[this.locale].maxdate = date;
	}
};

// IE6のCSSバグ対策（z-indexプロパティが効かないので、Ifreamを挟む処理）
IkyuYuiCalML.insertDummyIframe = function() {
	var isMSIE = /*@cc_on!@*/false;
	if (isMSIE) {
		if (typeof document.documentElement.style.msInterpolationMode == "undefined") { //IE6以下判定
			var placeIf = document.createElement("iframe");
			placeIf.id = "IkyuYuiCalMLMaskSelect";
			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.getXY(this.place));
		}
	}
};

// IE6のCSSバグ対策（z-indexプロパティが効かないので、Ifreamを挟む対策の後始末処理）
IkyuYuiCalML.removeDummyIframe = function() {
	var isMSIE = /*@cc_on!@*/false;
	if (isMSIE) {
		if (typeof document.documentElement.style.msInterpolationMode == "undefined") { //IE6以下判定
			var dom_obj = document.getElementById("IkyuYuiCalMLMaskSelect");
			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ライブラリロード
IkyuYuiCalML.loadYUI("/common/js/yui/build/");

IkyuYuiCalML.YUI_CAL_CONFIG["en"].mindate = min;
IkyuYuiCalML.YUI_CAL_CONFIG["en"].maxdate = max;


