// STRING

var STR_PAD_LEFT = 1;
var STR_PAD_RIGHT = 2;
var STR_PAD_BOTH = 3;
 
function pad(str, len, pad, dir) {
 
	if (typeof(len) == "undefined") { var len = 0; }
	if (typeof(pad) == "undefined") { var pad = ' '; }
	if (typeof(dir) == "undefined") { var dir = STR_PAD_RIGHT; }
 
	if (len + 1 >= str.length) {
 
		switch (dir){
 
			case STR_PAD_LEFT:
				str = Array(len + 1 - str.length).join(pad) + str;
			break;
 
			case STR_PAD_BOTH:
				var right = Math.ceil((padlen = len - str.length) / 2);
				var left = padlen - right;
				str = Array(left+1).join(pad) + str + Array(right+1).join(pad);
			break;
 
			default:
				str = str + Array(len + 1 - str.length).join(pad);
			break;
 
		} // switch
 
	}
 
	return str;
 
}

// DATE

Date.prototype.getDayOfWeekStartingAtMonday = function()
{
	dayOfWeek = this.getDay(); // Sunday = 0, Saturday = 6
	//console.log('dayOfWeek=', dayOfWeek);
	
	dayOfWeekMon = dayOfWeek-1;
	if (dayOfWeekMon < 0)
	{
		dayOfWeekMon = dayOfWeekMon+7;
	}
	//console.log('dayOfWeekMon=', dayOfWeekMon);
	
	return dayOfWeekMon;
}

Date.prototype.getYMD = function()
{
	year  = this.getFullYear().toString();
	month = pad((this.getMonth()+1).toString(), 2, '0', STR_PAD_LEFT);
	day   = pad(this.getDate().toString(), 2, '0', STR_PAD_LEFT);
	
	return year+month+day;
}

Date.prototype.getWeek = function()
{
	//console.log("getWeek()", this);
	
	var onejan = new Date(this.getFullYear(),0,1);
	
	var dateDiff = (this - onejan);
	//console.log('dateDiff=', dateDiff);
	
	var numDays = (dateDiff / 86400000) + onejan.getDayOfWeekStartingAtMonday()
	//console.log('numDays=', numDays);
	
	return Math.ceil((numDays)/7);
}

Date.prototype.addDay = function()
{
	this.setDate(this.getDate()+1);
}

Date.prototype.subtractDay = function()
{
	this.setDate(this.getDate()-1);
}

function nameOfMonth (m)
{
	if (m == 0) { return 'January'; }
	if (m == 1) { return 'February' } // F
	if (m == 2) { return 'March'; } // M
	if (m == 3) { return 'April'; } // A
	if (m == 4) { return 'May'; } // M
	if (m == 5) { return 'June'; } // J
	if (m == 6) { return 'July'; } // J
	if (m == 7) { return 'August'; } // A
	if (m == 8) { return 'September'; } // S
	if (m == 9) { return 'October'; } // O
	if (m == 10) { return 'November'; } // N
	if (m == 11) { return 'December'; } // D
}

var calendarDate = new Date();
var calendarY = 0;
var calendarM = 0;

function daysInMonth (y, m)
{
	if (m == 0) { return 31; } // J
	if (m == 1) { if (y % 4 == 0 && y % 100 != 0) { return 29; } else { return 28; } } // F
	if (m == 2) { return 31; } // M
	if (m == 3) { return 30; } // A
	if (m == 4) { return 31; } // M
	if (m == 5) { return 30; } // J
	if (m == 6) { return 31; } // J
	if (m == 7) { return 31; } // A
	if (m == 8) { return 30; } // S
	if (m == 9) { return 31; } // O
	if (m == 10) { return 30; } // N
	if (m == 11) { return 31; } // D
}

function lastYearYM(y, m)
{
	lastYear = [ y-1, m ];
	
	return lastYear;
}

function lastMonthYM(y, m)
{
	if (m == 0)
	{
		lastMonth = [ y-1, 11 ];
	}
	else
	{
		lastMonth = [ y, m-1 ];
	}
	
	return lastMonth;
}

function nextMonthYM(y, m)
{
	if (m == 11)
	{
		nextMonth = [ y+1, 0 ];
	}
	else
	{
		nextMonth = [ y, m+1 ];
	}
	
	return nextMonth;
}

