//
// calendar -- a javascript date picker designed for easy localization.
//
// $Id: DatePicker.js,v 1.1 2010/01/13 11:52:49 clmg Exp $
//
//
// Author: Per Norrman (pernorrman@telia.com)
// 
// Based on Tapestry 2.3-beta1 Datepicker by Paul Geerts
// 
// Thanks to:
//     Vladimir [vyc@quorus-ms.ru] for fixing the IE6 zIndex problem.
//
// The normal setup would be to have one text field for displaying the 
// selected date, and one button to show/hide the date picker control.
// This is  the recommended javascript code:
// 
//	<script language="javascript">
//		var cal;
//
//		function init() {
//			cal = new Calendar();
//			cal.setIncludeWeek(true);
//			cal.setFormat("yyyy-MM-dd");
//			cal.setMonthNames(.....);
//			cal.setShortMonthNames(....);
//			cal.create();
//			
//			document.form.button1.onclick = function() {
//				cal.toggle(document.form.button1);
//			}
//			cal.onchange = function() {
//				document.form.textfield1.value  = cal.formatDate();
//			}
//		}
//	</script>
//
// The init function is invoked when the body is loaded.
//
//

// ----- ハマス修正一覧  ------------------------------------------------------------------------------------------------------
/**
  * 修正点
  *  < 2004/05/13 >
  *    ・recDate_onclick_functionメソッドを各HTML(JSP)からjavascriptファイルへ移動し共通化
  *    ・recDate_onclick_functionメソッドの引数に値（日付）を反映したいエレメント名（要素名）を渡すよう変更
  *    ・変数 calendar_$RecDate をグローバル変数からローカル変数へ変更
  *    ・calendar_$RecDate == null の場合のみカレンダークラスのインスタンスを生成
  *        → 毎回ボタンがクリックされるたびに生成するように変更
  *          (最初の一回だけ生成するとエレメント情報を保持してしまうため、次に他のボタンがクリックされた場合も前のテキスト項目に値が反映されてしまう。)
  *          (特にレスポンス等に問題は無し。メモリはほんのちょっと使うかも。)
  *
  *  < 2004/05/14 >
  *    ・Calendarクラスのインスタンス生成時（コンストラクタ？）の処理を変更
  *    ・this._currentDate、this._selectedDateに格納する値（Date型）の
  *      チェック処理、文字変換処理、日付反映処理を追加
  *    ・カレンダー画面の年月日ボタンの表示を「Feb 15, 2004」形式から「2004年05月14日」形式へ変更
  *
  */

// ----- 2004/05/13 ハマス追加メソッド start ------------------------------------------------------------------------------------------------------

var calendar_$RecDate_$Array = new Array(0);

/**
  *  日付参照用ボタンクリック時に呼ばれるメソッド
  *  @param elementName 値を反映したい要素名（テキストフィールド）
  */
