﻿/* defaults */
/*
var sCalImageFolder = './f/';
var sCalLang = 'ru';
var iCalArrWidth = 16;
var iCalArrHeight = 16;
*/

var oCalArrPrev = new Image(iCalArrWidth, iCalArrHeight);
oCalArrPrev.src = sCalImageFolder + 'arr-cal-prev.gif';
var oCalArrPrevDisabled = new Image(iCalArrWidth, iCalArrHeight);
oCalArrPrevDisabled.src = sCalImageFolder + 'arr-cal-prev-d.gif';
var oCalArrNext = new Image(iCalArrWidth, iCalArrHeight);
oCalArrNext.src = sCalImageFolder + 'arr-cal-next.gif';
var oCalArrNextDisabled = new Image(iCalArrWidth, iCalArrHeight);
oCalArrNextDisabled.src = sCalImageFolder + 'arr-cal-next-d.gif';

var sCalIdPrefix = 'cal';

var aCalArrLabels = {
	ru: { prev: 'предыдущий месяц', next: 'следующий месяц' }
}

var aCalMonthNames = {
	ru: ['январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь']
}
var aCalMonthNamesGenitive = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']

var aWeekdayClass = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
var aCalWeekdayAbbrs = {
	ru: ['пн','вт','ср','чт','пт','сб','вс']
}
var aCalWeekAbbrs = { ru: 'нд', en: 'wk', bg: 'сд' }

var aToday = { ru: 'Сегодня', en: 'Today', bg: 'Днес' }


/*=========================*/
/*     calendar object     */
/*=========================*/

function Calendar(sCalId, aOptions) {
	this.sCalId = sCalId;
	this.dtStart = (aOptions.dtStart)? aOptions.dtStart : null;
	this.dtSelected = new Date(aOptions.dtSelected);
	this.dtEnd = (aOptions.dtEnd)? aOptions.dtEnd : null;
	this.dtCurrent = new Date(aOptions.dtSelected);
	this.aDates = aOptions.aDates;

	this.updateCurrents();

	this.fDateHandler = aOptions.fDateHandler;

	this.sAppendAfterId = aOptions.sAppendAfterId;

	/* build HTML */
	this.buildTable();
	
	return this;
}

Calendar.prototype.updateCurrents = function() {
	if (this && this.sCalId) {
		this.iCurrYear = this.dtCurrent.getFullYear();
		this.iCurrMonth = this.dtCurrent.getMonth();
		this.iMonthStart = this.getMonthStart();
		this.iMonthLength = this.getMonthLength();
	}
}

Calendar.prototype.getMonthStart = function(iMonth, iYear) {
	if (!iYear) iYear = this.iCurrYear;
	if (!iMonth) iMonth = this.iCurrMonth;
	
	var dtToMeasure = new Date(iYear, iMonth, 1);
	var iStart = dtToMeasure.getDay();
	return (iStart == 0)? 7 : iStart;
}

Calendar.prototype.getMonthLength = function(iMonth, iYear) {
	if (!iYear) iYear = this.iCurrYear;
	if (!iMonth) iMonth = this.iCurrMonth;
	
	var dtToMeasure = new Date(iYear, iMonth, 1);
	dtToMeasure.setMonth(dtToMeasure.getMonth() + 1);
	dtToMeasure.setDate(0);
	return dtToMeasure.getDate();
}


/* date click */
function executeCaledarDate(sCalId, iDate) {
	if (aCalendars[sCalId] && aCalendars[sCalId].fDateHandler) {
		var dtChosen = new Date(aCalendars[sCalId].iCurrYear, aCalendars[sCalId].iCurrMonth, iDate);
		aCalendars[sCalId].fDateHandler(dtChosen);
	}
}

/* month switch */
function showPrevCalendarMonth(sCalId) {
	if (aCalendars[sCalId])	aCalendars[sCalId].showPrevMonth();
}

Calendar.prototype.showPrevMonth = function(oThis) {
	if (this && this.dtCurrent) {
		if (this.dtCurrent.getMonth() == 0) {
			/* safari didn't get it the usual way */
			this.dtCurrent.setFullYear(this.dtCurrent.getFullYear() - 1);
			this.dtCurrent.setMonth(11, 15);
		} else {
			this.dtCurrent.setMonth(this.dtCurrent.getMonth() - 1, 15);
		}
		this.updateCurrents();
		this.updateTable();
	}
}

