﻿<!--
/**
 * Calendar
 * @param   beginYear           1990
 * @param   endYear             2010
 * @param   language            0(zh_cn)|1(en_us)|2(en_en)|3(zh_tw)|4(jp)
 * @param   pattern 			"yyyy-MM-dd"

 @ update 20090127
 1.deleted 3 bottom button.
 2.modified interface style and switch month style.
 3.added selecting current date function.
 4.canceled textbox's readonly attribute and limited string input in textbox.
 5.The calendar will be hided after the focus outside calendar and textbox.
 6.deleted 2 parameters, string2DatePattern & patternDelimiter, can automatically identify them by pattern

 * @author  Melody (honglang5942@sina.com)
 * NOTE!    you can use it free, but keep the copyright please
 * IMPORTANT:you must include this script file inner html body elment 
 * @see http://blog.2fstory.net
 
---------------------------------old version information------------------------------------------
/**
 * Calendar
 * @param   beginYear           1990
 * @param   endYear             2010
 * @param   language            0(zh_cn)|1(en_us)|2(en_en)|3(zh_tw)|4(jp)
 * @param   patternDelimiter    "-"
 * @param   date2StringPattern  "yyyy-MM-dd"
 * @param   string2DatePattern  "ymd"
 * @version V20060401
 * @version V20061217
 * @version V20080809 add to google project
 * @version V20081226 add language support for japanese 
 * @version V20090104 add fix some bugs in help.html
					  use style.display replace the style.visibility
					  some enhancements and changes
 * @author  KimSoft (jinqinghua [at] gmail.com)
 * NOTE!    you can use it free, but keep the copyright please
 * IMPORTANT:you must include this script file inner html body elment 
 * @see http://code.google.com/p/kimsoft-jscalendar/
-----------------------------------------------------------------------------------
 */
function Calendar(beginYear, endYear, language, pattern) {
	this.beginYear = beginYear || 1990;
	this.endYear   = endYear   || 2020;
	this.language  = language  || 0;
	this.pattern = pattern || Calendar.language["pattern"][this.language];
	this.patternDelimiter = this.pattern.replace(/^[yMd]{2,4}(\W).*$/gi,"$1") || "-";
	
	this.dateControl = null;
	this.panel  = this.$("__calendarPanel");
	this.iframe = window.frames["__calendarIframe"];
	this.form   = null;
	
	this.date = new Date();
	this.year = this.date.getFullYear();
	this.month = this.date.getMonth();
	this.day = this.date.getDay();
	this.curdate = this.date;
	this.browser = this.getBrowser();
	this.colors = {"border_today":"#C63","text_over":"#FFF","border_over":"#C96","bg_over":"#FF3","bg_out":"#EFEFEF"}
};

