function Calendar(objname, param){
	//對象objname
	this.objname = objname;
	
	//div 容器對象
	this.container = param && param.container || null;
	
	//類名
	this.cls = param && param.cls || 'calendar';
	
	//綁定數據
	this.data = param && param.data || null;
	
	//初始化日期
	this.init_date = param && param.init_date || null;
	
	//年份字符
	this.output_str = param && param.ouput_str || 'y年 m月'
	
	//星期字符
	this.week_str = param && param.week_str || '日,一,二,三,四,五,六';
	
	//handle functions
	this.handles = param && param.handles || [];
	
	//當前選中TD
	this.current_date = {};
	this.current_td = null;
	
	//get datestr
	this.getDate = function(){
		return this.init_date.y + '-' + (this.init_date.m+1) + '-' + this.init_date.d;
	}
	
	this.print = function(id){
		this.container = id ? document.getElementById(id) : this.container;
		
		var html = this.getHTML(this.init_date);
		
		if(!this.container){
			this.container = document.createElement('SPAN');
			document.body.appendChild(this.container);
		}
		this.container.innerHTML = html;
		
		//bind data
		this.bindData();
		
		//inner bind event
		this.innerBindEvent();
	}
		this.getHTML = function(date){
		date = date || this.init_date;
		
		var html = '';
		html += '<table summary="calendar" class="' + this.cls + '">';
		
		html += '<caption>';
		html += '<a href="#nogo" class="prevyear_btn">|&lt;</a> ';
		html += '<a href="#nogo" class="prevmonth_btn">&lt;</a> ';
		
		var output = this.output_str.replace('y', date.y);
		output = output.replace('m', date.m+1);
		output = output.replace('d', date.d);
		html += output;
		
		html += ' <a href="#nogo" class="nextmonth_btn">&gt;</a> ';
		html += '<a href="#nogo" class="nextyear_btn">&gt;|</a> ';
		html += '</caption>';
		
		//輸出星期字符
		var weeks = this.week_str.split(',');
		html += '<thead><tr>';
		for(var i=0; i<weeks.length; i++){
			html += '<th>' + weeks[i] + '</th>';
		}
		html += '</tr></thead><tbody>';
		
		//輸出日期期
		var date_serial = this.getDateSerial(date);
		var dobj = new Date();
		var last_month = this.getPrevMonth(date);
		var next_month = this.getNextMonth(date);
		
		for(var i=0; i<date_serial.length; i++){
			if(i%7 == 0){html += '<tr>';}
			
			if(i<7 && date_serial[i] > 20){
				html += '<td class="prevmonth_date" value="' + last_month.y + '-' + (last_month.m+1) + '-' + date_serial[i] + '">';	//上一個月份
			} else if(i>20 && date_serial[i]<7){
				html += '<td class="nextmonth_date" value="' + next_month.y + '-' + (next_month.m+1) + '-' + date_serial[i] + '">';	//下一個禦風
			} else if(dobj.getDate() == date_serial[i] && this.init_date.m == dobj.getUTCMonth() && this.init_date.y == dobj.getUTCFullYear()){
				html += '<td class="today" value="' + date.y + '-' + (date.m+1) + '-' + date_serial[i] + '">';						//今天
			} else {
				html += '<td value="' + date.y + '-' + (date.m+1) + '-' + date_serial[i] + '">';									//當前月份
			}
			html += date_serial[i] + '</td>';
			
			if(i%7 == 6){html += '</tr>';}
		}
		
		html += '</tbody></table>';
		return html;
	}
	
	//跳轉到下一個月
	this.gotoNextMonth = function(){
		this.init_date = this.getNextMonth(this.init_date);
		this.print();
		this.fireEvent('nextmonth', this.getDate());
		this.fireEvent('monthchange', this.getDate());
	}
	
	//跳轉到上一個月
	this.gotoPrevMonth = function(){
		this.init_date = this.getPrevMonth(this.init_date);
		this.print();
		this.fireEvent('prevmonth', this.getDate());
		this.fireEvent('monthchange', this.getDate());
	}
	
	//跳轉到下一年
	this.gotoNextYear = function(){
		this.init_date.y++;
		this.print();
		this.fireEvent('nextyear', this.getDate());
		this.fireEvent('monthchange', this.getDate());
	}
	
	//跳轉到上一年
	this.gotoPrevYear = function(){
		this.init_date.y--;
		this.print();
		this.fireEvent('prevyear', this.getDate());
		this.fireEvent('monthchange', this.getDate());
	}
	
	//獲取日期序列
	this.getDateSerial = function(date){
		var last_month_num = this.getDateNumInMonth(this.getPrevMonth(date));
		var cur_month_num = this.getDateNumInMonth(date);
		
		var cur_month_index = this.getFirstDateIndex(date);
		var date_serial = [];
		
		//獲取上一個月的數據
		for(var i=1; i<=cur_month_index; i++){
			date_serial.push(last_month_num - cur_month_index + i);
		}
		
		//獲取當前月份的數據
		for(var i=1; i<=cur_month_num; i++){
			date_serial.push(i);
		}
		
		//獲取下一個月份的數據
		var left = 7-date_serial.length%7;
		for(var i=1; i<left; i++){
			date_serial.push(i);
		}
		
		return date_serial;
	}
	
	//獲取月份的第一天的星期
	this.getFirstDateIndex = function(date){
		var dobj = new Date(date.y, date.m, 1);
		return dobj.getDay();
	}
	
	//綁定數據
	this.bindData = function(data){
		var data = data || this.data;
		this.data = data;
		
		if(!data || !this.container){
			return false;
		}
		
		var prev_month = this.getPrevMonth(this.init_date);
		var next_month = this.getPrevMonth(this.init_date);
		
		var tds = this.container.getElementsByTagName('TD');
		for(var i=0; i<tds.length; i++){
			var date_txt = tds[i].getAttribute('value');
			
			var count = 0;
			var first_notice;
			
			for(var len=0; len<data.length; len++){
				if(data[len].date == date_txt){
					tds[i].title = data[len].title;
					tds[i].className += ' ev';
					break;
				}
			}
		}
	}
	
	//具體天被點擊
	this.dateClick = function(_this){
		var date = this.getAttribute('value');
		
		//current_td;
		if(_this.current_td){
			_this.current_td.className = _this.current_td.className.replace(new RegExp("\\b" + 'selected' + "\\b\\s*", "g"), "");
		}

		_this.current_td = this;
		var tmp_cls = ' ' + _this.current_td.className + ' ';
		if(!(tmp_cls.indexOf(' selected ') >= 0)){
			_this.current_td.className += ' selected';
		}
		_this.init_date.d = this.innerHTML;
		_this.fireEvent('dateclick', date);
	}
	
	//內部默認事件
	this.innerBindEvent = function(){
		var as = this.container.getElementsByTagName('A');
		var _this = this;
		for(var i=as.length-1; i>=0; i--){
			if(as[i].className == 'prevyear_btn'){
				this.addEvent(as[i], 'click', function(){_this.gotoPrevYear();});
			}
			
			else if(as[i].className == 'prevmonth_btn'){
				this.addEvent(as[i], 'click', function(){_this.gotoPrevYear();});
			}
			
			else if(as[i].className == 'nextmonth_btn'){
				this.addEvent(as[i], 'click', function(){_this.gotoNextMonth();});
			}
			
			else if(as[i].className == 'nextyear_btn'){
				this.addEvent(as[i], 'click', function(){_this.gotoNextYear();});
			}
		}
		
		var tds = this.container.getElementsByTagName('TD');
		for(var i=tds.length-1; i>=0; i--){
			if(tds[i].getAttribute){
				(function(){
					var td = tds[i];	
					_this.addEvent(tds[i], 'click', function(){_this.dateClick.call(td, _this);});	
				})();
			}
		}
	}
	
	//啟動事件
	this.fireEvent = function(event, param){
		for(var i=0; i<this.handles.length; i++){
			if(this.handles[i].ev == event){
				this.handles[i].fn(param);
			}
		}
	}
	
	//綁定事件
	this.bindEvent = function(event, handle){
		this.handles.push({ev:event, fn:handle})
		return true;
	}
	
	//添加事件觸發
	this.addEvent = function(obj, ev, callback){
		if(document.all){
			obj.attachEvent(['on']+ev, callback);
		} else {
			obj.addEventListener(ev, callback, true );
		}
	}
		//上一個月
	this.getPrevMonth = function(date){
		var last_month = {};
		
		if(date.m == 0){
			last_month.y = date.y-1;
			last_month.m = 11;
		}else {
			last_month.y = date.y;
			last_month.m = date.m-1;
		}
		
		last_month.d = date.d;
		return last_month;
	}
	
	//下一個月
	this.getNextMonth = function(date){
		var next_month = {};
		if(date.m == 11){
			next_month.y = date.y+1;
			next_month.m = 0;
		} else {
			next_month.y = date.y;
			next_month.m = date.m+1;
		}
		
		next_month.d = date.d;
		return next_month;
	}
	
	this.getDateNumInMonth = function(date){
		var dobj = new Date(date.y,date.m,31);
		if(dobj.getDate() > 3)
			return 31;
		else 
			return (31 - dobj.getDate());
	}
	
	this.init = function(){
		if(!this.init_date){
			this.init_date = {};
			var date = new Date();
			this.init_date.y = date.getUTCFullYear();
			this.init_date.m = date.getUTCMonth();
			this.init_date.d = date.getDate();
		}
		
		//測試數據
		//數據格式參考:		
		this.data = [
			{title:'共有 1 條數據', date:'2008-11-13'},
			{title:'共有 2 條數據', date:'2008-11-14'}
		]
	}
	this.init();
}