//Copyright (C) 2007 poet All Rights Reserved.
//Blog    : ぽえっとの葉っぱたち : http://poetleaf.seesaa.net/
//Create  : 2007/01/15(Mon)
//Update  : 2009/06/01(Mon)
//Version : 1.3.12

strBuff = "";

//  ****  URLパラメータ  ****
urlParams = new Array(0);
/**
 * パラメータを初期化する。
 * 
 * URLSearchパラメータを簡単に利用できるようにデコード、分割する。
 * 利用する場合は、getParam(key) にて使用する。
 */
function initURLParam() {
	s = location.search;
	if (s == "") {
		loadCookie(false);
		return;
	}
	s = unescape(s.substring(1));
	urlParams = s.split("&");
//alert("urlParams = " + urlParams);
}

/**
 * パラメータを取得する。
 * 
 * @param key       パラメータのキー。
 * @return          キーに対応した値。キーが存在しない場合は "" が返る。
 */
function getURLParamValue(key) {
	if (urlParams == null) {
		return "";
	}
	l = key.length;
	for (m = 0; m < urlParams.length; m++) {
		s = urlParams[m];
		if (s.substring(0, l) == key) {
			return s.substring(l + 1);
		}
	}
	return "";
}


/**
 * 初期化処理。
 * 
 * @param flag     強制初期化フラグ true / false
 */
function initCal(flag) {
//alert("initCal(" + flag + ")");

	//  自動保存(autosave)
	//  条件を自動的に保存
	str = getURLParamValue("autosave");
	if (flag || str == "") {
		autoSave = AUTO_SAVE_OFF;
	} else {
		num = Number(str);
		if (num == AUTO_SAVE_OFF || num == AUTO_SAVE_ON) {
			autoSave = num;
		} else {
			autoSave = AUTO_SAVE_OFF;
		}
	}
	//  年月日(date)
	//  ない場合はシステム年月日
	str = getURLParamValue("date");
	if (flag || str == "") {
		nowdate = new Date();
		if (nowdate.getYear() < 2000) { 
			selectY = String(nowdate.getYear() + 1900);
		} else {
			selectY = String(nowdate.getYear());
		}
		if (nowdate.getMonth() + 1 < 10) {
			selectM = "0" + (nowdate.getMonth() + 1);
		} else {
			selectM = String(nowdate.getMonth() + 1);
		}
		if (nowdate.getMonth() < 10) {
			selectD = "0" + nowdate.getDate();
		} else {
			selectD = String(nowdate.getDate());
		}
	} else {
		strs = str.split("/");
		selectY = strs[0];
		selectM = strs[1];
		selectD = strs[2];
	}
	//  表示年月(disp)
	//  ない場合は年月日の年月
	str = getURLParamValue("disp");
	if (flag || str == "") {
		dispY = selectY;
		dispM = selectM;
	} else {
		strs = str.split("/");
		dispY = strs[0];
		dispM = strs[1];
	}

	//  イベント(event)
	//  ない場合は全て（EVENT_ALL）
	str = getURLParamValue("event");
	if (flag || str == "") {
		dispEvent = EVENT_ALL;
	} else {
		num = Number(str);
		if (num < 0 || event_name.length - 1 < num) {
			dispEvent = EVENT_ALL;
		} else {
			dispEvent = num;
		}
	}

	//  サーバ(server)
	//  ない場合は全て（SERVER_A_SEV）
	str = getURLParamValue("server");
	if (flag || str == "") {
		dispServer = SERVER_A_SEV;
	} else {
		num = Number(str);
		if (num < 0 || server_name.length - 1 < num) {
			dispServer = SERVER_A_SEV;
		} else {
			dispServer = num;
		}
	}

	//  表示種類(kind)
	//  ない場合は0:方眼式（６週間＊７日）（KIND_6_7）
	str = getURLParamValue("kind");
	if (flag || str == "") {
		dispKind = KIND_6_7;
	} else {
		num = Number(str);
		//  KIND_6_7   = 0; //  0:方眼式（６週間＊７日）
		//  KIND_31    = 1; //  1:縦１列（３１日）
		if (num < 0 || kind_list.length - 1 < num) {
			dispKind = KIND_6_7;
		} else {
			dispKind = num;
		}
	}

	//  ソート順(sort)
	//  ない場合は0:日時順　　（日時順→サーバ順→イベント順）（SORT_DATE）
	str = getURLParamValue("sort");
	if (flag || str == "") {
		dispSort = SORT_DATE;
	} else {
		num = Number(str);
		//  SORT_DATE   = 0;//  0:日時順（日時順→サーバ順→イベント順）
		//  SORT_SARVER = 1;//  1:サーバ順（サーバ順→日時順→イベント順）
		//  SORT_EVENT  = 2;//  2:イベント順（イベント順→日時順→サーバ順）
		//  SORT_UPDATE = 3;//  3:更新順（更新順→日時順→サーバ順→イベント順）
		if (num < 0 || sort_list.length - 1 < num) {
			dispSort = SORT_DATE;
		} else {
			dispSort = num;
		}
	}

	//  カスタム(custom)
	//  ない場合は0:標準（CUSTOM_OFF）
	str = getURLParamValue("custom");
	if (flag || str == "") {
		custom = CUSTOM_OFF;
	} else {
		num = Number(str);
		//  CUSTOM_OFF = 0; //  0:カスタムOFF
		//  CUSTOM_ON  = 1; //  1:カスタムON
		if (num == 0 || num == 1) {
			custom = num;
		} else {
			custom = CUSTOM_OFF;
		}
	}

	//  表示期間(range)
	//  ない場合は1ヶ月
	str = getURLParamValue("range");
	if (flag || str == "") {
		dispRange = 1;
	} else {
		num = Number(str);
		if (num < 0) {
			dispRange = 1;
		} else if (DISP_RANGE_MAX < num) {
			dispRange = DISP_RANGE_MAX;
		} else {
			dispRange = num;
		}
	}

/*	//  使用しない
	//  表示開始(start)
	//  ない場合は、-1
	//  適用条件：表示期間 - abs(表示開始) > 0
	str = getURLParamValue("start");
	if (str == "") {
		dispStart = 0;
	} else {
		num = Number(str);
		if (num < 0 && dispRange > Math.abs(num)) {
			dispStart = num;
		} else {
			dispStart = 0;
		}
	}
*/

	//  曜日表示種類(wkind)
	//  ない場合は3:英語３字（"Sun", "Mon",...）（cal_week_kind）
	str = getURLParamValue("wkind");
	if (flag || str == "") {
		dispWKind = cal_week_kind;
	} else {
		num = Number(str);
		//  CAL_WEEK_TYPE_1 = 1;	//  1:漢字１字（"日", "月",...）
		//  CAL_WEEK_TYPE_2 = 2;	//  2:漢字３字（"日曜日", "月曜日",...）
		//  CAL_WEEK_TYPE_3 = 3;	//  3:英語３字（"Sun", "Mon",...）
		//  CAL_WEEK_TYPE_4 = 4;	//  4:英語（"Sunday", "Monday",...）
		if (num < 1 || week_kind_list.length < num) {
			dispWKind = cal_week_kind;
		} else {
			dispWKind = num;
		}
	}

	//  開始曜日(wbegin)
	//  ない場合は1:月曜日始まり（cal_week_begin=CAL_WEEK_BEGIN_MON）
	str = getURLParamValue("wbegin");
	if (flag || str == "") {
		dispWBegin = cal_week_begin;
	} else {
		num = Number(str);
		//  CAL_WEEK_BEGIN_SUN = 0;	//  0:日曜日始まり
		//  CAL_WEEK_BEGIN_MON = 1; //  1:月曜日始まり
		if (num < 0 || week_begin_list.length - 1 < num) {
			dispWBegin = cal_week_begin;
		} else {
			dispWBegin = num;
		}
	}

}

