//
// Enhanced JavaScript Event Calendar
//
// Author:  Rick Pike
// Website: http://calendar.pikesys.com
// Email: calendar@pikesys.com
//'Version 0.3 - (07-May-2004)
//
// based on an earlier script by Kevin Ilsen (http://calendar.ilsen.net or kevin@ilsen.net)

// Configurable values are set to defaults here; you can override them before calling Calendar( ) from your HTML page

var SpecialDay=1;	// 1=Sunday, 2=Monday, . . . 7=Saturday
var ColorBackground="#FFFFFF";
var ColorSpecialDay = "red";
var ColorToday = "green";
var ColorEvent = "blue";
var showAltDate = false;  	// add display of alternate date using results from user supplied "getAltMonth(dy, mo, yr, last)" and "getAltDate(dy, mo, yr)" functions
var showHolidays = false; 	// add display of holidays using result from user supplied "holidays(dy, mo, yr)" function
var showAltHoly = false; 	// add display of alternate holidays using result from user supplied "getAltHoly(dy, mo, yr)" function
var showMsgBox = true; 	// span empty cells (before 1st day and after last) for messageBox use
var showMini = true; 		// add minimonth display of prior and next months if first and/or last boxes are available 
var showNav = true; 		// enable month navigation (might disable for print version)
var showImages = true; 	// enable event images (might disable for print version)
var showLinks = true; 		// enable event hyperlinks (might disable for print version)
var msgBoxColor = "#ffcc99";
var navColor = "#D3D3D3";
var topColor = "#ffff99";
var imageAlign = "left"; 	// default event image alignment
var imageScale = 100;		// percent scale factor for images
var altAlign = true; 		// alternate left/right alignment of event images on same date for readability
var DefaultFormat = "custom"; // for compatibility; set to "layer" to simplify formatting
var ExportPage = ""; 		// name of html page for displaying event text for export
var PrintPage = ""; 		// name of html page for printer-friendly format

// all format codes must have "|" to separate before and after tags
var DateFontSize=5;
var AltDateFormat = "<font color=#999999 size=2>|</font>";
var MonthFormat = "<font size=" + DateFontSize + "><b>|</b></font>";
var AltMonthFormat = "<br><font color=#999999 size=" + DateFontSize/2 + ">|</font>";
var HolidayFormat = "<font color=#999999 size=2><b><center>|</center></b></font>";
var AltHolyFormat = "<font  size=2><b><center>|</center></b></font>";
var DefaultLayerFormat = "<font size=2>|</font>";

var defaultMsgBox = "<FONT SIZE=2><b>Tip:</b> This calendar shows the expected release dates for the next six months and while publications listed are usually released in accordance with the advertised release dates, in some circumstances release dates may change.  Any changes will be advertised on the ABS website.</font>";

// Initialize the range of the calendar to Jan - Dec of the current year.
// Event definitions will change this as needed; or it can be explicitly
// overridden before calling Calendar( ) from the HTML page.

var today = new Date();
var FirstMonth=GetFullYear(today) * 100 + today.getMonth()+1;
var LastMonth=FirstMonth;

// Layers[] is an array of layer names and default formats. Call DefineLayer( ) to add the
// layer name and corresponding format. New layer names in event definitions will
// be added automatically (watch case and spelling).

var Layers = new Array;
var LayerString = "|";
var layerCount = 0;
var layerChange = false;

// MsgBoxes[] is a SPARSE array; Call AddMsgBox( ) to populate it

var MsgBoxes = new Array;

// Events[] is a SPARSE array; Call AddEvent( ) to populate it or DefineEvent( ) for
// compatibility with existing calendar definition scripts.

var Events = new Array;
var urlParmMon = getURLParam("dt");
function validateInput(urlVal)
{
if(urlVal !="")
{
   if(urlVal.length == 6)
     {
     	if(IsNumeric(urlVal)==false)
     	{     		
     		return false;     	       
     	}
     }
   else
   	return false;
}   	
}
// Each event is defined by calling the AddEvent( ) routine with the following parameters:
//
//   AddEvent(Date, Description, Layer, Format, Link, Image, Width, Height, Align, Alt)
//        Date is a numeric value in the format YYYYMMDD
//        Description is a string (may include embedded HTML tags such as <BR>, <strong>, etc.)
//        Layer is an event category whose display on the calendar can be toggled on/off by the user
//        Format specifies the source of the format info for Description. Note that any embedded
//        formats in Description will still be applied; this argument is primarily to provide
//        a more convenient way to specify formats. 
//            "layer" = use default format from layer definition (plus any embedded tags!)
//            "custom" = only use format tags embedded in Description string
//            "<...>|</...>" = series of before and after tags separated by a "|" to wrap around
//               Description (plus any embedded tags!)  
//        Link is the URL of the target page if a hyperlink is desired from this event entry
//        Image is the URL of the image if you want to display an image with this event
//        Width is the width of the image in pixels
//        Height is the height of the image in pixels
//        Align is the alignment of the image such as "left", or "right"
//        Alt is the alternate text of the image (for mouseover or non-graphic browser)

