//
// calendar -- a javascript date picker designed for easy localization.
//
// $Id$
//
//
// Author: Per Norrman (pernorrman@telia.com)
// 
// Based on Tapestry 2.3-beta1 Datepicker by Paul Geerts
// 
// Thanks to:
//     Vladimir [vyc@quorus-ms.ru] for fixing the IE6 zIndex problem.
//
// The normal setup would be to have one text field for displaying the 
// selected date, and one button to show/hide the date picker control.
// This is  the recommended javascript code:
// 
//	<script language="javascript">
//		var cal;
//
//		function init() {
//			cal = new Calendar();
//			cal.setIncludeWeek(true);
//			cal.setFormat("yyyy-MM-dd");
//			cal.setMonthNames(.....);
//			cal.setShortMonthNames(....);
//			cal.create();
//			
//			document.form.button1.onclick = function() {
//				cal.toggle(document.form.button1);
//			}
//			cal.onchange = function() {
//				document.form.textfield1.value  = cal.formatDate();
//			}
//		}
//	</script>
//
// The init function is invoked when the body is loaded.
//
//

function Calendar(date) {
	if (arguments.length == 0) {
		this._currentDate = new Date();
		this._selectedDate = null;
	}
	else {
		this._currentDate = new Date(date);
		this._selectedDate = new Date(date);
	}

	// Accumulated days per month, for normal and for leap years.
	// Used in week number calculations.	
    Calendar.NUM_DAYS = [0,31,59,90,120,151,181,212,243,273,304,334];
    
    Calendar.LEAP_NUM_DAYS = [0,31,60,91,121,152,182,213,244,274,305,335];
    

	this._bw = new bw_check();
	this._showing = false;	
	this._includeWeek = false;
	this._hideOnSelect = true;
	this._alwaysVisible = false;
	
	this._dateSlot = new Array(42);
	this._weekSlot = new Array(6);
	
	this._firstDayOfWeek = 1;
	this._minimalDaysInFirstWeek = 4;
	
	this._monthNames = [	
		"January",		"February",		"March",	"April",
		"May",			"June",			"July",		"August",
		"September",	"October",		"November",	"December"
	];
	
	this._shortMonthNames = [ 
		"jan", "feb", "mar", "apr", "may", "jun", 
		"jul", "aug", "sep", "oct", "nov", "dec"
	];
	
	// Week days start with Sunday=0, ... Saturday=6
	this._weekDayNames = [
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" 
	];
	
	this._shortWeekDayNames = 
		["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
	
	this._defaultFormat = "yyyy-MM-dd";
	
	this._format = this._defaultFormat; 

	this._calDiv = null;
	
	
}

/**
 *	CREATE the Calendar DOM element
 */
Calendar.prototype.create = function() {
	var div;
	var table;
	var tbody;
	var tr;
	var td;
	var dp = this;
	
	// Create the top-level div element
	this._calDiv = document.createElement("div");
	this._calDiv.className = "calendar";
	this._calDiv.style.position = "absolute";
	this._calDiv.style.display = "none";
	this._calDiv.style.border = "1px solid WindowText";
	this._calDiv.style.textAlign = "center";
	this._calDiv.style.background = "Window";
	this._calDiv.style.zIndex = "400";
	
	
	// header div
	div = document.createElement("div");
	div.className = "calendarHeader";
	div.style.background = "ActiveCaption";
	div.style.padding = "3px";
	div.style.borderBottom = "1px solid WindowText";
	this._calDiv.appendChild(div);
	
	table = document.createElement("table");
	table.style.cellSpacing = 0;
	div.appendChild(table);
	
	tbody = document.createElement("tbody");
	table.appendChild(tbody);
	
	tr = document.createElement("tr");
	tbody.appendChild(tr);
	
	// Previous Month Button
	td = document.createElement("td");
	this._previousMonth = document.createElement("button");
	this._previousMonth.className = "prevMonthButton"
	this._previousMonth.appendChild(document.createTextNode("<<"));
	//this._previousMonth.appendChild(document.createTextNode(String.fromCharCode(9668)));
	td.appendChild(this._previousMonth);
	tr.appendChild(td);
	
	
	
	//
	// Create the month drop down 
	//
	td = document.createElement("td");
	td.className = "labelContainer";
	tr.appendChild(td);
	this._monthSelect = document.createElement("select");
    for (var i = 0 ; i < this._monthNames.length ; i++) {
        var opt = document.createElement("option");
        opt.innerHTML = this._monthNames[i];
        opt.value = i;
        if (i == this._currentDate.getMonth()) {
            opt.selected = true;
        }
        this._monthSelect.appendChild(opt);
    }
	td.appendChild(this._monthSelect);
	

	// 
	// Create the year drop down
	//
	td = document.createElement("td");
	td.className = "labelContainer";
	tr.appendChild(td);
	this._yearSelect = document.createElement("select");
	for(var i=1920; i < 2050; ++i) {
		var opt = document.createElement("option");
		opt.innerHTML = i;
		opt.value = i;
		if (i == this._currentDate.getFullYear()) {
			opt.selected = false;
		}
		this._yearSelect.appendChild(opt);
	}
	td.appendChild(this._yearSelect);
	
	
	td = document.createElement("td");
	this._nextMonth = document.createElement("button");
	this._nextMonth.appendChild(document.createTextNode(">>"));
	//this._nextMonth.appendChild(document.createTextNode(String.fromCharCode(9654)));
	this._nextMonth.className = "nextMonthButton";
	td.appendChild(this._nextMonth);
	tr.appendChild(td);
	
	// Calendar body
	div = document.createElement("div");
	div.className = "calendarBody";
	this._calDiv.appendChild(div);
	this._table = div;
	
	// Create the inside of calendar body	
	
	var text;
	table = document.createElement("table");
	//table.style.width="100%";
	table.className = "grid";
	table.style.font 	 	= "small-caption";
	table.style.fontWeight 	= "normal";
	table.style.textAalign	= "center";
	table.style.color		= "WindowText";
	table.style.cursor		= "default";
	table.cellPadding		= "3";
	table.cellSpacing		= "0";
	
    div.appendChild(table);
	var thead = document.createElement("thead");
	table.appendChild(thead);
	tr = document.createElement("tr");
	thead.appendChild(tr);
	
	// weekdays header
	if (this._includeWeek) {
		td = document.createElement("th");
		text = document.createTextNode("w");
		td.appendChild(text);
		td.className = "weekNumberHead";
		td.style.textAlign = "left";
		tr.appendChild(td);
	}
	for(i=0; i < 7; ++i) {
		td = document.createElement("th");
		text = document.createTextNode(this._shortWeekDayNames[(i+this._firstDayOfWeek)%7]);
		td.appendChild(text);
		td.className = "weekDayHead";
		td.style.fontWeight = "bold";
		td.style.borderBottom = "1px solid WindowText";
		tr.appendChild(td);
	}
	
	// Date grid
	tbody = document.createElement("tbody");
	table.appendChild(tbody);
	
	for(week=0; week<6; ++week) {
		tr = document.createElement("tr");
		tbody.appendChild(tr);

		if (this._includeWeek) {
			td = document.createElement("td");
			td.className = "weekNumber";
			td.style.fontWeight = "normal";
			td.style.borderRight = "1px solid WindowText";
			td.style.textAlign = "left";
			text = document.createTextNode(String.fromCharCode(160));
			td.appendChild(text);
            //setCursor(td);
            td.align="center";
			tr.appendChild(td);
			var tmp = new Object();
			tmp.tag = "WEEK";
			tmp.value = -1;
			tmp.data = text;
			this._weekSlot[week] = tmp;
		}

		for(day=0; day<7; ++day) {
			td = document.createElement("td");
			text = document.createTextNode(String.fromCharCode(160));
			td.appendChild(text);
            setCursor(td);
            td.align="center";
            td.style.fontWeight="normal";
            
			tr.appendChild(td);
			var tmp = new Object();
			tmp.tag = "DATE";
			tmp.value = -1;
			tmp.data = text;
			this._dateSlot[(week*7)+day] = tmp;
			
		}
	}
	
	// Calendar Footer
	div = document.createElement("div");
	div.className = "calendarFooter";
	this._calDiv.appendChild(div);
	
	table = document.createElement("table");
	//table.style.width="100%";
	table.className = "footerTable";
	table.cellSpacing = 0;
	div.appendChild(table);
	
	tbody = document.createElement("tbody");
	table.appendChild(tbody);
	
	tr = document.createElement("tr");
	tbody.appendChild(tr);

	//
	// The TODAY button	
	//
	td = document.createElement("td");
	this._todayButton = document.createElement("button");
	var today = new Date();
	var buttonText = today.getDate() + " " + this._monthNames[today.getMonth()] + ", " + today.getFullYear();
	this._todayButton.appendChild(document.createTextNode(buttonText));
	td.appendChild(this._todayButton);
	tr.appendChild(td);
	
	//
	// The CLEAR button
	//
	td = document.createElement("td");
	this._clearButton = document.createElement("button");
	var today = new Date();
	buttonText = "Clear";
	this._clearButton.appendChild(document.createTextNode(buttonText));
	td.appendChild(this._clearButton);
	tr.appendChild(td);
	
	
	this._update();
	this._updateHeader();
	


	// IE55+ extension		
	this._previousMonth.hideFocus = true;
	this._nextMonth.hideFocus = true;
	this._todayButton.hideFocus = true;
	// end IE55+ extension
	
	// hook up events
	// buttons
	this._previousMonth.onclick = function () {
		dp.prevMonth();
	};

	this._nextMonth.onclick = function () {
		dp.nextMonth();
	};

	this._todayButton.onclick = function () {
		dp.setSelectedDate(new Date());
		dp.hide();
	};

	this._clearButton.onclick = function () {
		dp.clearSelectedDate();
		dp.hide();
	};
	

	this._calDiv.onselectstart = function () {
		return false;
	};
	
	this._table.onclick = function (e) {
		// find event
		if (e == null) e = document.parentWindow.event;
		
		// find td
		var el = e.target != null ? e.target : e.srcElement;
		while (el.nodeType != 1)
			el = el.parentNode;
		while (el != null && el.tagName && el.tagName.toLowerCase() != "td")
			el = el.parentNode;
		
		// if no td found, return
		if (el == null || el.tagName == null || el.tagName.toLowerCase() != "td")
			return;
		
		var d = new Date(dp._currentDate);
		var n = Number(el.firstChild.data);
		if (isNaN(n) || n <= 0 || n == null)
			return;
		
		if (el.className == "weekNumber")
			return;
			
		d.setDate(n);
		dp.setSelectedDate(d);

		if (!dp._alwaysVisible && dp._hideOnSelect) {
			dp.hide();
		}
		
	};
	
	
	this._calDiv.onkeydown = function (e) {
		if (e == null) e = document.parentWindow.event;
		var kc = e.keyCode != null ? e.keyCode : e.charCode;

		if(kc == 13) {
			var d = new Date(dp._currentDate).valueOf();
			dp.setSelectedDate(d);

			if (!dp._alwaysVisible && dp._hideOnSelect) {
				dp.hide();
			}
			return false;
		}
			
		
		if (kc < 37 || kc > 40) return true;
		
		var d = new Date(dp._currentDate).valueOf();
		if (kc == 37) // left
			d -= 24 * 60 * 60 * 1000;
		else if (kc == 39) // right
			d += 24 * 60 * 60 * 1000;
		else if (kc == 38) // up
			d -= 7 * 24 * 60 * 60 * 1000;
		else if (kc == 40) // down
			d += 7 * 24 * 60 * 60 * 1000;

		dp.setCurrentDate(new Date(d));
		return false;
	}
	
	// ie6 extension
	this._calDiv.onmousewheel = function (e) {
		if (e == null) e = document.parentWindow.event;
		var n = - e.wheelDelta / 120;
		var d = new Date(dp._currentDate);
		var m = d.getMonth() + n;
		d.setMonth(m);
		
		
		dp.setCurrentDate(d);
		
		return false;
	}

	this._monthSelect.onchange = function(e) {
		if (e == null) e = document.parentWindow.event;
		e = getEventObject(e);
		dp.setMonth(e.value);
	}

	this._monthSelect.onclick = function(e) {
		if (e == null) e = document.parentWindow.event;
		e = getEventObject(e);
		e.cancelBubble = true;
	}
	
	this._yearSelect.onchange = function(e) {
		if (e == null) e = document.parentWindow.event;
		e = getEventObject(e);
		dp.setYear(e.value);
	}


	document.body.appendChild(this._calDiv);
	
	
	return this._calDiv;
}

Calendar.prototype._update = function() {


	// Calculate the number of days in the month for the selected date
	var date = this._currentDate;
	var today = toISODate(new Date());
	
	
	var selected = "";
	if (this._selectedDate != null) {
		selected = toISODate(this._selectedDate);
	}
	var current = toISODate(this._currentDate);
	var d1 = new Date(date.getFullYear(), date.getMonth(), 1);
	var d2 = new Date(date.getFullYear(), date.getMonth()+1, 1);
	var monthLength = Math.round((d2 - d1) / (24 * 60 * 60 * 1000));
	
	// Find out the weekDay index for the first of this month
	var firstIndex = (d1.getDay() - this._firstDayOfWeek) % 7 ;
    if (firstIndex < 0) {
    	firstIndex += 7;
    }
	
	var index = 0;
	while (index < firstIndex) {
		this._dateSlot[index].value = -1;
		this._dateSlot[index].data.data = String.fromCharCode(160);
		this._dateSlot[index].data.parentNode.className = "";
		this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
		this._dateSlot[index].data.parentNode.style.border= "none";
		index++;
	}
        
    for (i = 1; i <= monthLength; i++, index++) {
		this._dateSlot[index].value = i;
		this._dateSlot[index].data.data = i;
		this._dateSlot[index].data.parentNode.className = "";
		this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
		this._dateSlot[index].data.parentNode.style.border= "none";
		if (toISODate(d1) == today) {
			this._dateSlot[index].data.parentNode.className = "today";
			this._dateSlot[index].data.parentNode.style.fontWeight = "bold";
		}
		if (toISODate(d1) == current) {
			this._dateSlot[index].data.parentNode.className += " current";
			this._dateSlot[index].data.parentNode.style.border= "1px dotted WindowText";
		}
		if (toISODate(d1) == selected) {
			this._dateSlot[index].data.parentNode.className += " selected";
			this._dateSlot[index].data.parentNode.style.border= "1px solid WindowText";
		}
		d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+1);
	}
	
	var lastDateIndex = index;
        
    while(index < 42) {
		this._dateSlot[index].value = -1;
		this._dateSlot[index].data.data = String.fromCharCode(160);
		this._dateSlot[index].data.parentNode.className = "";
		this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
		this._dateSlot[index].data.parentNode.style.border= "none";
		++index;
	}
	
	// Week numbers
	if (this._includeWeek) {
		d1 = new Date(date.getFullYear(), date.getMonth(), 1);
		for (i=0; i < 6; ++i) {
			if (i == 5 && lastDateIndex < 36) {
				this._weekSlot[i].data.data = String.fromCharCode(160);
				this._weekSlot[i].data.parentNode.style.borderRight = "none";
			} else {
				week = weekNumber(this, d1);
				this._weekSlot[i].data.data = week;
				this._weekSlot[i].data.parentNode.style.borderRight = "1px solid WindowText";
			}
			d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+7);
		}
	}
}

