// *****************************************************************************
//      Simple Calendar Widget - Cross-Browser Javascript pop-up calendar.
//
//   Copyright (C) 2005-2007  Anthony Garrett
//
//   This library is free software; you can redistribute it and/or
//   modify it under the terms of the GNU Lesser General Public
//   License as published by the Free Software Foundation; either
//   version 2.1 of the License, or (at your option) any later version.
//
//   This library is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//   Lesser General Public License for more details.
//
//   You should have received a copy of the GNU Lesser General Public
//   License along with this library; if not, it is available at
//   the GNU web site (http://www.gnu.org/) or by writing to the
//   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
//   Boston, MA  02110-1301  USA
//
// *****************************************************************************
//
// Contact:   Sorry, I can't offer support for this but if you find a problem
//            (or just want to tell me how useful you find it), please send
//            me an email at scwfeedback@tarrget.info (Note the two Rs in
//            tarrget).  I will try to fix problems quickly but this is a
//            spare time thing for me.
//
// Credits:   I wrote this from scratch myself but I couldn't have done it
//            without the superb "JavaScript The Definitive Guide" by David
//            Flanagan (Pub. O'Reilly ISBN 0-596-00048-0).  I also recognise
//            a contribution from my experience with PopCalendar 4.1 by
//            Liming(Victor) Weng.
//
// Link back: Please give me credit and link back to my page.  To ensure that
//            search engines give my page a higher ranking you can add the
//            following HTML to any indexed page on your web site:
//
//            <A HREF="http://www.tarrget.info/calendar/scw.htm">
//              Simple Calendar Widget by Anthony Garrett
//            </A>
//
// Features:  Easily customised
//                  (output date format, colours, language, year range and
//                   week start day)
//            Accepts a date as input
//                  (see comments below for formats).
//            Cross-browser code tested against;
//                  Internet Explorer 6.0.28     Mozilla  1.7.1
//                  Opera             7.52+      Firefox  0.9.1+
//                  Konqueror         3.4.0      Flock    0.4.9
//
// How to add the Calendar to your page:
//            This script needs to be defined for your page so, immediately
//            after the BODY tag add the following line;
//
//                  <script type='Text/JavaScript' src='scw.js'></script>
//
//            Your root directory of the web site should also contain an empty
//            file called "scwblank.html". See
//                  http://www.tarrget.info/calendar/IEnightmare.html
//            for a full explanation.
//

// This date is used throughout to determine today's date.

    var scwDateNow = new Date(Date.parse(new Date().toDateString()));

