/*  Simple Calendar Helper, version 1.3.1
 *  (c) 2005 Carl-Johan Kihlbom <cj@newcode.se>
 *
 *  Simple Calendar Helper is freely distributable under the terms of an
 *  MIT-style license.
 *
 *  For details, see the Simple Calendar Helper web site: http://newcode.se/lab/calendar/
 *
/*--------------------------------------------------------------------------*/

function Calendar (date, object, method, include_time, callback)
{
	// Constants
	this.ABBR_DAY_NAMES = ['Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör'];
	this.ABBR_MONTH_NAMES = ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'];
	
	// Public Methods
	this.selectCell = selectCell;
	this.changeMonth = changeMonth;
	this.selectDate = selectDate;
	this.setTitle = setTitle;
	this.values = values;
	this.dateString = dateString;
	this.dateTimeString = dateTimeString;
	
	// Private Methods
	this._initialize = initialize;
	this._initDate = initDate;
	this._initTable = initTable;
	this._initThead = initThead;
	this._initTime = initTime;
	this._drawTable = drawTable;
	this._createRow = createRow;
	this._createCell = createCell;
	this._daysInMonth = daysInMonth;
	this._firstWeekdayInMonth = firstWeekdayInMonth;
	this._callback = callback;
	
	// Public Variables
	this.date = date || new Date();
	this.object = object || 'calendar';
	this.method = method || 'control';
	this.name = object + '_' + method;
	
	// Private variables
	this._include_time = include_time;
	this._div;
	this._table;
	this._tbody;
	this._day;
	this._now_y;
	this._now_m;
	this._now_d;
	this._dim;
	this._fwdim;
	this._selected_date;
	
	this._initialize();
}

function selectCell (cell)
{
	this.date.setDate(cell.innerHTML);
	this.selectDate();
	
	if (this._callback)
		this._callback();
}

function changeMonth (change)
{
	this.date.setDate(1);
	
	var current_month = this.date.getMonth();
	if (current_month > 0 || change == +1)
	{
		this.date.setMonth(current_month + change);
	}
	else
	{
		this.date.setFullYear(this.date.getFullYear() - 1);
		this.date.setMonth(11);
	}
	
	this.setTitle();
	this._dim = this._daysInMonth();
	this._fwdim = this._firstWeekdayInMonth();
	
	this.date.setDate(Math.min(this._selected_date, this._dim));
	
	this.selectDate();
}

function selectDate (date)
{
	if (date)
		this.date = new Date(date);
		
	this._selected_date = this.date.getDate();
	
	document.getElementById(this.name + '_1i').value = this.date.getFullYear();
	document.getElementById(this.name + '_2i').value = this.date.getMonth() + 1;
	document.getElementById(this.name + '_3i').value = this.date.getDate();
	
	this._drawTable();
}

function setTitle (title)
{
	if (!title)
		title = this.ABBR_MONTH_NAMES[this.date.getMonth()] + ' ' + this.date.getFullYear();
	
	this._title_cell.innerHTML = title;
}

function values ()
{
	var year = document.getElementById(this.name + '_1i').value;
	var month = document.getElementById(this.name + '_2i').value;
	var date = document.getElementById(this.name + '_3i').value;
	var hour = document.getElementById(this.name + '_4i').value;
	var minute = document.getElementById(this.name + '_5i').value;
	
	return [year, month, date, hour, minute];
}

function dateString ()
{
	var month = this.date.getMonth() + 1;
	var day = this.date.getDate();
	
	var string = "";
	string += this.date.getFullYear();
	string += (month < 10 ? '0' : '') + month;
	string += (day < 10 ? '0' : '') + day;
	
	return string;
}

function dateTimeString ()
{
	var hours = this.date.getHours();
	var minutes = this.date.getMinutes();
	var seconds = this.date.getSeconds();
	
	var string = this.dateString();
	string += (hours < 10 ? '0' : '') + hours;
	string += (minutes < 10 ? '0' : '') + minutes;
	string += (seconds < 10 ? '0' : '') + seconds;
	
	return string;
}

function initialize ()
{
	this._div = document.getElementById(this.name);
	
	this._initDate();
	this._initTime();
	this.setTitle();
}