function nextYearYM(y, m)
{
	nextMonth = [ y+1, m ];
	
	return nextMonth;
}

function setMonthDirect(targetElementId, y, m)
{
	//console.log("setMonthDirect(", targetElementId, y, m, ")");
	
	mdDate = new Date();
	mdDate.setYear(y);
	mdDate.setMonth(m);
	mdDate.setDate(1);
	//console.log(mdDate);
	
	drawCalendar(targetElementId, mdDate);
}

function setMonth(monthselectElementId, targetElementId)
{
	//console.log('setMonth(', monthselectElementId, targetElementId, ')');
	
	monthSelector = document.getElementById(monthselectElementId);
	//console.log(monthSelector.value);
	
	ym = monthSelector.value;
	
	ymX = ym.split('-');
	
	newYear = ymX[0];
	newMonth = Number(ymX[1])-1;
	
	//console.log(newYear, newMonth);
	
	mdDate = new Date();
	mdDate.setYear(newYear);
	mdDate.setMonth(newMonth);
	mdDate.setDate(1);
	//console.log(mdDate);
	
	drawCalendar(targetElementId, calendarDate);
}

function goToToday(targetElementId)
{
	//console.log('goToToday');
	
	todaysDate = new Date();
	//console.log(todaysDate);
	
	drawCalendar(targetElementId, todaysDate);
}