/**
 * 親フレームの存在確認
 * 
 */
function aliveParent() {

	//  ☆☆☆カスタマイズ☆☆☆
	if (!!window.parent) {
		if (window.parent.name == "calendarparent") {
			return true;
		}
	}
	return false;
}


//  ****  カレンダーの生成  ****
/**
 * カレンダーを生成する。
 * 
 * @param pYear     表示年
 * @param pMonth    表示月
 * @param pRange    表示範囲（ヶ月）
 * @param pEvent    表示イベント
 * @param pServer   表示サーバ
 * @param pKind     表示形式
 * @param pSort     ソート順
 */
function createCal(pYear, pMonth, pRange, pEvent, pServer, pKind, pSort) {
/*
alert("pYear = " + pYear + ", pMonth = " + pMonth + ", pRange = " + pRange + 
		", pEvent = " + pEvent + ", pServer = " + pServer + 
		", pKind = " + pKind + ", pSort = " + pSort);
*/
	nowdate = new Date();
	pYear = delZero(pYear) ;
	pMonth = delZero(pMonth);

	strBuff = "";
	strBuff += "<table border='0' cellspacing='0' cellpadding='0'>\n";

	for (k = 0; k < pRange; k++) {
		strBuff += "  <tr valign='top'>\n";
		strBuff += "    <td>\n";
		maxDay = getMaxDayOfMonth(pYear, pMonth);
		nowdate.setDate(1);
		nowdate.setYear(pYear);
		nowdate.setMonth(pMonth - 1);
		pWDay = nowdate.getDay();

		//alert(pWDay);
		if (pKind == KIND_6_7) {
			createCalMonth(pYear, pMonth, maxDay, pWDay, 
					pEvent, pServer, pSort);
		} else if (pKind == KIND_31) {
			createCalMonth2(pYear, pMonth, maxDay, pWDay, 
					pEvent, pServer, pSort);
		} else {
			createCalMonth(pYear, pMonth, maxDay, pWDay, 
					pEvent, pServer, pSort);
		}

		strBuff += "    </td>\n";
		strBuff += "  </tr>\n";
		pMonth++;
		if (pMonth > 12) {
			pMonth = pMonth - 12;
			pYear++;
		}
	}

	strBuff += "</table>\n";
	return strBuff;
}

/**
 * 月の最大日を取得する。
 * 
 * @param pYear     年
 * @param pMonth    月
 * @return          指定年月の最大日
 */
function getMaxDayOfMonth(pYear, pMonth) {

	switch (pMonth) {
		case 1:
			maxDay = 31;
			break;
		case 2:
			if (((pYear % 4 == 0) && (pYear % 100 != 0)) || 
					(pYear % 400 == 0)) {
				maxDay = 29;
			} else {
				maxDay = 28;
			}
			break;
		case 3:
			maxDay = 31;
			break;
		case 4:
			maxDay = 30;
			break;
		case 5:
			maxDay = 31;
			break;
		case 6:
			maxDay = 30;
			break;
		case 7:
			maxDay = 31;
			break;
		case 8:
			maxDay = 31;
			break;
		case 9:
			maxDay = 30;
			break;
		case 10:
			maxDay = 31;
			break;
		case 11:
			maxDay = 30;
			break;
		case 12:
			maxDay = 31;
			break;
	}
	return maxDay;
}

/**
 * ひと月のカレンダーを生成する。
 * 
 * @parma pYear     年
 * @param pMonth    月
 * @param maxDay    指定年月の最大日
 * @param pWDay     指定年月の最初の曜日
 * @param pEvent    表示イベント
 * @param pServer   表示サーバ
 * @param pSort     ソート順
 */
