//******************************************************************************
// Initialize Global Variables
//******************************************************************************
var scwDateNow = new Date();
var scwSelectedDate = new Date();
var scwCalendarStartDate = new Date();
var scwEleClicked = null;

//******************************************************************************
// Customisation section
//******************************************************************************

// Set the bounds for the calendar here...
// If you want the year to roll forward you can use something like this...
//      var scwBaseYear = scwDateNow.getFullYear()-5;
// alternatively, hard code a date like this...
//      var scwBaseYear = 1990;

var scwBaseYear = scwDateNow.getFullYear() - 12;

// How many years do want to be valid and to show in the drop-down list?

var scwDropDownYears = 25;


// true if only working with the date (month day and year)
// false if also workign with the time (hour minute)
var scwDateOnly = true;


// All language-dependent changes can be made here...

// If you wish to work in a single language (other than English) then
// just replace the English (in the function scwSetLanguage below) with
// your own text.

// Using multiple languages:
// In order to keep this script to a resonable size I have not included
// languages here.  You can set language fields in a function that you
// should call  scwSetLanguage  the script will use your languages.
// I have included all the translations that have been sent to me in
// such a function on the demonstration page.

var scwLanguage;

function scwSetDefaultLanguage()
{
  // English
  scwNowText = 'Now:';
  scwSelectText = 'Select';
  scwDrag = 'click here to drag';
  scwArrMinuteNames = ['00','05','10','15','20','25','30','35','40','45','50','55'];

  scwArr12HourNames = ['12 am','1 am','2 am','3 am','4 am','5 am','6 am','7 am','8 am','9 am','10 am','11 am',
                       '12 pm','1 pm','2 pm','3 pm','4 pm','5 pm','6 pm','7 pm','8 pm','9 pm','10 pm','11 pm'];

  scwArr24HourNames = ['00','01','02','03','04','05','06','07','08','09','10','11',
                       '12','13','14','15','16','17','18','19','20','21','22','23'];

  scwArrMonthNames =  ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

  scwArrWeekInits = ['S','M','T','W','T','F','S'];

  scwInvalidDateMsg = 'The entered date is invalid.\n';
  scwOutOfRangeMsg = 'The entered date is out of range.';
  scwDoesNotExistMsg = 'The entered date does not exist.';
  scwInvalidAlert =
      [
      'Invalid date (',
      ') ignored.'
      ];

  scwDateDisablingError =
      [
      'Error ',
      ' is not a Date object.'
      ];

  scwRangeDisablingError =
      [
      'Error ',
      ' should consist of two elements.'
      ];
};

// Note:  Always start the scwArrWeekInits array with your string for
//        Sunday whatever scwWeekStart (below) is set to.

// scwWeekStart determines the start of the week in the display
// Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc..

var scwWeekStart = 0;

// The week start day for the display is taken as the week start
// for week numbering.  This ensures that only one week number
// applies to one line of the calendar table.
// [ISO 8601 begins the week with Day 1 = Monday.]

// If you want to see week numbering on the calendar, set
// this to true.  If not, false.

var scwWeekNumberDisplay = false;

// Week numbering rules are generally based on a day in the week
// that determines the first week of the year.  ISO 8601 uses
// Thursday (day four when Sunday is day zero).  You can alter
// the base day here.

// See http://www.cl.cam.ac.uk/~mgk25/iso-time.html for more information

var scwWeekNumberBaseDay = 4;

// Each of the calendar's alert message types can be disabled
// independently here.

var scwShowInvalidDateMsg = true, scwShowOutOfRangeMsg = true, scwShowDoesNotExistMsg = true,
  scwShowInvalidAlert = true, scwShowDateDisablingError = true, scwShowRangeDisablingError = true;

// Set the allowed input date delimiters here...
// E.g. To set the rising slash, hyphen, full-stop (aka stop or point),
//      comma and space as delimiters use
//              var scwArrDelimiters   = ['/','-','.',',',' '];

var scwArrDelimiters = ['/','-',':',' '];

// Set the format for the displayed 'Now' date and for the output
// date here.
//
// The format is described using delimiters of your choice (as set
// in scwArrDelimiters above) and case insensitive letters D, M and Y.
//
// NOTE: If no delimiters are input then the date output format is used
//       to parse the value.  This allows less flexiblility in the input
//       value than using delimiters but an accurately entered date
//       remains parsable.
//
// Definition               Returns
// ----------               -------
// D            date in the month without zero filling
// DD           date in the month left zero filled
// M            month number without zero filling
// MM           month number left zero filled
// MMM          month string from scwArrMonthNames
// YY           year number in two digits
// YYYY         year number in four digits
// HH           hour in two digits using 24 hour
// hh           hour in two digits with am/pm
// mm           minutes in two digits

// Displayed "Now" date format

//var scwDateDisplayFormat = 'YYYY-MM-DD hh:mm'; // e.g. 'MMM-DD-YYYY' for the US

// Output date format

//var scwDateOutputFormat  = 'DD MMM, YYYY'; // e.g. 'MMM-DD-YYYY' for the US
//var scwDateOutputFormat  = 'YYYY-MM-DD';
//var scwDateOutputFormat  = 'YYYY-MM-DD';
// this must be passed in as a parameter now
//var scwDateOutputFormat  = 'YYYY-MM-DD hh:mm';

// Note: The delimiters used should be in scwArrDelimiters.

// Personally I like the fact that entering 31-Sep-2005 displays
// 1-Oct-2005, however you may want that to be an error.  If so,
// set scwBlnStrict = true.  That will cause an error message to
// display and the selected month is displayed without a selected
// day. Thanks to Brad Allan for his feedback prompting this feature.

var scwBlnStrict = false;

// If you wish to disable any displayed day, e.g. Every Monday,
// you can do it by setting the following array.  The array elements
// match the displayed cells.
//
// You could put something like the following in your calling page
// to disable all weekend days;
//
//  for (var i=0;i<scwEnabledDay.length;i++)
//      {if (i%7%6==0) scwEnabledDay[i] = false;}
//
// The above approach will allow you to disable days of the week
// for the whole of your page easily.  If you need to set different
// disabled days for a number of date input fields on your page
// there is an easier way: You can pass additional arguments to
// scwShow. The syntax is described at the top of this script in
// the section:
//    "How to use the Calendar once it is defined for your page:"
//
// It is possible to use these two approaches in combination.

var scwEnabledDay = [true,true,true,true,true,true,true,
                     true,true,true,true,true,true,true,
                     true,true,true,true,true,true,true,
                     true,true,true,true,true,true,true,
                     true,true,true,true,true,true,true,
                     true,true,true,true,true,true,true];

// You can disable any specific date (e.g. 24-Jan-2006 or Now) by
// creating an element of the array scwDisabledDates as a date object
// with the value you want to disable.  Date ranges can be disabled
// by placing an array of two values (Start and End) into an element
// of this array.

var scwDisabledDates = new Array();

// e.g. To disable 10-Dec-2005:
//          scwDisabledDates[0] = new Date(2005,11,10);
//
//      or a range from 2004-Dec-25 to 2005-Jan-01:
//          scwDisabledDates[1] = [new Date(2004,11,25),new Date(2005,0,1)];
//
// Remember that Javascript months are Zero-based.