function recDate_onclick_function(elementName, formName) {

	if( calendar_$RecDate_$Array.length <= 0 ){
		
		var calendar_$RecDate = null;
		
		if( formName == null ) {
			if (document.forms[0].elements[elementName].value == "") {
				calendar_$RecDate = new Calendar();
			} else {
				calendar_$RecDate = new Calendar(document.forms[0].elements[elementName].value);
			}
		
			calendar_$RecDate.setMonthNames(new Array("1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"));
			calendar_$RecDate.setShortMonthNames(new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"));
			calendar_$RecDate.setWeekDayNames(new Array("\u65E5\u66DC\u65E5", "\u6708\u66DC\u65E5", "\u706B\u66DC\u65E5", "\u6C34\u66DC\u65E5", "\u6728\u66DC\u65E5", "\u91D1\u66DC\u65E5", "\u571F\u66DC\u65E5"));
			calendar_$RecDate.setShortWeekDayNames(new Array("\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"));
			calendar_$RecDate.setFormat("yyyy-MM-dd");
			calendar_$RecDate.setFirstDayOfWeek(0);
			calendar_$RecDate.setMinimalDaysInFirstWeek(1);
			calendar_$RecDate.setIncludeWeek(false);
		
			calendar_$RecDate.create();
			calendar_$RecDate.onchange = function() {
				document.forms[0].elements[elementName].value  = calendar_$RecDate.formatDate();
			}
		
			calendar_$RecDate.toggle(document.forms[0].elements[elementName]);
			
		} else {
			
			if (document.getElementsByName(formName)[0].elements[elementName].value == "") {
				calendar_$RecDate = new Calendar();
			} else {
				calendar_$RecDate = new Calendar(document.getElementsByName(formName)[0].elements[elementName].value);
			}
			
			calendar_$RecDate.setMonthNames(new Array("1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"));
			calendar_$RecDate.setShortMonthNames(new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"));
			calendar_$RecDate.setWeekDayNames(new Array("\u65E5\u66DC\u65E5", "\u6708\u66DC\u65E5", "\u706B\u66DC\u65E5", "\u6C34\u66DC\u65E5", "\u6728\u66DC\u65E5", "\u91D1\u66DC\u65E5", "\u571F\u66DC\u65E5"));
			calendar_$RecDate.setShortWeekDayNames(new Array("\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"));
			calendar_$RecDate.setFormat("yyyy-MM-dd");
			calendar_$RecDate.setFirstDayOfWeek(0);
			calendar_$RecDate.setMinimalDaysInFirstWeek(1);
			calendar_$RecDate.setIncludeWeek(false);
		
			calendar_$RecDate.create();
			calendar_$RecDate.onchange = function() {
				document.getElementsByName(formName)[0].elements[elementName].value  = calendar_$RecDate.formatDate();
			}
		
			calendar_$RecDate.toggle(document.getElementsByName(formName)[0].elements[elementName]);
		} 
		
		calendar_$RecDate_$Array = new Array(1);
		calendar_$RecDate_$Array[0] = calendar_$RecDate;
		
	} else {
		
		for( var i=0; i<calendar_$RecDate_$Array.length; i++ ){
			
			var calendar_$RecDate = calendar_$RecDate_$Array[i];
			calendar_$RecDate.hide();
		}
		
 	}
}


function recDate_onclick_functionId(elementName, formId) {
	
	if( calendar_$RecDate_$Array.length <= 0 ){
		
		var calendar_$RecDate = null;
		
		if( formId==null) {
			if (document.forms[0].elements[elementName].value == "") {
			calendar_$RecDate = new Calendar();
			} else {
				calendar_$RecDate = new Calendar(document.forms[0].elements[elementName].value);
			}
		
			calendar_$RecDate.setMonthNames(new Array("1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"));
			calendar_$RecDate.setShortMonthNames(new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"));
			calendar_$RecDate.setWeekDayNames(new Array("\u65E5\u66DC\u65E5", "\u6708\u66DC\u65E5", "\u706B\u66DC\u65E5", "\u6C34\u66DC\u65E5", "\u6728\u66DC\u65E5", "\u91D1\u66DC\u65E5", "\u571F\u66DC\u65E5"));
			calendar_$RecDate.setShortWeekDayNames(new Array("\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"));
			calendar_$RecDate.setFormat("yyyy-MM-dd");
			calendar_$RecDate.setFirstDayOfWeek(0);
			calendar_$RecDate.setMinimalDaysInFirstWeek(1);
			calendar_$RecDate.setIncludeWeek(false);
		
			calendar_$RecDate.create();
			calendar_$RecDate.onchange = function() {
				document.forms[0].elements[elementName].value  = calendar_$RecDate.formatDate();
			}
		
			calendar_$RecDate.toggle(document.forms[0].elements[elementName]);
			
		}  else {
			
			if (document.forms[formId].elements[elementName].value == "") {
			calendar_$RecDate = new Calendar();
			} else {
				calendar_$RecDate = new Calendar(document.forms[formId].elements[elementName].value);
			}
		
			calendar_$RecDate.setMonthNames(new Array("1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"));
			calendar_$RecDate.setShortMonthNames(new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"));
			calendar_$RecDate.setWeekDayNames(new Array("\u65E5\u66DC\u65E5", "\u6708\u66DC\u65E5", "\u706B\u66DC\u65E5", "\u6C34\u66DC\u65E5", "\u6728\u66DC\u65E5", "\u91D1\u66DC\u65E5", "\u571F\u66DC\u65E5"));
			calendar_$RecDate.setShortWeekDayNames(new Array("\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"));
			calendar_$RecDate.setFormat("yyyy-MM-dd");
			calendar_$RecDate.setFirstDayOfWeek(0);
			calendar_$RecDate.setMinimalDaysInFirstWeek(1);
			calendar_$RecDate.setIncludeWeek(false);
		
			calendar_$RecDate.create();
			calendar_$RecDate.onchange = function() {
				document.forms[formId].elements[elementName].value  = calendar_$RecDate.formatDate();
			}
		
			calendar_$RecDate.toggle(document.forms[formId].elements[elementName]);
			
		}
		
		calendar_$RecDate_$Array = new Array(1);
		calendar_$RecDate_$Array[0] = calendar_$RecDate;
		
	} else {
	
		for( var i=0; i<calendar_$RecDate_$Array.length; i++ ){
			var calendar_$RecDate = calendar_$RecDate_$Array[i];
			calendar_$RecDate.hide();
		}		
	}
	
}

// ----- 2004/05/13 ハマス追加メソッド end ---------------------------------------------------------------------------------------------------------


function Calendar(date) {
	if (arguments.length == 0) {
		this._currentDate = new Date();
		this._selectedDate = null;
	}
	else {

// ----- 2004/05/14 ハマス修正 start ------------------------------------------------------------------------------------------------------

/* 20040514 del
		this._currentDate = new Date(date);
		this._selectedDate = new Date(date);
*/

		// コンストラクタ引数取得
		var yyyymmdd = arguments[0];

		// 引数妥当性（半角英数字または"-"）チェック
		var flag = true;
		for (var i=0; i<yyyymmdd.length; i++) {
			var ch = yyyymmdd.charAt(i);
			if (ch >= "0" && ch <= "9") {
				continue;
			}
			if (ch == "-") {
				continue;
			}
			flag = false;
			break;
		}

		// "-"を削除
		yyyymmdd = yyyymmdd.replace("-","");
		yyyymmdd = yyyymmdd.replace("-","");

		// 文字列長チェック
		if (yyyymmdd.length != 8) {
			flag = false;
		}

		// 正常値（yyyymmdd）ならば
		if (flag == true) {
			var yyyy = yyyymmdd.substring(0,4);
			var mm   = yyyymmdd.substring(4,6);
			var imm = parseInt(mm,10) - 1;
			if (imm > 9) {
				mm = toString(imm);
			} else {
				mm = "0" + new String(imm);
			}
			var dd   = yyyymmdd.substring(6,8);
			this._currentDate = new Date(yyyy, mm, dd);
			this._selectedDate = new Date(yyyy, mm, dd);

		} else {
			this._currentDate = new Date();
			this._selectedDate = new Date();
		}
	}
	
// ----- 2004/05/14 ハマス修正 end ------------------------------------------------------------------------------------------------------

	// Accumulated days per month, for normal and for leap years.
	// Used in week number calculations.	
	Calendar.NUM_DAYS = [0,31,59,90,120,151,181,212,243,273,304,334];
	
	Calendar.LEAP_NUM_DAYS = [0,31,60,91,121,152,182,213,244,274,305,335];

	this._bw = new bw_check();
	this._showing = false;	
	this._includeWeek = false;
	this._hideOnSelect = true;
	this._alwaysVisible = false;
	
	this._dateSlot = new Array(42);
	this._weekSlot = new Array(6);
	
	this._firstDayOfWeek = 1;
	this._minimalDaysInFirstWeek = 4;
	
	this._monthNames = [	
		"January",		"February",		"March",	"April",
		"May",			"June",			"July",		"August",
		"September",	"October",		"November",	"December"
	];
	
	this._shortMonthNames = [ 
		"jan", "feb", "mar", "apr", "may", "jun", 
		"jul", "aug", "sep", "oct", "nov", "dec"
	];
	
	// Week days start with Sunday=0, ... Saturday=6
	this._weekDayNames = [
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" 
	];
	
	this._shortWeekDayNames = 
		["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
	
	this._defaultFormat = "yyyy-MM-dd";
	
	this._format = this._defaultFormat; 

	this._calDiv = null;
	
}

/**
 *	CREATE the Calendar DOM element
 */
Calendar.prototype.create = function() {
	var div;
	var table;
	var tbody;
	var tr;
	var td;
	var dp = this;
	
	// Create the top-level div element
	this._calDiv = document.createElement("div");
	this._calDiv.id = "calendar_$RecDate";
	this._calDiv.className = "calendar";
	this._calDiv.style.position = "absolute";
	this._calDiv.style.display = "none";
	this._calDiv.style.border = "1px solid WindowText";
	this._calDiv.style.textAlign = "center";
	this._calDiv.style.background = "Window";
	this._calDiv.style.zIndex = "400";
	
	// header div
	div = document.createElement("div");
	div.className = "calendarHeader";
	div.style.background = "ActiveCaption";
	div.style.padding = "3px";
	div.style.borderBottom = "1px solid WindowText";
	this._calDiv.appendChild(div);

	table = document.createElement("table");
	table.style.cellSpacing = 0;
	div.appendChild(table);

	tbody = document.createElement("tbody");
	table.appendChild(tbody);

	tr = document.createElement("tr");
	tbody.appendChild(tr);

	// Previous Month Button
	td = document.createElement("td");
	this._previousMonth = document.createElement("button");
	this._previousMonth.className = "prevMonthButton"
	this._previousMonth.appendChild(document.createTextNode("<<"));
	//this._previousMonth.appendChild(document.createTextNode(String.fromCharCode(9668)));
	td.appendChild(this._previousMonth);
	tr.appendChild(td);

	//
	// Create the month drop down 
	//
	td = document.createElement("td");
	td.className = "labelContainer";
	tr.appendChild(td);
	this._monthSelect = document.createElement("select");
	for (var i = 0 ; i < this._monthNames.length ; i++) {
		var opt = document.createElement("option");
		opt.innerHTML = this._monthNames[i];
		opt.value = i;
		if (i == this._currentDate.getMonth()) {
			opt.selected = true;
		}
		this._monthSelect.appendChild(opt);
	}
	td.appendChild(this._monthSelect);

	// 
	// Create the year drop down
	//
	td = document.createElement("td");
	td.className = "labelContainer";
	tr.appendChild(td);
	this._yearSelect = document.createElement("select");
	for(var i=1920; i < 2050; ++i) {
		var opt = document.createElement("option");
		opt.innerHTML = i;
		opt.value = i;
		if (i == this._currentDate.getFullYear()) {
			opt.selected = true;
		}
		this._yearSelect.appendChild(opt);
	}
	td.appendChild(this._yearSelect);

	td = document.createElement("td");
	this._nextMonth = document.createElement("button");
	this._nextMonth.appendChild(document.createTextNode(">>"));
	//this._nextMonth.appendChild(document.createTextNode(String.fromCharCode(9654)));
	this._nextMonth.className = "nextMonthButton";
	td.appendChild(this._nextMonth);
	tr.appendChild(td);

	// Calendar body
	div = document.createElement("div");
	div.className = "calendarBody";
	this._calDiv.appendChild(div);
	this._table = div;

	// Create the inside of calendar body

	var text;
	table = document.createElement("table");
	//table.style.width="100%";
	table.className = "grid";
	table.style.font 	 	= "small-caption";
	table.style.fontWeight 	= "normal";
	table.style.textAalign	= "center";
	table.style.color		= "WindowText";
	table.style.cursor		= "default";
	table.cellPadding		= "3";
	table.cellSpacing		= "0";

	div.appendChild(table);
	var thead = document.createElement("thead");
	table.appendChild(thead);
	tr = document.createElement("tr");
	thead.appendChild(tr);

	// weekdays header
	if (this._includeWeek) {
		td = document.createElement("th");
		text = document.createTextNode("w");
		td.appendChild(text);
		td.className = "weekNumberHead";
		td.style.textAlign = "left";
		tr.appendChild(td);
	}
	for(i=0; i < 7; ++i) {
		td = document.createElement("th");
		text = document.createTextNode(this._shortWeekDayNames[(i+this._firstDayOfWeek)%7]);
		td.appendChild(text);
		td.className = "weekDayHead";
		td.style.fontWeight = "bold";
		td.style.borderBottom = "1px solid WindowText";
		tr.appendChild(td);
	}

	// Date grid
	tbody = document.createElement("tbody");
	table.appendChild(tbody);
	
	for(week=0; week<6; ++week) {
		tr = document.createElement("tr");
		tbody.appendChild(tr);

		if (this._includeWeek) {
			td = document.createElement("td");
			td.className = "weekNumber";
			td.style.fontWeight = "normal";
			td.style.borderRight = "1px solid WindowText";
			td.style.textAlign = "left";
			text = document.createTextNode(String.fromCharCode(160));
			td.appendChild(text);
			//setCursor(td);
			td.align="center";
			tr.appendChild(td);
			var tmp = new Object();
			tmp.tag = "WEEK";
			tmp.value = -1;
			tmp.data = text;
			this._weekSlot[week] = tmp;
		}

		for(day=0; day<7; ++day) {
			td = document.createElement("td");
			text = document.createTextNode(String.fromCharCode(160));
			td.appendChild(text);
			setCursor(td);
			td.align="center";
			td.style.fontWeight="normal";

			tr.appendChild(td);
			var tmp = new Object();
			tmp.tag = "DATE";
			tmp.value = -1;
			tmp.data = text;
			this._dateSlot[(week*7)+day] = tmp;
		}
	}

	// Calendar Footer
	div = document.createElement("div");
	div.className = "calendarFooter";
	this._calDiv.appendChild(div);

	table = document.createElement("table");
	//table.style.width="100%";
	table.className = "footerTable";
	table.cellSpacing = 0;
	div.appendChild(table);

	tbody = document.createElement("tbody");
	table.appendChild(tbody);

	tr = document.createElement("tr");
	tbody.appendChild(tr);

	//
	// The TODAY button	
	//
	td = document.createElement("td");
	this._todayButton = document.createElement("button");
	var today = new Date();

// 20040514 mod		var buttonText = today.getDate() + " " + this._monthNames[today.getMonth()] + ", " + today.getFullYear();
	var buttonText = today.getFullYear() + "\u5e74" + this._monthNames[today.getMonth()] + today.getDate() + "\u65e5";
	this._todayButton.appendChild(document.createTextNode(buttonText));
	td.appendChild(this._todayButton);
	tr.appendChild(td);

	//
	// The CLEAR button
	//
	td = document.createElement("td");
	this._clearButton = document.createElement("button");
	var today = new Date();
	buttonText = "Clear";
	this._clearButton.appendChild(document.createTextNode(buttonText));
	td.appendChild(this._clearButton);
	tr.appendChild(td);

	this._update();
	this._updateHeader();

	// IE55+ extension		
	this._previousMonth.hideFocus = true;
	this._nextMonth.hideFocus = true;
	this._todayButton.hideFocus = true;
	// end IE55+ extension

	// hook up events
	// buttons
	this._previousMonth.onclick = function () {
		dp.prevMonth();
	};

	this._nextMonth.onclick = function () {
		dp.nextMonth();
	};

	this._todayButton.onclick = function () {
		dp.setSelectedDate(new Date());
		dp.hide();
	};

	this._clearButton.onclick = function () {
		dp.clearSelectedDate();
		dp.hide();
	};
	

	this._calDiv.onselectstart = function () {
		return false;
	};

	this._table.onclick = function (e) {
		// find event
		if (e == null) e = document.parentWindow.event;
		
		// find td
		var el = e.target != null ? e.target : e.srcElement;
		while (el.nodeType != 1)
			el = el.parentNode;
		while (el != null && el.tagName && el.tagName.toLowerCase() != "td")
			el = el.parentNode;
		
		// if no td found, return
		if (el == null || el.tagName == null || el.tagName.toLowerCase() != "td")
			return;
		
		var d = new Date(dp._currentDate);
		var n = Number(el.firstChild.data);
		if (isNaN(n) || n <= 0 || n == null)
			return;
		
		if (el.className == "weekNumber")
			return;
			
		d.setDate(n);
		dp.setSelectedDate(d);

		if (!dp._alwaysVisible && dp._hideOnSelect) {
			dp.hide();
		}
	};

	this._calDiv.onkeydown = function (e) {
		if (e == null) e = document.parentWindow.event;
		var kc = e.keyCode != null ? e.keyCode : e.charCode;

		if(kc == 13) {
			var d = new Date(dp._currentDate).valueOf();
			dp.setSelectedDate(d);

			if (!dp._alwaysVisible && dp._hideOnSelect) {
				dp.hide();
			}
			return false;
		}

		if (kc < 37 || kc > 40) return true;

		var d = new Date(dp._currentDate).valueOf();
		if (kc == 37) // left
			d -= 24 * 60 * 60 * 1000;
		else if (kc == 39) // right
			d += 24 * 60 * 60 * 1000;
		else if (kc == 38) // up
			d -= 7 * 24 * 60 * 60 * 1000;
		else if (kc == 40) // down
			d += 7 * 24 * 60 * 60 * 1000;

		dp.setCurrentDate(new Date(d));
		return false;
	}

	// ie6 extension
	this._calDiv.onmousewheel = function (e) {
		if (e == null) e = document.parentWindow.event;
		var n = - e.wheelDelta / 120;
		var d = new Date(dp._currentDate);
		var m = d.getMonth() + n;
		d.setMonth(m);

		dp.setCurrentDate(d);

		return false;
	}

	this._monthSelect.onchange = function(e) {
	
		if (e == null) e = document.parentWindow.event;
		e = getEventObject(e);

		var tmpValue = e.value;
		
		dp.setMonth(e.value);
		
		if( dp.getMonth() != tmpValue ){
			dp.setDate(1);
			dp.setMonth(tmpValue);
		}

	}

	this._monthSelect.onclick = function(e) {
		if (e == null) e = document.parentWindow.event;
		e = getEventObject(e);
		e.cancelBubble = true;
	}

	this._yearSelect.onchange = function(e) {
		if (e == null) e = document.parentWindow.event;
		e = getEventObject(e);
		dp.setYear(e.value);
	}

	document.body.appendChild(this._calDiv);

	return this._calDiv;
}

Calendar.prototype._update = function() {

	// Calculate the number of days in the month for the selected date
	var date = this._currentDate;
	var today = toISODate(new Date());

	var selected = "";
	if (this._selectedDate != null) {
		selected = toISODate(this._selectedDate);
	}
	var current = toISODate(this._currentDate);
	var d1 = new Date(date.getFullYear(), date.getMonth(), 1);
	var d2 = new Date(date.getFullYear(), date.getMonth()+1, 1);
	var monthLength = Math.round((d2 - d1) / (24 * 60 * 60 * 1000));

	// Find out the weekDay index for the first of this month
	var firstIndex = (d1.getDay() - this._firstDayOfWeek) % 7 ;
	if (firstIndex < 0) {
		firstIndex += 7;
	}

	var index = 0;
	while (index < firstIndex) {
		this._dateSlot[index].value = -1;
		this._dateSlot[index].data.data = String.fromCharCode(160);
		this._dateSlot[index].data.parentNode.className = "";
		this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
		this._dateSlot[index].data.parentNode.style.border= "none";
		index++;
	}

// alert("d1 = "+toISODate(d1) + "\nd2 = "+toISODate(d2) +"\ntoday = "+today + "\ncurrent = "+current + "\nselected = "+selected);

	for (i = 1; i <= monthLength; i++, index++) {
		this._dateSlot[index].value = i;
		this._dateSlot[index].data.data = i;
		this._dateSlot[index].data.parentNode.className = "";
		this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
		this._dateSlot[index].data.parentNode.style.border= "none";
		if (toISODate(d1) == today) {
			this._dateSlot[index].data.parentNode.className = "today";
			this._dateSlot[index].data.parentNode.style.fontWeight = "bold";
		}
		if (toISODate(d1) == current) {
			this._dateSlot[index].data.parentNode.className += " current";
			this._dateSlot[index].data.parentNode.style.border= "1px dotted WindowText";
		}
		if (toISODate(d1) == selected) {
			this._dateSlot[index].data.parentNode.className += " selected";
			this._dateSlot[index].data.parentNode.style.border= "1px solid WindowText";
		}
		d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+1);
	}

	var lastDateIndex = index;

	while(index < 42) {
		this._dateSlot[index].value = -1;
		this._dateSlot[index].data.data = String.fromCharCode(160);
		this._dateSlot[index].data.parentNode.className = "";
		this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
		this._dateSlot[index].data.parentNode.style.border= "none";
		++index;
	}

	// Week numbers
	if (this._includeWeek) {
		d1 = new Date(date.getFullYear(), date.getMonth(), 1);
		for (i=0; i < 6; ++i) {
			if (i == 5 && lastDateIndex < 36) {
				this._weekSlot[i].data.data = String.fromCharCode(160);
				this._weekSlot[i].data.parentNode.style.borderRight = "none";
			} else {
				week = weekNumber(this, d1);
				this._weekSlot[i].data.data = week;
				this._weekSlot[i].data.parentNode.style.borderRight = "1px solid WindowText";
			}
			d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+7);
		}
	}
}

Calendar.prototype.show = function(element) {
	
	var p = getPoint(element);

	if(!this._showing) {

		var p = getPoint(element);
		
		this._calDiv.style.top = ""+(p.y + element.offsetHeight + 1) + "px";
		this._calDiv.style.left = "" + p.x +"px";
		this._calDiv.style.display = "block";
		this._showing = true;
		
		/* -------- */
		if( this._bw.ie6 )
		{
		 	dw = this._calDiv.offsetWidth;
		 	dh = this._calDiv.offsetHeight;
		 	var els = document.getElementsByTagName("body");
		 	var body = els[0];
		 	if( !body ) return;

			//paste iframe under the modal
			 var underDiv = this._calDiv.cloneNode(false); 
			 underDiv.style.zIndex="390";
			 underDiv.style.margin = "0px";
			 underDiv.style.padding = "0px";
			 underDiv.style.display = "block";
			 underDiv.style.width = dw;
			 underDiv.style.height = dh;
			 underDiv.style.border = "1px solid WindowText";
			 underDiv.innerHTML = "<iframe src=\"javascript:false\" width=\"100%\" height=\"100%\" frameborder=\"0\"></iframe>";
			 body.appendChild(underDiv);
			 this._underDiv = underDiv;
		}
		/* -------- */
		if( this._bw.ie6 || this._bw.ie5 || this._bw.ie4 || this._bw.ie ){
	    	this._calDiv.focus();
	    }
		
	}
}

Calendar.prototype.hide = function() {
	
	if(this._showing) {
		this._calDiv.style.display = "none";
		this._showing = false;
		if( this._bw.ie6 ) {
			if( this._underDiv ) this._underDiv.removeNode(true);
		}
		calendar_$RecDate_$Array = new Array(0);
	}
}

Calendar.prototype.toggle = function(element) {
	if(this._showing) {
		this.hide(); 
	} else {
		this.show(element);
	}
}


Calendar.prototype.onchange = function() {};

Calendar.prototype.setCurrentDate = function(date) {
	if (date == null) {
		return;
	}

	// if string or number create a Date object
	if (typeof date == "string" || typeof date == "number") {
		date = new Date(date);
	}

	// do not update if not really changed
	if (this._currentDate.getDate() != date.getDate() ||
		this._currentDate.getMonth() != date.getMonth() || 
		this._currentDate.getFullYear() != date.getFullYear()) {
		
		this._currentDate = new Date(date);

		this._updateHeader();
		this._update();
		
	}
}

Calendar.prototype.setSelectedDate = function(date) {
	this._selectedDate = new Date(date);
	this.setCurrentDate(this._selectedDate);
	if (typeof this.onchange == "function") {
		this.onchange();
	}
}

Calendar.prototype.clearSelectedDate = function() {
	this._selectedDate = null;
	if (typeof this.onchange == "function") {
		this.onchange();
	}
}

Calendar.prototype.getElement = function() {
	return this._calDiv;
}

Calendar.prototype.setIncludeWeek = function(v) {
	if (this._calDiv == null) {
		this._includeWeek = v;
	}
}

Calendar.prototype.getSelectedDate = function () {
	if (this._selectedDate == null) {
		return null;
	} else {
		return new Date(this._selectedDate);
	}
}

Calendar.prototype._updateHeader = function () {

	// 
	var options = this._monthSelect.options;
	var m = this._currentDate.getMonth();
	for(var i=0; i < options.length; ++i) {
		options[i].selected = false;
		if (options[i].value == m) {
			options[i].selected = true;
		}
	}

	options = this._yearSelect.options;
	var year = this._currentDate.getFullYear();
	for(var i=0; i < options.length; ++i) {
		options[i].selected = false;
		if (options[i].value == year) {
			options[i].selected = true;
		}
	}
	
}

Calendar.prototype.setYear = function(year) {
	var d = new Date(this._currentDate);
	d.setFullYear(year);
	this.setCurrentDate(d);
}

Calendar.prototype.setMonth = function (month) {
	var d = new Date(this._currentDate);
	d.setMonth(month);
	this.setCurrentDate(d);
}

Calendar.prototype.setDate = function (date) {
	var d = new Date(this._currentDate);
	d.setDate(date);
	this.setCurrentDate(d);
}

Calendar.prototype.getYear = function() {
	return this._currentDate.getYear();
}

Calendar.prototype.getMonth = function() {
	return this._currentDate.getMonth();
}

Calendar.prototype.getDate = function() {
	return this._currentDate.getDate();
}

Calendar.prototype.nextMonth = function () {
	this.setMonth(this._currentDate.getMonth()+1);
}

Calendar.prototype.prevMonth = function () {
	this.setMonth(this._currentDate.getMonth()-1);
}

Calendar.prototype.setFirstDayOfWeek = function (nFirstWeekDay) {
	this._firstDayOfWeek = nFirstWeekDay;
}

Calendar.prototype.getFirstDayOfWeek = function () {
	return this._firstDayOfWeek;
}

Calendar.prototype.setMinimalDaysInFirstWeek = function(n) {
	this._minimalDaysInFirstWeek = n;
}

Calendar.prototype.getMinimalDaysInFirstWeek = function () {
	return this._minimalDaysInFirstWeek;
}

Calendar.prototype.setMonthNames = function(a) {
	// sanity test
	this._monthNames = a;
}

Calendar.prototype.setShortMonthNames = function(a) {
	// sanity test
	this._shortMonthNames = a;
}

Calendar.prototype.setWeekDayNames = function(a) {
	// sanity test
	this._weekDayNames = a;
}

Calendar.prototype.setShortWeekDayNames = function(a) {
	// sanity test
	this._shortWeekDayNames = a;
}

Calendar.prototype.getFormat = function() {
	return this._format;
}
	
Calendar.prototype.setFormat = function(f) {
	this._format = f;
}

Calendar.prototype.formatDate = function() {  
	if (this._selectedDate == null) {
		return "";
	}

	var bits = new Array();
	// work out what each bit should be
	var date = this._selectedDate;
	bits['d'] = date.getDate();
	bits['dd'] = pad(date.getDate(),2);
	bits['ddd'] = this._shortWeekDayNames[date.getDay()];
	bits['dddd'] = this._weekDayNames[date.getDay()];

	bits['M'] = date.getMonth()+1;
	bits['MM'] = pad(date.getMonth()+1,2);
	bits['MMM'] = this._shortMonthNames[date.getMonth()];
	bits['MMMM'] = this._monthNames[date.getMonth()];
	
	var yearStr = "" + date.getFullYear();
	yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
	bits['yyyy'] = yearStr;
	bits['yy'] = bits['yyyy'].toString().substr(2,2);

	// do some funky regexs to replace the format string
	// with the real values
	var frm = new String(this._format);
	var sect;
	for (sect in bits) {
	  frm = eval("frm.replace(/\\b" + sect + "\\b/,'" + bits[sect] + "');");
	}

	return frm;
}

function isLeapYear(year) {
	return ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
}

function yearLength(year) {
	if (isLeapYear(year))
		return 366;
	else
		return 365;
}

function dayOfYear(date) {
	var a = Calendar.NUM_DAYS;
	if (isLeapYear(date.getFullYear())) {
		a = Calendar.LEAP_NUM_DAYS;
	}
	var month = date.getMonth();
	
	return a[month] + date.getDate();
}

// ---------------------------------------------
// Week number stuff
// ---------------------------------------------

function weekNumber(cal, date) {

	var dow = date.getDay();
	var doy = dayOfYear(date);
	var year = date.getFullYear();

	// Compute the week of the year.  Valid week numbers run from 1 to 52
	// or 53, depending on the year, the first day of the week, and the
	// minimal days in the first week.  Days at the start of the year may
	// fall into the last week of the previous year; days at the end of
	// the year may fall into the first week of the next year.
	var relDow = (dow + 7 - cal.getFirstDayOfWeek()) % 7; // 0..6
	var relDowJan1 = (dow - doy + 701 - cal.getFirstDayOfWeek()) % 7; // 0..6
	var week = Math.floor((doy - 1 + relDowJan1) / 7); // 0..53
	if ((7 - relDowJan1) >= cal.getMinimalDaysInFirstWeek()) {
		++week;
	}

	if (doy > 359) { // Fast check which eliminates most cases
		// Check to see if we are in the last week; if so, we need
		// to handle the case in which we are the first week of the
		// next year.
		var lastDoy = yearLength(year);
		var lastRelDow = (relDow + lastDoy - doy) % 7;
		if (lastRelDow < 0) {
			lastRelDow += 7;
		}
		if (((6 - lastRelDow) >= cal.getMinimalDaysInFirstWeek())
			&& ((doy + 7 - relDow) > lastDoy)) {
			week = 1;
		}
	} else if (week == 0) {
		// We are the last week of the previous year.
		var prevDoy = doy + yearLength(year - 1);
		week = weekOfPeriod(cal, prevDoy, dow);
	}

	return week;
}

function weekOfPeriod(cal, dayOfPeriod, dayOfWeek) {
	// Determine the day of the week of the first day of the period
	// in question (either a year or a month).  Zero represents the
	// first day of the week on this calendar.
	var periodStartDayOfWeek =
		(dayOfWeek - cal.getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
	if (periodStartDayOfWeek < 0) {
		periodStartDayOfWeek += 7;
	}

	// Compute the week number.  Initially, ignore the first week, which
	// may be fractional (or may not be).  We add periodStartDayOfWeek in
	// order to fill out the first week, if it is fractional.
	var weekNo = Math.floor((dayOfPeriod + periodStartDayOfWeek - 1) / 7);

	// If the first week is long enough, then count it.  If
	// the minimal days in the first week is one, or if the period start
	// is zero, we always increment weekNo.
	if ((7 - periodStartDayOfWeek) >= cal.getMinimalDaysInFirstWeek()) {
		++weekNo;
	}

	return weekNo;
}

function getEventObject(e) {  // utility function to retrieve object from event
	if (navigator.appName == "Microsoft Internet Explorer") {
		return e.srcElement;
	} else {  // is mozilla/netscape
		// need to crawl up the tree to get the first "real" element
		// i.e. a tag, not raw text
		var o = e.target;
		while (!o.tagName) {
			o = o.parentNode;
		}
		return o;
	}
}

function addEvent(name, obj, funct) { // utility function to add event handlers

	if (navigator.appName == "Microsoft Internet Explorer") {
		obj.attachEvent("on"+name, funct);
	} else {  // is mozilla/netscape
		obj.addEventListener(name, funct, false);
	}
}

function deleteEvent(name, obj, funct) { // utility function to delete event handlers

	if (navigator.appName == "Microsoft Internet Explorer") {
		obj.detachEvent("on"+name, funct);
	} else {  // is mozilla/netscape
		obj.removeEventListener(name, funct, false);
	}
}

function setCursor(obj) {
   if (navigator.appName == "Microsoft Internet Explorer") {
		obj.style.cursor = "hand";
	} else {  // is mozilla/netscape
		obj.style.cursor = "pointer";
	}
}

function Point(iX, iY)
{
   this.x = iX;
   this.y = iY;
}

function getPoint(aTag)
{
	var oTmp = aTag;
	var point = new Point(0,0);

	do 
	{
		point.x += oTmp.offsetLeft;
		point.y += oTmp.offsetTop;
		oTmp = oTmp.offsetParent;
	}
	while (oTmp.tagName != "BODY");

	return point;
}

function toISODate(date) {
	var s = date.getFullYear();
	var m = date.getMonth() + 1;
	if (m < 10) {
		m = "0" + m;
	}
	var day = date.getDate();
	if (day < 10) {
		day = "0" + day;
	}
	return String(s) + String(m) + String(day);

}

function pad(number,X) {   // utility function to pad a number to a given width
	X = (!X ? 2 : X);
	number = ""+number;
	while (number.length < X) {
		number = "0" + number;
	}
	return number;
}

function bw_check()
{
	var is_major = parseInt( navigator.appVersion );
	this.nver = is_major;
	this.ver = navigator.appVersion;
	this.agent = navigator.userAgent;
	this.dom = document.getElementById ? 1 : 0;
	this.opera = window.opera ? 1 : 0;
	this.ie5 = ( this.ver.indexOf( "MSIE 5" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
	this.ie6 = ( this.ver.indexOf( "MSIE 6" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
	this.ie4 = ( document.all && !this.dom && !this.opera ) ? 1 : 0;
	this.ie = this.ie4 || this.ie5 || this.ie6;
	this.mac = this.agent.indexOf( "Mac" ) > -1;
	this.ns6 = ( this.dom && parseInt( this.ver ) >= 5 ) ? 1 : 0;
	this.ie3 = ( this.ver.indexOf( "MSIE" ) && ( is_major < 4 ) );
	this.hotjava = ( this.agent.toLowerCase().indexOf( 'hotjava' ) != -1 ) ? 1 : 0;
	this.ns4 = ( document.layers && !this.dom && !this.hotjava ) ? 1 : 0;
	this.bw = ( this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera );
	this.ver3 = ( this.hotjava || this.ie3 );
	this.opera7 = ( ( this.agent.toLowerCase().indexOf( 'opera 7' ) > -1 ) || ( this.agent.toLowerCase().indexOf( 'opera/7' ) > -1 ) );
	this.operaOld = this.opera && !this.opera7;
	return this;
};