// The function DefineEvent(Date, Description, Link, Image, Width, Height) is used
// for compatibility with previous calendar definition scripts

// Event constructor
//function printpage()
//{
//showNav = false; 	// enable month navigation (might disable for print version)
//showLinks = false
//initialCal=2;
//Calendar();
//alert("done");
//return false;
//}
function IsNumeric(sText)
{
   var ValidChars = "0123456789";
   var IsNumber=true;
   var Char;
 
   for (i = 0; i < sText.length && IsNumber == true; i++) 
      { 
      Char = sText.charAt(i); 
      if (ValidChars.indexOf(Char) == -1) 
         {
         IsNumber = false;
         }
      }
      //alert(IsNumber);
   return IsNumber;
   
   }

function Event(description, layer, format, link, image, width, height, align, alt) {

	this.description = description;
	if (link) this.link = link;
	if (image) {
	   this.image = image;
	   if (width) this.width = width;
	   if (height) this.height = height;
	   if (align) this.align = align;
	   if (alt) this.alt = alt;
	   //alert("Event: ("+this.width+","+this.height+")");
	}
	this.layer = (layer ? layer : "default");	 	// must have some associated layer
	
	if (format) {
	   if (CheckFormat(format)) this.format = format;
	}
}

// Compatibility function for existing calendar definition scripts
function DefineEvent(Date, Description, Link, Image, Width, Height) {
	AddEvent(Date, Description, "", "", Link, Image, Width, Height, "", "");
}

function AddEvent(Date, Description, Layer, Format, Link, Image, Width, Height, Align, Alt) {
	var i;

	if (!Events[Date]) Events[Date] = new Array;
	i = Events[Date].length;
	Events[Date][i] = new Event(Description, Layer, Format, Link, Image, Width, Height, Align, Alt);

	// Adjust the minimum and maximum month & year to include this date
	tmp = Math.floor(Date / 100);	
	if (tmp < FirstMonth) FirstMonth = tmp;
	if (tmp > LastMonth) LastMonth = tmp;

	// if EventLayer not in Layers, add it
	// NOTE: watch case in DefineLayer and DefineEvent to avoid undesired "duplicates"

	//alert("AddEvent("+Date+","+Description+","+Width+","+Height+"...)");
	if (Layer && !Layers[Layer]) DefineLayer(Layer);
}

// Layer constructor
function Layer(format, show) {
	if (format) {	
	   if (format.indexOf("|")>0) {
	      this.format = format;
	   } else {
	      alert("Invalid Calendar Format String: " + format);
	   }
	} else {
	   this.format = DefaultLayerFormat;
	}
	this.show = (show=="false" ? "false" : "true");	// watch boolean vs. string arg
}

function DefineLayer(LayerName, LayerFormat, LayerShow) {
	Layers[LayerName] = new Layer(LayerFormat, LayerShow);
	layerCount++;
}

// Utility function to populate an array with values
function arr() {
	for (var n=0;n<arr.arguments.length;n++) {
		this[n+1] = arr.arguments[n];
	}
}

// Create the array of month names (used in various places)
var months = new arr("January","February","March","April","May","June","July","August","September","October","November","December");

// Calendar( ) is the only routine that needs to be called to display the calendar
var cookieName = "layerCalendar";
var pre, post, tmp, gloMo, gloYr, gloYearmonth;