Calendar.prototype.show = function(element) {
	if(!this._showing) {
		var p = getPoint(element);
		this._calDiv.style.display = "block";
		this._calDiv.style.top = (p.y + element.offsetHeight + 1) + "px";
		this._calDiv.style.left = p.x + "px";
		this._showing = true;
		
		/* -------- */
	   	if( this._bw.ie6 )
	   	{
	     	dw = this._calDiv.offsetWidth;
	     	dh = this._calDiv.offsetHeight;
	     	var els = document.getElementsByTagName("body");
	     	var body = els[0];
	     	if( !body ) return;
	 
	    	//paste iframe under the modal
		     var underDiv = this._calDiv.cloneNode(false); 
		     underDiv.style.zIndex="390";
		     underDiv.style.margin = "0px";
		     underDiv.style.padding = "0px";
		     underDiv.style.display = "block";
		     underDiv.style.width = dw;
		     underDiv.style.height = dh;
		     underDiv.style.border = "1px solid WindowText";
		     underDiv.innerHTML = "<iframe width=\"100%\" height=\"100%\" frameborder=\"0\"></iframe>";
		     body.appendChild(underDiv);
		     this._underDiv = underDiv;
	   }
		/* -------- */
		this._calDiv.focus();
		
	}
};

Calendar.prototype.hide = function() {   
	if(this._showing) {
		this._calDiv.style.display = "none";
		this._showing = false;
		if( this._bw.ie6 ) {
		    if( this._underDiv ) this._underDiv.removeNode(true);
		}
	}
}

