// List of month names
var monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

// Enumeration of DOM node types
var NodeTypes = {ELEMENT               :  1,
                 ATTRIBUTE             :  2,
                 TEXT                  :  3,
                 CDATA_SECTION         :  4,
                 ENTITY_REFERENCE      :  5,
                 ENTITY                :  6,
                 PROCESSING_INSTRUCTION:  7,
                 COMMENT               :  8,
                 DOCUMENT              :  9,
                 DOCUMENT_TYPE         : 10,
                 DOCUMENT_FRAGMENT     : 11,
                 NOTATION              : 12};

// The name of the content being viewed (ie, 'Home', 'Pools', etc.)
var openLink  = null;

// Sets/clears the status bar in certain browsers
function StatusClear()    { window.status = '';   }
function StatusSet2 (msg) { window.status = msg;	}
function StatusSet  (msg) {
	window.status = msg;
	setTimeout('StatusSet2("' + msg + '")', 1);
}

// Prefixes a string with the specified character to create
// a new string with at least as many characters as requested
function PadLeft(str, newLength, padChar) {
	function RepeatString(str, count) {
		if (count     <= 0) return '' ;
		if (count     == 1) return str;
		if (count % 2 == 0)	return       RepeatString(str + str,  count      / 2);
		else                return str + RepeatString(str + str, (count - 1) / 2);
	}
  if (newLength <= str.length) return str;
  else return RepeatString(padChar, newLength - str.length) + str;
}

// Get the number of days in the selected month, and populate the DOB_Day select box
function ComputeMonthLength() {
	var year  = Number(document.getElementById('DOB_Year' ).value);
	var month = Number(document.getElementById('DOB_Month').value);
	// NOTE: The following test for leap-year only works until 2100, since
	//       2100 is the only year after 1900 divisible by 4 that is not a leap year
	var daysInMonth = 32 - new Date(year, month - 1, 32).getDate();
	var daySelect   = document.getElementById('DOB_Day');
	for (var date = 29; date <= 31; ++date) {
		daySelect.options[date - 1].style.display = (date <= daysInMonth ? '' : 'none');
	}
	daySelect.selectedIndex = Math.min(daySelect.selectedIndex, daysInMonth - 1);
}

// Collapses/Expands the submenu items in the left navigation pane
function ToggleSubMenu(tag) {
  var isOpen = (tag.className == 'DropdownOpen');
	tag.className = (isOpen ? 'DropdownClosed' : 'DropdownOpen');
	var subItem = tag.nextSibling;
	while (subItem.nodeType != NodeTypes.ELEMENT)
		subItem = subItem.nextSibling;
	while (subItem.className == 'MenuSubItem') {
		subItem.style.display = (isOpen ? 'none' : '');
		do {
			subItem = subItem.nextSibling;
		} while (subItem.nodeType != NodeTypes.ELEMENT);
	}
}

// Changes the data displayed in the content portion of the window
function ClickLink(newLink) {
	if (newLink == null) {
		// Try to parse which page to use from the message bar
		var page = window.location.hash;
		if (page.length == 0) {
			newLink = 'Home';
			window.location.hash = '#Home';
		} else {
			newLink = page.substring(1);
		}
	} else {
		window.location.hash = '#' + newLink;
	}
  if (newLink != openLink) {
		if (document.getElementById('Content' + newLink) == null) {
			alert('The requested page does not exist; Please remove all bookmarks linking to "'
			      + window.location + '"');
			newLink = (openLink == null ? 'Home' : openLink);
		  window.location.hash = '#' + newLink;
		} else {
			if (openLink != null) {
				document.getElementById('Content' + openLink).style.display = 'none';
				document.getElementById('Link'    + openLink).style.color   = '';
			}
			openLink = newLink;
			document.getElementById('Content' + openLink).style.display = 'block';
			var linkObj = document.getElementById('Link' + openLink);
			linkObj.style.color   = '#000000';
			document.title = 'Dayton Area Sharks - ' + linkObj.title;
		}
	}
}

// Calls ClickLink if the enter key or spacebar was pressed on a link
function ClickOnEnter(e, newLink) {
	if (!e) e = window.event;
	if (typeof(e.keyCode) == 'number') {
		e = e.keyCode;
	} else if (typeof(e.which) == 'number') {
		e = e.which;
	} else {
		e = e.charCode;
	}
	if (e == 13 || e == 32) {
		ClickLink(newLink);
		return false;
	}
	return true;
}

// Check for back/forward button navigation by polling the hash portion of the URL
function PollHashChange() {
	var hash = window.location.hash;
	if (hash.length > 0 && hash.substring(1) != openLink)
		ClickLink();
	setTimeout('PollHashChange()', 100);
}

// Prevents pasting using the context menu
function PreventContextMenu(e) {
	if (!e) e = window.event;
	if ('button' in e ? (e.button == 2) : (e.which == 3)) {
		alert('Pasting into this field has been made difficult in an attempt to\r\n' +
		      'coerce you into typing your e-mail address for verification purposes!');
		return false;
	}
	return true;
}

// Prevents pasting using ctrl-V
function PreventCtrlV(e) {
	if (!e) e = window.event;
	var keyCode;
	if ('keyCode' in e) {
		keyCode = e.keyCode;
	} else if ('which' in e) {
		keyCode = e.which;
	} else {
		keyCode = e.charCode;
	}

	if (e.ctrlKey && keyCode == 86) {
		alert('Pasting into this field has been made difficult in an attempt to\r\n' +
		      'coerce you into typing your e-mail address for verification purposes!');
		return false;
	}
	return true;
}


