function Diary (label, diaryYear, showTentativeFlags, backwardsLink, forwardsLink)
{
  this.mFirstDate = startOfDay (diaryYear, 0, 1);  // January is 0
  this.mLastDate = endOfDay (diaryYear, 11, 31);   // December is 11
  this.mModifiedDate;
  this.mItemsShown = 0;
  this.mCountDown = 500;
  this.mPerformancesOnly = false;
  this.mDateTentativeFound = false;
  this.mTimeTentativeFound = false;
  put ('<table border=1 cellpadding=2>');
  put ('<tr>');
  if (arguments.length > 1)
  {
    put ('<th colSpan=4><table width=100% cellspacing=0 border=0><tr>');
    put ('<th align=left><a class=no href="' + backwardsLink + '" target=_self><<<<<</a></th>');
    put ('<th align=center>' + label + '</th>');
    put ('<th align=right><a class=no href="' + forwardsLink + '" target=_self>>>>>></a></th>');
    put ('</tr></table></th>');
    this.mDisplayYearPointers = true;
    this.mShowTentativeFlags = showTentativeFlags;
  }
  else
  {
    put ('<th colSpan=4>' + label + '</th>');
    this.mDisplayYearPointers = false;
    this.mShowTentativeFlags = true;
  }
  put ('</tr>');

  put ('<tr align=middle>');
    put ('<td><b>Date</b></td>');
    put ('<td><b>Time</b></td>');
    put ('<td><b>Event</b></td>');
    put ('<td><b>Location</b></td>');
  put ('</tr>');
}

Diary.prototype.maximum = function (limit)
{
  this.mCountDown = limit;
  this.mFirstDate = startOfDay (today);
  this.mLastDate = endOfDay (2100, 11, 31);
}

Diary.prototype.until = function (date)
{
  this.mFirstDate = startOfDay (today);
  this.mLastDate = endOfDay (date);
}

Diary.prototype.performancesOnly = function ()
{
  this.mPerformancesOnly = true;
}

Diary.prototype.entry = function (text)
{
  var phrases = text.split (",");
  var dateTentative = phrases[0].charAt (0) == '#';
  var timeTentative = phrases[0].charAt (0) == '*';
  if (dateTentative || timeTentative)
    var type = phrases[0].substr (1);
  else
    var type = phrases[0];
  var dateBits = phrases[1].split ("/");
  // Note that month runs 0-11 - some idiot C programmer designed JavaScript
  var date = new Date (dateBits[2], dateBits[1] - 1, dateBits[0]);
  if ((date >= this.mFirstDate) && (date <= this.mLastDate) && (this.mCountDown > 0) && ((type == "normal") || (type == "special") || ! this.mPerformancesOnly))
  {
    this.mItemsShown += 1;
    if (type == "normal")
      this.mCountDown -= 1;
    this.mDateTentativeFound |= dateTentative;  // Bit-wise or should be OK here
    this.mTimeTentativeFound |= timeTentative;  // Bit-wise or should be OK here
    var colour = type == "normal" ? "class=blue" : type == "special" ? "class=green" : "class=red";
    put ('<tr align=middle>');
      put ('<td ' + colour + '>' + (dateTentative && this.mShowTentativeFlags ? "<i># " : "") + fullDate (date) + (dateTentative && this.mShowTentativeFlags ? "</i>" : "") + '</td>');
      put ('<td ' + colour + '>' + ((dateTentative || timeTentative) && this.mShowTentativeFlags ? "<i>" : "") + (timeTentative && this.mShowTentativeFlags ? "* " : "") + phrases[2] + ((dateTentative || timeTentative) && this.mShowTentativeFlags ? "</i>" : "") + '</td>');
      put ('<td ' + colour + '>' + (dateTentative && this.mShowTentativeFlags ? "<i>" : "") + phrases[3] + (dateTentative && this.mShowTentativeFlags ? "</i>" : "") + '</td>');
      put ('<td ' + colour + '>' + (dateTentative && this.mShowTentativeFlags ? "<i>" : "") + phrases[4] + (dateTentative && this.mShowTentativeFlags ? "</i>" : "") + '</td>');
    put ('</tr>');
  }
}

Diary.prototype.modified = function (text)
{
  if (this.mItemsShown == 0)
  {
    var dateBits = text.split ("/");
    // Note that month runs 0-11 - some idiot C programmer designed JavaScript
    this.mModifiedDate = new Date (dateBits[2], dateBits[1] - 1, dateBits[0]);
  }
}

Diary.prototype.finish = function ()
{
  put ('<tr><td colspan=4>');
    put ('<table width=100% border=0 cellpadding=3><tr>');
      if (this.mDisplayYearPointers)
        put ('<th align=left><a href="Diary.htm?' + (diaryYear - 1) + '" target=_self>' + (diaryYear - 1) + '</a></th>');
      put ('<td><p align = center><font color=black>');
        if (this.mItemsShown > 0)
        {
          if (this.mShowTentativeFlags)
          {
            if (this.mDateTentativeFound)
              putLine ('# Date and time subject to confirmation');
            if (this.mTimeTentativeFound)
              putLine ('* Time subject to confirmation');
          }
          put ('Diary entries last modified <span style="{color:#5735CA}">' + friendlyDate (this.mModifiedDate) + '</span>');
        }
        else
          put ('<span style="{color:red}"><b>No diary entry file for this year</b></span>');
      put ('</font></p></td>');
      if (this.mDisplayYearPointers)
        put ('<th align=right><a href="Diary.htm?' + (diaryYear + 1) + '" target=_self>' + (diaryYear + 1) + '</a></th>');
    put ('</tr></table>');
  put ('</td></tr>');
  put ('</table><br>');
}