Calendar.prototype.toggle = function(element) {
	if(this._showing) {
		this.hide(); 
	} else {
		this.show(element);
	}
}



Calendar.prototype.onchange = function() {};


Calendar.prototype.setCurrentDate = function(date) {
	if (date == null) {
		return;
	}

	// if string or number create a Date object
	if (typeof date == "string" || typeof date == "number") {
		date = new Date(date);
	}
	
	
	// do not update if not really changed
	if (this._currentDate.getDate() != date.getDate() ||
		this._currentDate.getMonth() != date.getMonth() || 
		this._currentDate.getFullYear() != date.getFullYear()) {
		
		this._currentDate = new Date(date);
	
		this._updateHeader();
		this._update();
		
	}
	
}

Calendar.prototype.setSelectedDate = function(date) {
	this._selectedDate = new Date(date);
	this.setCurrentDate(this._selectedDate);
	if (typeof this.onchange == "function") {
		this.onchange();
	}
}

Calendar.prototype.clearSelectedDate = function() {
	this._selectedDate = null;
	if (typeof this.onchange == "function") {
		this.onchange();
	}
}

Calendar.prototype.getElement = function() {
	return this._calDiv;
}

Calendar.prototype.setIncludeWeek = function(v) {
	if (this._calDiv == null) {
		this._includeWeek = v;
	}
}