// The disabling by date and date range does prevent the current day
// from being selected.  Disabling days of the week does not so you can set
// the scwActiveNow value to false to prevent selection.

var scwActiveNow = true;

// Dates that are out of the displayed month are shown at the start
// (unless the month starts on the first day of the week) and end of each
// month.
//
// Set scwOutOfMonthDisable to  true  to disable these dates (or  false
// to allow their selection).
//
// Set scwOutOfMonthHide    to  true  to hide    these dates (or  false
// to make them visible).

var scwOutOfMonthDisable = false;
var scwOutOfMonthHide = false;

// Dates that are out of the specified range can be displayed at the start
// of the very first month and end of the very last.  Set
// scwOutOfRangeDisable to  true  to disable these dates (or  false  to
// allow their selection).

var scwOutOfRangeDisable = true;

// If you want a special format for the cell that contains the current day
// set this to true.  This sets a thin border around the cell in the color
// set by scwNowCellBorderColor.

var scwFormatNowCell = true;
var scwNowCellBorderColor = 'cyan';

// You can allow the calendar to be dragged around the screen by
// using the setting scwAllowDrag to true.
// I can't say I recommend it because of the danger of the user
// forgetting which date field the calendar will update when there
// are multiple date fields on a page.

var scwAllowDrag = false;

// Closing the calendar by clicking on it (rather than elsewhere on the
// main page) can be inconvenient.  The scwClickToHide boolean value
// controls this feature.

var scwClickToHide = false;

//******************************************************************************
//------------------------------------------------------------------------------
// End of customisation section
//------------------------------------------------------------------------------
//******************************************************************************

//  Variables required by both scwShow and scwShowMonth
var scwPassEnabledDay = [true,true,true,true,true,true,true,
                         true,true,true,true,true,true,true,
                         true,true,true,true,true,true,true,
                         true,true,true,true,true,true,true,
                         true,true,true,true,true,true,true,
                         true,true,true,true,true,true,true];

var scwTargetEle, scwTriggerEle, scwMonthSum = 0, scwBlnFullInputDate = false,
/*scwPassEnabledDay      = new Array(),*/
/*scwSeedDate            = new Date(),*/
scwParmActiveNow = true, scwWeekStart = scwWeekStart % 7, scwNowText, scwDrag, scwArrMinuteNames, scwArr12HourNames,
  scwArr24HourNames, scwArrMonthNames, scwArrWeekInits, scwInvalidDateMsg, scwOutOfRangeMsg, scwDoesNotExistMsg,
  scwInvalidAlert, scwDateDisablingError, scwRangeDisablingError;

// Add a method to format a date into the required pattern
Date.prototype.scwFormat = function(scwFormat)
{
  var charCount = 0, codeChar = '', result = '';

  for (var i = 0; i <= scwFormat.length; i++)
  {
    if (i < scwFormat.length && scwFormat.charAt(i) == codeChar)
    {
      // If we haven't hit the end of the string and
      // the format string character is the same as
      // the previous one, just clock up one to the
      // length of the current element definition
      charCount++;
    }
    else
    {
      var ampm;

      switch (codeChar)
      {
        case 'Y':
            result += (this.getFullYear() % Math.pow(10, charCount)).toString().scwPadLeft(charCount);
            break;

        case 'M':
            // If we find an M, check the number of them to
            // determine whether to get the month number or
            // the month name.
            result += (charCount < 3)
              ? (this.getMonth() + 1).toString().scwPadLeft(charCount)
              : scwArrMonthNames[this.getMonth()];
            break;

        case 'D':
            // If we find a D, get the date and format it
            result += this.getDate().toString().scwPadLeft(charCount);
            break;

        case 'H':
            // 24 hours
            result += this.getHours().toString().scwPadLeft(charCount);
            break;

        case 'h':
            // 12 hours am/pm
            var hours = this.getHours();

            if (hours < 12)
            {
              ampm = ' am';

              if (hours == 0)
              {
                hours = 12;
              }
            }
            else
            {
              ampm = ' pm';

              if (hours > 12)
              {
                hours -= 12;
              }
            }
            result += hours.toString();
            break;

        case 'm':
            // minutes
            result += this.getMinutes().toString().scwPadLeft(charCount);

            if (ampm != undefined)
            {
              result += ampm;
            }
            break;

        default:
            // Copy any unrecognised characters across
            while (charCount-- > 0)
            {
              result += codeChar;
            }
      }

      if (i < scwFormat.length)
      {
        // Store the character we have just worked on
        codeChar = scwFormat.charAt(i);
        charCount = 1;
      }
    }
  }

  return result;
};

// Add a method to left pad zeroes

String.prototype.scwPadLeft = function(padToLength)
{
  var result = '';

  for (var i = 0; i < (padToLength - this.length); i++)
  {
    result += '0';
  }
  return (result + this);
};

// Set up a closure so that any next function can be triggered
// after the calendar has been closed AND that function can take
// arguments.

Function.prototype.runsAfterSCW = function()
{
  var func = this, args = new Array(arguments.length);

  for (var i = 0; i < args.length; ++i)
  {
    args[i] = arguments[i];
  }

  return function()
  { 
    // concat/join the two argument arrays
    for (var i = 0; i < arguments.length; ++i)
    {
      args[args.length] = arguments[i];
    }
    return (args.shift() == scwTriggerEle) ? func.apply(this, args) : null;
  };
};

// Set up some shortcuts

function scwID(id)
{
  if (document.getElementById(id) || (!document.getElementById(id) && document.getElementsByName(id).length == 0))
  // IF   An ID attribute is assigned
  // OR   No ID attribute is assigned but using IE and Opera
  //          (which will find the NAME attribute value using getElementById)
  // OR   No element has this ID or NAME attribute value
  //          (used internally by the script)
  // THEN Return the required element.
  {
    return document.getElementById(id);
  }
  else
  {
    if (document.getElementsByName(id).length == 1)
    // IF   No ID attribute is assigned
    // AND  Using a standards-based browser
    // AND  Only one element has the NAME attribute set to the value
    // THEN Return the required element (using the NAME attribute value).
    {
      return document.getElementsByName(id)[0];
    }
    else
    {
      if (document.getElementsByName(id).length > 1)
      { 
        // IF   No ID attribute is assigned
        // AND  using a standards-based browser
        // AND  more than one element has the NAME attribute set to the value
        // THEN alert developer to fix the fault.
        alert('SCW' + ' \nCannot uniquely identify element named: ' + id
          + '.\nMore than one identical NAME attribute defined'
          + '.\nSolution: Assign the required element a unique ID attribute value.');
      }
    }
  }
};

// Use a global variable for the return value from the next action
// IE fails to pass the function through if the target element is in
// a form and scwNextAction is not defined.

var scwNextActionReturn, scwNextAction;