function createCalMonth(pYear, pMonth, maxDay, pWDay, pEvent, pServer, pSort) {
	pDate = 1;
	strBuff += "<table border='1' cellspacing='1' cellpadding='2'>\n";

	// ６＊７方眼カレンダー
	// ヘッダ（操作と年月）
	strBuff += "  <tr>\n";
	strBuff += "    <td colspan=7 align=center>\n";
	strBuff += 
		"<table border='0' cellpadding='0' cellspacing='0'>\n" + 
		"  <tr align='center' width='100%'>\n" + 
		"    <th align='left' width='20'>\n" + 
		"      <a href=Javascript:moveCal('prevY') title=昨年へ>" + 
		"&lt;&lt;</a>&nbsp;&nbsp;" + 
		"<a href=Javascript:moveCal('prevM') title=昨月へ>&lt;</a>\n" + 
		"    </th>\n" + 
		"    <th align='center' width='100%'>\n" + 
		"      <a href=Javascript:moveCal('today') " + 
		"title=クリックで当月へジャンプ>" + 
		pYear + "/" + addZero(pMonth) + "</a>\n" + 
		"    </th>\n" + 
		"    <th align='right' width='20'>\n" + 
		"      <a href=Javascript:moveCal('nextM') title=翌月へ>" + 
		"&gt;</a>&nbsp;&nbsp;" + 
		"<a href=Javascript:moveCal('nextY') title=翌年へ>&gt;&gt;</a>\n" + 
		"    </th>\n" + 
		"  </tr>\n" + 
		"</table>\n";
	strBuff += "    </td>\n";
	strBuff += "  </tr>\n";

	// ヘッダ（曜日）
	strBuff += "  <tr align='center'>\n";
	for (i = 0; i < CAL_WEEK_LENGTH; i++) {
		ii = i;
		if (dispWBegin == CAL_WEEK_BEGIN_MON) {
			ii = exchageBeginMonday(ii);
		}
		c = cal_week[ii][CAL_WEEK_COLOR];
		strBuff += 
			"    <th width='100' height='14' bgcolor='" + 
			cal_color[c][CAL_HEAD_BACK] + "'>\n" + 
			"      <font color='" + cal_color[c][CAL_HEAD_TEXT] + "'>" + 
			cal_week[ii][dispWKind] + "</font>\n" + 
			"    </th>\n";
	}
	strBuff += "  </tr>\n";

	// 日にち
	flg = 0;
	furi_flg = -1;
	// pWDay=その月の開始曜日は0が日曜日の為、
	// -1（月曜日を0とする）+7 % 7（マイナスをプラスにて７の剰余を求める）
//alert("pWDay = " + pWDay + ", maxDay = " + maxDay);
	if (dispWBegin == CAL_WEEK_BEGIN_MON) {
		pWDay = (pWDay - 1 + 7) % 7;
	}
	tWDay = pWDay;

	// 当日表示用
	nowdate = new Date();
	if (nowdate.getYear() < 2000) { 
		nowY = nowdate.getYear() + 1900;
	} else {
		nowY = nowdate.getYear();
	}
	nowM = nowdate.getMonth() + 1;
	nowD = nowdate.getDate();

	//  当月のイベントを取得
	tEvListM = getSchedule(pYear, pMonth, "", 
			pEvent, pServer, "");

	while (pDate <= maxDay) {
		strBuff += "  <tr align='center'>\n";
		for (i = 0; i < 7; i++) {
			// 当月外表示
			if (tWDay > 0 || pDate > maxDay) {
				strBuff += "    <td width='100' height='74' " + 
					"align='left' valign='top' bgcolor='" + 
					cal_color[CAL_OUT][CAL_BACK] + 
					"'>&nbsp;<br></td>\n";
				tWDay--;
			//  当月表示
			} else {
				ii = i;
				if (dispWBegin == CAL_WEEK_BEGIN_MON) {
					ii = exchageBeginMonday(ii);
				}
				//  祝日の場合その番号を取得、-1は平日
				holNum = isHoliday(pYear, pMonth, pDate);
				strHol = "";
				if (holNum != -1) {
					strHol = getHolidayName(holNum);
					if (ii == 0) {
						furi_flg = holNum;
					}
				} else if (furi_flg != -1) {
					strHol = "振替休日";
					holNum = furi_flg;
					furi_flg = -1;
				}
				if (strHol != "") {
					strHol = "&nbsp;" + strHol;
				}

				//  色の取得
				cText = "";
				cBack = "";
				c = cal_week[ii][CAL_WEEK_COLOR];
				if ((holNum != -1) || (furi_flg != -1)) {
					cText = cal_color[CAL_HOL][CAL_TEXT];
					cBack = cal_color[CAL_HOL][CAL_BACK];
				} else {
					cText = cal_color[c][CAL_TEXT];
					cBack = cal_color[c][CAL_BACK];
				}

				//  日にち祝日文字列
				if (pYear == nowY && pMonth == nowM && pDate == nowD) {
					strDateHol = 
							"<font color='" + cBack + "'><b>" + 
							"<span style='background-color: " + 
							cText + 
							"'>" + pDate + 

							"</b>" + strHol + "</span></font><br>\n";
				} else {
					strDateHol = 
							"<font color='" + cText + "'><b>" + 
							pDate + "</b>" + strHol + "</font><br>\n";
				}
/*
alert("★1:pYear = " + pYear + ", pMonth = " + pMonth + ", pDate = " + pDate + 
		", pEvent = " + pEvent + ", pServer = " + pServer + 
		", pUpdate = ");
*/
				tEvList = extractSchedule(tEvListM, pYear, pMonth, pDate, 
						"", "", "");
				//  ソート
				sortSchedule(tEvList, pSort);

				strSch = "";
				if (tEvList != null && tEvList.length > 0) {
//alert("tEvList.length = " + tEvList.length);

					for (j = 0; j < tEvList.length; j++) {
						tEvent = tEvList[j];

						//  色、イベント、サーバの取得
						strEvCode = tEvent[SCH_COL_EVENT_CODE];
						evNum = getEventNum(strEvCode, EVENT_COL_CODE)
						strEvNS = event_name[evNum][EVENT_COL_NAME_S];
						cEvText = event_text;
						cEv = event_color[evNum];
						strEv = "      <span style='color: " + cEvText + "; " + 
								"background-color: " + cEv + "'>" + 
								strEvNS + "</span>";

						svNum = getServerNum(
								tEvent[SCH_COL_SERVER], SERVER_COL_NAME);
//alert("469 j = " + j + ", svNum = " + svNum);
						//  サーバ名略称取得
						strSvNS = server_name[svNum][SERVER_COL_NAME_S];
						cSvText = server_text;
						cSv = server_color[svNum];

						//  チャンネル直後のスペース（チャンネル２桁対応）
						strChSpace = " ";
						if (tEvent[SCH_COL_CH].length == 2) {
							strChSpace = "";
						}

						//  文字列生成
						strSch = strSch + 
						"      <a href='#" + getMarker(tEvent) + "' title='" + 
						createToolTip(tEvent, strHol) + "'>\n" + 
						tEvent[SCH_COL_BEGIN_TIME] + 
						" <span style='color: " + cSvText + "; " + 
						"background-color: " + cSv + "'>" + 
						strSvNS + "</span>" + 
						tEvent[SCH_COL_CH] + strChSpace + 
						tEvent[SCH_COL_PLACE_S] + "<br>\n" + 
						strEv + tEvent[SCH_COL_TITLE_S] + "</a>";
						if (j < tEvList.length - 1) {
							strSch = strSch + "<br>\n";
						}
					}
//alert("strSch = \n" + strSch);

				}
				strBuff += 
					"    <td width='100' height='71' " + 
					"align='left' valign='top' bgcolor='" + cBack + "'>" + 
					strDateHol + strSch + "</td>\n";

				pDate++;
			}
		}
		strBuff += "  </tr>\n";
	}

	strBuff += "</table>\n";
}