Calendar.prototype.getSelectedDate = function () {
	if (this._selectedDate == null) {
		return null;
	} else {
		return new Date(this._selectedDate);
	}
}



Calendar.prototype._updateHeader = function () {

	// 
	var options = this._monthSelect.options;
	var m = this._currentDate.getMonth();
	for(var i=0; i < options.length; ++i) {
		options[i].selected = false;
		if (options[i].value == m) {
			options[i].selected = true;
		}
	}
	
	options = this._yearSelect.options;
	var year = this._currentDate.getFullYear();
	for(var i=0; i < options.length; ++i) {
		options[i].selected = false;
		if (options[i].value == year) {
			options[i].selected = true;
		}
	}
	
}

Calendar.prototype.setYear = function(year) {
	var d = new Date(this._currentDate);
	d.setFullYear(year);
	this.setCurrentDate(d);
}

Calendar.prototype.setMonth = function (month) {
	var d = new Date(this._currentDate);
	d.setMonth(month);
	this.setCurrentDate(d);
}

Calendar.prototype.nextMonth = function () {
	this.setMonth(this._currentDate.getMonth()+1);
}

Calendar.prototype.prevMonth = function () {
	this.setMonth(this._currentDate.getMonth()-1);
}

Calendar.prototype.setFirstDayOfWeek = function (nFirstWeekDay) {
	this._firstDayOfWeek = nFirstWeekDay;
}