// ****************************************************************************
// Start of Function Library
//
//  Exposed functions:
//
//      scwShow             Entry point for display of calendar,
//                              called in main page.
//
//      scwShowMonth        Displays a month on the calendar,
//                              Called when a month is set or changed.
//
//      scwBeginDrag        Controls calendar dragging.
//
//      scwCancel           Called when the calendar background is clicked:
//                              Calls scwStopPropagation and may call scwHide.
//      scwHide             Hides the calendar, called on various events.
//      scwStopPropagation  Stops the propagation of an event.
//
// ****************************************************************************

function scwShow(scwEle, scwSource)
{
  // This date is used throughout to determine Now's date.
  scwDateNow = new Date();
  scwDateNow.setMinutes(Math.floor(scwDateNow.getMinutes() / 5) * 5);

  scwSelectedDate = new Date(scwDateNow);
  scwSelectedDate.setMinutes(0);

  if (!scwSource)
  {
    scwSource = window.event;
  }

  if (scwSource.tagName) // Second parameter isn't an event it's an element
  {
    var scwSourceEle = scwSource;

    if (scwID('scwIE'))
    {
      window.event.cancelBubble = true;
    }
    else
    {
      scwSourceEle.parentNode.addEventListener('click', scwStopPropagation, false);
    }
  }
  else // Second parameter is an event
  {
    var scwSourceEle = (scwSource.target) ? scwSource.target : scwSource.srcElement;

    // Stop the click event that opens the calendar from bubbling up to
    // the document-level event handler that hides it!
    if (scwSource.stopPropagation)
    {
      scwSource.stopPropagation();
    }
    else
    {
      scwSource.cancelBubble = true;
    }
  }

  scwTriggerEle = scwSourceEle;

  // The third argument is the format string
  scwDateOutputFormat = arguments[2];

  // Take any parameters that there might be from the third onwards as
  // day numbers to be disabled 0 = Sunday through to 6 = Saturday.
  scwDisableWeekdayString = arguments[3];

  if (scwDisableWeekdayString != null)
  {
    scwDisableWeekdayArray = scwDisableWeekdayString.split(',');

    for (var i = 0; i < 7; i++)
    {
      scwPassEnabledDay[(i + 7 - scwWeekStart) % 7] = true;

      for (var j = 0; j < scwDisableWeekdayArray.length; j++)
      {
        if (scwDisableWeekdayArray[j] == i)
        {
          scwPassEnabledDay[(i + 7 - scwWeekStart) % 7] = false;

          if (scwDateNow.getDay() == i)
          {
            scwParmActiveNow = false;
          }
        }
      }
    }
  }

  //   If no value is preset then the seed date is
  //      Now (when Now is in range) OR
  //      The middle of the date range.

  //scwSeedDate = scwDateNow;

  // Find the date and Strip space characters from start and
  // end of date input.

  var scwDateValue = '';

  if (scwEle.value)
  {
    scwDateValue = scwEle.value.replace(/^\s+/, '').replace(/\s+$/, '');
  }
  else
  {
    if (typeof scwEle.value == 'undefined')
    {
      var scwChildNodes = scwEle.childNodes;

      for (var i = 0; i < scwChildNodes.length; i++)
      {
        if (scwChildNodes[i].nodeType == 3)
        {
          scwDateValue = scwChildNodes[i].nodeValue.replace(/^\s+/, '').replace(/\s+$/, '');

          if (scwDateValue.length > 0)
          {
            scwTriggerEle.scwTextNode = scwChildNodes[i];
            scwTriggerEle.scwLength = scwChildNodes[i].nodeValue.length;
            break;
          }
        }
      }
    }
  }

  // Set the language-dependent elements

  scwSetDefaultLanguage();

  scwID('scwMinutes').options.length = 0;
  scwID('scwHours').options.length = 0;
  scwID('scwMonths').options.length = 0;
  scwID('scwYears').options.length = 0;

  if (scwDateOutputFormat.search(/H/) >= 0)
  {
    scwDateOnly = false;

    for (var i = 0; i < scwArr24HourNames.length; i++)
    {
      scwID('scwHours').options[i] = new Option(scwArr24HourNames[i], scwArr24HourNames[i]);
    }
  }
  else if (scwDateOutputFormat.search(/h/) >= 0)
  {
    scwDateOnly = false;

    for (var i = 0; i < scwArr12HourNames.length; i++)
    {
      scwID('scwHours').options[i] = new Option(scwArr12HourNames[i], scwArr12HourNames[i]);
    }
  }
  else
  {
    scwDateOnly = true;
  }

  if (scwDateOnly)
  {
    scwID('scwTime').style.visibility = 'hidden';
  }
  else
  {
    scwID('scwTime').style.visibility = 'inherit';

    for (var i = 0; i < scwArrMinuteNames.length; i++)
    {
      scwID('scwMinutes').options[i] = new Option(scwArrMinuteNames[i], scwArrMinuteNames[i]);
    }
  }

  scwID('scwDragText').innerHTML = scwDrag;

  for (var i = 0; i < scwArrMonthNames.length; i++)
  {
    scwID('scwMonths').options[i] = new Option(scwArrMonthNames[i], scwArrMonthNames[i]);
  }

  for (var i = 0; i < scwDropDownYears; i++)
  {
    scwID('scwYears').options[i] = new Option((scwBaseYear + i), (scwBaseYear + i));
  }

  for (var i = 0; i < scwArrWeekInits.length; i++)
  {
    scwID('scwWeekInit' + i).innerHTML = scwArrWeekInits[(i + scwWeekStart) % scwArrWeekInits.length];
  }

  if (scwID('scwFoot'))
  {
    scwID('scwFoot').innerHTML = scwNowText + ' ' + scwDateNow.scwFormat(scwDateOutputFormat);
  }

  var scwSelect = scwID('scwSelect');

  if (scwSelect)
  {
    scwSelect.innerHTML = scwSelectText;
    scwSelect.onclick = scwSelectedDateOutput;
    scwSelect.onmouseover = scwChangeClass;
    scwSelect.onmouseout = scwChangeClass;
  }

  if (scwDateValue.length == 0)
  {
    // If no value is entered and Now is within the range,
    // use Now's date, otherwise use the middle of the valid range.

    scwBlnFullInputDate = false;

    if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) < scwSelectedDate
      || (new Date(scwBaseYear, 0, 1)) > scwSelectedDate)
    {
      scwSelectedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears / 2), 5, 1);
    }
  }
  else
  {
    function scwInputFormat()
    {
      var scwArrSeed = [0,0,0,0,0];
      var scwArrInput = scwDateValue.split(new RegExp('[\\' + scwArrDelimiters.join('\\') + ']+', 'g'));

      // "Escape" all the user defined date delimiters above -
      // several delimiters will need it and it does no harm for
      // the others.

      // Strip any empty array elements (caused by delimiters)
      // from the beginning or end of the array. They will
      // still appear in the output string if in the output
      // format.

      if (scwArrInput[0] != null)
      {
        if (scwArrInput[0].length == 0)
        {
          scwArrInput.splice(0, 1);
        }

        if (scwArrInput[scwArrInput.length - 1].length == 0)
        {
          scwArrInput.splice(scwArrInput.length - 1, 1);
        }
      }

      scwBlnFullInputDate = false;

      // List all the allowed letters in the date format
      var template = ['D','M','Y','H','h','m'];

      // Prepare the sequence of date input elements
      var result = new Array();

      for (var i = 0; i < template.length; i++)
      {
        if (scwDateOutputFormat.search(template[i]) > -1)
        {
          result[scwDateOutputFormat.search(template[i])] = template[i];
        }
      }

      var scwDateSequence = result.join('');

      var indexYear = scwDateSequence.search(/Y/);
      var indexMonth = scwDateSequence.search(/M/);
      var indexDay = scwDateSequence.search(/D/);
      var indexHour = scwDateSequence.search(/h/);
      var indexMinute = scwDateSequence.search(/m/);

      if (indexHour < 0)
      {
        indexHour = scwDateSequence.search(/H/);
      }

      scwBlnFullInputDate = true;

      if (indexYear >= 0)
      {
        scwArrSeed[0] = scwArrInput[indexYear];
      }
      else
      {
        scwBlnFullInputDate = false;
      }

      if (indexMonth >= 0)
      {
        scwArrSeed[1] = scwArrInput[indexMonth];
      }
      else
      {
        scwBlnFullInputDate = false;
      }

      if (indexDay >= 0)
      {
        scwArrSeed[2] = scwArrInput[indexDay];
      }
      else
      {
        scwBlnFullInputDate = false;
      }

      if (indexHour >= 0)
      {
        scwArrSeed[3] = parseInt(scwArrInput[indexHour]);

        if (scwArrInput.length >= 6)
        {
          var ampm = scwArrInput[5].toString().toLowerCase();

          if (ampm == 'pm')
          {
            if (scwArrSeed[3] < 12)
            {
              scwArrSeed[3] += 12;
            }
          }
          else if (ampm == 'am')
          {
            if (scwArrSeed[3] >= 12)
            {
              scwArrSeed[3] -= 12;
            }
          }
        }
      }

      if (indexMinute >= 0)
      {
        scwArrSeed[4] = scwArrInput[indexMinute];
      }

      // These regular expressions validate the input date format
      // to the following rules;
      //         Day   1-31 (optional zero on single digits)
      //         Month 1-12 (optional zero on single digits)
      //                     or case insensitive name
      //         Year  One, Two or four digits

      // Months names are as set in the language-dependent
      // definitions and delimiters are set just below there

      var scwExpValDay = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'),
        scwExpValMonth = new RegExp('^(0?[1-9]|1[0-2]|' + scwArrMonthNames.join('|') + ')$', 'i'),
        scwExpValYear = new RegExp('^([0-9]{1,2}|[0-9]{4})$');

      // Apply validation and report failures

      if (scwExpValYear.exec(scwArrSeed[0]) == null || scwExpValMonth.exec(scwArrSeed[1]) == null
        || scwExpValDay.exec(scwArrSeed[2]) == null)
      {
        if (scwShowInvalidDateMsg)
        {
          alert(scwInvalidDateMsg + scwInvalidAlert[0] + scwDateValue + scwInvalidAlert[1]);
        }
        scwBlnFullInputDate = false;
        scwArrSeed[0] = scwBaseYear + Math.floor(scwDropDownYears / 2); // Year
        scwArrSeed[1] = '6';                                            // Month
        scwArrSeed[2] = 1;                                              // Day
        scwArrSeed[3] = 0;
        scwArrSeed[4] = 0;
      }

      // Return the  Year    in scwArrSeed[0]
      //             Month   in scwArrSeed[1]
      //             Day     in scwArrSeed[2]
      //alert(scwArrSeed[4]);

      return scwArrSeed;
    };

    // Parse the string into an array using the allowed delimiters
    var scwArrSeedDate = scwInputFormat();

    // So now we have the Year, Month and Day in an array.

    //   If the year is one or two digits then the routine assumes a
    //   year belongs in the 21st Century unless it is less than 50
    //   in which case it assumes the 20th Century is intended.

    if (scwArrSeedDate[0] < 100)
    {
      scwArrSeedDate[0] += (scwArrSeedDate[0] > 50) ? 1900 : 2000;
    }

    // Check whether the month is in digits or an abbreviation

    if (scwArrSeedDate[1].search(/\d+/) < 0)
    {
      for (i = 0; i < scwArrMonthNames.length; i++)
      {
        if (scwArrSeedDate[1].toUpperCase() == scwArrMonthNames[i].toUpperCase())
        {
          scwArrSeedDate[1] = i + 1;
          break;
        }
      }
    }

    scwSelectedDate = new Date(scwArrSeedDate[0], scwArrSeedDate[1] - 1, scwArrSeedDate[2]);

    if (scwArrSeedDate[3] >= 0)
    {
      scwSelectedDate.setHours(scwArrSeedDate[3]);
    }

    if (scwArrSeedDate[4] >= 0)
    {
      scwSelectedDate.setMinutes(scwArrSeedDate[4])
    }
  }

  // Test that we have arrived at a valid date

  if (isNaN(scwSelectedDate))
  {
    if (scwShowInvalidDateMsg)
    {
      alert(scwInvalidDateMsg + scwInvalidAlert[0] + scwDateValue + scwInvalidAlert[1]);
    }
    scwSelectedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears / 2), 5, 1);
    scwBlnFullInputDate = false;
  }
  else
  { 
    // Test that the date is within range,
    // if not then set date to a sensible date in range.

    if ((new Date(scwBaseYear, 0, 1)) > scwSelectedDate)
    {
      if (scwBlnStrict && scwShowOutOfRangeMsg)
      {
        alert(scwOutOfRangeMsg);
      }
      scwSelectedDate = new Date(scwBaseYear, 0, 1);
      scwBlnFullInputDate = false;
    }
    else
    {
      if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) < scwSelectedDate)
      {
        if (scwBlnStrict && scwShowOutOfRangeMsg)
        {
          alert(scwOutOfRangeMsg);
        }
        scwSelectedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears) - 1, 11, 1);
        scwBlnFullInputDate = false;
      }
      else
      {
        if (scwBlnStrict && scwBlnFullInputDate
          && (scwSelectedDate.getDate() != scwArrSeedDate[2] || (scwSelectedDate.getMonth() + 1) != scwArrSeedDate[1]
            || scwSelectedDate.getFullYear() != scwArrSeedDate[0]))
        {
          if (scwShowDoesNotExistMsg)
            alert(scwDoesNotExistMsg);
          scwSelectedDate = new Date(scwSelectedDate.getFullYear(), scwSelectedDate.getMonth() - 1, 1);
          scwBlnFullInputDate = false;
        }
      }
    }
  }

  // Test the disabled dates for validity
  // Give error message if not valid.

  for (var i = 0; i < scwDisabledDates.length; i++)
  {
    if (!(( typeof scwDisabledDates[i] == 'object') && (scwDisabledDates[i].constructor == Date)))
    {
      if (( typeof scwDisabledDates[i] == 'object') && (scwDisabledDates[i].constructor == Array))
      {
        var scwPass = true;

        if (scwDisabledDates[i].length != 2)
        {
          if (scwShowRangeDisablingError)
          {
            alert(scwRangeDisablingError[0] + scwDisabledDates[i] + scwRangeDisablingError[1]);
          }
          scwPass = false;
        }
        else
        {
          for (var j = 0; j < scwDisabledDates[i].length; j++)
          {
            if (!(( typeof scwDisabledDates[i][j] == 'object') && (scwDisabledDates[i][j].constructor == Date)))
            {
              if (scwShowRangeDisablingError)
              {
                alert(scwDateDisablingError[0] + scwDisabledDates[i][j] + scwDateDisablingError[1]);
              }
              scwPass = false;
            }
          }
        }

        if (scwPass && (scwDisabledDates[i][0] > scwDisabledDates[i][1]))
        {
          scwDisabledDates[i].reverse();
        }
      }
      else
      {
        if (scwShowRangeDisablingError)
        {
          alert(scwDateDisablingError[0] + scwDisabledDates[i] + scwDateDisablingError[1]);
        }
      }
    }
  }

  // Calculate the number of months that the entered (or
  // defaulted) month is after the start of the allowed
  // date range.

  scwMonthSum = 12 * (scwSelectedDate.getFullYear() - scwBaseYear) + scwSelectedDate.getMonth();

  scwID('scwYears').options.selectedIndex = Math.floor(scwMonthSum / 12);
  scwID('scwMonths').options.selectedIndex = (scwMonthSum % 12);
  
  if (scwDateOnly == false)
  {
    scwID('scwHours').options.selectedIndex = scwSelectedDate.getHours();
    scwID('scwMinutes').options.selectedIndex = Math.floor(scwSelectedDate.getMinutes() / 5);
  }

  // Check whether or not dragging is allowed and display drag handle if necessary

  scwID('scwDrag').style.display = (scwAllowDrag) ? '' : 'none';

  // Display the month

  scwShowMonth(0);

  // Position the calendar box

  // The object sniffing for Opera allows for the fact that Opera
  // is the only major browser that correctly reports the position
  // of an element in a scrollable DIV.  This is because IE and
  // Firefox omit the DIV from the offsetParent tree.

  scwTargetEle = scwEle;

  var offsetTop = parseInt(scwEle.offsetTop, 10) + parseInt(scwEle.offsetHeight, 10),
    offsetLeft = parseInt(scwEle.offsetLeft, 10);

  if (!window.opera)
  {
    while (scwEle.tagName != 'BODY' && scwEle.tagName != 'HTML')
    {
      offsetTop -= parseInt(scwEle.scrollTop, 10);
      offsetLeft -= parseInt(scwEle.scrollLeft, 10);
      scwEle = scwEle.parentNode;
    }
    scwEle = scwTargetEle;
  }

  do
  {
    scwEle = scwEle.offsetParent;
    offsetTop += parseInt(scwEle.offsetTop, 10);
    offsetLeft += parseInt(scwEle.offsetLeft, 10);
  } while (scwEle.tagName != 'BODY' && scwEle.tagName != 'HTML');

  scwID('scw').style.top = offsetTop + 'px';
  scwID('scw').style.left = offsetLeft + 'px';

  scwID('scwIframe').style.top = offsetTop + 'px';
  scwID('scwIframe').style.left = offsetLeft + 'px';
  scwID('scwIframe').style.width = (scwID('scw').offsetWidth - (scwID('scwIE') ? 2 : 4)) + 'px';
  scwID('scwIframe').style.height = (scwID('scw').offsetHeight - (scwID('scwIE') ? 2 : 4)) + 'px';
  scwID('scwIframe').style.visibility = 'inherit';

  // Show it on the page
  scwID('scw').style.visibility = 'inherit';
};

