// Version 10.02.09
// Version 10.02.11
	// Removed the need to manually call CalendarSet.setTheme('default')

var CalendarSet=
{
	_themeSet: false,
	_picker:
	{
		calendar: null,
		input: null,
		onclick: null
	},
	
	pickDate: function(input, onclick)
	{
		if(!!this._picker.input)
			this._picker.input.parentNode.removeChild(this._picker.calendar.div);
		
		if(!!input && this._picker.input!=input)
		{
			this._picker.input=input;
			this._picker.onclick=onclick;
			this._picker.calendar=new this._Calendar
			({
				css_class: 'picker',
				append_after: true,
				compact: true,
				start_date: input.value,
				onclick:function(date)
				{
					CalendarSet._picker.input.value=(date.getMonth()+1)+'/'+date.getDate()+'/'+date.getFullYear();
					
					if(!!CalendarSet._picker.onclick)
						(CalendarSet._picker.onclick.partial(date).bind(this))();
					
					CalendarSet.pickDate();
				}
			});
			if(this._picker.input.value!='')
				this._picker.calendar.addEvent({timestamp: CalendarSet.stringToDate(this._picker.input.value)});
			this._picker.calendar.write(input);
		}
		else
		{
			this._picker.calendar=null;
			this._picker.input=null;
			this._picker.onclick=null;
		}
	},
	
	_Calendar: function(options)
	{
		var parts;
		
		this.css_class=options.css_class;
		this.append_after=options.append_after;
		this.compact=options.compact;
		this.onclick=options.onclick;
		
		if(!!options.start_date)
		{
			if(typeof(options.start_date)=='object')
				this.date_shown=options.start_date;
			else if(typeof(options.start_date)=='string')
				this.date_shown=CalendarSet.stringToDate(options.start_date);
		}
		else
			this.date_shown=new Date();
		this.date_shown.setDate(1);
		
		this.container_element=null;
		this.events=[];
		
		if(!!options.events)
		{
			for(i=0; i<options.events.length; i++)
				this.addEvent(new CalendarSet.Event(options.events[i]));
		}
		
		if(!CalendarSet._themeSet)
			CalendarSet.setTheme('default');
	},
	
	Full: function(options)
	{
		if(!options)
			options={};
		options.css_class='full';
		options.compact=false;
		options.append_after=false;
		return (new CalendarSet._Calendar(options));
	},
	
	Mini: function(options)
	{
		if(!options)
			options={};
		options.css_class='mini';
		options.compact=true;
		options.append_after=false;
		return (new CalendarSet._Calendar(options));
	},
	
	Event: function(options)
	{
		if(typeof(options.timestamp)=='object')
			this.timestamp=options.timestamp;
		else
		{
			options.timestamp=parseInt(options.timestamp);
			if(options.timestamp<10000000000) // Timestamp must be in seconds; Javascript needs milliseconds
				options.timestamp*=1000;
			this.timestamp=new Date(options.timestamp);
		}
		if(!!options.title)
			this.title=options.title;
		if(!!options.description)
			this.description=options.description;
		if(!!options.href)
			this.href=options.href;
		if(!!options.onclick)
			this.onclick=options.onclick;
	},
	
	setTheme: function(theme)
	{
		var fileref;
		
		fileref=document.createElement('link');
		fileref.setAttribute('rel', 'stylesheet');
		fileref.setAttribute('type', 'text/css');
		fileref.setAttribute('href', '/themes/CalendarSet/'+theme+'/theme.css');
		fileref.setAttribute('media', 'screen');
		document.getElementsByTagName('head')[0].appendChild(fileref);
		
		fileref=document.createElement('link');
		fileref.setAttribute('rel', 'stylesheet');
		fileref.setAttribute('type', 'text/css');
		fileref.setAttribute('href', '/themes/CalendarSet/'+theme+'/print.css');
		fileref.setAttribute('media', 'print');
		document.getElementsByTagName('head')[0].appendChild(fileref);
		
		this._themeSet=true;
		return this;
	},
	
	stringToDate: function(string)
	{
		var parts;
		
		parts=string.split(/[\/\-\.]/);
		return new Date(parts[2], parts[0]-1, parts[1], 0, 0, 0);
	}
};