Calendar.prototype.getFirstDayOfWeek = function () {
	return this._firstDayOfWeek;
}

Calendar.prototype.setMinimalDaysInFirstWeek = function(n) {
	this._minimalDaysInFirstWeek = n;
}


Calendar.prototype.getMinimalDaysInFirstWeek = function () {
	return this._minimalDaysInFirstWeek;
}

Calendar.prototype.setMonthNames = function(a) {
	// sanity test
	this._monthNames = a;
}

Calendar.prototype.setShortMonthNames = function(a) {
	// sanity test
	this._shortMonthNames = a;
}

Calendar.prototype.setWeekDayNames = function(a) {
	// sanity test
	this._weekDayNames = a;
}

Calendar.prototype.setShortWeekDayNames = function(a) {
	// sanity test
	this._shortWeekDayNames = a;
}

Calendar.prototype.getFormat = function() {
	return this._format;
}
	
Calendar.prototype.setFormat = function(f) {
	this._format = f;
}

Calendar.prototype.formatDate = function() {  
	if (this._selectedDate == null) {
		return "";
	}
	
    var bits = new Array();
    // work out what each bit should be
    var date = this._selectedDate;
    bits['d'] = date.getDate();
    bits['dd'] = pad(date.getDate(),2);
    bits['ddd'] = this._shortWeekDayNames[date.getDay()];
    bits['dddd'] = this._weekDayNames[date.getDay()];

    bits['M'] = date.getMonth()+1;
    bits['MM'] = pad(date.getMonth()+1,2);
    bits['MMM'] = this._shortMonthNames[date.getMonth()];
    bits['MMMM'] = this._monthNames[date.getMonth()];
    
    var yearStr = "" + date.getFullYear();
    yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
    bits['yyyy'] = yearStr;
    bits['yy'] = bits['yyyy'].toString().substr(2,2);

    // do some funky regexs to replace the format string
    // with the real values
    var frm = new String(this._format);
    var sect;
    for (sect in bits) {
      frm = eval("frm.replace(/\\b" + sect + "\\b/,'" + bits[sect] + "');");
    }

    return frm;
}
	
                                                                                                       
function isLeapYear(year) {
	return ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
}

