function objCalendar(date, tableId, dateId, monthId){
	var me = this;
	var calendar = document.getElementById(tableId);
	var day = document.getElementById(dateId);
	var month = document.getElementById(monthId);

	calendar.isCalendar = true;

	me.date = new Date();
	me.date.setMonth(month.value);
	me.date.setDate(day.value);
	me.onClick = null;
	me.minDate = null;
	me.locked = false;
	
	initTable();

	function createCell(className, text, onClick){
		var cell = createElement("td");
		cell.className = className;
		cell.innerHTML = text;
		cell.isCalendar = true;

		if (isSet(onClick)){
			addEvent(cell, "click", function(){
				if (me.locked){
					return;
				}
				var date = new Date( fixMozYear(me.date.getYear()), me.date.getMonth(), text);
				if (isSet(me.minDate)){
					if (me.minDate > date){
						return;
					}
				}
				me.date = date;
				onClick(text);
			});
		}
		return cell;
	}

	function createDivCell(className, text){
		var div = createElement("div");
		div.className = className;
		div.style.textAlign="center";
		div.style.width="100%";
		div.style.height="100%";
		div.innerHTML = text;

		var cell = createElement("td");
		cell.isCalendar = true;
		appendChild(cell, div);

		return cell;
	
	}

	function incDate(date, num){
		return new Date( fixMozYear(date.getYear()), date.getMonth(), date.getDate() + num);
	}

	function initDates(table, date, onClick){
		//first off clear any date rows in the table
		while (table.rows.length > 0){
			table.deleteRow(0);
		}

		//create date object to base dates on, starting from the first off the month passed in
		var thisMonth = new Date( fixMozYear(date.getYear()) , date.getMonth(), 1);

		var cells = new Array();
		cells[0] = createCell("title_click", "&lt;");
		cells[1] = createDivCell("title", months[me.date.getMonth()] + "&nbsp;" + fixMozYear(me.date.getYear()));
		cells[2] = createCell("title_click", "&gt;");
		var monthTitle = cells[1];

		addEvent(cells[0], "click", function(){changeMonth(-1, cells[1])});
		addEvent(cells[2], "click", function(){changeMonth(1, cells[1])});

		addRow(calendar,cells);

		// loop to add rows
		for (var row=1; row < 8; row++){
			// init cells array
			cells = new Array();
			// loop to add each cell
			for (var column=0; column < 7; column++){
				// add column headers
				if (row == 1){	
					cells[column] = createCell("title", days[column]);
				} else {
					// keep adding blank cells till the first day is reached in the days array
					var className = (date.getDate() == thisMonth.getDate() ? "selected" : "data");
					if (isSet(me.minDate)){
						if (me.minDate > thisMonth){
							className = "not_selectable";
						}
					}

					if (thisMonth.getDate() == 1 && thisMonth.getMonth() == date.getMonth()){
						if (thisMonth.getDay() == column){
							cells[column] = createCell(className, thisMonth.getDate(), onClick);			
							thisMonth = incDate(thisMonth, 1);
						} else {
							cells[column] = createCell("no_data", "");		
						}
					// keep adding nunbered cells till end of month
					} else {
						if (thisMonth.getMonth() == date.getMonth()){
							cells[column] = createCell(className, thisMonth.getDate(), onClick);
							thisMonth = incDate(thisMonth, 1);
						} else {
							cells[column] = createCell("no_data", "");									
						}
					}
				}
			}

			if (row > 3 && cells[0].innerHTML == "") {
				// the row is empty - don't bother appending
				continue;
			}

			addRow(calendar,cells);
		}

		monthTitle.colSpan = 5;
		monthTitle.style.textAlign = "center";

//		document.write ( document.body.innerHTML );
	}

	function initTable(){
		initDates(calendar, me.date, function(day){
			date = new Date( fixMozYear(me.date.getYear()), me.date.getMonth(), day);

			if (isSet(me.onClick)){
				me.onClick(date, true);
			}
			initTable();
		});		
	}

	me.setDate = function(date){
		me.date = date;
		initTable();
	}

	function changeMonth(inc, label){
		
		//check if trying to set before today
		if (me.date.getMonth() == today.getMonth() && inc < 0){
			return;
		}

		//check if trying to after a year from now
		var yearDiff = me.date.getYear() - today.getYear();
		var month = yearDiff == 0 ? me.date.getMonth() : (me.date.getMonth() + (yearDiff*12));
		if (month - today.getMonth() == 11 && inc > 0){
			return;
		}

		//check if trying to set before min date
		if (me.date.getMonth() == me.minDate.getMonth() && inc < 0){
			return;
		}

		me.date.setMonth(me.date.getMonth() + inc);
		initTable();

		if (isSet(me.onClick)){
			me.onClick(me.date, false);
		}
	}
}

function hideElms(elmTag) {
	for (i=0; i<document.all.tags(elmTag).length; i++){
		obj = document.all.tags(elmTag)[i];
		if (!obj || !obj.offsetParent) continue;
		obj.style.visibility = "hidden";
	}
}

function showDiv(obj) {
	hideElms('SELECT');
	obj.style.visibility = "visible";
}