function scwHide()
{
  scwID('scw').style.visibility = 'hidden';
  scwID('scwIframe').style.visibility = 'hidden';

  if (typeof scwNextAction != 'undefined' && scwNextAction != null)
  {
    scwNextActionReturn = scwNextAction();
    // Explicit null set to prevent closure causing memory leak
    scwNextAction = null;
  }
};

function scwCancel(scwEvt)
{
  if (scwClickToHide)
  {
    scwHide();
  }
  scwStopPropagation(scwEvt);
};

function scwStopPropagation(scwEvt)
{
  if (scwEvt.stopPropagation)
  {
    scwEvt.stopPropagation();
  } // Capture phase
  else
  {
    scwEvt.cancelBubble = true;
  } // Bubbling phase
};

function scwBeginDrag(event)
{
  var elementToDrag = scwID('scw');

  var deltaX = event.clientX, deltaY = event.clientY, offsetEle = elementToDrag;

  do
  {
    deltaX -= parseInt(offsetEle.offsetLeft, 10);
    deltaY -= parseInt(offsetEle.offsetTop, 10);
    offsetEle = offsetEle.offsetParent;
  } while (offsetEle.tagName != 'BODY' && offsetEle.tagName != 'HTML');

  if (document.addEventListener)
  {
    document.addEventListener('mousemove', moveHandler, true); // Capture phase
    document.addEventListener('mouseup', upHandler, true);     // Capture phase
  }
  else
  {
    elementToDrag.attachEvent('onmousemove', moveHandler); // Bubbling phase
    elementToDrag.attachEvent('onmouseup', upHandler);     // Bubbling phase
    elementToDrag.setCapture();
  }

  scwStopPropagation(event);

  function moveHandler(scwEvt)
  {
    if (!scwEvt)
      scwEvt = window.event;

    elementToDrag.style.left = (scwEvt.clientX - deltaX) + 'px';
    elementToDrag.style.top = (scwEvt.clientY - deltaY) + 'px';

    scwID('scwIframe').style.left = (scwEvt.clientX - deltaX) + 'px';
    scwID('scwIframe').style.top = (scwEvt.clientY - deltaY) + 'px';

    scwStopPropagation(scwEvt);
  };

  function upHandler(scwEvt)
  {
    if (!scwEvt)
      scwEvt = window.event;

    if (document.removeEventListener)
    {
      document.removeEventListener('mousemove', moveHandler, true); // Capture phase
      document.removeEventListener('mouseup', upHandler, true);     // Capture phase
    }
    else
    {
      elementToDrag.detachEvent('onmouseup', upHandler);     // Bubbling phase
      elementToDrag.detachEvent('onmousemove', moveHandler); // Bubbling phase
      elementToDrag.releaseCapture();
    }

    scwStopPropagation(scwEvt);
  };
};