function showNextCalendarMonth(sCalId) {
	if (aCalendars[sCalId])	aCalendars[sCalId].showNextMonth();
}

Calendar.prototype.showNextMonth = function() {
	if (this && this.dtCurrent) {
		this.dtCurrent.setMonth(this.dtCurrent.getMonth() + 1, 15);
		this.updateCurrents();
		this.updateTable();
	}
}


/* build HTML table and contents */

Calendar.prototype.buildTable = function() {
	var sHTML = '<div id="' + this.sCalId + 'Div">';
	sHTML += this.buildHTML();
	sHTML += '</div>';

	if (this.sAppendAfterId) {
		var ePointer = document.getElementById(this.sAppendAfterId);
		if (ePointer) {
			var eContainer = document.createElement('div');
			ePointer.parentNode.insertBefore(eContainer, ePointer.nextSibling);
			eContainer.innerHTML = sHTML;
		}
	} else {
		document.write(sHTML);
	}
}

Calendar.prototype.updateTable = function() {
	if (this && this.sCalId) {
		if (!this.eContainer) this.eContainer = document.getElementById(this.sCalId + 'Div');
		if (this.eContainer) {
			this.eContainer.innerHTML = this.buildHTML();
		}
	}
}

Calendar.prototype.buildHTML = function() {
	var sHTML = '<table class="calendar ' + aWeekdayClass[this.iMonthStart] + ' m' + this.iMonthLength + '" id="' + this.sCalId + 'Table">';

	var bShowNextMonth = true;
	var bShowPrevMonth = true;
	if (this.aDates) {
		var sCurrentMonth = this.iCurrMonth + 1;
		sCurrentMonth = (sCurrentMonth < 10)? '0' + sCurrentMonth : sCurrentMonth;
		sCurrentMonth = this.iCurrYear + '-' + sCurrentMonth;
		for (var i = 0; i < this.aDates['months'].length; i++) {
			if (this.aDates['months'][i] == sCurrentMonth) {
				bShowNextMonth = (i + 1 < this.aDates['months'].length)? true : false;
				bShowPrevMonth = (i > 0)? true : false;
			}
		}
	}

	/* month and arrows */
	sHTML += '<tr><th colspan="7">';
		/* next arrow */
		if (this.dtEnd && !this.aDates) {
			this.dtCurrent.setMonth(this.dtCurrent.getMonth() + 1, 1);
			if (this.dtEnd < this.dtCurrent) bShowNextMonth = false;
			this.dtCurrent.setDate(0);
		}
		sHTML += '<img src="';
		sHTML += (bShowNextMonth)? oCalArrNext.src : oCalArrNextDisabled.src;
		sHTML += '" width="' + iCalArrWidth + '" height="' + iCalArrHeight + '" hspace="0"';
		if (bShowNextMonth) {
			sHTML += ' class="next" onclick="showNextCalendarMonth(\'' + this.sCalId + '\');" title="' + aCalArrLabels[sCalLang]['next'] + '"'
		} else {
			sHTML += ' class="next disabled"';
		}
		sHTML += '/>';

		/* prev arrow */
		if (this.dtStart && !this.aDates) {
			this.dtCurrent.setDate(0);
			if (this.dtStart > this.dtCurrent) bShowPrevMonth = false;
			this.dtCurrent.setMonth(this.dtCurrent.getMonth() + 1, 1);
		}
		sHTML += '<img src="';
		sHTML += (bShowPrevMonth)? oCalArrPrev.src : oCalArrPrevDisabled.src;
		sHTML += '" width="' + iCalArrWidth + '" height="' + iCalArrHeight + '" hspace="0"';
		if (bShowPrevMonth) {
			sHTML += ' class="prev" onclick="showPrevCalendarMonth(\'' + this.sCalId + '\');" title="' + aCalArrLabels[sCalLang]['prev'] + '"'
		} else {
			sHTML += ' class="prev disabled"';
		}
		sHTML += '/>';

		/* month and year */
		sHTML += aCalMonthNames[sCalLang][this.iCurrMonth] + ' ' + this.iCurrYear;
	sHTML += '</th></tr>';

	/* weekdays labels */
	sHTML += '<tr class="days">';
	for (var i = 0; i < aCalWeekdayAbbrs[sCalLang].length; i++) {
		sHTML += '<td';
		if (i > 4) sHTML += ' class="we"';
		sHTML += '>' + aCalWeekdayAbbrs[sCalLang][i] + '</td>';
	}
	sHTML += '</tr>';

	/* days */
	var iDate = 0;
	var dtCurrent = new Date(this.iCurrYear, this.iCurrMonth, 1, 23, 59, 0);
	var iWeek = 1;
	while (iDate < this.iMonthLength) {
		sHTML += '<tr>';
		for (var iWeekday = 1; iWeekday < 8; iWeekday++) {
			if (iWeek == 1 && iWeekday < this.iMonthStart) {
				sHTML += '<td></td>';
			} else if (iDate < this.iMonthLength) {
				sHTML += '<td';
				if (iWeekday > 5) sHTML += ' class="we"'
				sHTML += '>';
				dtCurrent.setDate(++iDate);
				var bSelected = (
					dtCurrent.getFullYear() == this.dtSelected.getFullYear() &&
					dtCurrent.getMonth() == this.dtSelected.getMonth() &&
					dtCurrent.getDate() == this.dtSelected.getDate()
				)? true : false;
				if (bSelected) sHTML += '<b>';
				var bLink = false;
				if (this.aDates) {
					if (
						this.aDates['days'][dtCurrent.getFullYear()] &&
						this.aDates['days'][dtCurrent.getFullYear()][dtCurrent.getMonth()] &&
						this.aDates['days'][dtCurrent.getFullYear()][dtCurrent.getMonth()][dtCurrent.getDate()]
					) bLink = true;
				} else if (this.dtStart <= dtCurrent && this.dtEnd >= dtCurrent) {
					bLink = true;
				}
				if (bLink) {
					sHTML += '<span class="link" onclick="executeCaledarDate(\'' + this.sCalId + '\',\'' + iDate + '\')">' + iDate;
				} else {
					sHTML += '<span>' + iDate;
				}
				if (bSelected) sHTML += '</b>';
				sHTML += '</span></td>';
			}
		}
		sHTML += '</tr>';
		iWeek++;
	}

	sHTML += '</table>';

	return sHTML;
}