CalendarSet._Calendar.prototype.write=function(element)
{
	var div, table, tbody, tr, td, row, col, i, days_in_month, display_date, weeks_in_month, today;
	
	if(!!element)
		this._element=element;
	
	div=document.createElement('div');
	div.className='CalendarSet CalendarSet_'+this.css_class;
	table=document.createElement('table');
	div.appendChild(table);
	tbody=document.createElement('tbody');
	table.appendChild(tbody);
	
	tr=document.createElement('tr');
	td=document.createElement('td');
	td.className='jump_month';
	td.onclick=function()
	{
		this.jumpMonths(-1).write();
	}.bind(this);
	td.appendChild(document.createTextNode('<'));
	tr.appendChild(td);
	td=document.createElement('td');
	td.className='month';
	td.setAttribute('colSpan', '5');
	if(this.compact)
		td.appendChild(document.createTextNode(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'][this.date_shown.getMonth()] +' '+ this.date_shown.getFullYear()));
	else
		td.appendChild(document.createTextNode(['January','Febuary','March','April','May','June','July','August','September','October','November','December'][this.date_shown.getMonth()] +' '+ this.date_shown.getFullYear()));
	tr.appendChild(td);
	td=document.createElement('td');
	td.className='jump_month';
	td.onclick=function()
	{
		this.jumpMonths(1).write();
	}.bind(this);
	td.appendChild(document.createTextNode('>'));
	tr.appendChild(td);
	tbody.appendChild(tr);
	
	tr=document.createElement('tr');
	for(col=0; col<7; col++)
	{
		td=document.createElement('td');
		td.className='weekday';
		if(this.compact)
			td.appendChild(document.createTextNode(['S','M','T','W','T','F','S'][col]));
		else
			td.appendChild(document.createTextNode(['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][col]));
		tr.appendChild(td);
	}
	tbody.appendChild(tr);
	
	days_in_month=[31,28+(this.date_shown.getFullYear()%4==0? 1 : 0),31,30,31,30,31,31,30,31,30,31][this.date_shown.getMonth()];
	display_date=new Date(this.date_shown.getTime());
	display_date.setDate(1);
	weeks_in_month=Math.ceil((display_date.getDay() + days_in_month) / 7);
	today=new Date();
	for(row=0; row<weeks_in_month; row++)
	{
		tr=document.createElement('tr');
		for(col=0; col<7; col++)
		{
			td=document.createElement('td');
			td.className='day';
			if(!((row==0 && col<display_date.getDay()) || (row==weeks_in_month-1 && display_date.getMonth()!=this.date_shown.getMonth())))
			{
				if(!!this.onclick)
				{
					td.onclick=this.onclick.partial(new Date(display_date)).bind(this);
					td.className+=' clickable';
				}
				td.appendChild(document.createTextNode(display_date.getDate()));
				if(display_date.getDate()==today.getDate() && display_date.getMonth()==today.getMonth() && display_date.getFullYear()==today.getFullYear())
					td.className+=' today';
				for(i=0; i<this.events.length; i++)
				{
					if(display_date.getDate()==this.events[i].timestamp.getDate() && display_date.getMonth()==this.events[i].timestamp.getMonth() && display_date.getFullYear()==this.events[i].timestamp.getFullYear())
					{
						td.className+=' selected';
						if(!!this.events[i].href)
						{
							td.className+=' clickable';
							td.onclick=function(href)
							{
								location.href=href;
							}.partial(this.events[i].href);
						}
						if(!!this.events[i].onclick)
						{
							td.className+=' clickable';
							td.onclick=this.events[i].onclick.bind(this.events[i]);
						}
						
						if(!this.compact)
						{
							td.appendChild(document.createTextNode(this.events[i].title)); // FIXME
						}
						else
						{
							if(this.events[i].title)
								td.title=this.events[i].title;
						}
					}
				}
				
				display_date.setDate(display_date.getDate()+1);
			}
			tr.appendChild(td);
		}
		tbody.appendChild(tr);
	}
	
	if(this.append_after)
	{
		if(this.div)
			this._element.parentNode.removeChild(this.div);
		this.div=this._element.parentNode.appendChild(div);
	}
	else
	{
		while(this._element.childNodes.length > 0)
			this._element.removeChild(this._element.childNodes[0]);
		this.div=this._element.appendChild(div);
	}
}

CalendarSet._Calendar.prototype.jumpMonths=function(months)
{
	this.date_shown.setMonth(this.date_shown.getMonth()+months);
	return this;
}

CalendarSet._Calendar.prototype.addEvent=function(event)
{
	this.events.push(event);
	return this;
}

