var Calendar = Class.create({
	/** コンストラクタ */
	initialize : function(element, defaultDate, options) {
		this.element = $(element);
		if(!this.element) return;
		this.options = Object.extend({
			keepDt:true,
			onUpdate:null,
			curMSelector        : ".curr-month",
			nextMSelector       : ".next-month",
			prevMSelector       : ".prev-month",
			dispYSelector       : ".year",
			dispMSelector       : ".month",
			calendarCellSelector: ".calendar-cell",
			todayClassName      : "today"
		}, options);

		// 現在の日付を取得
		this.defaultDate = defaultDate?defaultDate:new Date();

		var $this = this;
		var currMonth = this.element.select(this.options.curMSelector);
		for(var i = 0; i < currMonth.length; i++) {
			currMonth[i].observe('click', function(event) {event.stop();$this.onCurrMonth()});
		}
		// 次の月への操作
		var nextMonth = this.element.select(this.options.nextMSelector);
		for(var i = 0; i < nextMonth.length; i++) {
			nextMonth[i].observe('click', function(event) {event.stop();$this.onNextMonth()});
		}
		// 前の月への操作
		var prevMonth = this.element.select(this.options.prevMSelector);
		for(var i = 0; i < nextMonth.length; i++) {
			prevMonth[i].observe('click', function(event) {event.stop();$this.onPrevMonth()});
		}
		this.update();
	},
	update : function() {
		// 表示年月日
		var dt = this.getDate();
		var y  = dt.getFullYear(); // 年
		var m  = dt.getMonth()+1;  // 月
		var d  = dt.getDate();     // 日
		// 今日
		var cdt= new Date();
		var cy = cdt.getFullYear();
		var cm = cdt.getMonth()+1;
		var cd = cdt.getDate();
		
		// 1日の曜日を取得
		dt.setDate(1);
		day = dt.getDay();
		// 月の日数を取得
		md = new Date(y, m, 0).getDate();
		
		// 年を設定
		year  = this.element.down(this.options.dispYSelector);
		if(year) year.update(y);

		// 月を設定
		month = this.element.down(this.options.dispMSelector);
		if(month) month.update(m);

		// 日を設定
		cells = this.element.select(this.options.calendarCellSelector);
		if(cells.length == 42) {
			for(var i = 0; i < day; i++) {
				this.updateCell(cells[i]);
				cells[i].removeClassName(this.options.todayClassName);
			}
			var d = 1;
			for(var i=day; d <= md; i++) {
				if(y==cy && m==cm && d==cd) {
					cells[i].addClassName(this.options.todayClassName);
				}
				else
					cells[i].removeClassName(this.options.todayClassName);
				this.updateCell(cells[i], y, m, d++);
			}
			for(; i < cells.length; i++) {
				this.updateCell(cells[i]);
				cells[i].removeClassName(this.options.todayClassName);
			}
		}
		// 次の月への操作
		var nextMonth = this.element.select(this.options.nextMSelector);
		for(var i = 0; i < nextMonth.length; i++) {
			var s = nextMonth[i].down('span');
			if(s) s.update((m==12)?(1):(m+1));
		}
		// 前の月への操作
		var prevMonth = this.element.select(this.options.prevMSelector);
		for(var i = 0; i < nextMonth.length; i++) {
			var s = prevMonth[i].down('span');
			if(s) s.update((m==1)?(12):(m-1));
		}
		if(this.options.onUpdate) {
			this.options.onUpdate(this);
		}
	},
	updateCell : function(cell, y, m, d) {
		if(!y) {
			cell.down('span').update('&nbsp;');
		}
		else {
			cell.down('span').update(d);
			cell.title = y + '-' + m + '-' + d;
		}
	},
	getCells : function() {
		return this.element.select(this.options.calendarCellSelector);
	},
	getDate : function() {
		if(!this.dt) {
			if(this.options.keepDt) {
				var cookieDt = getCookie('EventCalendar.dt');
				if(cookieDt) {
					this.dt = new Date(cookieDt);
				}
				else {
					this.setDate(this.defaultDate);
				}
			}
			else {
				this.dt = new Date(this.defaultDate);
			}
		}
		return this.dt;
	},
	setDate : function(dt) {
		this.dt = new Date(dt?dt:this.defaultDate);
		if(this.options.keepDt) {
			setCookie('EventCalendar.dt', this.dt.toString());
		}
	},
	onCurrMonth : function() {
		this.setDate(new Date());
		this.update();
	},
	onNextMonth : function() {
		var dt = this.getDate();
		var y  = dt.getFullYear();
		var m  = dt.getMonth();
		this.setDate(new Date(y, m+1));
		this.update();
	},
	onPrevMonth : function() {
		var dt = this.getDate();
		var y  = dt.getFullYear();
		var m  = dt.getMonth();
		this.setDate(new Date(y, m-1));
		this.update();
	}
});