// A list of special event structures sorted by start date, with fields:
//   DATE_BEGIN  : Required inclusive serial start date
//   DATE_END    : Required inclusive serial end date
//   HAS_PRACTICE: Required boolean indicating if practice will be held as scheduled
//   NAME_SHORT  : Optional; If present this text is shown on the workout schedule
//   NAME_LONG   : Optional; If present this text is shown on the events calendars
//   ADDRESS     : Optional mailing address
//   CITY_STATE  : Optional 
//   POSTAL_CODE : Optional postal code as a string
//   LINK_MAP    : Optional url to a map of the meet location
//   LINK_INFO   : Optional url to meet information
//   MEET_INFO   : Optional structure array with the following fields
//       COST    : Required string indicating the cost associated with participation
//       DEADLINE: Required string indicating the meet entry deadline
//       DEADTYPE: Required string containing a capitalized english past-tense verb
var specialEvents = [/*
                     {DATE_BEGIN  : Date.parse('Dec 21, 2010'),
                      DATE_END    : Date.parse('Jan 06, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Holiday',
                      NAME_LONG   : 'Winter Break'},
                     {DATE_BEGIN  : Date.parse('Feb 26, 2011'),
                      DATE_END    : Date.parse('Feb 26, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'SWOM&nbsp;SCY&nbsp;Meet',
                      ADDRESS     : '1&nbsp;Eagles&nbsp;Way',
                      CITY_STATE  : 'Milford,&nbsp;OH',
                      POSTAL_CODE : '45150',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=1+Eagles+Way,+Milford,+OH+45150&sll=39.177849,-84.235826&sspn=0.024818,0.055747&gl=us&ie=UTF8&hq=&hnear=1+Eagles+Way,+Milford,+Clermont,+Ohio+45150&ll=39.180111,-84.241447&spn=0.198534,0.445976&z=12',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2011/20110226-SWOM.pdf',
                      MEET_INFO   : [{COST    : '$20',
                                      DEADLINE: Date.parse('Feb 23, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$30',
                                      DEADLINE: Date.parse('Feb 26, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Mar 19, 2011'),
                      DATE_END    : Date.parse('Mar 19, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Anderson&nbsp;Meet',
                      NAME_LONG   : 'Anderson&nbsp;SCY&nbsp;Meet',
                      ADDRESS     : '8108&nbsp;Clough&nbsp;Pike',
                      CITY_STATE  : 'Cincinnati,&nbsp;OH',
                      POSTAL_CODE : '45244',
                      LINK_MAP    : 'http://maps.google.com/maps?oe=utf-8&client=firefox-a&ie=UTF8&q=8108+Clough+Pike,+cincinnati,+oh&fb=1&gl=us&hnear=&cid=0,0,4175214650472351689&hq=8108+Clough+Pike,+cincinnati,+oh&ll=39.096229,-84.328308&spn=0.13056,0.308647&z=12',
                      LINK_INFO   : 'https://www.clubassistant.com/club/meet_information.cfm?c=1559&smid=2969',
                      MEET_INFO   : [{COST    : '$25',
                                      DEADLINE: Date.parse('Mar 16, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$40',
                                      DEADLINE: Date.parse('Mar 19, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Apr 03, 2011'),
                      DATE_END    : Date.parse('Apr 03, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Marlins&nbsp;SCY&nbsp;Meet',
                      NAME_LONG   : 'UC&nbsp;Marlins&nbsp;SCY&nbsp;Meet',
                      ADDRESS     : '2820 Bearcat Way',
                      CITY_STATE  : 'Cincinnati,&nbsp;OH',
                      POSTAL_CODE : '45221',
                      LINK_MAP    : 'http://maps.google.com/maps?q=39.132291,-84.515143&num=1&sll=39.133289,-84.51497&sspn=0.006295,0.006295&gl=us&ie=UTF8&ll=39.132324,-84.515247&spn=0.098536,0.222988&z=13',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2011/20110403-UC.pdf',
                      MEET_INFO   : [{COST    : '$30',
                                      DEADLINE: Date.parse('Mar 30, 2011'),
                                      DEADTYPE: 'Postmarked'},
                                     {COST    : '$40',
                                      DEADLINE: Date.parse('Apr 03, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Apr 30, 2011'),
                      DATE_END    : Date.parse('Apr 30, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'DAS&nbsp;Timetrial',
                      NAME_LONG   : 'DAS&nbsp;Intrasquad&nbsp;Meet',
                      ADDRESS     : '2&nbsp;Evanston&nbsp;Ave',
                      CITY_STATE  : 'Dayton,&nbsp;OH',
                      POSTAL_CODE : '45409',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=2+Evanston+Ave,+Dayton,+OH+45409&sll=39.736432,-84.174972&sspn=0.006155,0.013937&gl=us&ie=UTF8&hq=&hnear=2+Evanston+Ave,+Dayton,+Montgomery,+Ohio+45409&ll=39.736366,-84.1745&spn=0.049238,0.111494&z=14',
                      LINK_INFO   : 'http://static.daytonareasharks.com/Documents/2011-04-30 Dayton Area Sharks Intrasquad Meet Info.docx',
                      MEET_INFO   : [{COST    : 'Free!',
                                      DEADLINE: Date.parse('Apr 30, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('May 19, 2011'),
                      DATE_END    : Date.parse('May 19, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closes',
                      NAME_LONG   : 'Last&nbsp;WPAFB&nbsp;Practice'},
                     {DATE_BEGIN  : Date.parse('May 30, 2011'),
                      DATE_END    : Date.parse('May 30, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'YMCA&nbsp;Closes',
                      NAME_LONG   : 'Last&nbsp;YMCA&nbsp;Practice'},
                     {DATE_BEGIN  : Date.parse('Jun 01, 2011'),
                      DATE_END    : Date.parse('Jun 01, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Prairies&nbsp;Opens',
                      NAME_LONG   : 'First&nbsp;Prairies&nbsp;Practice'},
                     {DATE_BEGIN  : Date.parse('Jun 02, 2011'),
                      DATE_END    : Date.parse('Jun 02, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;Closes',
                      NAME_LONG   : 'Last&nbsp;UD&nbsp;Practice'},
                     {DATE_BEGIN  : Date.parse('Jun 18, 2011'),
                      DATE_END    : Date.parse('Jun 18, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : '25K&nbsp;OW&nbsp;Nationals',
                      ADDRESS     : '1156&nbsp;S&nbsp;Harbour&nbsp;Dr',
                      CITY_STATE  : 'Noblesville,&nbsp;IN',
                      POSTAL_CODE : '46062',
                      LINK_MAP    : 'http://maps.google.com/maps?oe=utf-8&client=firefox-a&ie=UTF8&q=1156+S+Harbour+Dr+Noblesville,+IN&fb=1&gl=us&hnear=0x89b7e298a4b0db27:0x7590c9c5d8a301e0,Linthicum,+MD&cid=0,0,8954078680159807686&ll=40.076495,-86.053162&spn=0.188097,0.445976&z=12',
                      LINK_INFO   : 'http://www.grinswim.org/2011USMS25K/2011USMS25Kentry.pdf',
                      MEET_INFO   : [{COST    : '$100&nbsp;Solo;&nbsp;$50&nbsp;Relay',
                                      DEADLINE: Date.parse('Apr 23, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$125&nbsp;Solo;&nbsp;$60&nbsp;Relay',
                                      DEADLINE: Date.parse('May 21, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Jul 24, 2011'),
                      DATE_END    : Date.parse('Jul 24, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Anderson&nbsp;Meet',
                      NAME_LONG   : 'Anderson&nbsp;LCM&nbsp;Meet',
                      ADDRESS     : '8108&nbsp;Clough&nbsp;Pike',
                      CITY_STATE  : 'Cincinnati,&nbsp;OH',
                      POSTAL_CODE : '45244',
                      LINK_MAP    : 'http://maps.google.com/maps?q=8108+Clough+Pike,+Cincinnati,+OH&hl=en&ll=39.090567,-84.32848&spn=0.049364,0.111494&sll=39.0909,-84.32848&sspn=0.098727,0.222988&gl=us&z=14',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2011/20110724-ABM.pdf',
                      MEET_INFO   : [{COST    : '$25',
                                      DEADLINE: Date.parse('Jul 21, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$35',
                                      DEADLINE: Date.parse('Jul 24, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Aug 03, 2011'),
                      DATE_END    : Date.parse('Aug 06, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'USMS&nbsp;Nationals',
                      NAME_LONG   : 'USMS&nbsp;LCM&nbsp;Nationals',
                      ADDRESS     : '661&nbsp;Heisman&nbsp;Dr',
                      CITY_STATE  : 'Auburn,&nbsp;AL',
                      POSTAL_CODE : '36849',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=661+Heisman+Dr,+Auburn,+AL+36849&aq=&sll=32.601006,-85.492065&sspn=0.006697,0.013937&gl=us&g=32.600313,-85.492989&ie=UTF8&hq=&hnear=661+Heisman+Dr,+Auburn,+Alabama+36849&ll=32.601494,-85.491486&spn=0.107159,0.222988&z=13',
                      LINK_INFO   : 'http://www.usms.org/comp/lcnats11/',
                      MEET_INFO   : [{COST    : '$50&nbsp;+&nbsp;$4/IE',
                                      DEADLINE: Date.parse('Jun 15, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$60&nbsp;+&nbsp;$4/IE',
                                      DEADLINE: Date.parse('Jun 29, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Aug 13, 2011'),
                      DATE_END    : Date.parse('Aug 13, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Ohio&nbsp;River&nbsp;OW&nbsp;Swim',
                      ADDRESS     : '2001&nbsp;Cardinal&nbsp;Harbour&nbsp;Rd',
                      CITY_STATE  : 'Prospect,&nbsp;KY',
                      POSTAL_CODE : '40059',
                      LINK_MAP    : 'http://maps.google.com/maps?q=2001+Cardinal+Harbour+Rd.,+Prospect,+Kentucky,+40059&oe=utf-8&client=firefox-a&ie=UTF8&hq=&hnear=2001+Cardinal+Harbour+Rd,+Prospect,+Kentucky+40059&gl=us&ll=38.420242,-85.608902&spn=0.398633,0.891953&z=11',
                      LINK_INFO   : 'http://ohioriverswim.weebly.com/uploads/3/4/4/5/3445834/2011_north_oldham_open_water_swim_flyer.pdf',
                      MEET_INFO   : [{COST    : '$35',
                                      DEADLINE: Date.parse('Jul 01, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$45',
                                      DEADLINE: Date.parse('Aug 08, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Aug 13, 2011'),
                      DATE_END    : Date.parse('Aug 13, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Splash&nbsp;&amp;&nbsp;Dash&nbsp;3',
                      ADDRESS     : '35&nbsp;Parkwood&nbsp;Dr',
                      CITY_STATE  : 'Tipp&nbsp;City,&nbsp;OH',
                      POSTAL_CODE : '45371',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=35+Parkwood+Dr,+Tipp+City,+OH+45371&aq=&sll=39.968401,-84.170106&sspn=0.003046,0.006968&gl=us&ie=UTF8&hq=&hnear=35+Parkwood+Dr,+Tipp+City,+Ohio+45371&ll=39.968701,-84.170294&spn=0.048743,0.111494&z=14',
                      LINK_INFO   : 'http://tippnews.com/wp-content/uploads/splashdash2011reg.pdf',
                      MEET_INFO   : [{COST    : '$20',
                                      DEADLINE: Date.parse('Aug 12, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$25',
                                      DEADLINE: Date.parse('Aug 13, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Aug 20, 2011'),
                      DATE_END    : Date.parse('Aug 20, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Team&nbsp;Party',
                      CITY_STATE  : 'Dayton,&nbsp;OH',
                      POSTAL_CODE : '45440',
                      LINK_MAP    : 'http://maps.google.com/maps?q=45440&hl=en&ll=39.672578,-84.095192&spn=0.201628,0.445976&sll=37.0625,-95.677068&sspn=52.550571,114.169922&z=12',
                      MEET_INFO   : [{COST: 'Side&nbsp;Dish or&nbsp;Dessert',
                                      DEADLINE: Date.parse('Aug 20, 2011'),
                                      DEADTYPE: 'RSVP'}]},*/
                     {DATE_BEGIN  : Date.parse('Oct 06, 2011'),
                      DATE_END    : Date.parse('Oct 06, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Oct 08, 2011'),
                      DATE_END    : Date.parse('Oct 08, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Iron&nbsp;Shark',
                      ADDRESS     : '2&nbsp;Evanston&nbsp;Ave',
                      CITY_STATE  : 'Dayton,&nbsp;OH',
                      POSTAL_CODE : '45409',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=2+Evanston+Ave,+Dayton,+OH+45409&sll=39.736432,-84.174972&sspn=0.006155,0.013937&gl=us&ie=UTF8&hq=&hnear=2+Evanston+Ave,+Dayton,+Montgomery,+Ohio+45409&ll=39.736366,-84.1745&spn=0.049238,0.111494&z=14',
                      MEET_INFO   : [{COST    : 'Free!',
                                      DEADLINE: Date.parse('Oct 08, 2011'),
                                      DEADTYPE: '<a href="mailto:cody@daytonareasharks.com">E-mail Cody</a>'}]},
                     {DATE_BEGIN  : Date.parse('Oct 10, 2011'),
                      DATE_END    : Date.parse('Oct 10, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Oct 13, 2011'),
                      DATE_END    : Date.parse('Oct 13, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Last&nbsp;WPAFB<br />Thu&nbsp;Practice'},
                     {DATE_BEGIN  : Date.parse('Nov 05, 2011'),
                      DATE_END    : Date.parse('Nov 05, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Miami&nbsp;SCM&nbsp;Meet',
                      NAME_LONG   : 'Miami&nbsp;Redfin&nbsp;SCM&nbsp;Meet',
                      ADDRESS     : '700&nbsp;South&nbsp;Oak&nbsp;St',
                      CITY_STATE  : 'Oxford,&nbsp;OH',
                      POSTAL_CODE : '45056',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=642+Oak+Street,+Oxford,+OH&sll=39.502,-84.7369&sspn=0.003088,0.006968&ie=UTF8&hq=&hnear=642+Oak+St,+Oxford,+Butler,+Ohio+45056&ll=39.500862,-84.736176&spn=0.049406,0.111494&z=14&iwloc=A',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2011/20111105-Miami.pdf',
                      MEET_INFO   : [{COST    : '$25',
                                      DEADLINE: Date.parse('Oct 26, 2011'),
                                      DEADTYPE: 'Postmarked'},
                                     {COST    : '$40',
                                      DEADLINE: Date.parse('Nov 05, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Nov 23, 2011'),
                      DATE_END    : Date.parse('Nov 23, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB Closed'},
                     {DATE_BEGIN  : Date.parse('Nov 24, 2011'),
                      DATE_END    : Date.parse('Nov 26, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Thanksgiving',
                      NAME_LONG   : 'Thanksgiving Break'},
                     {DATE_BEGIN  : Date.parse('Dec 10, 2011'),
                      DATE_END    : Date.parse('Dec 10, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'DAS&nbsp;SCY&nbsp;Meet',
                      ADDRESS     : '2&nbsp;Evanston&nbsp;Ave',
                      CITY_STATE  : 'Dayton,&nbsp;OH',
                      POSTAL_CODE : '45409',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=2+Evanston+Ave,+Dayton,+OH+45409&sll=39.736432,-84.174972&sspn=0.006155,0.013937&gl=us&ie=UTF8&hq=&hnear=2+Evanston+Ave,+Dayton,+Montgomery,+Ohio+45409&ll=39.736366,-84.1745&spn=0.049238,0.111494&z=14',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2011/20111210-DAS.pdf',
                      MEET_INFO   : [{COST    : '$30',
                                      DEADLINE: Date.parse('Dec 06, 2011'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$40',
                                      DEADLINE: Date.parse('Dec 10, 2011'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Dec 19, 2011'),
                      DATE_END    : Date.parse('Dec 19, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Dec 20, 2011'),
                      DATE_END    : Date.parse('Dec 20, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;5:30-6:30'},
                     {DATE_BEGIN  : Date.parse('Dec 21, 2011'),
                      DATE_END    : Date.parse('Dec 21, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Dec 22, 2011'),
                      DATE_END    : Date.parse('Dec 22, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;5:30-6:30'},
                     {DATE_BEGIN  : Date.parse('Dec 24, 2011'),
                      DATE_END    : Date.parse('Dec 24, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Christmas&nbsp;Eve'},
                     {DATE_BEGIN  : Date.parse('Dec 26, 2011'),
                      DATE_END    : Date.parse('Dec 26, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Dec 27, 2011'),
                      DATE_END    : Date.parse('Dec 27, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;5:30-6:30'},
                     {DATE_BEGIN  : Date.parse('Dec 28, 2011'),
                      DATE_END    : Date.parse('Dec 28, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Dec 29, 2011'),
                      DATE_END    : Date.parse('Dec 29, 2011'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;5:30-6:30'},
                     {DATE_BEGIN  : Date.parse('Dec 31, 2011'),
                      DATE_END    : Date.parse('Dec 31, 2011'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'New&nbsp;Year\'s&nbsp;Eve'},
                     {DATE_BEGIN  : Date.parse('Jan 02, 2012'),
                      DATE_END    : Date.parse('Jan 02, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'WPAFB&nbsp;Closed'},
                     {DATE_BEGIN  : Date.parse('Jan 03, 2012'),
                      DATE_END    : Date.parse('Jan 03, 2012'),
                      HAS_PRACTICE: false},
                     {DATE_BEGIN  : Date.parse('Jan 05, 2012'),
                      DATE_END    : Date.parse('Jan 05, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;6:00-7:00'},
                     {DATE_BEGIN  : Date.parse('Jan 07, 2012'),
                      DATE_END    : Date.parse('Jan 07, 2012'),
                      HAS_PRACTICE: false},
                     {DATE_BEGIN  : Date.parse('Jan 10, 2012'),
                      DATE_END    : Date.parse('Jan 10, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;6:00-7:00'},
                     {DATE_BEGIN  : Date.parse('Jan 12, 2012'),
                      DATE_END    : Date.parse('Jan 12, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'UD&nbsp;6:00-7:00'},
                     {DATE_BEGIN  : Date.parse('Jan 28, 2012'),
                      DATE_END    : Date.parse('Jan 28, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Video&nbsp;Clinic'},
                     {DATE_BEGIN  : Date.parse('Feb 11, 2012'),
                      DATE_END    : Date.parse('Feb 11, 2012'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'Miami&nbsp;SCY&nbsp;Meet',
                      NAME_LONG   : 'Miami&nbsp;Redfin&nbsp;SCY&nbsp;Meet',
                      ADDRESS     : '750&nbsp;South&nbsp;Oak&nbsp;St',
                      CITY_STATE  : 'Oxford,&nbsp;OH',
                      POSTAL_CODE : '45056',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=642+Oak+Street,+Oxford,+OH&sll=39.502,-84.7369&sspn=0.003088,0.006968&ie=UTF8&hq=&hnear=642+Oak+St,+Oxford,+Butler,+Ohio+45056&ll=39.500862,-84.736176&spn=0.049406,0.111494&z=14&iwloc=A',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2012/20120211-MardiGras.pdf',
                      MEET_INFO   : [{COST    : '$25',
                                      DEADLINE: Date.parse('Feb 04, 2012'),
                                      DEADTYPE: 'Postmarked'},
                                     {COST    : '$40',
                                      DEADLINE: Date.parse('Feb 11, 2012'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Apr 12, 2012'),
                      DATE_END    : Date.parse('Apr 15, 2012'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'YMCA&nbsp;Nationals',
                      NAME_LONG   : 'YMCA&nbsp;SCY&nbsp;Nationals',
                      ADDRESS     : '501&nbsp;Seabreeze&nbsp;Blvd',
                      CITY_STATE  : 'Fort&nbsp;Lauderdale,&nbsp;FL',
                      POSTAL_CODE : '33316',
                      LINK_MAP    : 'http://maps.google.com/maps?q=501+Seabreeze+Blvd+Fort+Lauderdale,+FL+33316&oe=utf-8&client=firefox-a&ie=UTF8&hq=&hnear=501+Seabreeze+Blvd,+Fort+Lauderdale,+Broward,+Florida+33316&gl=us&ei=wOzZS7b-FoH68AbKodVW&ved=0CBMQ8gEwAA&ll=26.116602,-80.105438&spn=0.109898,0.154324&z=13',
                      LINK_INFO   : 'http://www.ymcaswimminganddiving.org/2012masters/2012MastersEntryPacket.pdf',
                      MEET_INFO   : [{COST    : '$30&nbsp;+&nbsp;$8/IE&nbsp;+&nbsp;$6/RE',
                                      DEADLINE: Date.parse('Mar 14, 2012'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Apr 14, 2012'),
                      DATE_END    : Date.parse('Apr 14, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'LMSC&nbsp;Challenge',
                      NAME_LONG   : 'Great&nbsp;Lakes&nbsp;Challenge',
                      ADDRESS     : '1411&nbsp;Ridge&nbsp;Street',
                      CITY_STATE  : 'Bowling&nbsp;Green,&nbsp;OH',
                      POSTAL_CODE : '43403',
                      LINK_MAP    : 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=1411+Ridge+Street,+Bowling+Green,+OH++43403&aq=&sll=41.378161,-83.631084&sspn=0.012011,0.027874&g=1411+Ridge+Road,+Bowling+Green,+OH++43403&ie=UTF8&hq=&hnear=1411+Ridge+St,+Bowling+Green,+Wood,+Ohio+43403&ll=41.377968,-83.625011&spn=0.096091,0.222988&z=13',
                      LINK_INFO   : 'http://www.ohiolmsc.org/meets/upcoming/2012/20120414-BGSU.pdf',
                      MEET_INFO   : [{COST    : '$25',
                                      DEADLINE: Date.parse('Apr 09, 2012'),
                                      DEADTYPE: 'Postmarked'},
                                     {COST    : '$40',
                                      DEADLINE: Date.parse('Apr 14, 2012'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Apr 26, 2012'),
                      DATE_END    : Date.parse('Apr 29, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'USMS&nbsp;Nationals',
                      NAME_LONG   : 'USMS&nbsp;SCY&nbsp;Nationals',
                      ADDRESS     : '1921&nbsp;West&nbsp;Lee&nbsp;St',
                      CITY_STATE  : 'Greensboro,&nbsp;NC',
                      POSTAL_CODE : '27403',
                      LINK_MAP    : 'http://maps.google.com/maps?q=1921+West+Lee+Street+greensboro+nc&ll=36.060756,-79.82563&spn=0.146263,0.308647&oe=utf-8&client=firefox-a&hnear=1921+W+Lee+St,+Greensboro,+North+Carolina+27403&gl=us&t=m&z=12&vpsrc=6',
                      LINK_INFO   : 'http://www.usms.org/content/scnats12meetinfo',
                      MEET_INFO   : [{COST    : '$50&nbsp;+&nbsp;$4/IE',
                                      DEADLINE: Date.parse('Mar 09, 2012'),
                                      DEADTYPE: 'Received'},
                                     {COST    : '$60&nbsp;+&nbsp;$4/IE',
                                      DEADLINE: Date.parse('Mar 23, 2012'),
                                      DEADTYPE: 'Received'}]},
                     {DATE_BEGIN  : Date.parse('Jun 02, 2012'),
                      DATE_END    : Date.parse('Jun 02, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Greenswell&nbsp;OW&nbsp;Swim',
                      NAME_LONG   : 'Greenswell&nbsp;OW&nbsp;Swim&nbsp;#1',
                      ADDRESS     : '3615&nbsp;S&nbsp;Old&nbsp;State&nbsp;Rd',
                      CITY_STATE  : 'Delaware,&nbsp;OH',
                      POSTAL_CODE : '43015',
                      LINK_MAP    : 'http://maps.google.com/maps?q=alum+creek+state+park+ohio&ll=40.248874,-82.965317&spn=0.138095,0.308647&oe=utf-8&client=firefox-a&fb=1&gl=us&hq=alum+creek+state+park+ohio&hnear=alum+creek+state+park+ohio&cid=0,0,985171496251616438&t=m&z=12&vpsrc=6'},
                     {DATE_BEGIN  : Date.parse('Jun 10, 2012'),
                      DATE_END    : Date.parse('Jun 17, 2012'),
                      HAS_PRACTICE: false,
                      NAME_SHORT  : 'FINA&nbsp;World&nbsp;Champs',
                      ADDRESS     : 'Piazzale&nbsp;2&nbsp;Giugno',
                      CITY_STATE  : 'Riccione,&nbsp;Italy',
                      POSTAL_CODE : '47838',
                      LINK_MAP    : 'http://maps.google.com/maps?q=Piazzale+2+Giugno,+Riccione,+Italia&hl=en&ll=44.00541,12.636337&spn=0.130139,0.308647&sll=44.005819,12.63608&sspn=0.004067,0.009645&vpsrc=6&gl=us&hnear=Piazzale+2+Giugno,+47838+Riccione+Rimini,+Emilia+Romagna,+Italy&t=m&z=12',
                      LINK_INFO   : 'http://www.finamasters2012.org/entries.asp'},
                     {DATE_BEGIN  : Date.parse('Jul 05, 2012'),
                      DATE_END    : Date.parse('Jul 08, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'USMS&nbsp;Nationals',
                      NAME_LONG   : 'USMS&nbsp;LCM&nbsp;Nationals',
                      ADDRESS     : '455&nbsp;North&nbsp;10th&nbsp;St',
                      CITY_STATE  : 'Omaha,&nbsp;NE',
                      POSTAL_CODE : '68102',
                      LINK_MAP    : 'http://maps.google.com/maps?q=455+North+10th+Street,+Omaha,+NE&ll=41.263614,-95.929184&spn=0.136003,0.308647&oe=utf-8&client=firefox-a&hnear=455+N+10th+St,+Omaha,+Douglas,+Nebraska+68102&gl=us&t=m&z=12&vpsrc=6',
                      LINK_INFO   : 'http://www.usms.org/comp/lcnats12/'},
                     {DATE_BEGIN  : Date.parse('Jul 14, 2012'),
                      DATE_END    : Date.parse('Jul 14, 2012'),
                      HAS_PRACTICE: true,
                      NAME_SHORT  : 'Greenswell&nbsp;OW&nbsp;Swim',
                      NAME_LONG   : 'Greenswell&nbsp;OW&nbsp;Swim&nbsp;#2',
                      ADDRESS     : '3615&nbsp;S&nbsp;Old&nbsp;State&nbsp;Rd',
                      CITY_STATE  : 'Delaware,&nbsp;OH',
                      POSTAL_CODE : '43015',
                      LINK_MAP    : 'http://maps.google.com/maps?q=alum+creek+state+park+ohio&ll=40.248874,-82.965317&spn=0.138095,0.308647&oe=utf-8&client=firefox-a&fb=1&gl=us&hq=alum+creek+state+park+ohio&hnear=alum+creek+state+park+ohio&cid=0,0,985171496251616438&t=m&z=12&vpsrc=6'}];

// A list of pool locations, given as pool name, address, and a url to a google map of the location
var poolData = [['Beavercreek&nbsp;YMCA'         , '560 Grange Hall Rd.  Beavercreek, OH  45430',
                 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=560+Grange+Hall+Road,+Beavercreek,+OH+45430&sll=39.707682,-84.086244&sspn=0.012199,0.027874&gl=us&g=560+Grange+Hall+Road,+Beavercreek,+OH&ie=UTF8&hq=&hnear=560+Grange+Hall+Rd,+Beavercreek,+Greene,+Ohio+45430&ll=39.709102,-84.086437&spn=0.047079,0.111494&z=14'],
                ['The&nbsp;Prairies'             , 'The Praries Office located on Chapel Ln.'   ,
                 'http://maps.google.com/maps?q=39.765642,-84.115026&num=1&sll=39.766155,-84.110705&sspn=0.006295,0.006295&hl=en&ie=UTF8&ll=39.765731,-84.114933&spn=0.048756,0.111494&z=14'],
                ['University&nbsp;of&nbsp;Dayton', '2 Evanston Ave.  Dayton, OH  45409'         ,
                 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=2+evanston+avenue+dayton+oh&sll=39.736445,-84.174467&sspn=0.002838,0.006968&gl=us&ie=UTF8&hq=&hnear=2+Evanston+Ave,+Dayton,+Montgomery,+Ohio+45409&ll=39.736894,-84.1745&spn=0.04706,0.111494&z=14'],
                ['Wright-Patterson&nbsp;AFB'     , 'Dodge Gym'                                  ,
                 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=607+Lahm+Circle,+Wright-Patterson+AFB,+OH&sll=39.810576,-84.043431&sspn=0.002938,0.006968&gl=us&ie=UTF8&hq=&hnear=607+Lahm+Cir,+Wright-Patterson+AFB,+Greene,+Ohio+45433&ll=39.810778,-84.043179&spn=0.047009,0.111494&z=14']];

// A rotating list of workout types
var workoutTypes = [['A', 'Endurance', 'Pace'     , 'Sprint'   , 'Stroke'   , 'Endurance'],
                    ['B', 'Endurance', 'Endurance', 'Pace'     , 'Sprint'   , 'Stroke'   ],
                    ['C', 'Endurance', 'Stroke'   , 'Endurance', 'Pace'     , 'Sprint'   ],
                    ['D', 'Endurance', 'Sprint'   , 'Stroke'   , 'Endurance', 'Pace'     ]];

// A label indicating the training focus throughout the season
var workoutFocus = ['<a href="Documents/DAS Freestyle Clinic.ppt"    title="Freestyle Technique Slides"   >Free</a>',
                    '<a href="Documents/DAS Backstroke Clinic.ppt"   title="Backstroke Technique Slides"  >Back</a>',
                    '<a href="Documents/DAS Breaststroke Clinic.ppt" title="Breaststroke Technique Slides">Breast</a>',
                    '<a href="Documents/DAS Butterfly Clinic.ppt"    title="Butterfly Technique Slides"   >Fly</a>',
                    'Starts/Turns',
                    'Base 1'   , 'Base 1'   , 'Base 1'   ,
                    'Base 2'   , 'Base 2'   , 'Base 2'   ,
                    'Base 3'   , 'Base 3'   , 'Base 3'   , 'Base 3' ,
                    'Build 1'  , 'Build 1'  , 'Build 1'  ,
                    'Build 2'  , 'Build 2'  , 'Build 2'  ,
                    'Build 3'  , 'Build 3'  , 'Build 3'  ,
                    'Peak 1'   , 'Peak 2'   , 'Race 1'   , 'Race 2' ];

// A list of days on which practice is offered (prefixed by 0)
var practiceDays = [0, 1, 2, 3, 4, 6];

// The constants used to initialize the calendar
var startDate    = Date.parse('Oct 02, 2011'); // Must be a Sunday
var startWorkout = 3; // The row from workoutTypes that applies to the week beginning on startDate

// The pages contained within the DAS website
var linkNames = ['Home' , 'Team'  , 'Coaches', 'EMail'  , 'Workout', 'Pools',
                 'Equip', 'Events', 'Results', 'Records', 'Links'  ];

// Function that populates the e-mail list select objects
function PopulateDropdownBoxes() {
  var curYear     = new Date().getFullYear();
  var daySelect   = document.getElementById('DOB_Day'  );
  var monthSelect = document.getElementById('DOB_Month');
  var yearSelect  = document.getElementById('DOB_Year' );
  var newOption;

  daySelect  .remove(0);
  for (var day   = 1; day   <= 31; ++day  ) {
    newOption       = document.createElement('option');
    newOption.value = PadLeft(String(day), 2, '0');
    newOption.text  = String(day);
    try      { daySelect  .add(newOption, null); } // Non-IE
    catch(e) { daySelect  .add(newOption      ); } // IE
  }

  monthSelect.remove(0);
  for (var month = 1; month <= 12; ++month) {
    newOption       = document.createElement('option');
    newOption.value = PadLeft(String(month), 2, '0');
    newOption.text  = monthNames[month - 1];
    try      { monthSelect.add(newOption, null); } // Non-IE
    catch(e) { monthSelect.add(newOption      ); } // IE
  }

  yearSelect .remove(0);
  for (var year  = curYear - 90; year <= curYear ; ++year) {
    newOption       = document.createElement('option');
    newOption.value = PadLeft(String(year % 100), 2, '0');
    newOption.text  = String(year);
    try      { yearSelect .add(newOption, null); } // Non-IE
    catch(e) { yearSelect .add(newOption      ); } // IE
  }
  yearSelect.selectedIndex = 60;
}

// Adds the next five events to the upcoming events sidebar
function ListUpcomingEvents() {
  var now     = new Date();
  var today   = now.getTime() - 1000 * (60 * (60 * now.getUTCHours() +
                now.getUTCMinutes()) + now.getUTCSeconds()) - now.getUTCMilliseconds();
  var infoDiv = document.getElementById('InfoDiv');
  for (var eIdx = 0, eCount = 0; eIdx < specialEvents.length && eCount < 5; ++eIdx) {
    if (specialEvents[eIdx].DATE_END < today) continue;
    var eventName;
    if ('NAME_LONG' in specialEvents[eIdx]) {
      eventName = specialEvents[eIdx].NAME_LONG;
    } else if ('NAME_SHORT' in specialEvents[eIdx]) {
      eventName = specialEvents[eIdx].NAME_SHORT;
    } else { continue; }
    var dateBegin = new Date(specialEvents[eIdx].DATE_BEGIN);
    var dateEnd   = new Date(specialEvents[eIdx].DATE_END  );
    var eventStr  = '<hr />';
    if ('LINK_INFO' in specialEvents[eIdx]) {
      eventStr += '<h2><a onclick="window.open(\'' +
                  specialEvents[eIdx].LINK_INFO +
                  '\',\'event_info\');" onmouseover="StatusSet(\'' +
                  specialEvents[eIdx].LINK_INFO +
                  '\');" onmouseout="StatusClear();" title="Event Info">' +
                  eventName + '</a></h2>';
    } else {
      eventStr += '<h2>' + eventName + '</h2>';
    }
    eventStr += '<p>' + monthNames[dateBegin.getUTCMonth()] + ' ' +
                PadLeft(String(dateBegin.getUTCDate()), 2, '0');
    if (dateBegin.getTime() != dateEnd.getTime()) {
      eventStr += ' - ';
      if (dateBegin.getUTCMonth() != dateEnd.getUTCMonth()) {
        eventStr += monthNames[dateEnd.getUTCMonth()] + ' ';
      }
      eventStr += PadLeft(String(dateEnd.getUTCDate()), 2, '0');
    }
    eventStr += ', ' + String(dateEnd.getUTCFullYear());
    if ('CITY_STATE' in specialEvents[eIdx]) {
      eventStr += '<br />';
      if ('LINK_MAP' in specialEvents[eIdx]) {
        eventStr += '<a onclick="window.open(\'' +
                    specialEvents[eIdx].LINK_MAP +
                    '\',\'event_map\');" onmouseover="StatusSet(\'' +
                    specialEvents[eIdx].LINK_MAP +
                    '\');" onmouseout="StatusClear();" title="Map this Event">' +
                    specialEvents[eIdx].CITY_STATE + '</a>';
      } else {
        eventStr += specialEvents[eIdx].CITY_STATE;
      }
    }
    infoDiv.innerHTML += eventStr + '</p>';
    ++eCount;
  }
}

// Lists all the events, both past and future, in the specialEvents array
function CreateEventSchedule() {
  var now   = new Date();
  var today = now.getTime() - 1000 * (60 * (60 * now.getUTCHours() +
              now.getUTCMinutes()) + now.getUTCSeconds()) - now.getUTCMilliseconds();

  var tbody = document.getElementById('ScheduleContent');
  while (tbody.rows.length > 0) tbody.deleteRow(0);
  for (var eIdx = 0, rowIdx = 0; eIdx < specialEvents.length; ++eIdx) {
    // If the event is unnamed, don't display it
    if (!('CITY_STATE' in specialEvents[eIdx])) continue;

    // Create a new row in the table
    tbody.insertRow(rowIdx);
    var row = tbody.rows[rowIdx++];
    for (var col = 0; col < 5; ++col) row.insertCell(col);

    // Insert the name of the event
    var name = ('NAME_LONG' in specialEvents[eIdx] ? specialEvents[eIdx].NAME_LONG :
                                                     specialEvents[eIdx].NAME_SHORT);
    if ('LINK_INFO' in specialEvents[eIdx]) {
      row.cells[0].innerHTML = '<a onclick="window.open(\'' +
                               specialEvents[eIdx].LINK_INFO +
                               '\',\'event_info\');" onmouseover="StatusSet(\'' +
                               specialEvents[eIdx].LINK_INFO +
                               '\');" onmouseout="StatusClear();" title="Meet Info">' +
                               name + '</a>';
    } else {
      row.cells[0].innerHTML = name;
    }

    // Insert the date of the event
    var cell       = row.cells[1];
    var dateBegin  = new Date(specialEvents[eIdx].DATE_BEGIN);
    var dateEnd    = new Date(specialEvents[eIdx].DATE_END  );
    cell.innerHTML = monthNames[dateBegin.getUTCMonth()] + '&nbsp;' +
                     PadLeft(String(dateBegin.getUTCDate()), 2, '0');
    if (specialEvents[eIdx].DATE_BEGIN != specialEvents[eIdx].DATE_END) {
      cell.innerHTML += '&nbsp;-&nbsp;';
      if (dateBegin.getUTCMonth() != dateEnd.getUTCMonth()) {
  	    cell.innerHTML += monthNames[dateEnd.getUTCMonth()] + '&nbsp;';
      }
      cell.innerHTML += PadLeft(String(dateEnd.getUTCDate()), 2, '0');
    }
    cell.innerHTML += ',&nbsp;' + String(dateEnd.getUTCFullYear());

    // Insert the location of the event
    var hasMap = ('LINK_MAP' in specialEvents[eIdx]);
    var locStr = (hasMap ? '<a onclick="window.open(\'' +
                           specialEvents[eIdx].LINK_MAP +
                           '\',\'event_map\');" onmouseover="StatusSet(\'' +
                           specialEvents[eIdx].LINK_MAP +
                           '\');" onmouseout="StatusClear();" title="Map this Event">' : '');
    if ('CITY_STATE' in specialEvents[eIdx]) {
      if ('ADDRESS' in specialEvents[eIdx]) {
        locStr += specialEvents[eIdx].ADDRESS + '<br />';
      }
      locStr += specialEvents[eIdx].CITY_STATE;
      if ('POSTAL_CODE' in specialEvents[eIdx]) {
        locStr += '&nbsp;' + specialEvents[eIdx].POSTAL_CODE;
      }
    }
    if (hasMap) locStr += '</a>';
    row.cells[2].innerHTML = locStr;

    // Insert the entry deadlines and entry cost
    if ('MEET_INFO' in specialEvents[eIdx]) {
      for (var iIdx = 0; iIdx < specialEvents[eIdx].MEET_INFO.length; ++iIdx) {
        if (iIdx > 0) {
          row.cells[3].innerHTML += '<br />';
          row.cells[4].innerHTML += '<br />';
        }
        var isBold   = (specialEvents[eIdx].MEET_INFO[iIdx].DEADLINE >= today);
        var deadDate = new Date(specialEvents[eIdx].MEET_INFO[iIdx].DEADLINE);

        var deadStr  = (isBold ? '<b>' : '');
        var costStr  = deadStr;
        deadStr += specialEvents[eIdx].MEET_INFO[iIdx].DEADTYPE +
                   '&nbsp;by&nbsp;' + monthNames[deadDate.getUTCMonth()] +
                   '&nbsp;' + PadLeft(String(deadDate.getUTCDate()), 2, '0') +
                   ',&nbsp;' + String(deadDate.getUTCFullYear());
        costStr += specialEvents[eIdx].MEET_INFO[iIdx].COST;
        if (isBold) { deadStr += '</b>'; costStr += '</b>'; }

        row.cells[3].innerHTML += deadStr;
        row.cells[4].innerHTML += costStr;
      }
    } else {
      row.cells[3].innerHTML = 'Unknown';
      row.cells[4].innerHTML = 'Unknown';
    }
  }
}

// Function that dynamically generates the practice schedule based on event information
function CreateWorkoutTable() {
  // Get the previous Sunday's date at 00:00:00 UTC time
  var now        = new Date();
  var today      = now.getTime() - 1000 * (60 * (60 * now.getUTCHours() +
                   now.getUTCMinutes()) + now.getUTCSeconds()) - now.getUTCMilliseconds();
  var prevSunday = today - 864e5 * now.getUTCDay();
  var nextDate   = startDate;

  // Get the index of the next event from the special event list
  var eventIdx = 0;

  var tbody = document.getElementById('WorkoutContent');
  while (tbody.rows.length > 0) tbody.deleteRow(0);
  for (var rowIdx = 0; rowIdx < workoutFocus.length; ++rowIdx) {
    // Ensure that eventIdx points to the first event that could affect the current row
    while (eventIdx < specialEvents.length && nextDate > specialEvents[eventIdx].DATE_END)
	    ++eventIdx;

    // Compute which workout type is going to be performed
    var workoutTypeIdx = (rowIdx + startWorkout) % workoutTypes.length;

    // Create a new row in the tbody element
    tbody.insertRow(rowIdx);
    var row = tbody.rows[rowIdx];
    row.className = workoutTypes[workoutTypeIdx][0];

    // Insert a new cell containing the date
    row.insertCell(0);
    var cell = row.cells[0];
    cell.style.fontFamily = 'Monospace';

    // If the current row is this week, make the date bold
    if (nextDate == prevSunday) cell.style.fontWeight = 'bold';

    var curDate = new Date(nextDate);
    cell.innerHTML = monthNames[curDate.getUTCMonth()] + '&nbsp;' +
                     PadLeft(String(curDate.getUTCDate()), 2, '0') + ',&nbsp;' +
                     String(curDate.getUTCFullYear());
//*
    // Insert a new cell containing the week's focus
    row.insertCell(1);
    cell = row.cells[1];

    // If the current row is this week, make the focus bold
    if (nextDate == prevSunday) cell.style.fontWeight = 'bold';
    
    cell.innerHTML = workoutFocus[rowIdx];
//*/
    // Insert a new cell for each workout type
    for (var colIdx = 1; colIdx < workoutTypes[workoutTypeIdx].length; ++colIdx) {
      // Insert a new cell
      row.insertCell(colIdx + 1);
      cell = row.cells[colIdx + 1];

      // Compute the date for the current cell
      var cellDate = nextDate + 864e5 * practiceDays[colIdx];

      // Loop through all events that have a start date prior to the date of the current cell
      var hasPractice = true;
      for (var eIdx = eventIdx; eIdx < specialEvents.length &&
           cellDate >= specialEvents[eIdx].DATE_BEGIN  ; ++eIdx) {
        if (cellDate > specialEvents[eIdx].DATE_END    ) continue;
        hasPractice &= specialEvents[eIdx].HAS_PRACTICE;
        if ('NAME_SHORT' in specialEvents[eIdx]) {
          if ('LINK_INFO' in specialEvents[eIdx]) {
            var newHTML = '<br/><a onclick="window.open(\'' +
                          specialEvents[eIdx].LINK_INFO +
                          '\', \'event_info\');" onmouseover="StatusSet(\'' +
                          specialEvents[eIdx].LINK_INFO +
                          '\');" onmouseout="StatusClear();" title="' +
                          ('NAME_LONG' in specialEvents[eIdx] ?
                           specialEvents[eIdx].NAME_LONG :
                           specialEvents[eIdx].NAME_SHORT);
            if ('CITY_STATE' in specialEvents[eIdx])
              newHTML += ' in ' + specialEvents[eIdx].CITY_STATE;
            cell.innerHTML += newHTML + '">' + specialEvents[eIdx].NAME_SHORT + '</a>';
          } else {
            cell.innerHTML += '<br/>' + specialEvents[eIdx].NAME_SHORT;
          }
        }
      }

      // If the current cell is today, make the date bold
      if (cellDate == today) cell.style.fontWeight = 'bold';

      // If there is a special event, add it to the cell
      if (hasPractice) {
        cell.innerHTML = workoutTypes[workoutTypeIdx][colIdx] + cell.innerHTML;
      } else {
        cell.innerHTML = 'CANCELLED' + cell.innerHTML;
	    }
    }

    // Increment the date by one week
    nextDate += 6048e5;
  }
}

// Add the last modified date to the page
function AddLastModified() {
  var lmDate  = new Date(document.lastModified);
  if (lmDate != 0) {
    var lastMod = document.getElementById('LastModified');
    lastMod.innerHTML = 'Last Updated ' + monthNames[lmDate.getUTCMonth()] + ' ' +
                        String(lmDate.getUTCDate()) + ', ' + String(lmDate.getUTCFullYear());
  }
}

// Setup the tab order of the elements on the page
function SetupKeyboardNavigation() {
  for (var idx = 0; idx < linkNames.length; ++idx) {
    var elmt = document.getElementById('Link' + linkNames[idx]);
    elmt.tabIndex = 0;
    elmt.onkeyup = function (e) { ClickOnEnter(e, this.id.substring(4)); };
    elmt.onclick = function (e) { ClickLink   (   this.id.substring(4)); };
    do {
      elmt = elmt.parentNode;
      elmt.tabIndex = -1;
    } while (elmt.tagName.toLowerCase() != 'div');
  }
}

// The function called by the body.onload event
function Initialize() {
  // Set the font size based on the client computer's screen resolution
  document.getElementsByTagName('body')[0].style['fontSize'] =
    String(Math.round(screen.availHeight / 100)) + 'pt';
  // Convert the event dates to UTC time to elliminate issues presented with DST
  startDate -= 6e4 * new Date(startDate).getTimezoneOffset();
  for (var eIdx = 0; eIdx < specialEvents.length; ++eIdx) {
    specialEvents[eIdx].DATE_BEGIN -= 6e4 * new Date(specialEvents[eIdx].DATE_BEGIN).getTimezoneOffset();
    specialEvents[eIdx].DATE_END   -= 6e4 * new Date(specialEvents[eIdx].DATE_END  ).getTimezoneOffset();
    if ('MEET_INFO' in specialEvents[eIdx]) {
      for (var dIdx = 0; dIdx < specialEvents[eIdx].MEET_INFO.length; ++dIdx)
        specialEvents[eIdx].MEET_INFO[dIdx].DEADLINE -= 6e4 * new Date(
          specialEvents[eIdx].MEET_INFO[dIdx].DEADLINE).getTimezoneOffset();
    }
  }
  // Generate the dynamic content on the page
  // PopulateDropdownBoxes();
  ListUpcomingEvents();
  CreateEventSchedule();
  CreateWorkoutTable();
  AddLastModified();
  SetupKeyboardNavigation();
  // Perform some interactivity requests on behalf of the client
  ClickLink();
  setTimeout('PollHashChange()', 100);
}
