/**
 * This is a script to build a calendar made up of separate month tables.
 * The information for calendar days is taken from an XML file.
 */

 // Set up the day constants

 var SATURDAY = 0;
 var SUNDAY = 1;
 var MONDAY = 2;
 var TUESDAY = 3;
 var WEDNESDAY = 4;
 var THURSDAY = 5;
 var FRIDAY = 6;

 var xmlDoc = null;

function loadCalendar() {
  // Use the standard DOM level 2 technique, if it is supported.
  if (document.implementation && document.implementation.createDocument) {
      // Create a new Document object
      xmlDoc = document.implementation.createDocument("", "", null);
      // Specify what should happen when it finishes loading
      xmlDoc.onload = function(  ) { buildCalendar(xmlDoc); }
  }
  // Otherwise, use Microsoft's proprietary API for Internet Explorer
  else if (window.ActiveXObject) {
      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");   // Create doc
      xmlDoc.onreadystatechange = function(  ) {              // Specify onload
          if (xmlDoc.readyState == 4) buildCalendar(xmlDoc);
      }
  }
  xmlDoc.load("scripts/calendars.xml"); // Start loading!
}

function buildCalendar(xmldoc) {
    // Get a reference to the year tags in the XML doc
    var years = xmldoc.getElementsByTagName("year");
    var offset = 0;
    var yearTag, monthTag = 0;
    var k, l = 0;
    var rowNum = 0;
    var dayCell = 0;

    // For each of the years in the XML file
    for (yearTag=0; yearTag<years.length; yearTag++) {

        // get the corresponding year space in the HTML document
        var yearVal = years[yearTag].getAttribute("id");
        var yearSlot = years[yearTag].getAttribute("position");
        var yearSpace = document.getElementById(yearSlot);
        if (yearSpace != null) {

            // Create a year heading and put it in the year space.
            var yearHead = document.createElement("h2");
            yearSpace.insertBefore(yearHead, yearSpace.firstChild);
            yearHead.appendChild(document.createTextNode(years[yearTag].getAttribute("id")));

            // Get an array of the months from the current year
            var months = years[yearTag].getElementsByTagName("month");
            for (monthTag=0; monthTag<months.length; monthTag++) {

                // Build an array to represent the month. This is put into a matrix of 42 (6X7)
                // cells so that each calendar will be put into the same sized block.
                var calDays = new Array(42);
                var dayClass = new Array(42);
                var days = months[monthTag].getElementsByTagName("day");
                var startDay = months[monthTag].getAttribute("startDay");

                switch (startDay) {
                  case "Saturday":
                      offset = SATURDAY;
                      break;
                  case "Sunday":
                      offset = SUNDAY;
                      break;
                  case "Monday":
                      offset = MONDAY;
                      break;
                  case "Tuesday":
                      offset = TUESDAY;
                      break;
                  case "Wednesday":
                      offset = WEDNESDAY;
                      break;
                  case "Thursday":
                      offset = THURSDAY;
                      break;
                  case "Friday":
                      offset = FRIDAY;
                      break;
                  default:
                      alert("The startDay attribute is missing from one or more\nof the months in the XML file " + xmldoc);
                }

                // Add the month information from the XML doc to the array.
                for (l = 0; l < calDays.length; l++) {
                    if (l < offset || l >= days.length+offset) {
                        calDays[l] = String.fromCharCode(160);
                        dayClass[l] = "X";
                    }else{
                        calDays[l] = days[l-offset].firstChild.nodeValue;
                        dayClass[l] = days[l-offset].getAttribute("className");
                    }
                }

                // Get the corresponding month from the HTML doc
                var monthName = new String(months[monthTag].getAttribute("name"));
                var monthTable = document.getElementById(monthName);
                var tableRows = monthTable.getElementsByTagName("tr");
                var tableCells = tableRows[0].getElementsByTagName("td");

                //Create a string from the month name and the year
                var monthYear = new String(monthName.substring(0,3) + " " + yearVal); // This contains a non-breaking space character entered using ALT-0160
                                                                                                                    // The non-breaking space is inclued to prevent IE from wrapping
                //Put the string in the header of the calendar table
                tableCells[0].firstChild.nodeValue = monthYear;

                // Create the calendar table from the XML file.
                k=0;
                rowNum = 0;
                while (k < calDays.length) {
                  rowNum = Math.floor(k/7+2); // The +2 is included here so the array is entered from the third row on.
                  if (k%7 == 0) { // If this is the first cell in the row
            //debug(typeof(tableRows[rowNum].firstChild.firstChild));
                    tableRows[rowNum].firstChild.appendChild(document.createTextNode(calDays[k])); // Change the text in the cell
                    tableRows[rowNum].firstChild.className = dayClass[k];
                  }else{ // Otherwise
                    // Append a new cell
                    dayCell = tableRows[rowNum].insertCell(k%7);
                    dayCell.appendChild(document.createTextNode(calDays[k]));
                    dayCell.className = dayClass[k];
                  }
                  k++
              }
          }// end of inner for
        } // end of if (yearSpace != null)
    }// end of outer for

}

 /**
 * This debug function displays plain-text debugging messages in a
 * special box at the end of a document. It is a useful alternative
 * to using alert(  ) to display debugging messages.
 **/
function debug(msg) {
    // If we haven't already created a box within which to display
    // our debugging messages, then do so now. Note that to avoid
    // using another global variable, we store the box node as
    // a proprty of this function.
    if (!debug.box) {
        // Create a new <div> element
        debug.box = document.createElement("div");
        // Specify what it looks like using CSS style attributes
        debug.box.setAttribute("style",
                               "background-color: white; " +
                               "font-family: monospace; " +
                               "border: solid black 3px; " +
                               "padding: 10px;");

        // Append our new <div> element to the end of the document
        document.body.appendChild(debug.box);

        // Now add a title to our <div>. Note that the innerHTML property is
        // used to parse a fragment of HTML and insert it into the document.
        // innerHTML is not part of the W3C DOM standard, but it is supported
        // by Netscape 6 and Internet Explorer 4 and later. We can avoid
        // the use of innerHTML by explicitly creating the <h1> element,
        // setting its style attribute, adding a Text node to it, and
        // inserting it into the document, but this is a nice shortcut.
        debug.box.innerHTML = "<h1 style='text-align:center'>Debugging Output</h2>";
    }

    // When we get here, debug.box refers to a <div> element into which
    // we can insert our debugging message.
    // First create a <p> node to hold the message.
    var p = document.createElement("p");
    // Now create a text node containing the message, and add it to the <p>
    p.appendChild(document.createTextNode(msg));
    // And append the <p> node to the <div> that holds the debugging output
    debug.box.appendChild(p);
}