/**
 * ひと月のカレンダー（縦１列）を生成する。
 * 
 * @parma pYear     年
 * @param pMonth    月
 * @param maxDay    指定年月の最大日
 * @param pWDay     指定年月の最初の曜日
 * @param pEvent    表示イベント
 * @param pServer   表示サーバ
 * @param pSort     ソート順
 */
function createCalMonth2(pYear, pMonth, maxDay, pWDay, pEvent, pServer, pSort) {
	pDate = 1;
	strBuff += "<table border='1' cellspacing='1' cellpadding='2'>\n";

	// ３１縦１列カレンダー
	// ヘッダ（操作と年月）
	strBuff += "  <tr>\n";
	strBuff += "    <td colspan='7' align=center>\n";
	strBuff +=  
		"<table border='0' cellpadding='0' cellspacing='0'>\n" + 
		"  <tr align='center' width='100%'>\n" + 
		"    <th align='left' width='20'>\n" + 
		"      <a href=Javascript:moveCal('prevY') title=昨年へ>" + 
		"&lt;&lt;</a>&nbsp;&nbsp;" + 
		"<a href=Javascript:moveCal('prevM') title=昨月へ>&lt;</a>\n" + 
		"    </th>\n" + 
		"    <th align='center' width='100%'>\n" + 
		"      <a href=Javascript:moveCal('today') " + 
		"title=クリックで当月へジャンプ>" + 
		pYear + "/" + addZero(pMonth) + "</a>\n" + 
		"    </th>\n" + 
		"    <th align='right' width='20'>\n" + 
		"      <a href=Javascript:moveCal('nextM') title=翌月へ>" + 
		"&gt;</a>&nbsp;&nbsp;" + 
		"<a href=Javascript:moveCal('nextY') title=翌年へ>&gt;&gt;</a>\n" + 
		"    </th>\n" + 
		"  </tr>\n" + 
		"</table>\n";
	strBuff += "    </td>\n";
	strBuff += "  </tr>\n";

	// ヘッダ（曜日）
	cText = cal_color[CAL_MTH][CAL_HEAD_TEXT];
	cBack = cal_color[CAL_MTH][CAL_HEAD_BACK];

	strBuff += "  <tr>\n";
	strBuff += "    <th width='60' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>日にち</font></th>\n";
	strBuff += "    <th width='70' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>時間</font></th>\n";
	strBuff += "    <th width='84' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>サーバ</font></th>\n";
	strBuff += "    <th width='300' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>内容</font></th>\n";
	strBuff += "    <th width='200' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>場所</font></th>\n";
	strBuff += "  </tr>\n";

	// メイン
	tWDay = pWDay;
	furi_flg = -1;
	tSameDate = 0;

	// 当日表示用
	nowdate = new Date();
	if (nowdate.getYear() < 2000) { 
		nowY = nowdate.getYear() + 1900;
	} else {
		nowY = nowdate.getYear();
	}
	nowM = nowdate.getMonth() + 1;
	nowD = nowdate.getDate();

	//  当月のイベントを取得
	tEvListM = getSchedule(pYear, pMonth, "", pEvent, pServer, "");

	while (pDate <= maxDay) {

		//  祝日区分
		//  祝日の場合その番号を取得、-1は平日
		holNum = isHoliday(pYear, pMonth, pDate);
		strHol = "";
		if (holNum != -1) {
			strHol = getHolidayName(holNum);
			if (tWDay == 0) {
				furi_flg = holNum;
			}
		} else if (furi_flg != -1) {
			strHol = "振替休日";
			holNum = furi_flg;
			furi_flg = -1;
		}

		//  スケジュールの取得
		tEvList = extractSchedule(tEvListM, pYear, pMonth, pDate, "", "", "");

		// 同一日開催件数取得
		rowSpan = 1;
		if (tEvList != null && tEvList.length > 0) {
//alert("tEvList.length = " + tEvList.length);
			//  ソート
			sortSchedule(tEvList, pSort);
			tSameDate =  tEvList.length;
			rowSpan = tSameDate;
			if (strHol != "") {
				rowSpan = rowSpan + 1;
			}
		} else {
			tSameDate = 1;
			rowSpan = tSameDate;
		}

		//  色の取得
		cText = "";
		cBack = "";
		c = cal_week[tWDay][CAL_WEEK_COLOR];
		if ((holNum != -1) || (furi_flg != -1)) {
			cText = cal_color[CAL_HOL][CAL_TEXT];
			cBack = cal_color[CAL_HOL][CAL_BACK];
		} else {
			cText = cal_color[c][CAL_TEXT];
			cBack = cal_color[c][CAL_BACK];
		}

		for (i = 0; i < tSameDate; i++) {

			strBuff += "  <tr>\n";

			//  日にち
			if (pYear == nowY && pMonth == nowM && pDate == nowD) {
				strDate = 
						"<span style='color: " + cBack + 
						"; background-color: " + cText + 
						"'>" + addZero(pMonth) + "/" + addZero(pDate) + 
						"(" + cal_week[tWDay][dispWKind] + ")</span>";
			} else {
				strDate = addZero(pMonth) + "/" + addZero(pDate) + 
						"(" + cal_week[tWDay][dispWKind] + ")";
			}

			if (rowSpan > 1 && i == 0) {
				strBuff += "    <td width='60' bgcolor='" + cBack + "' " + 
						"rowspan='" + rowSpan + "'>" + 
						"<font color='" + cText + "'>" + strDate + 
						"</font></td>\n";
			} else if (rowSpan > 1) {
				strBuff += "    \n";
			} else {
				strBuff += "    <td width='60' bgcolor='" + cBack + "'>" + 
						"<font color='" + cText + "'>" + strDate + 
						"</font></td>\n";
			}

			//  予定なし、祝日、振替休日の場合
			if (i == 0 && 
					(tEvList == null || tEvList.length == 0 || strHol != "")) {
				strBuff += "    <td width='70' bgcolor='" + cBack + "'>" + 
						"&nbsp;</td>\n";
				strBuff += "    <td width='84' bgcolor='" + cBack + "'>" + 
						"&nbsp;</td>\n";

				strContents = "";
				if (strHol != "") {
					strContents = "      <font color='" + cText + "'>" + 
						strHol + "</font>";
				} else {
					strContents = "&nbsp;"
				}
				strBuff += "    <td width='300' bgcolor='" + 
						cBack + "'>\n" + strContents + "</td>\n";
				strBuff += "    <td width='200' bgcolor='" + cBack + "'>" + 
						"&nbsp;</td>\n";
				strBuff += "  </tr>\n";
				if (tEvList == null || tEvList.length == 0) {
					break;
				}

				strBuff += "  <tr>\n";
			}

			tEvent = tEvList[i];

//alert("pDate = " + pDate + ", tEvList = " + tEvList);
			//  色、イベント、サーバの取得
			strEvCode = tEvent[SCH_COL_EVENT_CODE];
			evNum = getEventNum(strEvCode, EVENT_COL_CODE)
			strEvName = event_name[evNum][EVENT_COL_NAME];
			cEvText = event_text;
			cEv = event_color[evNum];
			strEv = "      <span style='color: " + cEvText + "; " + 
					"background-color: " + cEv + "'>" + 
					strEvName + "</span>";

			strSvName = tEvent[SCH_COL_SERVER];
			svNum = getServerNum(
					strSvName, SERVER_COL_NAME);
			cSvText = server_text;
			cSv = server_color[svNum];
			strSv = "      <span style='color: " + cSvText + "; " + 
					"background-color: " + cSv + "'>" + 
					strSvName + "</span>";

//alert("pDate = " + pDate + ", tEvList = " + tEvList);
			strTime = tEvent[SCH_COL_BEGIN_TIME] + "〜" + 
					tEvent[SCH_COL_END_TIME];
			strBuff += "    <td width='70' bgcolor='" + cBack + "'>" + 
					strTime + "</td>\n";

			strBuff += "    <td width='84' bgcolor='" + cBack + "'>\n" + 
					strSv + "&nbsp;" + 
					tEvent[SCH_COL_CH] + "ch</td>\n";

			//  文字列生成
			strContents = 
				"      <a href='#" + getMarker(tEvent) + "'>\n" + 
				strEv + "　" + 
				tEvent[SCH_COL_TITLE] + "</a>";

			strBuff += "    <td width='300' bgcolor='" + cBack + "'>\n" + 
					strContents + "</td>\n";

			strBuff += "    <td width='200' bgcolor='" + cBack + "'>" + 
					tEvent[SCH_COL_PLACE] + "</td>\n";

			strBuff += "  </tr>\n";
		}

		pDate++;
		tWDay = (++tWDay) % 7;

	}

	strBuff += "</table>\n";

}