function scwSetOutput(scwOutputDate)
{
  var oldvalue;
  var newvalue = scwOutputDate.scwFormat(scwDateOutputFormat);
  
  if (typeof scwTargetEle.value == 'undefined')
  {
    oldvalue = scwTriggerEle.scwTextNode.nodeValue;
    scwTriggerEle.scwTextNode.replaceData(0, scwTriggerEle.scwLength, newvalue);
  }
  else
  {
    oldvalue = scwTargetEle.value;
    scwTargetEle.value = newvalue;
  }
  
  scwHide();
  
  if (scwTargetEle.onchange && oldvalue != newvalue)
  {
    scwTargetEle.onchange();
  }
};

function scwSelectedDateOutput()
{
  if (scwDateOnly == false)
  {
    scwSelHours = scwID('scwHours');
    scwSelMinutes = scwID('scwMinutes');

    scwSelectedDate.setHours(scwSelHours.options.selectedIndex);
    scwSelectedDate.setMinutes(scwSelMinutes.options.selectedIndex * 5);
  }

  scwSetOutput(scwSelectedDate);
}

function scwChangeClass(scwEvt)
    {
      var scwEle = scwEventTrigger(scwEvt);

      if (scwEle.nodeType == 3)
      {
        scwEle = scwEle.parentNode;
      }

      switch (scwEle.className)
      {
        case 'scwCells':
            scwEle.className = 'scwCellsHover';
            break;

        case 'scwCellsHover':
            scwEle.className = 'scwCells';
            break;

        case 'scwCellsExMonth':
            scwEle.className = 'scwCellsExMonthHover';
            break;

        case 'scwCellsExMonthHover':
            scwEle.className = 'scwCellsExMonth';
            break;

        case 'scwCellsWeekend':
            scwEle.className = 'scwCellsWeekendHover';
            break;

        case 'scwCellsWeekendHover':
            scwEle.className = 'scwCellsWeekend';
            break;

        case 'scwFoot':
            scwEle.className = 'scwFootHover';
            break;

        case 'scwFootHover':
            scwEle.className = 'scwFoot';
            break;

        case 'scwInputDate':
            scwEle.className = 'scwInputDateHover';
            break;

        case 'scwInputDateHover':
            scwEle.className = 'scwInputDate';
            break;
      }

      return true;
    }