//******************************************************************************
//------------------------------------------------------------------------------
// 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()-0;

    // How many years do want to be valid and to show in the drop-down list?

    var scwDropDownYears   = 2;

    // 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()
        {try
            {scwSetLanguage();}
         catch (exception)
            {// English
             scwToday               = 'Today:';
             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       =    1;

    // 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 'Today' 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

    // Displayed "Today" date format

    var scwDateDisplayFormat = 'd';     // e.g. 'MMM-DD-YYYY' for the US

    // Output date format

    var scwDateOutputFormat  = 'DD MMM YYYY'; // e.g. 'MMM-DD-YYYY' for the US

    // Note: The delimiters used should be in scwArrDelimiters.

    // scwZindex controls how the pop-up calendar interacts with the rest
    // of the page.  It is usually adequate to leave it as 1 (One) but I
    // have made it available here to help anyone who needs to alter the
    // level in order to ensure that the calendar displays correctly in
    // relation to all other elements on the page.

    var scwZindex          = 1;

    // 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 are using ReadOnly or Disabled fields to return the date
    // value into, it can be useful to show a button on the calendar
    // that allows the value to be cleared.  If you want to do that,
    // set scwClearButton = true;


    // 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.


    // You can disable any specific date (e.g. 24-Jan-2006 or Today) 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.


    // 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:
    //
    // 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 scwActiveToday value to false to prevent selection.

    var scwActiveToday = false;

    // 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 colour
    // set by scwTodayCellBorderColour.

    var scwFormatTodayCell = true;
    var scwTodayCellBorderColour = 'red';


    // I have made every effort to isolate the pop-up script from any
    // CSS defined on the main page but if you have anything set that
    // affects the pop-up (or you may want to change the way it looks)
    // then you can address it in the following style sheets.

    document.writeln(
        '<style type="text/css">'                                       +
            '.scw           {padding:1px;vertical-align:top;}'       +
            'iframe.scw     {position:relative;z-index:' + scwZindex    +
                            ';top:0px;left:0px;visibility:visible;'      +
                            'width:1px;height:1px;}'                    +
            'table.scw      {padding:0px;visibility:visible;'            +
                            'position:relative;cursor:default;'         +
                            'width:200px;top:0px;left:0px;'             +
                            'z-index:' + (scwZindex+1)                  +
                            ';text-align:center;}'                      +
        '</style>'  );

    // This style sheet can be extracted from the script and edited into regular
    // CSS (by removing all occurrences of + and '). That can be used as the
    // basis for themes. Classes are described in comments within the style
    // sheet.


//******************************************************************************
//------------------------------------------------------------------------------
// End of customisation section
//------------------------------------------------------------------------------
//******************************************************************************

//  Variables required by both scwShow and scwShowMonth

    var scwTargetEle,
        scwTriggerEle,
        scwMonthSum            = 0,
        scwBlnFullInputDate    = false,
        scwSeedDate            = new Date(),
        scwParmActiveToday     = true,
        scwWeekStart           = scwWeekStart%7,
        scwToday,
        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   {switch (codeChar)
                            {case 'y': case 'Y':
                                result += (this.getFullYear()%Math.
                                            pow(10,charCount)).toString().
                                            scwPadLeft(charCount);
                                break;
                             case 'm': 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': case 'D':
                                // If we find a D, get the date and format it
                                result += this.getDate().toString().
                                            scwPadLeft(charCount);
                                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.
//      showCal             Legacy name of scwShow:
//                              Passes only legacy arguments,
//                              not the optional day disabling arguments.
//
//      scwShowMonth        Displays a month on the calendar,
//                              Called when a month is set or changed.
//
//
//      scwCancel           Called when the calendar background is clicked:
//                              Calls scwStopPropagation and may call scwHide.
//      scwHide             Hides the calendar, called on various events.
//
// ****************************************************************************

function scwShow() {
  
  scwSetDefaultLanguage();
  scwSeedDate = scwDateNow;

    // Find the date and Strip space characters from start and
    // end of date input.

    var scwDateValue = '';
	 


    scwID('scwMonths').options.length = 0;
    for (var i=0;i<scwArrMonthNames.length;i++)
      {scwID('scwMonths').options[i] = new Option(scwArrMonthNames[i],scwArrMonthNames[i]);}
    
    scwID('scwYears').options.length = 0;
    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 (((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
	 (new Date(scwBaseYear, 0, 0))                    < scwDateNow) ||
	(scwEle.readOnly || scwEle.disabled)
	)   {
      scwID('scwFoot').style.display = '';
      scwID('scwNow').innerHTML = '';
      if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
	  (new Date(scwBaseYear, 0, 0))                    < scwDateNow
	  )   {scwID('scwNow').style.display = '';
	
      }
      else   {
	scwID('scwNow').style.display = 'none';
      }
    }
         else   {scwID('scwFoot').style.display = 'none';}
    
    if (scwDateValue.length==0)
            {// If no value is entered and today is within the range,
             // use today's date, otherwise use the middle of the valid range.

             scwBlnFullInputDate=false;

             if ((new Date(scwBaseYear+scwDropDownYears,0,0))<scwSeedDate ||
                 (new Date(scwBaseYear,0,1))                 >scwSeedDate
                )
                {scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears / 2), 5, 1);}
            }
         else
            {function scwInputFormat()
                {var scwArrSeed = new Array(),
                     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;

                 scwDateOutputFormat = scwDateOutputFormat.toUpperCase();

                 // List all the allowed letters in the date format
                 var template = ['D','M','Y'];

                 // 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('');

                 // Separate the elements of the date input
                 switch (scwArrInput.length)
                    {case 1:
                        {if (scwDateOutputFormat.indexOf('Y')>-1 &&
                             scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('Y'))
                            {scwArrSeed[0] = parseInt(scwArrInput[0].substring(scwDateOutputFormat.indexOf('Y'),
                                                                               scwDateOutputFormat.lastIndexOf('Y')+1),10);
                            }
                         else   {scwArrSeed[0] = 0;}

                         if (scwDateOutputFormat.indexOf('M')>-1 &&
                             scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('M'))
                            {scwArrSeed[1] = scwArrInput[0].substring(scwDateOutputFormat.indexOf('M'),
                                                                      scwDateOutputFormat.lastIndexOf('M')+1);
                            }
                         else   {scwArrSeed[1] = '6';}

                         if (scwDateOutputFormat.indexOf('D')>-1 &&
                             scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('D'))
                            {scwArrSeed[2] = parseInt(scwArrInput[0].substring(scwDateOutputFormat.indexOf('D'),
                                                                               scwDateOutputFormat.lastIndexOf('D')+1),10);
                            }
                         else   {scwArrSeed[2] = 1;}

                         if (scwArrInput[0].length==scwDateOutputFormat.length) {scwBlnFullInputDate = true;}
                         break;
                        }
                     case 2:
                        {// Year and Month entry
                         scwArrSeed[0] =
                             parseInt(scwArrInput[scwDateSequence.
                                                    replace(/D/i,'').
                                                    search(/Y/i)],10);  // Year
                         scwArrSeed[1] = scwArrInput[scwDateSequence.
                                                    replace(/D/i,'').
                                                    search(/M/i)];      // Month
                         scwArrSeed[2] = 1;                             // Day
                         break;
                        }
                     case 3:
                        {// Day Month and Year entry

                         scwArrSeed[0] =
                             parseInt(scwArrInput[scwDateSequence.
                                                    search(/Y/i)],10);  // Year
                         scwArrSeed[1] = scwArrInput[scwDateSequence.
                                                    search(/M/i)];      // Month
                         scwArrSeed[2] =
                             parseInt(scwArrInput[scwDateSequence.
                                                    search(/D/i)],10);  // Day

                         scwBlnFullInputDate = true;
                         break;
                        }
                     default:
                        {// A stuff-up has led to more than three elements in
                         // the date.
                         scwArrSeed[0] = 0;     // Year
                         scwArrSeed[1] = 0;     // Month
                         scwArrSeed[2] = 0;     // Day
                        }
                    }

                 // 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
                    }

                 // Return the  Year    in scwArrSeed[0]
                 //             Month   in scwArrSeed[1]
                 //             Day     in scwArrSeed[2]

                 return scwArrSeed;
                };

             // Parse the string into an array using the allowed delimiters

             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;
                        }
                    }
                }

             scwSeedDate = new Date(scwArrSeedDate[0],scwArrSeedDate[1]-1,scwArrSeedDate[2]);
            }

         // Test that we have arrived at a valid date

         if (isNaN(scwSeedDate))
            {if (scwShowInvalidDateMsg) {alert(scwInvalidDateMsg + scwInvalidAlert[0] + scwDateValue + scwInvalidAlert[1]);}
             scwSeedDate = 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)) > scwSeedDate)
                {if (scwBlnStrict && scwShowOutOfRangeMsg) {alert(scwOutOfRangeMsg);}
                 scwSeedDate = new Date(scwBaseYear,0,1);
                 scwBlnFullInputDate=false;
                }
             else
                {if ((new Date(scwBaseYear+scwDropDownYears,0,0))<scwSeedDate)
                    {if (scwBlnStrict && scwShowOutOfRangeMsg) {alert(scwOutOfRangeMsg);}
                     scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears)-1,11,1);
                     scwBlnFullInputDate=false;
                    }
                 else
                    {if (scwBlnStrict && scwBlnFullInputDate &&
                          (scwSeedDate.getDate()      != scwArrSeedDate[2] ||
                           (scwSeedDate.getMonth()+1) != scwArrSeedDate[1] ||
                           scwSeedDate.getFullYear()  != scwArrSeedDate[0]
                          )
                        )
                        {if (scwShowDoesNotExistMsg) alert(scwDoesNotExistMsg);
                         scwSeedDate = new Date(scwSeedDate.getFullYear(),scwSeedDate.getMonth()-1,1);
                         scwBlnFullInputDate=false;
                        }
                    }
                }
            }

         // Test the disabled dates for validity
         // Give error message if not valid.

         for (var i=0;i<scwBookedDates.length;i++)  {
	   if (!((typeof scwBookedDates[i] == 'object') && (scwBookedDates[i].constructor == Date))){
	     if ((typeof scwBookedDates[i] == 'object') && (scwBookedDates[i].constructor == Array)) {
	       var scwPass = true;
	       if (scwBookedDates[i].length !=2) {
		 if (scwShowRangeDisablingError)  {  alert(scwRangeDisablingError[0] + scwBookedDates[i] + scwRangeDisablingError[1]); }
		 scwPass = false;
	       } else {
		 for (var j=0;j<scwBookedDates[i].length;j++) {
		   if (!((typeof scwBookedDates[i][j] == 'object') && (scwBookedDates[i][j].constructor == Date))) {
		     if (scwShowRangeDisablingError) { alert(  scwDateDisablingError[0] + scwBookedDates[i][j] + scwDateDisablingError[1]);  }
		     scwPass = false;
		   }
		 }
	       }
	       
	       if (scwPass && (scwBookedDates[i][0] > scwBookedDates[i][1])) {scwBookedDates[i].reverse();}
	     } else {
	       if (scwShowRangeDisablingError) {alert(scwDateDisablingError[0] + scwBookedDates[i] + scwDateDisablingError[1]);}
	     }
	   }
	 }

         for (var i=0;i<scwPendingDates.length;i++)  {
	   if (!((typeof scwPendingDates[i] == 'object') && (scwPendingDates[i].constructor == Date))){
	     if ((typeof scwPendingDates[i] == 'object') && (scwPendingDates[i].constructor == Array)) {
	       var scwPass = true;
	       if (scwPendingDates[i].length !=2) {
		 if (scwShowRangeDisablingError)  {  alert(scwRangeDisablingError[0] + scwPendingDates[i] + scwRangeDisablingError[1]); }
		 scwPass = false;
	       } else {
		 for (var j=0;j<scwPendingDates[i].length;j++) {
		   if (!((typeof scwPendingDates[i][j] == 'object') && (scwPendingDates[i][j].constructor == Date))) {
		     if (scwShowRangeDisablingError) { alert(  scwDateDisablingError[0] + scwPendingDates[i][j] + scwDateDisablingError[1]);  }
		     scwPass = false;
		   }
		 }
	       }
	       
	       if (scwPass && (scwPendingDates[i][0] > scwPendingDates[i][1])) {scwPendingDates[i].reverse();}
	     } else {
	       if (scwShowRangeDisablingError) {alert(scwDateDisablingError[0] + scwPendingDates[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*(scwSeedDate.getFullYear()-scwBaseYear)+scwSeedDate.getMonth();

         scwID('scwYears' ).options.selectedIndex = Math.floor(scwMonthSum/12);
         scwID('scwMonths').options.selectedIndex = (scwMonthSum%12);



         // Display the month

         scwShowMonth(0);

         var offsetTop =0,          offsetLeft=0;


         // Show it on the page
         scwID('scw').style.visibility='inherit';
        };





    function scwShowMonth(scwBias)
        {// 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 showCal routine
         //                  (which initiates the display).

         var scwShowDate  = new Date(Date.parse(new Date().toDateString())),
             scwStartDate = new Date();

         // 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.setHours(12);

         scwSelYears  = scwID('scwYears');
         scwSelMonths = scwID('scwMonths');

         if (scwSelYears.options.selectedIndex>-1)
            {scwMonthSum=12*(scwSelYears.options.selectedIndex)+scwBias;
             if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;}
            }
         else
            {if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;}}

         scwShowDate.setFullYear(scwBaseYear + Math.floor(scwMonthSum/12),(scwMonthSum%12),1);

         // 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 the drop down boxes.
         scwTemp = (12*parseInt((scwShowDate.getFullYear()-scwBaseYear),10)) + parseInt(scwShowDate.getMonth(),10);

         if (scwTemp > -1 && scwTemp < (12*scwDropDownYears))  {
	   scwSelYears.options.selectedIndex=Math.floor(scwMonthSum/12);
	   scwSelMonths.options.selectedIndex=(scwMonthSum%12);
	   
	   scwCurMonth = scwShowDate.getMonth();
	     
	   scwShowDate.setDate((((scwShowDate.getDay()-scwWeekStart)<0)?-6:1)+scwWeekStart-scwShowDate.getDay());
	   
	   // This statement moved by Michael Cerveny to make version 3.55
	   var scwCompareDateValue = new Date(scwShowDate.getFullYear(), scwShowDate.getMonth(), scwShowDate.getDate()).valueOf();
	   
	   scwStartDate = new Date(scwShowDate);
	   
	   if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow && (new Date(scwBaseYear, 0, 0)) < scwDateNow)  
	     {
	     var scwNow = scwID('scwNow');
	     
	     function scwNowOutput() {scwSetOutput(scwDateNow);};
	     
	   }
	   
	   function scwSetOutput(scwOutputDate)
	   {if (typeof scwTargetEle.value == 'undefined')
	       {scwTriggerEle.scwTextNode.replaceData(0,scwTriggerEle.scwLength,scwOutputDate.scwFormat(scwDateOutputFormat));}
	     else {scwTargetEle.value = scwOutputDate.scwFormat(scwDateOutputFormat);}
	   };
	   
	   function scwCellOutput(scwEvt)  {
	     var scwEle = scwEventTrigger(scwEvt),
	       scwOutputDate = new Date(scwStartDate);
	     
	     if (scwEle.nodeType==3) scwEle=scwEle.parentNode;
	     
	     scwOutputDate.setDate(scwStartDate.getDate() + parseInt(scwEle.id.substr(8),10));
	     
	     scwSetOutput(scwOutputDate);
	   };

	   function scwChangeClass(scwEvt)
	   {var scwEle = scwEventTrigger(scwEvt);
	     
	     if (scwEle.nodeType==3) {scwEle=scwEle.parentNode;}
	     
	     
	     return true;
	   }

	   function scwEventTrigger(scwEvt)
	   {if (!scwEvt) {scwEvt = event;}
	     return scwEvt.target||scwEvt.srcElement;
	   };
	   
	   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);
	   };
	   
	   // 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.
	   
	   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];
			    var scwBooked = false;
			    var scwPending = false;
			    scwCell.style.visibility =   (scwOutOfMonthHide && (scwShowDate < (new Date(scwShowDate.getFullYear(), scwCurMonth,1, scwShowDate.getHours()))  ||  scwShowDate >	   (new Date(scwShowDate.getFullYear(),	scwCurMonth+1,0,   scwShowDate.getHours())) ) )?'hidden':'inherit';
			    
			      
			    for (var k=0;k<scwBookedDates.length;k++)      {
			      if ((typeof scwBookedDates[k]=='object') &&  (scwBookedDates[k].constructor == Date) && scwCompareDateValue == scwBookedDates[k].valueOf()   ) {scwBooked = true;}
			      else {
				if ((typeof scwBookedDates[k]=='object') && (scwBookedDates[k].constructor == Array) &&	scwCompareDateValue >= scwBookedDates[k][0].valueOf() && scwCompareDateValue <= scwBookedDates[k][1].valueOf()) {scwBooked = true;}
			      }
			    }

			      
			    for (var k=0;k<scwPendingDates.length;k++)      {
			      if ((typeof scwPendingDates[k]=='object') &&  (scwPendingDates[k].constructor == Date) && scwCompareDateValue == scwPendingDates[k].valueOf()   ) {scwPending = true;}
			      else {
				if ((typeof scwPendingDates[k]=='object') && (scwPendingDates[k].constructor == Array) &&	scwCompareDateValue >= scwPendingDates[k][0].valueOf() && scwCompareDateValue <= scwPendingDates[k][1].valueOf()) {scwPending = true;}
			      }
			    }
			    if (scwBooked) { 
			      scwCell.className=
				(scwShowDate.getMonth()!=scwCurMonth)
				?'scwCellsExMonthDisabled' :(scwBlnFullInputDate && scwShowDate.toDateString()== scwSeedDate.toDateString())
				?'scwInputDateDisabled' :(scwShowDate.getDay()%6==0)
				?'scwCellsBooked' :'scwCellsBooked';
			      
			      scwCell.style.borderColor =
				(scwFormatTodayCell && scwShowDate.toDateString()==scwDateNow.toDateString())
				?scwTodayCellBorderColour  :(scwCell.currentStyle)
				?scwCell.currentStyle['backgroundColor'] :(window.getComputedStyle)
				?document.defaultView.getComputedStyle(scwCell,null).getPropertyValue('background-color') :'';

			    } else if (scwPending) { 
			      scwCell.className=
				(scwShowDate.getMonth()!=scwCurMonth)
				?'scwCellsExMonthDisabled' :(scwBlnFullInputDate && scwShowDate.toDateString()== scwSeedDate.toDateString())
				?'scwInputDateDisabled' :(scwShowDate.getDay()%6==0)
				?'scwCellsPending' :'scwCellsPending';
			      
			      scwCell.style.borderColor =
				(scwFormatTodayCell && scwShowDate.toDateString()==scwDateNow.toDateString())
				?scwTodayCellBorderColour  :(scwCell.currentStyle)
				?scwCell.currentStyle['backgroundColor'] :(window.getComputedStyle)
				?document.defaultView.getComputedStyle(scwCell,null).getPropertyValue('background-color') :'';
			    } else {
			      scwCell.className=
				(scwShowDate.getMonth()!=scwCurMonth)
				?'scwCellsExMonth' :(scwBlnFullInputDate &&  scwShowDate.toDateString()==  scwSeedDate.toDateString())
				?'scwInputDate'    :(scwShowDate.getDay()%6==0)
				?'scwCellsWeekend' :'scwCells';
			      
			      scwCell.style.borderColor =
				(scwFormatTodayCell && scwShowDate.toDateString() == scwDateNow.toDateString())
				?scwTodayCellBorderColour :(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='inherit';
           }
        };

// *************************
//  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 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''>");

    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>" +
                "<tfoot>" +
                  "<tr id='scwFoot'>" +
                    "<td colspan='8' style='padding:0px;'>" +
                      "<table width='100%'>" +
                        "<tr>" +
                          "<td class='scwNow' id='scwNow'></td>" +
                        "</tr>" +
                      "</table>" +
                    "</td>" +
                  "</tr>" +
                "</tfoot>" +
              "</table>" +
            "</td>" +
          "</tr>" +
        "</table>");


// ***************************
//  End of Calendar structure
// ***************************
// ****************************************
// Start of document level event definition
// ****************************************


// ****************************************
//  End of document level event definition
// ****************************************
// ************************************
//  End of Simple Calendar Widget Code
// ************************************