/**
 * 日曜日スタート時の曜日から月曜日スタート時の曜日に変換する。
 *
 * @param pWDay     曜日の数字0（日曜日）〜6（土曜日）
 * @return          曜日の数字0（月曜日）〜6（日曜日）
 */
function exchageBeginMonday(pWDay) {
	return ((pWDay + 1) % 7);
}

/**
 * イベント番号を取得する。
 * 
 * @param pEvStr    イベント文字列
 * @param pEvNCol   イベントカラム定数
 * @return          イベント番号
 */
function getEventNum(pEvStr, pEvNCol) {
	for (l = 0; l <event_name.length; l++) {
		tEvStr = event_name[l][pEvNCol];
		if (tEvStr == pEvStr) {
			return l;
		}
	}
}

/**
 * サーバ番号を取得する。
 * 
 * @param pSvStr    サーバ文字列
 * @param pSvNCol   サーバカラム定数
 * @return          サーバ番号
 */
function getServerNum(pSvStr, pSvNCol) {
	for (l = 0; l <server_name.length; l++) {
		tSvStr = server_name[l][pSvNCol];
		if (tSvStr == pSvStr) {
			return l;
		}
	}
}

/**
 * マーカーを取得する。
 * 
 * @param pEvent    イベント
 * @return          マーカー文字列
 */
function getMarker(pEv) {

	tempD = pEv[SCH_COL_DATE];
	return pEv[SCH_COL_ID] + 
			tempD.substring(0, 4) + 
			tempD.substring(5, 7) + 
			tempD.substring(8, 10);
}

//  ****  イベント一覧の生成  ****
/**
 * イベント一覧を生成する。
 * 
 * @param pYear     表示年
 * @param pMonth    表示月
 * @param pRange    表示範囲（ヶ月）
 * @param pEvent    表示イベント
 * @param pServer   表示サーバ
 * @param pSort     ソート順
 */