function scwEventTrigger(scwEvt)
{
  if (!scwEvt)
  {
    scwEvt = event;
  }

  return scwEvt.target || scwEvt.srcElement;
};

// Set the selectable Month and Year
// May be called: from the left and right arrows
//                  (shift month -1 and +1 respectively)
//                from the month selection list
//                from the year selection list
//                from the scwShow routine
//                  (which initiates the display).
function scwShowMonth(scwBias)
{
  function scwCellOutput(scwEvt)
  {
    var scwEle = scwEventTrigger(scwEvt);
    var scwSelectedDatePrevious = scwSelectedDate;

    scwSelectedDate = new Date(scwCalendarStartDate);

    if (scwEle.nodeType == 3)
    {
      scwEle = scwEle.parentNode;
    }

    scwSelectedDate.setDate(scwCalendarStartDate.getDate() + parseInt(scwEle.id.substr(8), 10));

    if (scwDateOnly == true)
    {
      scwSetOutput(scwSelectedDate);
    }
    else
    {
      // make previous cell not selected
      if (scwEleClicked)
      {
        scwEleClicked.className = (scwSelectedDatePrevious.getMonth() != scwSelMonths.options.selectedIndex)
          ? 'scwCellsExMonth'
          : (scwSelectedDatePrevious.getDay() % 6 == 0)
          ? 'scwCellsWeekend'
          : 'scwCells';
      }

      // new cell selected
      scwEle.className = 'scwInputDate';

      // clicked is the cell just now clicked
      scwEleClicked = scwEle;
    }
  };

  function scwWeekNumber(scwInDate)
  { 
    // The base day in the week of the input date
    var scwInDateWeekBase = new Date(scwInDate);

    scwInDateWeekBase.setDate(scwInDateWeekBase.getDate() - scwInDateWeekBase.getDay() + scwWeekNumberBaseDay
      + ((scwInDate.getDay() > scwWeekNumberBaseDay)
        ? 7
        : 0));

    // The first Base Day in the year
    var scwFirstBaseDay = new Date(scwInDateWeekBase.getFullYear(), 0, 1);

    scwFirstBaseDay.setDate(scwFirstBaseDay.getDate() - scwFirstBaseDay.getDay() + scwWeekNumberBaseDay);

    if (scwFirstBaseDay < new Date(scwInDateWeekBase.getFullYear(), 0, 1))
    {
      scwFirstBaseDay.setDate(scwFirstBaseDay.getDate() + 7);
    }

    // Start of Week 01
    var scwStartWeekOne = new Date(scwFirstBaseDay - scwWeekNumberBaseDay + scwInDate.getDay());

    if (scwStartWeekOne > scwFirstBaseDay)
    {
      scwStartWeekOne.setDate(scwStartWeekOne.getDate() - 7);
    }

    // Subtract the date of the current week from the date of the
    // first week of the year to get the number of weeks in
    // milliseconds.  Divide by the number of milliseconds
    // in a week then round to no decimals in order to remove
    // the effect of daylight saving.  Add one to make the first
    // week, week 1.  Place a string zero on the front so that
    // week numbers are zero filled.

    var scwWeekNo = '0' + (Math.round((scwInDateWeekBase - scwFirstBaseDay) / 604800000, 0) + 1);

    // Return the last two characters in the week number string

    return scwWeekNo.substring(scwWeekNo.length - 2, scwWeekNo.length);
  };

  function scwFootOutput()
  {
    scwSetOutput(scwDateNow);
  };

  function scwFooterInitialize(scwFoot)
  {
    if (scwDisabledDates.length == 0)
    {
      if (scwActiveNow && scwParmActiveNow)
      {
        scwFoot.onclick = scwFootOutput;
        scwFoot.className = 'scwFoot';

        if (scwID('scwIE'))
        {
          scwFoot.onmouseover = scwChangeClass;
          scwFoot.onmouseout = scwChangeClass;
        }
      }
      else
      {
        scwFoot.onclick = null;
        scwFoot.className = 'scwFootDisabled';

        if (scwID('scwIE'))
        {
          scwFoot.onmouseover = null;
          scwFoot.onmouseout = null;
        }

        if (document.addEventListener)
        {
          scwFoot.addEventListener('click', scwStopPropagation, false);
        }
        else
        {
          scwFoot.attachEvent('onclick', scwStopPropagation);
        }
      }
    }
    else
    {
      for (var k = 0; k < scwDisabledDates.length; k++)
      {
        if (!scwActiveNow
          || !scwParmActiveNow
            || (( typeof scwDisabledDates[k] == 'object')
              && (((scwDisabledDates[k].constructor == Date) && scwDateNow.valueOf() == scwDisabledDates[k].valueOf())
                || ((scwDisabledDates[k].constructor == Array)
                  && scwDateNow.valueOf() >= scwDisabledDates[k][0].valueOf()
                    && scwDateNow.valueOf() <= scwDisabledDates[k][1].valueOf()))))
        {
          scwFoot.onclick = null;
          scwFoot.className = 'scwFootDisabled';

          if (scwID('scwIE'))
          {
            scwFoot.onmouseover = null;
            scwFoot.onmouseout = null;
          }

          if (document.addEventListener)
          {
            scwFoot.addEventListener('click', scwStopPropagation, false);
          }
          else
          {
            scwFoot.attachEvent('onclick', scwStopPropagation);
          }
          break;
        }
        else
        {
          scwFoot.onclick = scwFootOutput;
          scwFoot.className = 'scwFoot';

          if (scwID('scwIE'))
          {
            scwFoot.onmouseover = scwChangeClass;
            scwFoot.onmouseout = scwChangeClass;
          }
        }
      }
    }
  }

  //---------------------------------------------------------------------------
  // Start of scwShowMonth
  scwSelYears = scwID('scwYears');
  scwSelMonths = scwID('scwMonths');

  if (scwSelYears.options.selectedIndex > -1)
  {
    scwMonthSum = 12 * (scwSelYears.options.selectedIndex);
  }

  if (scwSelMonths.options.selectedIndex > -1)
  {
    scwMonthSum += scwSelMonths.options.selectedIndex;
  }

  if (scwBias != 0)
  {
    var scwMonthSumNew = scwMonthSum + scwBias;
    var scwYearsIndexNew = Math.floor(scwMonthSumNew / 12);
    
    if (scwYearsIndexNew < 0 || scwYearsIndexNew >= scwDropDownYears)
    { 
      // user requesting date out of range
      return;
    }
    
    scwSelYears.options.selectedIndex = scwYearsIndexNew;
    scwSelMonths.options.selectedIndex = (scwMonthSumNew % 12);
      
    scwMonthSum = scwMonthSumNew;
  }
  
  
  var scwFoot = scwID('scwFoot');

  if (scwFoot)
  {
    scwFooterInitialize(scwFoot);
  }

  var scwCalendarStartDate = new Date(Date.parse(new Date().toDateString()));


  scwCalendarMonth = scwMonthSum % 12;
  if (scwCalendarMonth != scwSelectedDate.getMonth())
  {
    // new month, previous click isn't displayed, so don't store it
    scwEleClicked = null;
  }
  
  // If the Week numbers are displayed, shift the week day names to the right.
  scwID('scwWeek_').style.display = (scwWeekNumberDisplay) ? '' : 'none';

  // Opera has a bug with setting the selected index.
  // It requires the following work-around to force SELECTs to display correctly.
  if (window.opera)
  {
    scwID('scwMonths').style.display = 'inherit';
    scwID('scwYears').style.display = 'inherit';
  }

  // set start date to be the first of the month
  scwCalendarStartDate.setFullYear(scwBaseYear + Math.floor(scwMonthSum / 12), scwCalendarMonth, 1);
  // now to the first day displayed on the calendar
  scwCalendarStartDate.setDate((((scwCalendarStartDate.getDay() - scwWeekStart) < 0)
    ? -6
    : 1)
    + scwWeekStart - scwCalendarStartDate.getDay());

  // This statement moved by Michael Cerveny to make version 3.55
  var scwCompareDateValue =
    new Date(scwCalendarStartDate.getFullYear(), scwCalendarStartDate.getMonth(),
      scwCalendarStartDate.getDate()).valueOf();

  // Treewalk to display the dates.
  // I tried to use getElementsByName but IE refused to cooperate
  // so I resorted to this method which works for all tested
  // browsers.

  // Set the time to the middle of the day so that the handful of
  // regions that have daylight saving shifts that change the day
  // of the month (i.e. turn the clock back at midnight or forward
  // at 23:00) do not mess up the date display in the calendar.
  scwShowDate = new Date(scwCalendarStartDate);
  scwShowDate.setHours(12);

  var scwCells = scwID('scwCells');

  for (i = 0; i < scwCells.childNodes.length; i++)
  {
    var scwRows = scwCells.childNodes[i];

    if (scwRows.nodeType == 1 && scwRows.tagName == 'TR')
    {
      if (scwWeekNumberDisplay)
      {
        //Calculate the week number using scwShowDate
        scwTmpEl = scwRows.childNodes[0];
        scwTmpEl.innerHTML = scwWeekNumber(scwShowDate);
        scwTmpEl.style.borderColor = (scwTmpEl.currentStyle)
          ? scwTmpEl.currentStyle['backgroundColor']
          : (window.getComputedStyle)
            ? document.defaultView.getComputedStyle(scwTmpEl, null).getPropertyValue('background-color')
            : '';
        scwTmpEl.style.display = '';
      }
      else
      {
        scwRows.childNodes[0].style.display = 'none';
      }

      for (j = 1; j < scwRows.childNodes.length; j++)
      {
        var scwCols = scwRows.childNodes[j];

        if (scwCols.nodeType == 1 && scwCols.tagName == 'TD')
        {
          scwRows.childNodes[j].innerHTML = scwShowDate.getDate();
          var scwCell = scwRows.childNodes[j],
            scwDisabled = ((scwOutOfRangeDisable
              && (scwShowDate < (new Date(scwBaseYear, 0, 1, scwShowDate.getHours()))
                || scwShowDate > (new Date(scwBaseYear + scwDropDownYears, 0, 0, scwShowDate.getHours()))))
              || (scwOutOfMonthDisable
                && (scwShowDate < (new Date(scwShowDate.getFullYear(), scwCalendarMonth, 1, scwShowDate.getHours()))
                  || scwShowDate
                  > (new Date(scwShowDate.getFullYear(), scwCalendarMonth + 1, 0, scwShowDate.getHours())))))
              ? true
              : false;

          scwCell.style.visibility = (scwOutOfMonthHide
            && (scwShowDate < (new Date(scwShowDate.getFullYear(), scwCalendarMonth, 1, scwShowDate.getHours()))
              || scwShowDate > (new Date(scwShowDate.getFullYear(), scwCalendarMonth + 1, 0, scwShowDate.getHours()))))
            ? 'hidden'
            : 'inherit';

          for (var k = 0; k < scwDisabledDates.length; k++)
          {
            if (( typeof scwDisabledDates[k] == 'object') && (scwDisabledDates[k].constructor == Date)
              && scwCompareDateValue == scwDisabledDates[k].valueOf())
            {
              scwDisabled = true;
            }
            else
            {
              if (( typeof scwDisabledDates[k] == 'object') && (scwDisabledDates[k].constructor == Array)
                && scwCompareDateValue >= scwDisabledDates[k][0].valueOf()
                && scwCompareDateValue <= scwDisabledDates[k][1].valueOf())
              {
                scwDisabled = true;
              }
            }
          }

          if (scwDisabled
            || !scwEnabledDay[j - 1 + (7 * ((i * scwCells.childNodes.length) / 6))]
              || !scwPassEnabledDay[(j - 1 + (7 * (i * scwCells.childNodes.length / 6))) % 7])
          {
            scwRows.childNodes[j].onclick = null;

            if (scwID('scwIE'))
            {
              scwRows.childNodes[j].onmouseover = null;
              scwRows.childNodes[j].onmouseout = null;
            }

            scwCell.className = (scwShowDate.getMonth() != scwCalendarMonth)
              ? 'scwCellsExMonthDisabled'
              : (scwBlnFullInputDate && scwShowDate.toDateString() == scwSelectedDate.toDateString())
                ? 'scwInputDateDisabled'
                : (scwShowDate.getDay() % 6 == 0)
                  ? 'scwCellsWeekendDisabled'
                  : 'scwCellsDisabled';

            scwCell.style.borderColor = (scwFormatNowCell && scwShowDate.toDateString() == scwDateNow.toDateString())
              ? scwNowCellBorderColor
              : (scwCell.currentStyle)
                ? scwCell.currentStyle['backgroundColor']
                : (window.getComputedStyle)
                  ? document.defaultView.getComputedStyle(scwCell, null).getPropertyValue('background-color')
                  : '';
          }
          else
          {
            scwRows.childNodes[j].onclick = scwCellOutput;

            //if (scwID('scwIE'))
            //{
              //scwRows.childNodes[j].onmouseover = scwChangeClass;
              //scwRows.childNodes[j].onmouseout = scwChangeClass;
            //}

            scwCell.className = (scwShowDate.getMonth() != scwCalendarMonth)
              ? 'scwCellsExMonth'
              : (scwBlnFullInputDate && scwShowDate.toDateString() == scwSelectedDate.toDateString())
                ? 'scwInputDate'
                : (scwShowDate.getDay() % 6 == 0)
                  ? 'scwCellsWeekend'
                  : 'scwCells';

            if (scwCell.className == 'scwInputDate')
            {
              scwEleClicked = scwCell;
            }

            scwCell.style.borderColor = (scwFormatNowCell && scwShowDate.toDateString() == scwDateNow.toDateString())
              ? scwNowCellBorderColor
              : (scwCell.currentStyle)
                ? scwCell.currentStyle['backgroundColor']
                : (window.getComputedStyle)
                  ? document.defaultView.getComputedStyle(scwCell, null).getPropertyValue('background-color')
                  : '';
          }

          scwShowDate.setDate(scwShowDate.getDate() + 1);
          scwCompareDateValue = new Date(scwShowDate.getFullYear(), scwShowDate.getMonth(),
            scwShowDate.getDate()).valueOf();
        }
      }
    }
  }

  // Opera has a bug with setting the selected index.
  // It requires the following work-around to force SELECTs to display correctly.
  // Also Opera's poor dynamic rendering prior to 9.5 requires
  // the visibility to be reset to prevent garbage in the calendar
  // when the displayed month is changed.

  if (window.opera)
  {
    scwID('scwMonths').style.display = 'inline';
    scwID('scwYears').style.display = 'inline';
    scwID('scw').style.visibility = 'hidden';
    scwID('scw').style.visibility = 'inherit';

    if (scwDateOnly == false)
    {
      scwID('scwHours').style.display = 'inline';
      scwID('scwMinutes').style.display = 'inline';
    }
  }
};

