google.load("gdata", "2.x", { packages : ["calendar"] });

var setEventCalendar = function(id,feed,mode,dayNames){

	this.targetId = id;
	this.feedUri = feed;

	this.mode = mode || "normal";
	this.dayNames = dayNames || [
		'日',
		'月',
		'火',
		'水',
		'木',
		'金',
		'土'
	];

	this.calendarService = new google.gdata.calendar.CalendarService();
	this.realDate = new Date();
	this.cell = new Array();
	if (id && feed) this.init();
}

setEventCalendar.prototype = {

	init: function(){
		this.addEvent((function(that){return function(){that.render()}})(this));
	},
	leapYear: function(year){
		return year % 4 ? 0 : year % 100 ? 1 : year % 400 ? 0 : 1;
	},
	padNumber: function(num) {
		if (num <= 9) return "0" + num;
		return num;
	},
	render: function(y,m){
		cell = this.cell;
		cell.length = 0;

		var self = this;
		var target = document.getElementById(this.targetId);
		while(target.hasChildNodes()){
			target.removeChild(target.firstChild);
		}
	
		if(y && m) {
			m--;
		} else {
			y = this.realDate.getFullYear();
			m = this.realDate.getMonth();
		}
		
		/* target date */
		var date = new Date(y,m);
		var crYear = date.getFullYear();
		var crMonth = date.getMonth();
		var crDay = date.getDate();
	
		/* prev month */
		var prevDate = new Date(crYear, crMonth - 1);
		var prevYear = prevDate.getFullYear();
		var prevMonth = prevDate.getMonth();
	
		prevDate.setMonth(prevMonth + 1);
		prevDate.setDate(0);
		var prevLastDay = prevDate.getDate();
	
		/* next month */
		var nextDate = new Date(crYear, crMonth + 1);
		var nextYear = nextDate.getFullYear();
		var nextMonth = nextDate.getMonth();
	
		var monthTable = new Array(31,28 + this.leapYear(crYear),31,30,31,30,31,31,30,31,30,31);
	
		date.setDate(1);
		crWeek = date.getDay();

		var wrapper = document.createElement('div');
		wrapper.className = "eventCalendar";
	
		var div = document.createElement('div');
		div.className = "calendarHeader";
		var table = document.createElement('table');
		var tbody = document.createElement('tbody');
		var tr = document.createElement('tr');
	
		var td = document.createElement('td');
			td.className = "calendarPrevLink";
		var a = document.createElement('span');
			a.onclick = function(){
				self.render(prevYear,prevMonth + 1);
				return false;
			}
		var text = document.createTextNode(prevMonth + 1 + "月");
		a.appendChild(text);
		td.appendChild(a);
		tr.appendChild(td);
	
		var td = document.createElement('td');
			td.className = "calendarTitle";
		var text = document.createTextNode(crYear + "年 " + (crMonth + 1) + "月");
		td.appendChild(text);
		tr.appendChild(td);
	
		var td = document.createElement('td');
			td.className = "calendarNextLink";
		var a = document.createElement('span');
			a.onclick = function(){
				self.render(nextYear,nextMonth + 1);
				return false;
			}
		var text = document.createTextNode(nextMonth + 1 + "月");
		a.appendChild(text);
		td.appendChild(a);
		tr.appendChild(td);
	
		tbody.appendChild(tr);
		table.appendChild(tbody);
		div.appendChild(table);
		wrapper.appendChild(div);

		var div = document.createElement('div');
		div.className = "calendarBody";
	
		var table = document.createElement('table');
		table.cellSpacing = "1"
		table.cellPadding = "0"
		var thead = document.createElement('thead');
		var tr = document.createElement("tr");
		for (var i = 0, len = this.dayNames.length; i < len; i++){
			var th = document.createElement("th");
		    var txt = document.createTextNode(this.dayNames[i]);
		    if (i == 0){
		    	th.className = "sunday";
		    } else if (i == 6){
		    	th.className = "saturday";
		    }	    
			th.appendChild(txt);
		    tr.appendChild(th);
		}
		thead.appendChild(tr);
		table.appendChild(thead);
		
		var line = Math.ceil( ( monthTable[crMonth] + crWeek ) / 7 ) * 7;
		var tbody = document.createElement('tbody');
		for (var i = 0; i < line; i++){
			if (i % 7 == 0) tr = document.createElement('tr');
			var callDate = i - crWeek + 1;
			var num;
			var classNameString;
	
			cell[callDate] = document.createElement('td');
			var span = document.createElement("span");
			if (callDate < 1){
				num = prevLastDay + callDate;
				classNameString = "disable";
			} else if (monthTable[crMonth] < callDate){
				num = callDate - monthTable[crMonth];
				classNameString = "disable";
			} else {
				num = callDate;
				classNameString = "y" + crYear + " m" + (crMonth + 1) + " d" + callDate;
				if (i % 7 == 0){
					classNameString += " sunday";
				} else if (i % 7 == 6) {
					classNameString += " saturday";
				}
				if (crYear == this.realDate.getFullYear() && crMonth == this.realDate.getMonth() && callDate == this.realDate.getDate()){
					classNameString += " today";
				}
			}
			var txt = document.createTextNode(num);
			cell[callDate].appendChild(txt);
			cell[callDate].className = classNameString;
			tr.appendChild(cell[callDate]);
			if (i % 7 == 6) tbody.appendChild(tr);
		}
		
		tbody.appendChild(tr);
		table.appendChild(tbody);
		div.appendChild(table);
		wrapper.appendChild(div);

		target.appendChild(wrapper);
		this.getEvent(crYear,this.padNumber((crMonth + 1)),monthTable[crMonth]);
	},
	getEvent: function(y,m,d) {

		var content = this.target;
		var self = this;

		var startMin = google.gdata.DateTime.fromIso8601(y + '-' + m + '-01T00:00:00.000-08:00');
		var startMax = google.gdata.DateTime.fromIso8601(y + '-' + m + '-' + d + 'T00:00:00.000-08:00');

		var handleError = function(error) {
			content.innerHTML = '<pre>' + error + '</pre>';
		};

		var feedUri = "http://www.google.com/calendar/feeds/" + this.feedUri[0] + "/public/full";
		var query = new google.gdata.calendar.CalendarEventQuery(feedUri);
		query.setOrderBy('starttime');
		query.setSortOrder('ascending');
		query.setSingleEvents(true);
		query.setMinimumStartTime(startMin);
		query.setMaximumStartTime(startMax);

		var callback = function(root) {

			var eventEntries = root.feed.getEntries();
			if (eventEntries.length > 0) {

				for (var j = 0, jlen = eventEntries.length; j < jlen; j++) {
					var event = eventEntries[j];
					var times = event.getTimes();

					if (times.length > 0) {
						startDateTime = times[0].getStartTime();
						startJSDate = startDateTime.getDate();
					}
					cell[startJSDate.getDate()].title = event.getTitle().getText();
					cell[startJSDate.getDate()].className += " event1";
				}
			}
		};
		this.calendarService.getEventsFeed(query, callback, handleError);
		var feedUri = "http://www.google.com/calendar/feeds/" + this.feedUri[1] + "/public/full";
		var query = new google.gdata.calendar.CalendarEventQuery(feedUri);
		query.setOrderBy('starttime');
		query.setSortOrder('ascending');
		query.setSingleEvents(true);
		query.setMinimumStartTime(startMin);
		query.setMaximumStartTime(startMax);

		var callback = function(root) {

			var eventEntries = root.feed.getEntries();
			if (eventEntries.length > 0) {

				for (var j = 0, jlen = eventEntries.length; j < jlen; j++) {
					var event = eventEntries[j];
					var times = event.getTimes();

					if (times.length > 0) {
						startDateTime = times[0].getStartTime();
						startJSDate = startDateTime.getDate();
					}
					cell[startJSDate.getDate()].title = event.getTitle().getText();
					cell[startJSDate.getDate()].className += " event2";
				}
			}
		};
		this.calendarService.getEventsFeed(query, callback, handleError);
	},
	addEvent: function(fn){
		try{
			window.addEventListener("load",fn,false);
		}catch(e){
			window.attachEvent("onload",fn);
		}
	}
}