function createEventList(pYear, pMonth, pRange, pEvent, pServer, pSort) {
/*
alert("pYear = " + pYear + ", pMonth = " + pMonth + ", pRange = "+ pRange + 
		", pEvent = " + pEvent + ", pServer = " + pServer + 
		", pSort = " + pSort);
*/
	nowdate = new Date();
	pYear = delZero(pYear) ;
	pMonth = delZero(pMonth);

	strBuff = "";
	strBuff += "<table border='1' cellspacing='1' cellpadding='2'>\n";

	//  ヘッダ
	cText = cal_color[CAL_MTH][CAL_HEAD_TEXT];
	cBack = cal_color[CAL_MTH][CAL_HEAD_BACK];
	strBuff += "  <tr>\n";
	strBuff += "    <th width='60' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>日にち</font></th>\n";
	strBuff += "    <th width='70' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>時間</font></th>\n";
	strBuff += "    <th width='84' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>サーバ</font></th>\n";
	strBuff += "    <th width='507' bgcolor='" + cBack + "'>" + 
			"<font color='" + cText + "'>内容</font></th>\n";
	strBuff += "  </tr>\n";

	tEvList = new Array();
	//  月ごとにイベントリストを保持
	tEvLs = new Array(pRange);
	nEvY = new Array(pRange);
	nEvM = new Array(pRange);

	//  対象年月のスケジュールの取得
	for (k = 0; k < pRange; k++) {
/*
alert("★3:pYear = " + pYear + ", pMonth = " + pMonth + ", pDate = " + "" + 
		", pEvent = " + pEvent + ", pServer = " + pServer + 
		", pUpdate = ");
*/
		tEvL = getSchedule(pYear, pMonth, "", pEvent, pServer, "");
//alert("tEvL.length = " + tEvL.length);
		tEvLs[k] = tEvL;
		nEvY[k] = pYear;
		nEvM[k] = pMonth;

		if (tEvList.length == 0) {
			tEvList = tEvL;
		} else {
			tEvList = tEvList.concat(tEvL);
		}

		pMonth++;
		if (pMonth > 12) {
			//  その年の未確定イベントを追加
			tEvL = getSchedule(pYear, "99", "", pEvent, pServer, "");
			tEvLs[k] = tEvLs[k].concat(tEvL);

			if (tEvList.length == 0) {
				tEvList = tEvL;
			} else {
				tEvList = tEvList.concat(tEvL);
			}

			pMonth = pMonth - 12;
			pYear++;
		}
	}

	//  その年の未確定イベントを追加
	tEvL = getSchedule(pYear, "99", "", pEvent, pServer, "");
	tEvLs[k - 1] = tEvLs[k - 1].concat(tEvL);
	if (tEvList.length == 0) {
		tEvList = tEvL;
	} else {
		tEvList = tEvList.concat(tEvL);
	}

	//  未確定イベントを追加
	tEvL = getSchedule("9999", "99", "", pEvent, pServer, "");
	tEvLs[k - 1] = tEvLs[k - 1].concat(tEvL);
	if (tEvList.length == 0) {
		tEvList = tEvL;
	} else {
		tEvList = tEvList.concat(tEvL);
	}

//alert("tEvList.length = " + tEvList.length);

	//  ソート
	sortSchedule(tEvList, pSort);

	//  イベントリストの表示
	furi_flg = -1;
	tSameDate = 0;
	same_date_flg = 0;
	nIndex = 0;
	nofix_flg = 0;

	for (i = 0; i < tEvList.length; i++) {
//alert("i = "+ i + " / tEvList.length = " + tEvList.length);
		//  日にちの取得
		tEvent = tEvList[i];
		str = tEvent[SCH_COL_DATE];
		str = str.toLowerCase().replace(new RegExp("x", "g"), "9");
		//  日にち未確定イベントの処理
		nofix_flg = 0;
		if (str.toLowerCase().indexOf("99") > -1) {
			nofix_flg = 1;
		}
		strs = str.split("/");
		tYear  = Number(strs[0]);
		tMonth = Number(strs[1]);
		tDate  = Number(strs[2]);
		//  曜日の取得
		nowdate.setDate(1);
		nowdate.setYear(tYear);
		nowdate.setMonth(tMonth - 1);
		nowdate.setDate(tDate);
		//  日にち未確定イベントの処理
		if (nofix_flg == 1) {
			tWDay = CAL_WEEK_OUT;
		} else {
			tWDay = nowdate.getDay();
		}
		//  休日区分
		holNum = isHoliday(tYear, tMonth, tDate);
		furi_flg = -1;
		//  月曜日の時は日曜日が祝日であるかチェックする。
		if (holNum == -1 && tWDay == 1) {
			furi_flg = isHoliday(tYear, tMonth, tDate - 1);
		}
		//  同一日開催件数取得
		if (same_date_flg == 0) {
			//  サーバ条件が全ての場合、""にするが、
			//  サーバソートの場合は、全ては"すべて"（イベント値）とする。
			inServer = pServer;
			if (pSort == SORT_SARVER) {
				inServer = getServerNum(
						tEvent[SCH_COL_SERVER], SERVER_COL_NAME);
			}
			inEvent = pEvent;
			if (pSort == SORT_EVENT) {
				inEvent = getEventNum(
						tEvent[SCH_COL_EVENT_CODE], EVENT_COL_CODE);
			}
			strUpdate = "";
			if (pSort == SORT_UPDATE) {
				strUpdate = tEvent[SCH_COL_LAST_UPDATE];
			}
/*
alert("★4:tYear = " + tYear + ", tMonth = " + tMonth + ", tDate = " + tDate + 
		", inEvent = " + inEvent + ", inServer = " + inServer + 
		", strUpdate = " + strUpdate);
*/
			//  絞り込み対象のデータを特定
			for (j = 0; j < tEvLs.length; j++) {
				if (tYear == nEvY[j] && tMonth == nEvM[j]) {
					nIndex = j;
					break;
				}
			}

			tSameDate = extractSchedule(tEvLs[nIndex], tYear, tMonth, tDate, 
					inEvent, inServer, strUpdate).length;
			if (tSameDate >= 2) {
				same_date_flg = tSameDate;
			}
		}

		//  色、イベント、サーバの取得
		cText = "";
		cBack = "";
		c = cal_week[tWDay][CAL_WEEK_COLOR];
		if ((holNum != -1) || (furi_flg != -1)) {
			cText = cal_color[CAL_HOL][CAL_TEXT];
			cBack = cal_color[CAL_HOL][CAL_BACK];
		} else {
			cText = cal_color[c][CAL_TEXT];
			cBack = cal_color[c][CAL_BACK];
		}

		strEvCode = tEvent[SCH_COL_EVENT_CODE];
		evNum = getEventNum(strEvCode, EVENT_COL_CODE)
		strEvName = event_name[evNum][EVENT_COL_NAME];
		cEvText = event_text;
		cEv = event_color[evNum];
		strEv = "      <span style='color: " + cEvText + "; " + 
				"background-color: " + cEv + "'>" + 
				strEvName + "</span>";

		strSvName = tEvent[SCH_COL_SERVER];
		svNum = getServerNum(
				strSvName, SERVER_COL_NAME);
		cSvText = server_text;
		cSv = server_color[svNum];
		strSv = "      <span style='color: " + cSvText + "; " + 
				"background-color: " + cSv + "'>" + 
				strSvName + "</span>";

		strBuff += "  <tr>\n";

		strDate = addZero(tMonth) + "/" + addZero(tDate) + 
				"(" + cal_week[tWDay][dispWKind] + ")";
		strDate = strDate.replace(new RegExp("99", "g"), "xx");

		if (same_date_flg > 0 && tSameDate == same_date_flg) {
			strBuff += "    <td width='60' bgcolor='" + cBack + "' " + 
					"rowspan='" + tSameDate + "'>" + 
					"<font color='" + cText + "'>" + strDate + 
					"</font></td>\n";
			same_date_flg--;
		} else if (same_date_flg > 0) {
			strBuff += "    \n";
			same_date_flg--;
		} else {
			strBuff += "    <td width='60' bgcolor='" + cBack + "'>" + 
					"<font color='" + cText + "'>" + strDate + 
					"</font></td>\n";
		}

		strTime = tEvent[SCH_COL_BEGIN_TIME] + "〜" + tEvent[SCH_COL_END_TIME];
		strBuff += "    <td width='70' bgcolor='" + cBack + "'>" + 
				strTime + "</td>\n";

		strBuff += "    <td width='84' bgcolor='" + cBack + "'>\n" + 
				strSv + "&nbsp;" + tEvent[SCH_COL_CH] + "ch</td>\n";

		strContents = "      <a name='" + getMarker(tEvent) + "'>\n" + 
				strEv + "　" + 
				"<b>" + tEvent[SCH_COL_TITLE] + "</a></b><br>\n" + 
				"場所：" + tEvent[SCH_COL_PLACE] + "<br>\n" + 
				linkCDetailURL(tEvent[SCH_COL_DETEIL]) + "<br>\n" + 
				"<font color='" + cBack + "'>" + 
				"ぽえってぃ予定：" + tEvent[SCH_COL_BOOKING] + 
				"　結果：" + tEvent[SCH_COL_RESULT] + "</font>\n" + 
				"　　登録日：" + tEvent[SCH_COL_REGIST_DATE] + 
				"　最終更新日：" + tEvent[SCH_COL_LAST_UPDATE] + "\n" + 
				"　　<a href='#' onClick='history.back();return false;'>" + 
				"↑</a>";

		strBuff += "    <td width='507' bgcolor='" + cBack + "'>\n" + 
				strContents + "</td>\n";

		strBuff += "  </tr>\n";
	}

	//  イベントが0件の場合の処理
	if (tEvList.length == 0) {
		cText = cal_color[CAL_SUN][CAL_TEXT];
		cBack = cal_color[CAL_OUT][CAL_BACK];
		strBuff += "  <tr>\n" + 
				"    <td colspan='4' bgcolor='" + cBack + "'>" + 
				"<span style='color: " + cText + "'>" + 
				"指定の年月にはイベントが登録されていません。<br>\n" + 
				"過去（２００５〜２００６年）のイベントに関しては、" + 
				"『<a href='http://poetleaf.seesaa.net/'>" + 
				"ぽえっとの葉っぱたち</a>』の" + 
				"スケジュール記事をご覧下さい。<br>\n" + 
				"また、３ヶ月以上先のイベントにつきましては、" + 
				"毎月月末頃に１か月分を順次登録する予定です。<br>\n" + 
				"</font>" + 
				"</td>\n" + 
				"  </tr>";
	}

	strBuff += "</table>\n";
	return strBuff;
}