// *************************
//  End of Function Library
// *************************
// ***************************
// Start of Calendar structure
// ***************************

document.writeln("<!--[if IE]><div id='scwIE'></div><![endif]-->");
document.writeln("<!--[if lt IE 7]><div id='scwIElt7'></div><![endif]-->");
document.write("<iframe class='scw' " + (scwID('scwIElt7')
  ? "src='/scwblank.html '"
  : '')
  + "id='scwIframe' name='scwIframe' frameborder='0'>" + "</iframe>" + "<table id='scw' class='scw'>"
  + "<tr class='scw'>" + "<td class='scw'>" + "<table class='scwHead' id='scwHead' width='100%' "
  + "cellspacing='0' cellpadding='0'>" + "<tr id='scwDrag' style='display:none;'>" + "<td colspan='4' class='scwDrag' "
  + "onmousedown='scwBeginDrag(event);'>" + "<span id='scwDragText'></span>" + "</td>" + "</tr>"
  + "<tr class='scwHead' >" + "<td class='scwHead'>"
  + "<input class='scwHead' id='scwHeadLeft' type='button' value='<' " + "onclick='scwShowMonth(-1);'  /></td>"
  + "<td class='scwHead'>" + "<select id='scwMonths' class='scwHead' " + "onchange='scwShowMonth(0);'>" + "</select>"
  + "</td>" + "<td class='scwHead'>" + "<select id='scwYears' class='scwHead' " + "onchange='scwShowMonth(0);'>"
  + "</select>" + "</td>" + "<td class='scwHead'>" + "<input class='scwHead' id='scwHeadRight' type='button' value='>' "
  + "onclick='scwShowMonth(1);' /></td>" + "</tr>" + "</table>" + "</td>" + "</tr>" + "<tr class='scw'>"
  + "<td class='scw'>" + "<table class='scwCells' align='center'>" + "<thead>"
  + "<tr><td class='scwWeekNumberHead' id='scwWeek_' ></td>");