function Calendar( ) {
	var curdy, curmo, yr, mo, dy, firstday, yearmonth, bgn, lastdate, jump;
	var weekdays = new arr("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
	//var thispage=window.location.href;	
        //var ampNum = thispage.indexOf('&');
        //if(ampNum > 0)
            thispage="/ausstats/abs@.nsf/webpages/abs release calendar?opendocument";
          if(urlParmMon !="")          
          {          	
             if(validateInput(urlParmMon)==false)                                
                 urlParmMon="";
          } 
        thispage=thispage+"&dt=";
        //alert(thispage);
	var myMsgBox = "<FONT SIZE=2><b>Tip:</b>  Releases can be filtered in/out of the calendar by checking/unchecking the filter events and applying the changes.<br></FONT>" ;
	// define default MsgBox messages
	AddMsgBox(0, defaultMsgBox);
	AddMsgBox(0, myMsgBox);
	
	// Save current day and month for comparison
	curdy = today.getDate();
	curmo = today.getMonth()+1;
	
	initCal(curmo);
	mo = gloMo; yr = gloYr; yearmonth = gloYearmonth;
	getLayersVisible(); 		// get layer visibility settings from cookie
	
	// Create a date object for the first day of the desired month
	bgn = new Date(months[mo] + " 1," + yr);
	// Get the day-of-week of the first day, and the # days in the month
	firstday = bgn.getDay();
	lastdate = NumDaysIn(mo,yr);
	lastday = 1+(firstday + lastdate - 1)%7;
	prev = next = "&nbsp;";
	if (showNav) {
		if (yearmonth > FirstMonth)
			prev = '<span id="linkcal"><a class="navlink" href="' + thispage + PrevYearMonth(yearmonth)+'">&lt;-- View '+months[PrevMonth(mo)]+'</a></span>';
		if (yearmonth < LastMonth)
			next += '<span id="linkcal"><a class="navlink" href="' + thispage +NextYearMonth(yearmonth)+'">View '+months[NextMonth(mo)]+' --&gt;</a></span>';
	}

	parseFormat(MonthFormat);	
	tmp = "<TABLE BORDER=2 BGCOLOR="+ColorBackground+" cellspacing=0><TR BORDER=0 BGCOLOR="+topColor+">";
	tmp += "<TD ALIGN=CENTER BGCOLOR="+topColor+">" + prev + "</TD>";
	tmp += "<TD ALIGN=CENTER COLSPAN=5>" + pre + months[mo] + " " + yr + post;
	
	if (showAltDate) {
		parseFormat(AltMonthFormat);
		altMonth = getAltMonth(1, mo, yr, lastdate);
		tmp += pre + (altMonth ? altMonth : "") + post;
	}
	tmp += "</TD><TD ALIGN=CENTER BGCOLOR="+topColor+">" + next + "</TD></TR>";
	document.write("<style>IMG.centerText {	VERTICAL-ALIGN: top }</style>");
	document.write(tmp);
	if (showNav) {
	tmp = "<TR BGCOLOR="+topColor+" id='linkcal'>";
		tmp += "<TD colspan=7 align=center valign=middle><FORM>";					
		tmp += 'Jump to month:&nbsp;&nbsp;';		
		document.write(tmp);		
		BuildSelectionList(yearmonth, thispage);		
		tmp="";
		if (ExportPage) tmp += '&nbsp;&nbsp;|&nbsp;&nbsp;<a class="navlink" href="' + ExportPage+ "&dt="+yearmonth+'">' + imgexport +'Export Events Displayed</a>';		
		document.write(tmp);		
		if (PrintPage) document.write('&nbsp;&nbsp;|&nbsp;&nbsp;<a class="navlink" href="' + PrintPage + "&dt=" + yearmonth+'">'  + imgprint +'Print-friendly</a>');
		//if (PrintPage) document.write('&nbsp;&nbsp;|&nbsp;&nbsp;<a class="navlink" onclick="printpage();" href="#">'  + imgprint +'Print-friendly</a>');
		tmp = "&nbsp;&nbsp;|&nbsp;&nbsp;<a href ='#fp'>Filter Products</a><br></FORM></TD>";
		document.write(tmp + "</TR>");		
	}
	document.write("<TR BGCOLOR="+navColor+">");
	
	for (var i=1;i<=7;i++){
		document.write("<TD ALIGN=CENTER WIDTH=14%><FONT SIZE=2><b>"+weekdays[i]+"</b></FONT></TD>");
	}
	dy = 1;
	document.write("</TR><TR>");

	while (dy <= lastdate) {
		for (var i=1; i<=7; i++) {
			
			// If the day cell is before the first day of the month, print a miniMonth display of previous month in the first cell, 
			// otherwise print a space in this cell of the table.
			if (dy == 1 && i <= firstday) {
				if (i == 1) {
					if (showMini) {
						document.write("<TD BGCOLOR="+ColorBackground+">");	
						MiniMonth(PrevYearMonth(yearmonth));
					} else {
						document.write("<TD>&nbsp;");
					}
				} else if (showMsgBox && i==2) { 	// span empty cells to allow messageBox
					msgSpan = firstday - 1;
					document.write("<TD BGCOLOR=" + navColor + " COLSPAN=" + msgSpan +">&nbsp;");
					DoMsgBox(yearmonth, msgSpan);
				} else if (!showMsgBox) {
					document.write("<TD>&nbsp;");
				}
				document.write("</TD>");

			// If the day cell is after the last day of the month, print a miniMonth display of following month in the last cell, 
			// otherwise print a space in this cell of the table.
			} else if (dy > lastdate) {
				if (i == 7) {
					if (showMini) {
						document.write("<TD BGCOLOR="+ColorBackground+">");	
						MiniMonth(NextYearMonth(yearmonth));
					} else {
						document.write("<TD>&nbsp;");
					}
				} else if (showMsgBox && i==(lastday+1)) { 	// span empty cells to allow messageBox
					msgSpan = 6 - lastday;
					document.write("<TD BGCOLOR=" + navColor + " COLSPAN=" + msgSpan +">&nbsp;");
					DoMsgBox(yearmonth, msgSpan);
				} else if (!showMsgBox) {
					document.write("<TD>&nbsp;");
				}
				document.write("</TD>");

			// Otherwise, write date and the event, if any, in this cell of the table.
			} else {
				document.write("<TD VALIGN=TOP>");
				ShowDate(yr,mo,dy,i,curmo,curdy);
				document.write("</TD>");				
				dy++;
			}
		}
		document.write("</TR>");
	}

	if (showNav) {
		prev = next = "&nbsp;";
		if (yearmonth > FirstMonth)
			prev = '<span id="linkcal"><a class="navlink" href="' + thispage + PrevYearMonth(yearmonth)+'">&lt;-- View '+months[PrevMonth(mo)]+'</a></span>';
		if (yearmonth < LastMonth)
			next += '<span id="linkcal"><a class="navlink" href="' + thispage +NextYearMonth(yearmonth)+'">View '+months[NextMonth(mo)]+' --&gt;</a></span>';
		tmp = "<TR BGCOLOR="+topColor+" id='linkcal'><TD ALIGN=CENTER BGCOLOR="+topColor+">" + prev + "</TD>";
		tmp += "<TD colspan=5 align=center valign=middle>&nbsp;</td>";										
		tmp += "<TD ALIGN=CENTER BGCOLOR="+topColor+">" + next + "</TD>";		
		document.write(tmp + "</TR>");
		document.write("<TR BGCOLOR="+topColor+"><TD colspan=7 align=center>");
		document.write("<b>Product Flags :</b>&nbsp;<font size=2><img src='" + imgloc + "MEIcal/$File/MEIcal.gif' alt='Main Economic Indicator'>" +"Main Economic Indicator Publication&nbsp;<img src='" + imgloc 
	+ "microdatacal/$File/microdatacal.gif' alt='Confidentialised Unit Record File Microdata'>"+"Microdata&nbsp;<img src='" + imgloc + "First Issuecal/$File/First Issuecal.gif' alt='First Issue'>"  
        +"First Issue of Product&nbsp;<img src='" + imgloc + "Final Issuecal/$File/Final Issuecal.gif' alt='Final Issue'>" +"Final Issue of Product<br></font>");
        document.write("</TD></TR>");
		if (layerCount>1) {
			document.write("<TR BGCOLOR="+topColor+"><TD colspan=7 align=center>");
			ChooseLayers(yearmonth, thispage);
			document.write("&nbsp;&nbsp;<a href = '#top'>Back to top</a></TD></TR>");
		}
	}
	document.write("</TABLE>");	
}

// Display a date in the appropriate color, with events (if there are any)

function ShowDate(yr, mo, dy, dayofweek, currentmonth, currentday) {

	var ind, DayHighlighted, tmp, event;

	tmp = "<TABLE><TR VALIGN=TOP><TD ALIGN=LEFT WIDTH=10%>";
	tmp += "<FONT SIZE=" + DateFontSize;	// Note open tag!	
	DayHighlighted = false;

	//if ((mo == currentmonth) && (dy == currentday)) {
	//	tmp += " COLOR=" + ColorToday;
	//	DayHighlighted = true;
	//} 
	//else if (dayofweek == SpecialDay) {
	//	tmp += " COLOR=" + ColorSpecialDay;
	//	DayHighlighted = true;
	//}

	ind = (((yr * 100) + mo) * 100) + dy;
	if (Events[ind]) {
		//event = Events[ind];
		//if (!DayHighlighted) tmp += " COLOR=" + ColorEvent;
//	} else {
//		event = "&nbsp;<BR>&nbsp;";
	}
	
	tmp += "><B>" + dy + (dy<10 ? "&nbsp;" : "") + "&nbsp;</B></FONT></TD>";	 	// close tag
	document.write(tmp);
	
	if (showAltDate) {
		altDate = getAltDate(dy, mo, yr);
		parseFormat(AltDateFormat);
		document.write("<TD ALIGN=RIGHT>" + pre + altDate + post + "</TD>");
	}
	document.write("</TR></TABLE>");

	if (showAltHoly) {
		tmp = getAltHoly(dy,mo,yr);
		if (tmp) {
			parseFormat(AltHolyFormat);
			document.write(pre + tmp + post + "<BR>");
		}
	}
	
	if (showHolidays) {
		tmp = holidays(dy,mo,yr);
		if (tmp) {
			parseFormat(HolidayFormat);
			document.write(pre + tmp + post + "<BR>");
		}
	}
//	document.write("<P><FONT SIZE=1>" + event + "</FONT>");

	images=0;
	for (j in Events[ind]) {
		ev = Events[ind][j];
		// with(Events[ind][j]) { // greatly improves readability of following
		//for (k in ev) { alert("ev["+k+"]="+ev[k]) }
		//  document.write("Events[" + ind + "][" + j + "][" + k + "] = " + EscapeLtGt(Events[ind][j][k]), "<br>");
		//alert("-> Layers[Events["+ind+"]["+j+"]."+ev.layer+"].show="+Layers[ev.layer].show);
		tmp = "";		
		if (Layers[ev.layer].show == "true") {
			//alert("(+)showing event for "+ind+" in layer "+ev.layer);
			// Build the HTML string for this event
			tmp += (j>0 ? "<br>" : "");
			if (ev.image && showImages) {
				if (ev.align) {
					align = ev.align;
				//} else if (altAlign && images>0) {
				//	align = (lastAlign=="left" ? "right" : "left");
				} else {
					align = imageAlign;
				}
				
				tmp += '<img src="' + imgloc + ev.image +'cal' +'/$File/' +ev.image +'cal' +'.gif" '+
					   (ev.width ? '"  width="' + ev.width*imageScale/100 : '') +
					   (ev.height ? '" height="' + ev.height*imageScale/100 : '') +
					   (ev.alt ? '" alt="' + ev.alt : '') +					   
					   '" align="' + align + '" valign="top">&nbsp;&nbsp;';
				lastAlign = align;
				images++;
			}
			format = "";
			if (ev.format == "layer") { // use format from layer (and embedded tags)
				format = Layers[ev.layer].format;
			} else if (ev.format == "custom") { // use only embedded tags
				format = "";
			} else if (ev.format) { 	// format string?
				if (CheckFormat(ev.format)) format = ev.format;
			} else if (DefaultFormat == "layer") { // use format from layer if no custom format
				format = Layers[ev.layer].format;
			}
			parseFormat(format);
			//tmp += pre + (ev.link && showLinks ? ev.description.link(ev.link) : ev.description) + post + "<br>";
			tmp += pre + (ev.link && showLinks ? "<a class=\"eventlink\" href="+ev.link+">"+ev.description+".</a>" : ev.description+".") + post + "<br>";
			
		} else {
			//alert("(-)skipping event for "+ind+" in layer "+ev.layer);
		}
	document.write("<FONT SIZE=1>" + tmp + "</FONT>");
	}
}

function exportCal( ) {
	var curdy, curmo, yr, mo, dy, firstday, yearmonth, lastdate;

	// Save current day and month for comparison
	curdy = today.getDate();
	curmo = today.getMonth()+1;

	initCal(curmo);
	mo = gloMo; yr = gloYr; yearmonth = gloYearmonth;
	getLayersVisible();	
	
	// Create a date object for the first day of the desired month
	lastdate = NumDaysIn(mo,yr);

	tmp = "<textarea NAME=\"txt\"  ROWS=20 COLS=75 WRAP=VIRTUAL>";
	tmp += '"Subject","Start Date","Start Time","End Date","End Time","All day event","Description","Show time as","Location"\n';
	document.write(tmp);
	for (dy=1; dy<=lastdate; dy++) {
		ind = (((yr * 100) + mo) * 100) + dy;
		evdate = dy + "/" + mo + "/" + yr;
		for (j in Events[ind]) {
			ev = Events[ind][j];
			if (Layers[ev.layer].show == "true") {
				//alert("(+)showing event for "+ind+" in layer "+ev.layer);
				tmp = qw(ev.description) + "," + qw(evdate) + ",,,," + qw("true") + ",," + 
					 qw("3") + "," + qw("CalendarScript");
				if (ev.description) document.write(tmp+"\n");
			} else {
				//alert("(-)skipping event for "+ind+" in layer "+ev.layer);
			}
		}
	}
	document.write("</textarea>");
}

function getLayersVisible() {
	// get layer visibility settings from cookie
	prefix = cookieName + "|";
	cookie = unescape(document.cookie);
	//alert(cookie);	
	pos = cookie.indexOf(prefix);	
	if (pos>=0) {
	    pos += prefix.length;	    
	    sep = cookie.indexOf("~");
	    if (sep == -1) sep = cookie.length;	    
	    var layerCookies = cookie.substring(pos, sep).split("|");
	    for (i=0; i<layerCookies.length; i++) {
	        sep = layerCookies[i].indexOf("=");
		name = layerCookies[i].substring(0, sep);
		value = layerCookies[i].substring(sep+1, layerCookies[i].length);
		if (Layers[name]) Layers[name].show = value;
		//alert("Read cookie: "+name+"="+value);
		//alert("Read cookie: "+name+"="+value+" Layers["+name+"]="+Layers[name].show);
	    }
	}
}
function initCal(curmo) {

	// create default layer
	if (!Layers["default"]) DefineLayer("default", DefaultLayerFormat);
	
	// Default to current month and year
	mo = curmo;
	yr = GetFullYear(today);
	yearmonth = (yr * 100) + mo;

	// If querystring parameter is present, get the month/year ("calendar.htm?YYYYMM")
	   if(urlParmMon !=""){
               yearmonth=parseInt(urlParmMon);
	       mo = yearmonth % 100;
	       yr = (yearmonth - mo) / 100;
	   }       

	// Constrain to the range of months with events
	if (yearmonth < FirstMonth) {
		mo = FirstMonth % 100;
		yr = (FirstMonth - mo) / 100;
		yearmonth = FirstMonth;
	}
	if (yearmonth > LastMonth) {
		mo = LastMonth % 100;
		yr = (LastMonth - mo) / 100;
		yearmonth = LastMonth;
	}
	gloMo = mo; gloYr = yr; gloYearmonth = yearmonth;
}

function qw(string) {
	return "&quot;" + string + "&quot;";
}

// Create a mini display of the desired month

function MiniMonth(yearmonth) {
	var bgn, firstday, lastdate, miniweek;
	var days = new arr("S","M","T","W","T","F","S");

	mo = yearmonth % 100;
	yr = (yearmonth - mo) / 100;
	bgn = new Date(months[mo] + " 1," + yr);
	// Get the day-of-week of the first day, and the # days in the month
	firstday = bgn.getDay();
	lastdate = NumDaysIn(mo,yr);
	document.write("<b><tt><Font Size=2><div align=center>&nbsp;" + months[mo] + "</div></font>");
	miniweek = "<font size=1>&nbsp;<u>";
	for (d in days) { miniweek += "&nbsp;" + days[d] + "&nbsp;"; }
	document.write(miniweek,"</u>");
	dy = 1;
	// Rest of the weeks . . .
	while (dy <= lastdate) {
		miniweek = "<br>";
		for (var i=1;i<=7;i++) {
			// If the day is less than the day of the week of the first day of the month, append spaces
			if (dy == 1 && i <= firstday){
				miniweek += "&nbsp;&nbsp;&nbsp;";
			// End minimonth if the day > last day of the month
			} else if (dy > lastdate) {
				break;
			// Otherwise, append date (w/ extra space for single digits)
			} else {
				miniweek += "&nbsp;" + ( dy<10 ? "&nbsp;" : "" ) +dy;
				dy++;
			}
		}
		document.write(miniweek);
	}
	document.write("</font></tt></b>");
}


// Remaining routines are utilities used above

function NumDaysIn(mo,yr) {
	if (mo==4 || mo==6 || mo==9 || mo==11) return 30;
	else if ((mo==2) && LeapYear(yr)) return 29;
	else if (mo==2) return 28;
	else return 31;
}

function LeapYear(yr) {
	return ( (yr%4 == 0 && yr%100 != 0) || yr % 400 == 0 ? true : false );
}

// fixes a Netscape 2 and 3 bug
function GetFullYear(d) { // d is a date object
	var yr = d.getYear();
	return ( yr < 1000 ? yr + 1900 : yr );
}

function PrevMonth(mth) {
	return ( mth == 1 ? 12 : mth - 1 );
}

function NextMonth(mth) {
	return ( mth == 12 ? 1 : mth + 1 );
}

function PrevYearMonth(yrmth) {
	return ( yrmth%100 == 1 ? yrmth-100+11 : yrmth-1 );
}

function NextYearMonth(yrmth) {
	return ( yrmth%100 == 12 ? yrmth-11+100 : yrmth+1 );
}

function JumpTo(calendar, thispage) {
	var sel, yrmo;

	sel = calendar.selectedIndex;
	yrmo = calendar.form.jumpmonth[sel].value;
	document.location = thispage + yrmo;	
}

function BuildSelectionList(current, thispage) {
	var mo, yr, yearmonth;

	yearmonth = FirstMonth;
	tmp = "<select name=\"jumpmonth\" size=1 onchange=\"JumpTo(this,'" + thispage + "')\">";
	while (yearmonth <= LastMonth) {
		mo = yearmonth % 100;
		yr = (yearmonth - mo) / 100;
		selected = (yearmonth == current ? " selected" : "");
		tmp += "<option value=" + yearmonth + selected + ">" + months[mo]+" "+yr;
		yearmonth = NextYearMonth(yearmonth);
	}

	document.write(tmp + "</select>");
}

// Create a message box

function DoMsgBox(yearmonth, msgSpan) {
	if (MsgBoxes[yearmonth]) {
		for (j in MsgBoxes[yearmonth]) { 	// find first unshown message for month that fits
			monthlyMsg =MsgBoxes[yearmonth][j];
			if (!monthlyMsg.shown) {
				//document.write("monthlyMsg.minspan = " + monthlyMsg.minspan + "<br>");
				if (!monthlyMsg.minspan || monthlyMsg.minspan <= msgSpan) {
					tmp = "<table border=2 bgcolor=" + msgBoxColor + " align=center>";
					tmp += "<TR><TD>"+ monthlyMsg.message + "</TD></TR></table>";
					document.write(tmp);
					monthlyMsg.shown = true;
					return;
				}
			}
		}
	}
	if (MsgBoxes[0]) { 	// show default MsgBox messages if they exists
		for (j in MsgBoxes[0]) { 	// find first unshown message for month that fits
			monthlyMsg =MsgBoxes[0][j];
			//alert(j);
			//alert(monthlyMsg);
			if (!monthlyMsg.shown) {
				//document.write("monthlyMsg.minspan = " + monthlyMsg.minspan + "<br>");
				if (!monthlyMsg.minspan || monthlyMsg.minspan <= msgSpan) {
					tmp = "<table border=2 bgcolor=" + msgBoxColor + " align=center>";
					tmp += "<TR><TD>"+ monthlyMsg.message + "</TD></TR></table>";
					document.write(tmp);
					monthlyMsg.shown = true;
					return;
				}
			}
		}
	}
}

// Utility routines

function escramVal(j,k){var a,b,c,d,e;a='<a href=\"mai';c='\">';a+='lto:';b=j+'@';e='</a>';b+=k;d=b;return(a+b+c+d+e);}

function parseFormat(format) {
	// pre and post are globals
	pre = post = "";
	if (format) {		
		var sep = format.indexOf("|");
		if (sep > 0) {  // split format into pre and post strings
			pre = format.substring(0, sep);
			post= format.substring(1+sep, format.length);
		}
	}
}

function CheckFormat(String) {
	var okay;
	okay =(String == "layer" || String == "custom" || String.indexOf("|")>0);
	if (!okay) alert("Invalid Calendar Format String: " + String);
	return okay;
}
	
// MsgBox constructor
function MsgBox(message,minspan,maxspan) {
	//alert("MsgBox("+message+","+minspan+","+maxspan+")");
	this.message = message;
	this.minspan = (minspan ? minspan : 1);
        if (maxspan) this.maxspan = maxspan;
	//this.shown = false;
}

function AddMsgBox(yearmonth,message,minspan,maxspan) {
	var i;

	if (!MsgBoxes[yearmonth]) MsgBoxes[yearmonth] = new Array;
	i = MsgBoxes[yearmonth].length;
	MsgBoxes[yearmonth][i] = new MsgBox(message,minspan,maxspan);
}

function ChooseLayers(yearmonth, thispage) {
	var i, checked;
	tmp = '<a name="fp"></a><form name="layerform">'+ '<b>Filter Events:</b>&nbsp;';
	//mk code
	//Layers.sort();
	var myarray=new Array ()
	//["43","64","53","25"]
        //myarray.sort(function(a,b){return a - b}) 
        
        var arrcnt = 0;
        var arrtmp=""
        for (i in Layers)
        	
        {
           myarray[arrcnt]=i;
         //  alert(arrcnt);
           arrtmp=arrtmp +" " +myarray[arrcnt];
           arrcnt++;          
        }
       // alert("Last:" + arrcnt);
        //alert(arrtmp);
        arrtmp=""
        myarray.sort();       
        for (var x =0;x<= myarray.length-1; x++)
          {
          		if (myarray[x] != "default") {
			checked = (Layers[myarray[x]].show == "true" ? " checked" : "");
			parseFormat(Layers[myarray[x]].format);
			tmp += pre + '<input type="checkbox" name="' + myarray[x] + 'catno" value="' + myarray[x] + '"' +checked + 
				' onClick="ChangeLayer(\''+myarray[x]+'\')">' + myarray[x] + "&nbsp;" + post;
		}
		   arrtmp=arrtmp +" " +myarray[x];
           
          }
        //alert(arrtmp);
	
	//for (i in Layers) {
	//	if (i != "default") {
	//		checked = (Layers[i].show == "true" ? " checked" : "");
	//		parseFormat(Layers[i].format);
	//		tmp += pre + '<input type="checkbox" name="' + i + 'catno" value="' + i + '"' +checked + 
	//			' onClick="ChangeLayer(\''+i+'\')">' + i + "&nbsp;" + post;
	//	}
 	//}
	//if (layerChange) {
	tmp += '&nbsp;<input type="button" name="ApplyChanges" value="Apply Changes"' +
		'onClick="ApplyLayerChange(\'' + thispage + yearmonth + '\')">';
	//}
	//alert(tmp);
	document.write(tmp + "</form>");
}

function ChangeLayer(layer) {
	layerChange=true;
	//mk code
	tmplayer=layer +"catno";
	//alert(tmplayer);
	Layers[layer].show = document.layerform[tmplayer].checked;
}

function ApplyLayerChange(thispage, yearmonth) {
	layerChange=false;
	cookie = cookieName;
	for (layer in Layers) {
		if (layer != "default") {
			cookie += "|" + layer + "=" + Layers[layer].show;
		}
	}
	// persist cookie?
	cookie+="~";
	//var DateVal =(new Date(new Date().getTime()+ 63072000000)).toGMTString();
	//var Dateval1 =(new Date(new Date().getTime())).toGMTString();
	//alert(Dateval1);
	var DateVal =(new Date(new Date().getTime()+ 600000)).toGMTString();
	document.cookie = "relcal=" + escape(cookie) + ";domain=" + cookiedomain + "; path=/" +"; expires="+ DateVal;	
	document.location = thispage + (yearmonth ? yearmonth : "");
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               function getURLParam(strParamName){
  var strReturn = "";
  var strHref = window.location.href;
  //strHref=decodeURIComponent(strHref);
  //alert(strHref);
  if ( strHref.indexOf("&") > -1 ){
    var strQueryString = "&" + strHref.substr(strHref.indexOf("&")).toLowerCase();
    var aQueryString = strQueryString.split("&");
    for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
      if ( 
aQueryString[iParam].indexOf(strParamName.toLowerCase() + "=") > -1 ){
        var aParam = aQueryString[iParam].split("=");
        strReturn = aParam[1];
        break;
      }
    }
  }
  return unescape(strReturn);
} 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