function initDate ()
{
	for (var i = 1; i <= 3; i++)
		this._div.innerHTML += '<input type="hidden" name="' + this.object + '[' + this.method + '(' + i +'i)]" id="' + this.name + '_' + i + 'i" />'
	
	this._initTable();
	
	today = new Date();
	this._now_y = today.getFullYear();
	this._now_m = today.getMonth();
	this._now_d = today.getDate();
	this._dim = this._daysInMonth();
	this._fwdim = this._firstWeekdayInMonth();
	
	this.selectDate();
}

function initTable ()
{
	this._table = this._div.appendChild(document.createElement('table'));
	this._table.cellSpacing = 0;
	this._table.cellPadding = 2;
	this._initThead();

	this._tbody = this._table.appendChild(document.createElement('tbody'));
}

function initThead ()
{
	this._table.createTHead();
	for (var i = 0; i < 2; i++)
		this._table.tHead.insertRow(i);

	var prev_month = this._table.tHead.rows[0].insertCell(0);
	prev_month.style.textAlign = 'left';
	prev_month.innerHTML = '<a href="#" onclick="' + this.name + '.changeMonth(-1); return false;">&laquo;</a>';

	this._title_cell = this._table.tHead.rows[0].insertCell(1);
	this._title_cell.style.textAlign = 'center';
	this._title_cell.colSpan = 5;

	var next_month = this._table.tHead.rows[0].insertCell(2);
	next_month.style.textAlign = 'right';
	next_month.innerHTML = '<a href="#" onclick="' + this.name + '.changeMonth(+1); return false;">&raquo;</a>';

	for (var i = 1; i <= 7; i++)
	{
		var cell = document.createElement('th');
		this._table.tHead.rows[1].appendChild(cell);
		cell.innerHTML = this.ABBR_DAY_NAMES[i % 7];
	}
}

function initTime ()
{
	this.date.setSeconds(0);
	
	if (!this._include_time)
	{
		this.date.setHours(0);
		this.date.setMinutes(0);
		
		return;
	}
	
	var min = this.date.getMinutes();
	var diff = min % 5;
	if (diff > 0)
		min = min + (5 - diff)
		
	this.date.setMinutes(min);
	
	var p = document.createElement('p');
	this._div.appendChild(p);
	p.innerHTML = 'Time: <select name="' + this.object + '[' + this.method + '(4i)]" id="' + this.name + '_4i"></select>:' + 
											'<select name="' + this.object + '[' + this.method + '(5i)]" id="' + this.name + '_5i"></select>';
	
	var hour_menu = document.getElementById(this.name + '_4i');
	var min_menu = document.getElementById(this.name + '_5i');
	
	for (var i = 0; i < 24; i++)
		hour_menu.options[hour_menu.options.length] = new Option((i<10 ? '0'+i : i), i);
	
	for (var i = 0; i < 60; i += 5)
		min_menu.options[min_menu.options.length] = new Option((i<10 ? '0'+i : i), i);
	
	hour_menu.selectedIndex = this.date.getHours();
	min_menu.selectedIndex = min / 5;
}

function drawTable ()
{
	this._day = 0;
	
	while (this._tbody.rows.length > 0)
		this._tbody.deleteRow(0);
	
	while (this._day < this._dim)
		this._createRow();
}

function createRow ()
{
	var row = this._tbody.insertRow(this._tbody.rows.length);
	for (var i = 1; i <= 7; i++)
		this._createCell(row, i % 7)
}

function createCell (row, wday)
{
	var cell = row.insertCell(row.cells.length);
	if ((!this._day && wday != this._fwdim) || (this._day == this._dim))
	{
		cell.innerHTML = "&nbsp;";
		return;
	}
	
	this._day++;
	
	if (this._day == this._now_d && this.date.getFullYear() == this._now_y && this.date.getMonth() == this._now_m)
		Element.addClassName(cell, "today");
	if (this._day == this._selected_date)
		Element.addClassName(cell, "selected");
	
	cell.innerHTML = "<a href=\"#\" onclick=\"" + this.name + ".selectCell(this); return false;\">" + this._day + "</a>";
}

function daysInMonth ()
{
	var d = new Date(this.date);
	d.setMonth(d.getMonth()+1);
	d.setDate(0);
	
	return d.getDate();
}

function firstWeekdayInMonth ()
{
	var d = new Date(this.date);
	d.setDate(1);
	
	return d.getDay();
}