function drawCalendar(targetElementId, dateObject)
{
	//console.log("drawCalendar(", targetElementId, ")");
	
	todaysDateReference = new Date();
	//console.log(todaysDateReference);
	
	todayYMD = todaysDateReference.getYMD();
	
	if (typeof(dateObject) == 'undefined')
	{
		dateObject = calendarDate;
	}
	
	//console.log(dateObject);
	
	dateObject.setDate(1);
	//console.log(dateObject);
	
	thisYear  = dateObject.getFullYear();
	thisMonth = dateObject.getMonth();
	
	firstDayOfWeek = dateObject.getDayOfWeekStartingAtMonday(); // Sunday = 0, Saturday = 6
	//console.log('firstDayOfWeek=',firstDayOfWeek);
	
	calendarFirstDayOfWeek = firstDayOfWeek;
	//console.log('calendarFirstDayOfWeek=',calendarFirstDayOfWeek);
	
	calendarDays = daysInMonth(dateObject.getFullYear(), dateObject.getMonth());
	//console.log('calendarDays=', calendarDays);
	
	lastMonth = lastMonthYM(dateObject.getFullYear(), dateObject.getMonth());
	//console.log('lastMonth=', lastMonth);
	
	daysInLastMonth = daysInMonth(lastMonth[0], lastMonth[1]);
	//console.log('daysInLastMonth=', daysInLastMonth);
	
	nextMonth = nextMonthYM(dateObject.getFullYear(), dateObject.getMonth());
	//console.log('nextMonth=', nextMonth);
	
	runningDate = new Date();
	
	myRows = [ ];
	myCells = [ ];
	if (calendarFirstDayOfWeek > 0)
	{
		firstDate = new Date();
		firstDate.setYear(lastMonth[0]);
		firstDate.setMonth(lastMonth[1]);
		firstDate.setDate(daysInLastMonth-calendarFirstDayOfWeek+1);
		
		for (var z = 0; z < calendarFirstDayOfWeek; z++)
		{
			myDate = (daysInLastMonth-calendarFirstDayOfWeek+z+1);

			runningDate.setYear(lastMonth[0]);
			runningDate.setMonth(lastMonth[1]);
			runningDate.setDate(myDate);
			
			dateId = runningDate.getYMD();
			
			myCells.push("<td class='Spc'><a href='javascript:selectDay("+lastMonth[0]+", "+lastMonth[1]+", "+myDate+");' id='day"+dateId+"' class='NotSelected'><span>"+myDate+"</span></a></td>");
		}
		
		weekNumber = dateObject.getWeek();
	}
	else
	{
		weekNumber = dateObject.getWeek()-1;
	}
	
	calendarDay = 1;
	while (calendarDay <= calendarDays)
	{
		runningDate.setYear(thisYear);
		runningDate.setMonth(thisMonth);
		runningDate.setDate(calendarDay);
		
		dateId = runningDate.getYMD();
		
		cellClass = "Day";
		if (dateId == todayYMD)
		{
			cellClass += " Today";
		}
		
		myCells.push("<td class='"+cellClass+"'><a href='javascript:selectDay("+thisYear+", "+thisMonth+", "+calendarDay+");' id='day"+dateId+"' class='NotSelected'><span>"+calendarDay+"</span></a></td>");
		
		if (myCells.length == 7)
		{
			weekNumber++;
			myRows.push("<tr id='week"+weekNumber+"' class='NotSelected'>"+myCells.join('')+"<td class='Wk'><a href='javascript:selectWeek("+thisYear+", "+weekNumber+");'>&laquo;</a></td></tr>");
			myCells = [ ];
		}
		
		calendarDay++;
		dateObject.setDate(calendarDay);
		
		runningDate.addDay();
	}
	
	daysNextMonth = 1;
	if (myCells.length > 0)
	{
		for (var z = myCells.length; z <= 6 ; z++)
		{
			runningDate.setYear(nextMonth[0]);
			runningDate.setMonth(nextMonth[1]);
			runningDate.setDate(daysNextMonth);
			
			dateId = runningDate.getYMD();
			
			myCells.push("<td class='Spc'><a href='javascript:selectDay("+nextMonth[0]+", "+nextMonth[1]+", "+daysNextMonth+");' id='day"+dateId+"' class='NotSelected'><span>"+daysNextMonth+"</span></a></td>");
			daysNextMonth++;
		}
		
		weekNumber = weekNumber+1;
		myRows.push("<tr id='week"+weekNumber+"' class='NotSelected'>"+myCells.join('')+"<td class='Wk'><a href='javascript:selectWeek("+thisYear+", "+weekNumber+");'>&laquo;</a></td></tr>");
	}
	
	headRow = "<tr><th class='D'>M</th>\n"
	         +"    <th class='D'>T</th>\n"
	         +"    <th class='D'>W</th>\n"
	         +"    <th class='D'>T</th>\n"
	         +"    <th class='D'>F</th>\n"
	         +"    <th class='W'>S</th>\n"
	         +"    <th class='W'>S</th>\n"
	         +"    <th class='X'><a href='javascript:unselectDates();'>X</a></th></tr>\n";
	
	calendarHtml = "<div id='monthSelect' class='NotSelected'>\n"
	              +"<table id='calendarTable'>\n"
	              +headRow
	              +myRows.join('')
	              +"</table>\n"
	              +"</div>\n";
	
	backOneYear     = lastYearYM(thisYear, thisMonth);
	backOneMonth    = lastMonthYM(thisYear, thisMonth);
	thisMonthText   = nameOfMonth(thisMonth)+" "+thisYear;
	forwardOneMonth = nextMonthYM(thisYear, thisMonth);
	forwardOneYear  = nextYearYM(thisYear, thisMonth);
	
	navigationHtml = "<div class='Navigation'>\n"
	                +"<table><tr>\n"
	                +"<td class='M'><a href=\"javascript:selectMonth('"+thisYear+"', '"+thisMonth+"');\" class='Month'>"+thisMonthText+"</a></td>\n"
	                +"<td class='B'><a href=\"javascript:setMonthDirect('"+targetElementId+"', "+backOneMonth[0]+", "+backOneMonth[1]+");\">&lt;</a></td>\n"
	                +"<td class='T'><a href=\"javascript:goToToday('"+targetElementId+"');\">&bull;</a></td>\n"
	                +"<td class='F'><a href=\"javascript:setMonthDirect('"+targetElementId+"', "+forwardOneMonth[0]+", "+forwardOneMonth[1]+");\">&gt;</a></td>\n"
	                +"</tr></table>\n"
	                +"</div>\n";
	
	combinedHtml = "<div class='SelectCalendar'>\n"
	              +navigationHtml
	              +calendarHtml
	              +"</div>\n";
	
	targetDiv = document.getElementById(targetElementId);
	
	targetDiv.innerHTML = combinedHtml;
	
	calendarY = thisYear;
	calendarM = thisMonth;
}

var calendarFunctionsLoaded = true;