function yearLength(year) {
	if (isLeapYear(year))
		return 366;
	else
		return 365;
}

function dayOfYear(date) {
	var a = Calendar.NUM_DAYS;
	if (isLeapYear(date.getFullYear())) {
		a = Calendar.LEAP_NUM_DAYS;
	}
	var month = date.getMonth();
	
	return a[month] + date.getDate();
}

// ---------------------------------------------
// Week number stuff
// ---------------------------------------------

function weekNumber(cal, date) {

	var dow = date.getDay();
	var doy = dayOfYear(date);
	var year = date.getFullYear();

	// Compute the week of the year.  Valid week numbers run from 1 to 52
	// or 53, depending on the year, the first day of the week, and the
	// minimal days in the first week.  Days at the start of the year may
	// fall into the last week of the previous year; days at the end of
	// the year may fall into the first week of the next year.
	var relDow = (dow + 7 - cal.getFirstDayOfWeek()) % 7; // 0..6
	var relDowJan1 = (dow - doy + 701 - cal.getFirstDayOfWeek()) % 7; // 0..6
	var week = Math.floor((doy - 1 + relDowJan1) / 7); // 0..53
	if ((7 - relDowJan1) >= cal.getMinimalDaysInFirstWeek()) {
		++week;
	}

	if (doy > 359) { // Fast check which eliminates most cases
		// Check to see if we are in the last week; if so, we need
		// to handle the case in which we are the first week of the
		// next year.
		var lastDoy = yearLength(year);
		var lastRelDow = (relDow + lastDoy - doy) % 7;
		if (lastRelDow < 0) {
			lastRelDow += 7;
		}
		if (((6 - lastRelDow) >= cal.getMinimalDaysInFirstWeek())
			&& ((doy + 7 - relDow) > lastDoy)) {
			week = 1;
		}
	} else if (week == 0) {
		// We are the last week of the previous year.
		var prevDoy = doy + yearLength(year - 1);
		week = weekOfPeriod(cal, prevDoy, dow);
	}

	return week;
}