/**
 * スケジュールをソートする。
 * 
 * @parma pArray    
 * @param pSort     ソート順
 */
function sortSchedule(pArray, pSort) {

	if (pSort == SORT_DATE) {
		pArray.sort(sortDate);
	} else if (pSort == SORT_SARVER) {
		pArray.sort(sortServer);
	} else if (pSort == SORT_EVENT) {
		pArray.sort(sortEvent);
	} else if (pSort == SORT_UPDATE) {
		pArray.sort(sortUpdate);
	}
}

/**
 * 日時順でソートする。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function sortDate(pA, pB) {

	//  0:日時順　　（日時順→サーバ順→イベント順）
	res = diffDate(pA, pB);
	if (res == 0) {
		res = diffServer(pA, pB);
		if (res == 0) {
			res = diffEvent(pA, pB);
		}
	}
	return res;
}

/**
 * サーバ順でソートする。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function sortServer(pA, pB) {

	//  1:サーバ順　（サーバ順→日時順→イベント順）
	res = diffServer(pA, pB);
	if (res == 0) {
		res = diffDate(pA, pB);
		if (res == 0) {
			res = diffEvent(pA, pB);
		}
	}
	return res;
}

/**
 * イベント順でソートする。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function sortEvent(pA, pB) {

	//  2:イベント順（イベント順→日時順→サーバ順）
	res = diffEvent(pA, pB);
	if (res == 0) {
		res = diffDate(pA, pB);
		if (res == 0) {
			res = diffServer(pA, pB);
		}
	}
	return res;
}

/**
 * 更新順でソートする。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function sortUpdate(pA, pB) {

	//  3:更新順　　（更新順→日時順→サーバ順→イベント順）
	res = diffUpdate(pA, pB);
	if (res == 0) {
		res = diffDate(pA, pB);
		if (res == 0) {
			res = diffServer(pA, pB);
			if (res == 0) {
				res = diffEvent(pA, pB);
			}
		}
	}
	return res;
}

/**
 * 日時を比較する。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function diffDate(pA, pB) {

	tADate = pA[SCH_COL_DATE];
	tBDate = pB[SCH_COL_DATE];
	tATime = pA[SCH_COL_BEGIN_TIME];
	tBTime = pB[SCH_COL_BEGIN_TIME];
	tA = tADate.substring(0, 4) + tADate.substring(5, 7) + 
			tADate.substring(8, 10) + 
			tATime.substring(0, 2) + tATime.substring(3, 5);
	tB = tBDate.substring(0, 4) + tBDate.substring(5, 7) + 
			tBDate.substring(8, 10) + 
			tBTime.substring(0, 2) + tBTime.substring(3, 5);
	//  日にちや時間に"x"が含まれている場合の対策
	tA = tA.toLowerCase().replace(new RegExp("x", "g"), "9");
	tB = tB.toLowerCase().replace(new RegExp("x", "g"), "9");
	tnA = Number(tA);
	tnB = Number(tB);
	return (tnA - tnB);
}

/**
 * サーバを比較する。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function diffServer(pA, pB) {

	tASv = pA[SCH_COL_SERVER];
	tBSv = pB[SCH_COL_SERVER];
	tASvNum = getServerNum(tASv, SERVER_COL_NAME);
	tBSvNum = getServerNum(tBSv, SERVER_COL_NAME);
	return (tASvNum - tBSvNum);
}

/**
 * イベントを比較する。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function diffEvent(pA, pB) {

	tAEvCode = pA[SCH_COL_EVENT_CODE];
	tBEvCode = pB[SCH_COL_EVENT_CODE];
	tAEvNum = getEventNum(tAEvCode, EVENT_COL_CODE);
	tBEvNum = getEventNum(tBEvCode, EVENT_COL_CODE);
	return (tAEvNum - tBEvNum);
}

/**
 * 更新日を比較する。
 * 
 * @param pA        内容A。
 * @param pB        内容B。
 * @return          内容Aが前：負数＜０＜正数：後
 */
