
function addLoadEvent(func) {   
   var oldonload = window.onload;   
   if (typeof window.onload != 'function') {   
     window.onload = func;   
   } else {   
    window.onload = function() {   
       oldonload();   
       func();   
     }   
   }   
 }   



String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/g,"");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/g,"");
}
String.prototype.removeLinebreaks = function() {
	return this.replace(/\r?\n/g,"");
}



String.prototype.stripHTML = function() {
	return this.replace(/<.*?>/g, "");
}


function getCurrentMonthYearInMonthTitleFormat()
{
	var now = new Date();

	function monthText(monthDay)
	{
		var months = [ "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" ];
		return (months[monthDay]);
	}

	return monthText(now.getMonth()) + " '" + now.getFullYear().toString().substr(2);
}



function tableFilter (phrase, table, includePastDates)
{
	var match;

	function stringInArray(string, array)
	{
		for (var i = 0; i < array.length; i++)
		{
			if (string.toLowerCase().indexOf(array[i].toLowerCase()) >= 0)
				return true;
		}
		return false;
	}
	
	words = phrase.toLowerCase().trim().split(" ");

	debugLogEntry (sprintf("words.length=%d", words.length));
	debugLogEntry ("Words: " + words);
	
	for (var r = 1; r < table.rows.length; r++)
	{
				
		if (table.rows[r].cells[0].nodeName == "TH")
			continue;		// Skip past month heading
		
		if (table.rows[r].className == 'dayheading')
			continue;		// Skip past day heading

		
		if (stringInArray (table.rows[r].className, words))
			table.rows[r].style.display = '';
		else
			table.rows[r].style.display = 'none';
	}
	
	removeEmptyDayHeadings (table);
	match = removeEmptyMonthHeadings (table);
	if (!includePastDates) removeEntriesInThePast (table, match);
}


function removeEntriesInThePast (table, match)
{
	debugLogEntry (getFunctionName ());
	debugLogEntry (sprintf("Matching row %2d", match));
	
	if (match == 0 || match >= table.rows.length) return;		// Safety - if match didn't find the right month
	
	for (var r = 0; r < match; r++)
	{
		table.rows[r].style.display = 'none';
	}
}


function removeEmptyDayHeadings (table)
{

	function findDayHeadingRows (table, dayHeadingRows)
	{
		debugLogEntry (getFunctionName ());
		var i = 0;
		
		for (var r = 0; r < table.rows.length; r++)
		{
			if (table.rows[r].className == 'dayheading')
			{
				dayHeadingRows[i++] = r;
				// debugLogEntry (sprintf("day heading row %2d", r));
			}
		}
		debugLogEntry ("========================================");
	}

	debugLogEntry (getFunctionName ());
	var dayHeadingRows = [];		// Store row numbers of Day heading marked by class="dayheading"
	
	// printTable (table);

	findDayHeadingRows (table, dayHeadingRows);
	// debugLogEntry (dayHeadingRows);	// log whole array

	while (dayHeadingRows.length > 1)
	{
		if (allHidden (table, dayHeadingRows[0] + 1, dayHeadingRows[1] - 1))   // Check whether every row between two day headings is hidden
			table.rows[dayHeadingRows[0]].style.display = 'none';		// Hide Day  Heading
		else
			table.rows[dayHeadingRows[0]].style.display = '';			// Re-display Day heading if previously hidden
		dayHeadingRows.shift ();
	}
	if (dayHeadingRows[0] < table.rows.length)
	{
		if (allHidden (table, dayHeadingRows[0] + 1, table.rows.length - 1))   // Check between last Day heading and end of table
			table.rows[dayHeadingRows[0]].style.display = 'none';		// Hide Day Heading
		else
			table.rows[dayHeadingRows[0]].style.display = '';			// Re-display Day heading if previously hidden
	}	
}



function removeEmptyMonthHeadings (table)
{
	var match = 0;

	function findMonthRows (table, monthRows)
	{
		debugLogEntry (getFunctionName ());
		var i = 0;
		var match = 0;
		var monthYearInMonthTitleFormat = getCurrentMonthYearInMonthTitleFormat();

		for (var r = 0; r < table.rows.length; r++)
		{
			if (table.rows[r].cells[0].nodeName == "TH")
			{
				// debugLogEntry ("----" + table.rows[r].innerHTML + "++++");
				debugLogEntry ("[" + table.rows[r].innerHTML.stripHTML().removeLinebreaks() + "]");
				if (monthYearInMonthTitleFormat == table.rows[r].innerHTML.stripHTML().removeLinebreaks())
				{
					debugLogEntry ("MATCH!" + r);
					match = r;
				}
				
				monthRows[i++] = r;
				// debugLogEntry (sprintf("row %2d", r));
			}
		}
		// debugLogEntry ("========================================");
		return match;
	}


	var monthRows = [];		// Store row numbers of Month heading marked by <TH>
	
	//printTable (table);

	match = findMonthRows (table, monthRows);
	debugLogEntry (monthRows);	// log whole array

	while (monthRows.length > 1)
	{
		if (allHidden (table, monthRows[0] + 1, monthRows[1] - 1))   // Check whether every row between two month headings is hidden
			table.rows[monthRows[0]].style.display = 'none';		// Hide Month Heading
		else
			table.rows[monthRows[0]].style.display = '';			// Re-display Month heading if previously hidden
		monthRows.shift ();
	}
	if (monthRows[0] < table.rows.length)
	{
		if (allHidden (table, monthRows[0] + 1, table.rows.length - 1))   // Check between last month heading and end of table
			table.rows[monthRows[0]].style.display = 'none';		// Hide Month Heading
		else
			table.rows[monthRows[0]].style.display = '';			// Re-display Month heading if previously hidden
	}
	
	debugLogEntry (sprintf("Matching row %2d", match));
	return match;
}



function allHidden (table, from, to)
{
	// debugLogEntry (sprintf ("ALL HIDDEN ? from: %d, to: %d", from, to));
	
	for (var r = from; r <= to; r++)
	{
		if (table.rows[r].cells[0].nodeName == "TH")				// Skip Month headings - should only find Month heading between day headings
			continue;
		if (table.rows[r].style.display != 'none') return false;
	}
	return true;
}



function printTable (table)
{
	
	for (var r = 0; r < table.rows.length; r++)
	{
		debugLogEntry (sprintf("row %2d, %20s -%5s- [%s] [%s]", r, table.rows[r].className, table.rows[r].style.display, table.rows[r].cells[0].nodeName, table.rows[r].innerHTML));
	}
	debugLogEntry ("p========================================");
}