/* init functions */

var aCalendars = [];
var iCalNo = 0;
function createCalendar(aOptions) {
	var sCalId = sCalIdPrefix + ++iCalNo;
	aCalendars[sCalId] = new Calendar(sCalId, aOptions);
}

var aCalendarDates = [];
function createXMLCalendar(sResponseXML) {
	var sCalId = sCalIdPrefix + ++iCalNo;
	
	aCalendarDates[sCalId] = [];
	aCalendarDates[sCalId]['days'] = [];
	var aDates = aCalendarDates[sCalId]['days'];
	for (var i = 0; (eDate = sResponseXML.documentElement.getElementsByTagName('DATE')[i]); i++) {
		var iYear  = parseInt(eDate.getAttribute('year'));
		var iMonth = parseInt(eDate.getAttribute('month'));
		var iDay   = parseInt(eDate.getAttribute('day'));
		if (!aDates[iYear]) aDates[iYear] = [];
		if (!aDates[iYear][iMonth]) aDates[iYear][iMonth] = [];
		aDates[iYear][iMonth][iDay] = 1;
	}
	aCalendarDates[sCalId]['months'] = [];
	var aMonths = aCalendarDates[sCalId]['months'];
	for (var i in aDates) {
		for (var j in aDates[i]) {
			var sMonth = parseInt(j) + 1;
			sMonth = (j < 10)? '0' + sMonth : sMonth;
			aMonths[aMonths.length] = i + '-' + sMonth;
		}
	}
	aMonths.sort( function(a,b) { return (a < b)? -1 : 1 } )
	// create calendar
	aCalendars[sCalId] = new Calendar(sCalId, {
		aDates: aCalendarDates[sCalId],
		sAppendAfterId: 'calendarControl',
		fDateHandler: goToDate,
		dtSelected: ((window.dtSelected)? window.dtSelected : new Date())
	});
}


function transformDate(sDate) {
	var aDate = sDate.split('.');
	var sTransformedDate = aDate[0] + ' ' + aCalMonthNamesGenitive[aDate[1] - 1] + ' ' + aDate[2];
	document.write(sTransformedDate);
}