Calendar.language = {
	"year"   : ["\u5e74", "", "", "\u5e74","\u5e74"],
	"months" : [
				["\u4e00\u6708","\u4e8c\u6708","\u4e09\u6708","\u56db\u6708","\u4e94\u6708","\u516d\u6708","\u4e03\u6708","\u516b\u6708","\u4e5d\u6708","\u5341\u6708","\u5341\u4e00\u6708","\u5341\u4e8c\u6708"],
				["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
				["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
				["\u4e00\u6708","\u4e8c\u6708","\u4e09\u6708","\u56db\u6708","\u4e94\u6708","\u516d\u6708","\u4e03\u6708","\u516b\u6708","\u4e5d\u6708","\u5341\u6708","\u5341\u4e00\u6708","\u5341\u4e8c\u6708"],
				["\u4e00\u6708","\u4e8c\u6708","\u4e09\u6708","\u56db\u6708","\u4e94\u6708","\u516d\u6708","\u4e03\u6708","\u516b\u6708","\u4e5d\u6708","\u5341\u6708","\u5341\u4e00\u6708","\u5341\u4e8c\u6708"]				
				],
	"weeks"  : [
				["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d"],
				["S","M","T","W","T","F","S"],
				["S","M","T","W","T","F","S"],
				["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d"],
				["\u65e5","\u6708","\u706b","\u6c34","\u6728","\u91d1","\u571f"],
				],
	"pattern" : ["yyyy-MM-dd", "MM/dd/yyyy", "yyyy-MM-dd", "yyyy-MM-dd", "yyyy-MM-dd"]
};

Calendar.prototype.draw = function() {
	calendar = this;
	
	var _cs = [];
	_cs[_cs.length] = '<form id="__calendarForm" name="__calendarForm" method="post">';
	_cs[_cs.length] = '<table id="__calendarTable" width="100%" cellspacing="1" align="center">';
	_cs[_cs.length] = ' <tr>';
	_cs[_cs.length] = '  <th><input class="l" name="goPrevMonthButton" type="button" id="goPrevMonthButton" value="◀" \/><\/th>';
	_cs[_cs.length] = '  <th colspan="5"><select class="year" name="yearSelect" id="yearSelect"><\/select><select class="month" name="monthSelect" id="monthSelect"><\/select><\/th>';
	_cs[_cs.length] = '  <th><input class="r" name="goNextMonthButton" type="button" id="goNextMonthButton" value="▶" \/><\/th>';
	_cs[_cs.length] = ' <\/tr>';
	_cs[_cs.length] = ' <tr>';
	for(var i = 0; i < 7; i++) {
		_cs[_cs.length] = '<th class="theader">';
		_cs[_cs.length] = Calendar.language["weeks"][this.language][i];
		_cs[_cs.length] = '<\/th>';	
	}
	_cs[_cs.length] = '<\/tr>';
	for(var i = 0; i < 6; i++){
		_cs[_cs.length] = '<tr align="center">';
		for(var j = 0; j < 7; j++) {
			switch (j) {
				case 0: _cs[_cs.length] = '<td class="sun">&nbsp;<\/td>'; break;
				case 6: _cs[_cs.length] = '<td class="sat">&nbsp;<\/td>'; break;
				default:_cs[_cs.length] = '<td class="normal">&nbsp;<\/td>'; break;
			}
		}
		_cs[_cs.length] = '<\/tr>';
	}
	_cs[_cs.length] = '<\/table>';
	_cs[_cs.length] = '<\/form>';
	
	this.iframe.document.body.innerHTML = _cs.join("");
	this.form = this.iframe.document.forms["__calendarForm"];

	this.form.goPrevMonthButton.onclick = function () {calendar.goPrevMonth(this);}
	this.form.goNextMonthButton.onclick = function () {calendar.goNextMonth(this);}
	this.form.yearSelect.onchange = function () {calendar.update(this);}
	this.form.monthSelect.onchange = function () {calendar.update(this);}
};

Calendar.prototype.bindYear = function() {
	var ys = this.form.yearSelect;
	ys.length = 0;
	for (var i = this.beginYear; i <= this.endYear; i++){
		ys.options[ys.length] = new Option(i + Calendar.language["year"][this.language], i);
	}
};

Calendar.prototype.bindMonth = function() {
	var ms = this.form.monthSelect;
	ms.length = 0;
	for (var i = 0; i < 12; i++){
		ms.options[ms.length] = new Option(Calendar.language["months"][this.language][i], i);
	}
};

Calendar.prototype.goPrevMonth = function(e){
	if (this.year == this.beginYear && this.month == 0){return;}
	this.month--;
	if (this.month == -1) {
		this.year--;
		this.month = 11;
	}
	this.date = new Date(this.year, this.month, 1);
	this.changeSelect();
	this.bindData();
};

Calendar.prototype.goNextMonth = function(e){
	if (this.year == this.endYear && this.month == 11){return;}
	this.month++;
	if (this.month == 12) {
		this.year++;
		this.month = 0;
	}
	this.date = new Date(this.year, this.month, 1);
	this.changeSelect();
	this.bindData();
};

Calendar.prototype.changeSelect = function() {
	var ys = this.form.yearSelect;
	var ms = this.form.monthSelect;
	for (var i= 0; i < ys.length; i++){
		if (ys.options[i].value == this.date.getFullYear()){
			ys[i].selected = true;
			break;
		}
	}
	for (var i= 0; i < ms.length; i++){
		if (ms.options[i].value == this.date.getMonth()){
			ms[i].selected = true;
			break;
		}
	}
};

Calendar.prototype.update = function (e){
	this.year  = e.form.yearSelect.options[e.form.yearSelect.selectedIndex].value;
	this.month = e.form.monthSelect.options[e.form.monthSelect.selectedIndex].value;
	this.date = new Date(this.year, this.month, this.day);
	this.changeSelect();
	this.bindData();
};

Calendar.prototype.bindData = function () {
	var calendar = this;
	var dateArray = this.getMonthViewDateArray(this.date.getFullYear(), this.date.getMonth());
	var tds = this.getElementsByTagName("td", this.$("__calendarTable", this.iframe.document));
	for(var i = 0; i < tds.length; i++) {
  		tds[i].style.backgroundColor = calendar.colors["bg_out"];
		tds[i].onclick = null;
		tds[i].onmouseover = null;
		tds[i].onmouseout = null;
		tds[i].style.borderColor = "";
		tds[i].innerHTML = dateArray[i] || "&nbsp;";
		if (i > dateArray.length - 1) continue;
		if (dateArray[i]){
			tds[i].style.cursor = "pointer";
			tds[i].onclick = function () {
				if (calendar.dateControl){
					calendar.dateControl.value = new Date(calendar.date.getFullYear(),
														calendar.date.getMonth(),
														this.innerHTML).format(calendar.pattern);
				}
				calendar.hide();
			}
			tds[i].onmouseover = function () {
				this.style.backgroundColor = calendar.colors["border_over"];
				this.style.borderColor = calendar.colors["border_over"]
				this.style.color = calendar.colors["text_over"];
			}
			tds[i].onmouseout  = function () {
				this.style.backgroundColor = calendar.colors["bg_out"];
				this.style.borderColor = "";
				this.style.color = "";
			}
			var today = new Date();
			if (today.getFullYear() == calendar.date.getFullYear()) {
				if (today.getMonth() == calendar.date.getMonth()) {
					if (today.getDate() == dateArray[i]) {
						tds[i].style.borderColor = calendar.colors["border_today"];
						tds[i].onmouseout  = function () {
							this.style.borderColor = calendar.colors["border_today"];
							this.style.backgroundColor = calendar.colors["bg_out"];
							this.style.color = "";
						}
					}
				}
			}
			if (calendar.curdate.getFullYear() == calendar.date.getFullYear()) {
				if (calendar.curdate.getMonth() == calendar.date.getMonth()) {
					if (calendar.curdate.getDate() == dateArray[i]) {
						tds[i].style.borderColor = calendar.colors["border_over"];
						tds[i].style.backgroundColor = calendar.colors["bg_over"];
						tds[i].onmouseout  = function () {
							this.style.borderColor = calendar.colors["border_over"];
							this.style.backgroundColor = calendar.colors["bg_over"];
							this.style.color = "";
						}
					}
				}
			}
		}//end if
	}//end for
};

Calendar.prototype.getMonthViewDateArray = function (y, m) {
	var dateArray = new Array(42);
	var dayOfFirstDate = new Date(y, m, 1).getDay();
	var dateCountOfMonth = new Date(y, m + 1, 0).getDate();
	for (var i = 0; i < dateCountOfMonth; i++) {
		dateArray[i + dayOfFirstDate] = i + 1;
	}
	return dateArray;
};

// Get Browser Type
Calendar.prototype.getBrowser = function() {
	var b;
	if ((navigator.userAgent.indexOf("MSIE") >= 0) && (navigator.userAgent.indexOf('Opera') < 0)) {
		b = "IE"; 
	}else if (navigator.userAgent.indexOf("Firefox") >= 0) {
		b = "Firefox"; 
	}else if (navigator.userAgent.indexOf("Opera") >= 0){
		b = "Opera"; 
	}else {
		b = "Other";
	}
	return b;
}	
// Get Event
Calendar.prototype.gEvent = function() {
    var browser = Calendar.prototype.getBrowser();
	var evt = (browser == "IE" ? window.event : arguments.callee.caller.arguments[0]);
	this.x = (browser == "IE" ? evt.clientX : evt.pageX);
	this.y = (browser == "IE" ? evt.clientY : evt.pageY);
	this.srcElement = (browser == "IE" ? evt.srcElement : evt.target);
	this.keyCode = (browser == "IE" ? evt.keyCode : evt.which);
	this.returnValue = evt.returnValue;
	this.cancelReturnValue = function() {
		this.returnValue = false;
		if (browser == "IE") {
			evt.returnValue = false;
		}else{
			evt.preventDefault();
		}
	}
}
// Add Event
Calendar.prototype.addEvent = function(obj,eventTypeName,fn){
	if(obj.addEventListener){
		obj.addEventListener(eventTypeName,fn,true);
		return true;
	}else if(obj.attachEvent){
		return obj.attachEvent("on"+eventTypeName,fn);
	}else{
		return false;
	}
}
/*
if (typeof (HTMLElement) != "undefined") {
	HTMLElement.prototype.contains = function(obj) {
		while (obj != null && typeof (obj.tagName) != "undefind") { 
			if (obj == this) return true; 
			obj = obj.parentNode; 
		} 
		return false;
	};
}
Object.prototype.contains(obj) {

	alert();
    return this.contains(obj);
}
*/		
Calendar.prototype.keyDownEvt = function() {
	var evt = new Calendar.prototype.gEvent();
	if (!((evt.keyCode>=48&&evt.keyCode<=57)||evt.keyCode==8||evt.keyCode==189||evt.keyCode||evt.keyCode==37||evt.keyCode==39||evt.keyCode==46)) {
		evt.cancelReturnValue();
	}
}
function getActiveElement(e) {
	var target;
	if (Calendar.prototype.getBrowser()=="IE") { 
		target = document.activeElement; //Si IE
	} else { 
		target = e ? e.explicitOriginalTarget : null; // Si Firefox
	}
	return target;
}
Calendar.prototype.show = function (dateControl, popuControl) {
	var iframe = (this.browser == "IE") ? Calendar.prototype.$("__calendarIframe") : Calendar.prototype.$("__calendarIframe").contentWindow;
	this.addEvent(iframe, "blur", function(e) {
			//document.getElementById("txt").innerHTML = getActiveElement(e).tagName;//+","+(getActiveElement(e).window.frameElement.id);
				if (dateControl!=getActiveElement(e)) calendar.hide();
			} );
	this.addEvent(dateControl,"blur",function(e) {
			if (iframe!=getActiveElement(e)&&dateControl!=getActiveElement(e)&&Calendar.prototype.$("__calendarPanel")!=getActiveElement(e)) calendar.hide();} );
	this.addEvent(dateControl,"keydown",this.keyDownEvt);
	if (this.panel.style.display == "block") {
		this.panel.style.display = "none";
	}
	if (!dateControl){
		throw new Error("arguments[0] is necessary!")
	}
	this.dateControl = dateControl;
	popuControl = popuControl || dateControl;

	this.draw();
	this.bindYear();
	this.bindMonth();
	if (dateControl.value.length > 0){
		this.date  = new Date(dateControl.value.toDate(this.patternDelimiter, this.pattern));
		this.year  = this.date.getFullYear();
		this.month = this.date.getMonth();
	}
	this.curdate = this.date;
	this.changeSelect();
	this.bindData();

	var xy = this.getAbsPoint(popuControl);
	this.panel.style.left = xy.x + "px";
	this.panel.style.top = (xy.y + dateControl.offsetHeight) + "px";
	this.panel.style.display = "block";
};

Calendar.prototype.hide = function() {
	this.panel.style.display = "none";
};

Calendar.prototype.$ = function(id, object){
	object = object || document;
	return document.getElementById ? object.getElementById(id) : document.all(id);
};

Calendar.prototype.getElementsByTagName = function(tagName, object){
	object = object || document;
	return document.getElementsByTagName ? object.getElementsByTagName(tagName) : document.all.tags(tagName);
};

Calendar.prototype.getAbsPoint = function (e){
	var x = e.offsetLeft;
	var y = e.offsetTop;
	while(e = e.offsetParent){
		x += e.offsetLeft;
		y += e.offsetTop;
	}
	return {"x": x, "y": y};
};
Date.prototype.format = function(style) {
	var o = {
		"M+" : this.getMonth() + 1, //month
		"d+" : this.getDate(),      //day
		"h+" : this.getHours(),     //hour
		"m+" : this.getMinutes(),   //minute
		"s+" : this.getSeconds(),   //second
		"w+" : "\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d".charAt(this.getDay()),   //week
		"q+" : Math.floor((this.getMonth() + 3) / 3),  //quarter
		"S"  : this.getMilliseconds() //millisecond
	}
	if (/(y+)/.test(style)) {
		style = style.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	}
	for(var k in o){
		if (new RegExp("("+ k +")").test(style)){
			style = style.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
		}
	}
	return style;
};
String.prototype.toDate = function(delimiter, pattern) {
	delimiter = delimiter || "-";
	pattern = pattern || "ymd";
	var a = this.split(delimiter);
	pattern = pattern.replace(/([ymd]){2,4}[\/-]([ymd]){2,4}[\/-]([ymd]){2,4}/ig,"$1$2$3");
	var y = parseInt(a[pattern.indexOf("y")], 10);
	if(y.toString().length <= 2) y += 2000;
	if(isNaN(y)) y = new Date().getFullYear();
	var m = parseInt(a[pattern.indexOf("M")], 10) - 1;
	var d = parseInt(a[pattern.indexOf("d")], 10);
	if(isNaN(d)) d = 1;
	return new Date(y, m, d);
};

var divs = [];
divs[divs.length] = '<div id="__calendarPanel" style="position:absolute;display:none;background-color:#FFFFFF;border:1px solid #CCCCCC;width:140px;height:158px;">';
divs[divs.length] = '<iframe name="__calendarIframe" id="__calendarIframe" width="100%" height="100%" scrolling="no" frameborder="0" style="margin:0px;"><\/iframe>';
divs[divs.length] = '<\/div>';
document.write(divs.join(""));

var __ci = window.frames['__calendarIframe'];
var cis = [];
cis[cis.length] ='<!DOCTYPE html PUBLIC "-\/\/W3C\/\/DTD XHTML 1.0 Transitional\/\/EN" "http:\/\/www.w3.org\/TR\/xhtml1\/DTD\/xhtml1-transitional.dtd">';
cis[cis.length] ='<html xmlns="http:\/\/www.w3.org\/1999\/xhtml">';
cis[cis.length] ='<head>';
cis[cis.length] ='<meta http-equiv="Content-Type" content="text\/html; charset=utf-8" \/>';
cis[cis.length] ='<title>Web Calendar(UTF-8) Written By Melody<\/title>';
cis[cis.length] ='<style type="text\/css">';
cis[cis.length] ='<!--';
cis[cis.length] ='body {font-size:12px;margin:0px;text-align:center;cursor:default;}';
cis[cis.length] ='form {margin:0px;}';
cis[cis.length] ='select {font-size:12px;background-color:#EFEFEF;}';
cis[cis.length] ='table {background-color:#FFFFFF; border:solid 0px #EFEFEF; padding:1px;}';
cis[cis.length] ='th {font-weight:normal;background-color:#FFF;padding:0px;text-align:center;height:22px;}';
cis[cis.length] ='th.theader {font-weight:normal;background-color:#999999;color:#FFF;font:9pt Tahoma;height:19px;}';
cis[cis.length] ='select.year {width:52px;font:9pt Tahoma;}';
cis[cis.length] ='select.month {width:46px;font:9pt Tahoma;}';
cis[cis.length] ='td {text-align:center;font:9pt Tahoma; padding: 1px;border:solid 1px #EFEFEF; padding:1px;}';
cis[cis.length] ='td.sat {color:#0000FF;background-color:#EFEFEF;}';
cis[cis.length] ='td.sun {color:#FF0000;background-color:#EFEFEF;}';
cis[cis.length] ='td.normal {background-color:#EFEFEF;padding:1px;}';
cis[cis.length] ='input.l {border: 0px;background-color:#FFF;width:18px;height:18px;color:#666;cursor:pointer;}';
cis[cis.length] ='input.r {border: 0px;background-color:#FFF;width:18px;height:18px;color:#666;cursor:pointer;}';
cis[cis.length] ='input.b {border: 0px;background-color:#EFEFEF;width:100%;height:18px;}';
cis[cis.length] ='-->';
cis[cis.length] ='<\/style>';
cis[cis.length] ='<\/head>';
cis[cis.length] ='<body id="bod">';
cis[cis.length] ='<\/body>';
cis[cis.length] ='<\/html>';
__ci.document.writeln(cis.join(""));
__ci.document.close();
var calendar = new Calendar();
//-->