function weekOfPeriod(cal, dayOfPeriod, dayOfWeek) {
	// Determine the day of the week of the first day of the period
	// in question (either a year or a month).  Zero represents the
	// first day of the week on this calendar.
	var periodStartDayOfWeek =
		(dayOfWeek - cal.getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
	if (periodStartDayOfWeek < 0) {
		periodStartDayOfWeek += 7;
	}

	// Compute the week number.  Initially, ignore the first week, which
	// may be fractional (or may not be).  We add periodStartDayOfWeek in
	// order to fill out the first week, if it is fractional.
	var weekNo = Math.floor((dayOfPeriod + periodStartDayOfWeek - 1) / 7);

	// If the first week is long enough, then count it.  If
	// the minimal days in the first week is one, or if the period start
	// is zero, we always increment weekNo.
	if ((7 - periodStartDayOfWeek) >= cal.getMinimalDaysInFirstWeek()) {
		++weekNo;
	}

	return weekNo;
}




function getEventObject(e) {  // utility function to retrieve object from event
    if (navigator.appName == "Microsoft Internet Explorer") {
        return e.srcElement;
    } else {  // is mozilla/netscape
        // need to crawl up the tree to get the first "real" element
        // i.e. a tag, not raw text
        var o = e.target;
        while (!o.tagName) {
            o = o.parentNode;
        }
        return o;
    }
}

function addEvent(name, obj, funct) { // utility function to add event handlers

    if (navigator.appName == "Microsoft Internet Explorer") {
        obj.attachEvent("on"+name, funct);
    } else {  // is mozilla/netscape
        obj.addEventListener(name, funct, false);
    }
}


function deleteEvent(name, obj, funct) { // utility function to delete event handlers

    if (navigator.appName == "Microsoft Internet Explorer") {
        obj.detachEvent("on"+name, funct);
    } else {  // is mozilla/netscape
        obj.removeEventListener(name, funct, false);
    }
}

function setCursor(obj) {
   if (navigator.appName == "Microsoft Internet Explorer") {
        obj.style.cursor = "hand";
    } else {  // is mozilla/netscape
        obj.style.cursor = "pointer";
    }
}

function Point(iX, iY)
{
   this.x = iX;
   this.y = iY;
}


function getPoint(aTag)
{
   var oTmp = aTag;  
   var point = new Point(0,0);
  
   do 
   {
      point.x += oTmp.offsetLeft;
      point.y += oTmp.offsetTop;
      oTmp = oTmp.offsetParent;
   } 
   while (oTmp.tagName != "BODY");

   return point;
}

function toISODate(date) {
	var s = date.getFullYear();
	var m = date.getMonth() + 1;
	if (m < 10) {
		m = "0" + m;
	}
	var day = date.getDate();
	if (day < 10) {
		day = "0" + day;
	}
	return String(s) + String(m) + String(day);
	
}

function pad(number,X) {   // utility function to pad a number to a given width
	X = (!X ? 2 : X);
	number = ""+number;
	while (number.length < X) {
	    number = "0" + number;
	}
	return number;
}

function bw_check()
{
    var is_major = parseInt( navigator.appVersion );
    this.nver = is_major;
    this.ver = navigator.appVersion;
    this.agent = navigator.userAgent;
    this.dom = document.getElementById ? 1 : 0;
    this.opera = window.opera ? 1 : 0;
    this.ie5 = ( this.ver.indexOf( "MSIE 5" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
    this.ie6 = ( this.ver.indexOf( "MSIE 6" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
    this.ie4 = ( document.all && !this.dom && !this.opera ) ? 1 : 0;
    this.ie = this.ie4 || this.ie5 || this.ie6;
    this.mac = this.agent.indexOf( "Mac" ) > -1;
    this.ns6 = ( this.dom && parseInt( this.ver ) >= 5 ) ? 1 : 0;
    this.ie3 = ( this.ver.indexOf( "MSIE" ) && ( is_major < 4 ) );
    this.hotjava = ( this.agent.toLowerCase().indexOf( 'hotjava' ) != -1 ) ? 1 : 0;
    this.ns4 = ( document.layers && !this.dom && !this.hotjava ) ? 1 : 0;
    this.bw = ( this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera );
    this.ver3 = ( this.hotjava || this.ie3 );
    this.opera7 = ( ( this.agent.toLowerCase().indexOf( 'opera 7' ) > -1 ) || ( this.agent.toLowerCase().indexOf( 'opera/7' ) > -1 ) );
    this.operaOld = this.opera && !this.opera7;
    return this;
};