function diffUpdate(pA, pB) {

	tADate = pA[SCH_COL_LAST_UPDATE];
	tBDate = pB[SCH_COL_LAST_UPDATE];
	if (tADate.match(/[^A-Za-z0-9\(\)\/]/)) {
		alert("Schedule Ver.:" + SCHECULE_VER + "\n" + 
				"ID:" + getMarker(pA) + "\n" + 
				"のデータに間違いがあります。\n" + 
				"お手数ですが、以上の内容を管理者にご連絡ください。");
		return 0;
	}
	if (tBDate.match(/[^A-Za-z0-9()/]/)) {
		alert("Schedule Ver.:" + SCHECULE_VER + "\n" + 
				"ID:" + getMarker(pA) + "\n" + 
				"のデータに間違いがあります。\n" + 
				"お手数ですが、以上の内容を管理者にご連絡ください。");

		return 0;
	}

	tA = tADate.substring(0, 4) + tADate.substring(5, 7) + 
			tADate.substring(8, 10);
	tB = tBDate.substring(0, 4) + tBDate.substring(5, 7) + 
			tBDate.substring(8, 10);
	tnA = Number(tA);
	tnB = Number(tB);
	return (tnB - tnA);	//  降順なので順番は逆
}

/**
 * 詳細のリンクを編集する。。
 * 
 * @param pContents 内容。
 */
function linkCDetailURL(pContents) {

	// 内容を\nで分解する
	strs = pContents.split("\n");
	strContents = "";
	for (m = 0; m < strs.length; m++) {
		str = strs[m];
		index = str.lastIndexOf("http://");
		if (index > -1) {
			s = "";
			sindex = str.indexOf(" ");
			if (sindex == -1) {
				sindex = 0;
			} else {
				sindex = sindex + 1;
				s = str.substring(0, sindex);
			}
			s += "<a href='" + str.substring(index, str.length) + "' " + 
			"style='text-decoration:underline; color: blue' target='_blank'>" + 
					str.substring(sindex, index) + "</a>";
			str = s;
		}
		if (strContents != "") {
			strContents = strContents + "<br>\n";
		}
		strContents = strContents + str;
	}
	return strContents;

}


//  ****  共通メソッド  ****
/**
 * リンクタイトル用生成メソッド。
 * イベントのリンクのツールチップ（タイトル）を生成する。
 * 
 * @param pA        イベント内容。
 * @param pHol      祝日名。
 * @return          タイトル戻り値
 */
function createToolTip(pA, pHol) {

	//  【イベント名ＮＮＮ】
	//  yyyy/mm/dd(Ddd)  祝日名
	//  HH:MM〜HH:MM
	//  ＮＮＮＮＮサーバ  Xch
	//  場所：ＮＮＮ
	return "【" + pA[SCH_COL_TITLE] + "】&#10;" + 
			pA[SCH_COL_DATE] + "(" + pA[SCH_COL_WEEK_DAY] + ")  " + 
			pHol + "&#10;" + 
			pA[SCH_COL_BEGIN_TIME] + "〜" + pA[SCH_COL_END_TIME] + "&#10;" + 
			pA[SCH_COL_SERVER] + "サーバ  " + pA[SCH_COL_CH] + "ch&#10;" + 
			"場所：" + pA[SCH_COL_PLACE];
}


//  ****  汎用メソッド  ****
/**
 * 月日用にゼロを追加する。
 * 
 * @param num       文字列の数値
 * @return          num を数値に変換して 9 より大きい場合にのみ、
 *                  先頭に"0"を付加する。
 */
function addZero(num) {
	num = parseInt(num, 10);
	if (num > 9) {
		return String(num)
	}
	return  "0" + String(num);
}

/**
 * ミリ秒用にゼロを追加する。
 * 
 * @param num       文字列の数値
 * @return          num を数値に変換して 9 より大きい場合にのみ、
 *                  先頭に"0"を付加する。
 */
function addZero3(num) {
	num = parseInt(num, 10);
	if (num > 99) {
		return String(num)
	} else if (num > 9) {
		return  "0" + String(num);
	}
	return  "00" + String(num);
}

/**
 * 文字列を数値に変換する。
 * 
 * @param num       文字列の数値。文字列の頭に"0"が付加されていても正しく
 *                  変換される。（Ex. "01" => "1"）
 * @return          num を数値に変換して返す。
 */
function delZero(num) {
	return parseInt(num, 10);
}

function size_focus() {
	x=629;
	y=563;
	resizeTo(x,y);
	xxx = screen.width / 2 - x / 2;
	yyy = screen.height / 2 - y / 2;
	moveTo(xxx,yyy);
	self.focus();
}