for (i = 0; i < 7; i++)
{
  document.write("<td class='scwWeek' id='scwWeekInit" + i + "'></td>");
}

document.write("</tr>" + "</thead>" + "<tbody id='scwCells' " + "onClick='scwStopPropagation(event);'>");

for (i = 0; i < 6; i++)
{
  document.write("<tr>" + "<td class='scwWeekNo' id='scwWeek_" + i + "'></td>");

  for (j = 0; j < 7; j++)
  {
    document.write("<td class='scwCells' id='scwCell_" + (j + (i * 7)) + "'></td>");
  }

  document.write("</tr>");
}

document.write("</tbody></table>");

document.write("<table class='scwFoot' id='scwTime' width='100%' " + "cellspacing='0' cellpadding='0' border='0'>"
  + "<tr class='scwFoot' >" + "<td width='50%'></td>" + "<td class='scwFoot'>"
  + "<select id='scwHours' class='scwFoot'> </select>" + "</td>" + "<td class='scwFoot'>:</td>" + "<td class='scwFoot'>"
  + "<select id='scwMinutes' class='scwFoot'> </select>" + "</td>"
  + "<td width='50%' id='scwSelect' class='scwFoot'></td></tr></table>");

if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow && (new Date(scwBaseYear, 0, 0)) < scwDateNow)
{
  document.write("<table><tr class='scwFoot'>" + "<td class='scwFoot' id='scwFoot' colspan='8'>" + "</td>"
    + "</tr></table>");
}

document.write("</td>" + "</tr>");
/*
  document.write(
   "<tr class='scw' >" +
     "<td class='scw'>" +
        "</td>" +
      "</tr>");
  */
document.write("</table>");

if (document.addEventListener)
{
  scwID('scw').addEventListener('click', scwCancel, false);
  scwID('scwHeadLeft').addEventListener('click', scwStopPropagation, false);
  scwID('scwMonths').addEventListener('click', scwStopPropagation, false);
  scwID('scwMonths').addEventListener('change', scwStopPropagation, false);
  scwID('scwYears').addEventListener('click', scwStopPropagation, false);
  scwID('scwYears').addEventListener('change', scwStopPropagation, false);
  scwID('scwHeadRight').addEventListener('click', scwStopPropagation, false);
}
else
{
  scwID('scw').attachEvent('onclick', scwCancel);
  scwID('scwHeadLeft').attachEvent('onclick', scwStopPropagation);
  scwID('scwMonths').attachEvent('onclick', scwStopPropagation);
  scwID('scwMonths').attachEvent('onchange', scwStopPropagation);
  scwID('scwYears').attachEvent('onclick', scwStopPropagation);
  scwID('scwYears').attachEvent('onchange', scwStopPropagation);
  scwID('scwHeadRight').attachEvent('onclick', scwStopPropagation);
}

// ***************************
//  End of Calendar structure
// ***************************
// ****************************************
// Start of document level event definition
// ****************************************

if (document.addEventListener)
{
  document.addEventListener('click', scwHide, false);
}
else
{
  document.attachEvent('onclick', scwHide);
}

// ****************************************
//  End of document level event definition
// ****************************************
// ************************************
//  End of Simple Calendar Widget Code
// ************************************