function tCalendar() {
	var	MonthOffset	= new Array(0,31,59,90,120,151,181,212,243,273,304,334);
	var	MonthDays	= new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	var MonthNames	= new Array("January", "February", "March", "April", "May",
		 "June", "July", "August", "September", "October", "November", "December");

	var	BaseWidth= 0;
	var	MinYear		= 2008;
	var	MaxYear		= 2011;
	var	StartYear	= 2000;
	var StartDay	= 7;
	var Visible		= false;
	var Current_Month;
	var Current_Year;
	var	Info			= new Array();
	var	Lookups		= new Array(0, 3, 8, 13, 18, 23, 28, 33, 38, 43);    

// Update the current month to the data in the database

this.Update= function() {
	var 	Length, ID;
	var		Element;
	var		Count		= Info.length;
	
	var 	Current		= new Date();
	var 	MX			= Current.getMonth() + 1;
	var 	DX			= Current.getDate();
	
	var		YX			= Current.getFullYear();
	var		Today;
	
	var		Month		= Current_Month;
	var		Year		= Current_Year;

// Set the title

	if (Element= document.getElementById("MonthName")) {
		Element.innerHTML= MonthNames[Month - 1] + " " + Year;
		}

// Setup the current marker too
	
	MX= "0" + MX;
	MX= MX.substring(MX.length - 2);

	DX= "0" + DX;
	DX= DX.substring(DX.length - 2);

	YX= "0" + YX;
	YX= YX.substring(YX.length - 2);

	Today= 'c' + YX + MX + DX;		// Which calendar item is today

// Calculate which day of week based on start year

	Years= Year - StartYear;
	Days= 365 * Years + MonthOffset[Month-1] + StartDay;

	LeapYearOffset= Years % 4;
	Days += (Years - LeapYearOffset) / 4;
	if (LeapYearOffset) {
		Days++;
		}
	else if (Month > 2) {
		Days++;
		}

	FirstDay= 1 + (Days - 1) % 7;		// one based
	LastDay= FirstDay + MonthDays[Month-1] - 1;
	if ((Month==2) && (!LeapYearOffset)) { 
		LastDay++ 
		};

// Now setup the calendar

	Y= Year.toString().substring(2, 4);
	M= '0' + Month;
	M= M.substring(M.length-2);
	DayNumber= 1;
	for (var I= 1; I <= 42; I++) {
		X= I + 9;				// Allow for 9 special styles
		X= '0' + X;
		X= X.substring(X.length-2);
		
		if (Element= document.getElementById('c'+X)) {
			if ((I >= FirstDay) && (I <= LastDay)) {
				D= '0' + DayNumber;
				D= D.substring(D.length-2);
				T= 'c'+Y.toString()+M.toString()+D.toString();
				
				Lookups[I+9]= 0;
				if (Today == T) {
					Element.innerHTML= "<b>"+ DayNumber +"</b>"
					Element.style['color']= cToday;
					}
				else {
					Element.innerHTML= DayNumber;
					Element.style['color']= cOtherDays;
					}
				DayNumber++;	
				
				Element.className= 'Cal0';
				for (var J= 0; J < Count; J += 5) {
					if (T == Info[J]) {
						Element.className= 'Cal'+Info[J+1];
						Lookups[I+9]= J + 3;
						}
					}
				}
			else {
				Lookups[I+9]= 0;
				Element.innerHTML="";
				Element.className= 'Cal0';
				}	
			}
		}
	}

// Create the loader for the calendar. Gets the whole thing into an array

this.Load= function(Owner) {
	var	xmlhttp;
	var	Message= "Calendar`" + Owner;

	if (window.XMLHttpRequest) {
		xmlhttp= new XMLHttpRequest();
		}
	else {
		xmlhttp= new ActiveXObject("Microsoft.XMLHTTP");
		}

	xmlhttp.onreadystatechange = function() {};
	xmlhttp.open("POST", WebDirectory + "cgi/readcalendar.cgi", false);
	xmlhttp.setRequestHeader("Content-Type", "text/xml");
	xmlhttp.setRequestHeader("Content-length", Message.length);
	xmlhttp.send(Message);

	Info= xmlhttp.responseText.split('`');
	Info.length= Info.length-1;			// Generator adds a '0' on end.
	}

// Use the first entries to set the drop down

this.LoadTypes= function() {
	for (var I= 0; I < 9; I++) {
		option= document.createElement("OPTION");
		option.text= Info[5*I+3];
		option.value= Info[5*I+1];
		document.Operation.CalType.options.add(option);
		}
	}

this.Save= function(Owner) {
	var	xmlhttp;
	var	Message	= "Calendar`" + Owner;
	var	Count		= Info.length;

	for (var I= 0; I < Count; I += 5) {
		if (Info[I+4] > 0) {
			Message += "`" + Info[I] + "`" + Info[I+1] +
				"`" + Info[I+2] + "`" + Info[I+3];
			}
		}

	if (window.XMLHttpRequest) {
		xmlhttp= new XMLHttpRequest();
		}
	else {
		xmlhttp= new ActiveXObject("Microsoft.XMLHTTP");
		}

	xmlhttp.onreadystatechange = function() {};
	xmlhttp.open("POST", WebDirectory + "cgi/writecalendar.cgi", false);
	xmlhttp.setRequestHeader("Content-Type", "text/xml");
	xmlhttp.setRequestHeader("Content-length", Message.length);
	xmlhttp.send(Message);
	}

// Button controls

this.NextMonth= function() {
	if (Current_Month == 12) {
		if (Current_Year < MaxYear) {
			Current_Year++;
			Current_Month= 1;
			this.Update();
			}
		}
	else {
		Current_Month++;
		this.Update();
		}
	}
	
this.PrevMonth= function() {
	if (Current_Month == 1) {
		if (Current_Year > MinYear) {
			Current_Year--;
			Current_Month= 12;
			this.Update();
			}
		}
	else {
		Current_Month--;
		this.Update();
		}
	}
	
this.NextYear= function() {
	if (Current_Year < MaxYear) {
		Current_Year++;
		this.Update();
		}
	}
	
this.PrevYear= function() {
	if (Current_Year > MinYear) {
		Current_Year--;
		this.Update();
		}
	}

// Information hot points

this.Event= function(Index) {
	var		Count		= Info.length;
	var		Width;
	
	if (Index > 0) {
		if ((Lookups[Index]) && Info[Lookups[Index]-2]) {
			if (Element= document.getElementById('floatinfo')) {
				if (!(Width= parseInt(Info[Lookups[Index]-1],10))) {
					Width= BaseWidth;
					}
				
				if ((X= MouseX-(Width/2)) < 5) {
					X=5
					};

				Element.style.left= X;
				Element.style.top= MouseY+20; 
				Element.width= Width;

				if (!Visible) {
					Visible= !Visible;
					Element.style.visibility= 'visible';
					}

				if (Element= document.getElementById('textinfo')) {
					Element.innerHTML= Info[Lookups[Index]];
					}
				}
			}
		}
	
	else {
		if (Element= document.getElementById('floatinfo')) {
			if (Visible) {
				Visible= !Visible;
				Element.style.visibility= 'hidden';
				}
			}
		}
	}
	
this.Setup= function() {
	var 	Current		= new Date();

	Current_Month		= Current.getMonth() + 1;
	Current_Year		= Current.getFullYear();

	if (Element= document.getElementById('floatinfo')) {
		BaseWidth= Element.width;
		}

	this.Update();
	}

// Define the editor functions

this.Clear= function() {
	var	Element;
	
	if (Element= document.getElementById('EditBay')) {
		Element.innerHTML= '';
		}
		
	document.Operation.CalWidth.value= 0;
	document.Operation.CalType.selectedIndex= 0;

	if (Element= document.getElementById('CalDate')) {	
		Element.innerHTML= '';
		}
	}

this.LoadDay= function(Index) {
	var	Element;
	var Item, Count, X;
	var	Text			= '';
	var	Width			= 0;
	var	Selected	= 0;

// Found it in our table

	if (Item= Lookups[Index]) {
		Text= Info[Item];
		Width= Info[Item-1];
		
		Count= document.Operation.CalType.length;
		for (var I= 1; I < Count; I++) {
		  X= document.Operation.CalType.options[I].value;
			if (X == Info[Item-2]) {
				Selected= I;		// Indicate the type
				break;
				}
			}
		}

// Now change the calendar entry

	R= 0;
	Y= '0' + Index;
	Y= Y.substring(Y.length-2);
	if (Element= document.getElementById('c'+Y)) {
		X= Element.innerHTML;
		
// Show the date

		if (Element= document.getElementById('CalDate')) {	
			if (X > 0) {
				Element.innerHTML= Current_Month+'/'+X+'/'+Current_Year;
				R= 1;
				}
			else if (Index < 10) {
				Element.innerHTML= 'Not Applicable';
				R= 1;
				}
			}

// Show the text, width, and the type selected

		if (Element= document.getElementById('EditBay')) {
			Element.innerHTML= Text;
			}
		
		document.Operation.CalWidth.value= Width;
		document.Operation.CalType.selectedIndex= Selected;
		}
		
	return R;
	}
	
this.SaveDay= function(Index) {
	var	Element;
	var Item, X;
	var	Text			= '';
	var	Width			= 0;
	var	CType			= 0;
	
	if (Element= document.getElementById('EditBay')) {
		Text= Element.innerHTML;
		Element.innerHTML= '';
		}

	if (Item= Lookups[Index]) {		// In the list already?
		if ((Text.length) &&
			 (document.Operation.CalType.selectedIndex)) {
			Info[Item]= Text;
			CType= document.Operation.CalType.options[
				document.Operation.CalType.selectedIndex].value;
			}
		else {
			Info[Item]= '';
			}

		Info[Item-1]= document.Operation.CalWidth.value;
		Info[Item+1]= 1;	// Marked changed

		if (Index > 9) {
		  Info[Item-2]= CType;
			X= '0' + Index;
			X= X.substring(X.length-2);
			if (Element= document.getElementById('c'+X)) {
				Element.className= 'Cal'+CType;
				}
		  }
		}

// Not in the list, we need to add it if a type selected

	else if (document.Operation.CalType.selectedIndex) {
		Item= Info.length;	// location of the identifier

		Y= '0' + Index;
		Y= Y.substring(Y.length-2);
		if (Element= document.getElementById('c'+Y)) {
			DX= Element.innerHTML;
			
			MX= "0" + Current_Month;
			MX= MX.substring(MX.length - 2);

			DX= "0" + DX;
			DX= DX.substring(DX.length - 2);

			YX= "0" + Current_Year;
			YX= YX.substring(YX.length - 2);

			Info[Item++]= 'c' + YX + MX + DX;		// Which calendar item is today
			
			Info[Item]= document.Operation.CalType.options[
				 document.Operation.CalType.selectedIndex].value;
			Element.className= 'Cal'+Info[Item++];
			
			Info[Item++]= document.Operation.CalWidth.value;

			Info[Item]= Text;
			Lookups[Index]= Item++;

			Info[Item]= 1;	// Marked changed
			}
		}

	document.Operation.CalWidth.value= 0;
	document.Operation.CalType.selectedIndex= 0;
	if (Element= document.getElementById('CalDate')) {	
		Element.innerHTML= '';
		}
	}

this.Edit= function(Item) {
	var	Element;
	
	Editor.ReadPtr= 'Calendar.Clear()';
	Editor.WritePtr= 'Calendar.SaveDay('+Item+')';
	
	if (this.LoadDay(Item)) {
		if (Element= document.getElementById('EditBay')) {
			Editor.OnX(Element, "editbar");
			}
		}
	else {
		if (Element= document.getElementById('CalDate')) {
			Element.innerHTML= '';
			}

		Editor.Off();
		}
	}

this.State= function(Activating) {
	Login.Complete();

	if (Activating) {
		if (Login.Valid()) {
			if (Security.Access('EditBay')) {
				document.UserLogin.Session.value= Security.GetSession();
				document.UserLogin.UserID.value= Security.GetUserID();
				document.UserLogin.TimeStamp.value= Security.GetTimeStamp();
				document.UserLogin.Level.value= Security.GetLevel();
				document.UserLogin.Parameters.value= '';

				Security.Reset();
				Login.Reset();

				document.UserLogin.action= CGIDir + 'calendargen.cgi';
				document.UserLogin.submit();
				}
			else {
				alert("You are not allowed to change the calendar!");
				}
			}
		}

	Security.Reset();
	Login.Reset();
	}
}

Calendar= new tCalendar();

