// *****************************************************************************
//      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.
//
// How to use the Calendar once it is defined for your page:
//
//            Simply choose an event to trigger the calendar (like an onClick
//            or an onMouseOver) and an element to work on (for the calendar
//            to take its initial date from and write its output date to) then
//            write it like this;
//
//                  <<event>>="scwShow(<<element>>,event);"
//
//            e.g. onClick="scwShow(scwID('myElement'),event);"
//            or   onMouseOver="scwShow(this,event);"
//
//            NOTE: If you wish to use the calendar with an Anchor tag, do
//                  not use the syntax:   href="javascript:scwShow(...)"
//                  Instead you should use the following;
//
//                  <a href="#" onclick="scwShow(<<element>>,event);return false;">
//                      <<your text>>
//                  </a>
//
//            If you are using a text node then specify the text's parent node
//            in the function call. The date should be the only text under that
//            node;
//
//            e.g.  <p onclick="scwShow(this,event);"><<date>></p>
//
//            You can also disable days of the week by adding arguments to the
//            call to scwShow.  The values should be Sunday = 0 through to
//            Saturday = 6.  A call to scwShow with Friday and Monday disabled
//            would look something like this;
//
//                  scwShow(<<element>>,event,5,1);
//
//            Finally you can use the following technique to run a function
//            when the calendar closes:
//
//                  scwNextAction=<<function>>.runsAfterSCW(this,<<arguments>>);
//                  scwShow(<<element>>,event <<,optional arguments above>>);
//
//            Where <<function>> is a function defined on the calling page
//            and <<arguments>> is the list of arguments being passed to that
//            function.
//
// *****************************************************************************
//
// See http://www.tarrget.info/calendar/scw.htm for a complete version history
//
// Version   Date        By               Description
// =======   ====        ===============  ===========
//   3.58    2007-04-04  Anthony Garrett  Resolved an error caused when the date
//                                         range does not include the current year.
//                                         Thanks to Steve Davis for letting me know.
//
//                                        Fixed "Today" selector display which
//                                         was incorrectly visible when year range
//                                         ended last year. (Also the result of
//                                         investigations based on Steve Davis'
//                                         feedback).
//
//   3.59    2007-06-13  Anthony Garrett  Added Verdana to font list of
//                                         calendar's CSS.  Resolves rendering
//                                         bug in Safari Beta 3 for Windows.
//
//   3.60    2007-07-31  Anthony Garrett  Fixed javascript error that occurred
//                                         when the target element had no value
//                                         attribute.  The error had no impact
//                                         on the behaviour of the script.  Thanks
//                                         to John Phelps for reporting this bug.
//
//   3.70    2007-09-21  Anthony Garrett  Updated the event trapping to make it
//                                         less intrusive on the page body.
//                                         NOTE: This requires that a calendar's
//                                         second parameter should be the calling
//                                         event (not the calling object as in
//                                         previous versions).
//                                         Thanks to Steve Davis for the bug report
//                                         that led to this change.
//
//                                        Fixed a bug that caused undelimited
//                                         dates to be handled incorrectly. They
//                                         are now parsed against the full date
//                                         output format then checked for validity.
//                                         Thanks to Dan Wood for raising this bug.
//
//                                        Replaced the date input sequence user
//                                         configuration setting with parsing the
//                                         sequence from the full format. New users
//                                         are often confused by the sequence and
//                                         in practice (to allow the calendar's date
//                                         output to be used for input) the sequence
//                                         must always match the full format element
//                                         order.
//
//                                        Extended IFRAME backing to all calendar objects
//                                         in order to improve calendar display over
//                                         some embedded applets and objects.  Thanks to
//                                         Stanko Kupcevic for his feedback on this.
//                                         NOTE: It is not possible to protect any
//                                         JavaScript object displayed over an
//                                         embedded DYNAMIC (and, therefore refreshed)
//                                         object because browsers usually do not
//                                         directly control the screen handling within
//                                         the object.  The best advice therefore remains
//                                         to design pages in such a way that the calendar
//                                         does not overlap embedded objects.
//
// *****************************************************************************

// ************************************
// Start of Simple Calendar Widget Code
// ************************************

// This date is used throughout to determine today's date.

    var scwbDateNow = 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 scwbBaseYear = scwbDateNow.getFullYear()-5;
    // alternatively, hard code a date like this...
    //      var scwbBaseYear = 1990;

    //var scwbBaseYear        = scwbDateNow.getFullYear()-10;
    var scwbBaseYear        = scwbDateNow.getFullYear()-70;

    // How many years do want to be valid and to show in the drop-down list?

    var scwbDropDownYears   = 53;

    // 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 scwbSetLanguage 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  scwbSetLanguage  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 scwbLanguage;

    function scwbSetDefaultLanguage()
        {try
            {scwbSetLanguage();}
         catch (exception)
            {// English
             scwbToday               = 'Today:';
             scwbDrag                = 'click here to drag';
             scwbArrMonthNames       = ['Jan','Feb','Mar','Apr','May','Jun',
                                       'Jul','Aug','Sep','Oct','Nov','Dec'];
             scwbArrWeekInits        = ['S','M','T','W','T','F','S'];
             scwbInvalidDateMsg      = 'The entered date is invalid.\n';
             scwbOutOfRangeMsg       = 'The entered date is out of range.';
             scwbDoesNotExistMsg     = 'The entered date does not exist.';
             scwbInvalidAlert        = ['Invalid date (',') ignored.'];
             scwbDateDisablingError  = ['Error ',' is not a Date object.'];
             scwbRangeDisablingError = ['Error ',
                                       ' should consist of two elements.'];
            }
        };

    // Note:  Always start the scwbArrWeekInits array with your string for
    //        Sunday whatever scwbWeekStart (below) is set to.

    // scwbWeekStart determines the start of the week in the display
    // Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc..

    var scwbWeekStart       =    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 scwbWeekNumberDisplay    = 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 scwbWeekNumberBaseDay    = 4;

    // Each of the calendar's alert message types can be disabled
    // independently here.

    var scwbShowInvalidDateMsg       = true,
        scwbShowOutOfRangeMsg        = true,
        scwbShowDoesNotExistMsg      = true,
        scwbShowInvalidAlert         = true,
        scwbShowDateDisablingError   = true,
        scwbShowRangeDisablingError  = 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 scwbArrDelimiters   = ['/','-','.',',',' '];

    var scwbArrDelimiters   = ['/','-','.',',',' '];

    // 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 scwbArrDelimiters 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 scwbArrMonthNames
    // YY           year number in two digits
    // YYYY         year number in four digits

    // Displayed "Today" date format

    //var scwbDateDisplayFormat = 'dd-mm-yy';     // e.g. 'MMM-DD-YYYY' for the US
    //var scwbDateDisplayFormat = 'dd/mmm/yyyy';     // e.g. 'MMM-DD-YYYY' for the US
    var scwbDateDisplayFormat = 'dd-mm-yyyy';     // e.g. 'MMM-DD-YYYY' for the US

    // Output date format

    //var scwbDateOutputFormat  = 'DD MMM, YYYY'; // e.g. 'MMM-DD-YYYY' for the US
    //var scwbDateOutputFormat  = 'DD-MMM-YYYY'; // e.g. 'MMM-DD-YYYY' for the US
    var scwbDateOutputFormat  = 'DD-MM-YYYY'; // e.g. 'MMM-DD-YYYY' for the US

    // Note: The delimiters used should be in scwbArrDelimiters.

    // scwbZindex 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 scwbZindex          = 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 scwbBlnStrict = 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 scwbBlnStrict       = 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<scwbEnabledDay.length;i++)
    //      {if (i%7%6==0) scwbEnabledDay[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
    // scwbShow. 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 scwbEnabledDay      = [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 Today) by
    // creating an element of the array scwbDisabledDates 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 scwbDisabledDates   = new Array();

    // e.g. To disable 10-Dec-2005:
    //          scwbDisabledDates[0] = new Date(2005,11,10);
    //
    //      or a range from 2004-Dec-25 to 2005-Jan-01:
    //          scwbDisabledDates[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 scwbActiveToday value to false to prevent selection.

    var scwbActiveToday = 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 scwbOutOfMonthDisable to  true  to disable these dates (or  false
    // to allow their selection).
    //
    // Set scwbOutOfMonthHide    to  true  to hide    these dates (or  false
    // to make them visible).

    var scwbOutOfMonthDisable = false;
    var scwbOutOfMonthHide    = 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
    // scwbOutOfRangeDisable to  true  to disable these dates (or  false  to
    // allow their selection).

    var scwbOutOfRangeDisable = 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 scwbTodayCellBorderColour.

    var scwbFormatTodayCell = true;
    var scwbTodayCellBorderColour = 'red';

    // You can allow the calendar to be dragged around the screen by
    // using the setting scwbAllowDrag 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 scwbAllowDrag = false;

    // Closing the calendar by clicking on it (rather than elsewhere on the
    // main page) can be inconvenient.  The scwbClickToHide boolean value
    // controls this feature.

    var scwbClickToHide = false;

    // 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">'                                       +
            '.scwb           {padding:1px;vertical-align:middle;}'       +
            'iframe.scwb     {position:absolute;z-index:' + scwbZindex    +
                            ';top:0px;left:0px;visibility:hidden;'      +
                            'width:1px;height:1px;}'                    +
            'table.scwb      {padding:0px;visibility:hidden;'            +
                            'position:absolute;cursor:default;'         +
                            'width:200px;top:0px;left:0px;'             +
                            'z-index:' + (scwbZindex+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.

    document.writeln(
        '<style type="text/css">'                                       +
            '/* IMPORTANT:  The scwb calendar script requires all '      +
            '               the classes defined here.'                  +
            '*/'                                                        +
            'table.scwb      {padding:       1px;'                       +
                            'vertical-align:middle;'                    +
                            'border:        ridge 2px;'                 +
                            'font-size:     10pt;'                      +
                            'font-family:   ' +
                                   'Verdana,Arial,Helvetica,Sans-Serif;'+
                            'font-weight:   bold;}'                     +
            'td.scwbDrag,'                                               +
            'td.scwbHead                 {padding:       0px 0px;'       +
                                        'text-align:    center;}'       +
            'td.scwbDrag                 {font-size:     8pt;}'          +
            'select.scwbHead             {margin:        3px 1px;'       +
                                        'text-align:    center;}'       +
            'input.scwbHead              {height:        22px;'          +
                                        'width:         22px;'          +
                                        'vertical-align:middle;'        +
                                        'text-align:    center;'        +
                                        'margin:        2px 1px;'       +
                                        'font-weight:   bold;'          +
                                        'font-size:     10pt;'          +
                                        'font-family:   fixedSys;}'     +
            'input.scwbOK                {height:        22px;'         +
                                        'width:         25px;'          +
                                        'vertical-align:middle;'        +
                                        'text-align:    center;'        +
                                        'margin:        1px 1px;'       +
                                        'font-weight:   bold;'          +
                                        'font-size:     10pt;'          +
                                        'font-family:   fixedSys;}'     +
            'td.scwbWeekNumberHead,'                                     +
            'td.scwbWeek                 {padding:       0px;'           +
                                        'text-align:    center;'        +
                                        'font-weight:   bold;}'         +
            'td.scwbFoot,'                                               +
            'td.scwbFootHover,'                                          +
            'td.scwbFoot:hover,'                                         +
            'td.scwbFootDisabled         {padding:       0px;'           +
                                        'text-align:    center;'        +
                                        'font-weight:   normal;}'       +
            'table.scwbCells             {text-align:    right;'         +
                                        'font-size:     8pt;'           +
                                        'width:         96%;}'          +
            'td.scwbCells,'                  +
            'td.scwbCellsHover,'             +
            'td.scwbCells:hover,'            +
            'td.scwbCellsDisabled,'          +
            'td.scwbCellsExMonth,'           +
            'td.scwbCellsExMonthHover,'      +
            'td.scwbCellsExMonth:hover,'     +
            'td.scwbCellsExMonthDisabled,'   +
            'td.scwbCellsWeekend,'           +
            'td.scwbCellsWeekendHover,'      +
            'td.scwbCellsWeekend:hover,'     +
            'td.scwbCellsWeekendDisabled,'   +
            'td.scwbInputDate,'              +
            'td.scwbInputDateHover,'         +
            'td.scwbInputDate:hover,'        +
            'td.scwbInputDateDisabled,'      +
            'td.scwbWeekNo,'                 +
            'td.scwbWeeks                {padding:           3px;'       +
                                        'width:             16px;'      +
                                        'height:            16px;'      +
                                        'border-width:      1px;'       +
                                        'border-style:      solid;'     +
                                        'font-weight:       bold;'      +
                                        'vertical-align:    middle;}'   +
            '/* Blend the colours into your page here...    */'         +
            '/* Calendar background */'                                 +
            'table.scwb                  {background-color:  #6666CC;}'  +
            '/* Drag Handle */'                                         +
            'td.scwbDrag                 {background-color:  #9999CC;'   +
                                        'color:             #CCCCFF;}'  +
            '/* Week number heading */'                                 +
            'td.scwbWeekNumberHead       {color:             #6666CC;}'  +
            '/* Week day headings */'                                   +
            'td.scwbWeek                 {color:             #CCCCCC;}'  +
            '/* Week numbers */'                                        +
            'td.scwbWeekNo               {background-color:  #776677;'   +
                                        'color:             #CCCCCC;}'  +
            '/* Enabled Days */'                                        +
            '/* Week Day */'                                            +
            'td.scwbCells                {background-color:  #CCCCCC;'   +
                                        'color:             #000000;}'  +
            '/* Day matching the input date */'                         +
            'td.scwbInputDate            {background-color:  #CC9999;'   +
                                        'color:             #FF0000;}'  +
            '/* Weekend Day */'                                         +
            'td.scwbCellsWeekend         {background-color:  #CCCCCC;'   +
                                        'color:             #CC6666;}'  +
            '/* Day outside the current month */'                       +
            'td.scwbCellsExMonth         {background-color:  #CCCCCC;'   +
                                        'color:             #666666;}'  +
            '/* Today selector */'                                      +
            'td.scwbFoot                 {background-color:  #6666CC;'   +
                                        'color:             #FFFFFF;}'  +
            '/* MouseOver/Hover formatting '                            +
            '       If you want to "turn off" any of the formatting '   +
            '       then just set to the same as the standard format'   +
            '       above.'                                             +
            ' '                                                         +
            '       Note: The reason that the following are'            +
            '       implemented using both a class and a :hover'        +
            '       pseudoclass is because Opera handles the rendering' +
            '       involved in the class swap very poorly and IE6 '    +
            '       (and below) only implements pseudoclasses on the'   +
            '       anchor tag.'                                        +
            '*/'                                                        +
            '/* Active cells */'                                        +
            'td.scwbCells:hover,'                                        +
            'td.scwbCellsHover           {background-color:  #FFFF00;'   +
                                        'cursor:            pointer;'   +
                                        'color:             #000000;}'  +
            '/* Day matching the input date */'                         +
            'td.scwbInputDate:hover,'                                    +
            'td.scwbInputDateHover       {background-color:  #FFFF00;'   +
                                        'cursor:            pointer;'   +
                                        'color:             #000000;}'  +
            '/* Weekend cells */'                                       +
            'td.scwbCellsWeekend:hover,'                                 +
            'td.scwbCellsWeekendHover    {background-color:  #FFFF00;'   +
                                        'cursor:            pointer;'   +
                                        'color:             #000000;}'  +
            '/* Day outside the current month */'                       +
            'td.scwbCellsExMonth:hover,'                                 +
            'td.scwbCellsExMonthHover    {background-color:  #FFFF00;'   +
                                        'cursor:            pointer;'   +
                                        'color:             #000000;}'  +
            '/* Today selector */'                                      +
            'td.scwbFoot:hover,'                                         +
            'td.scwbFootHover            {color:             #FFFF00;'   +
                                        'cursor:            pointer;'   +
                                        'font-weight:       bold;}'     +
            '/* Disabled cells */'                                      +
            '/* Week Day */'                                            +
            '/* Day matching the input date */'                         +
            'td.scwbInputDateDisabled    {background-color:  #999999;'   +
                                        'color:             #000000;}'  +
            'td.scwbCellsDisabled        {background-color:  #999999;'   +
                                        'color:             #000000;}'  +
            '/* Weekend Day */'                                         +
            'td.scwbCellsWeekendDisabled {background-color:  #999999;'   +
                                        'color:             #CC6666;}'  +
            '/* Day outside the current month */'                       +
            'td.scwbCellsExMonthDisabled {background-color:  #999999;'   +
                                        'color:             #666666;}'  +
            'td.scwbFootDisabled         {background-color:  #6666CC;'   +
                                        'color:             #FFFFFF;}'  +
        '</style>'
                    );

//******************************************************************************
//------------------------------------------------------------------------------
// End of customisation section
//------------------------------------------------------------------------------
//******************************************************************************

//  Variables required by both scwbShow and scwbShowMonth

    var scwbTargetEle,
        scwbTriggerEle,
        scwbMonthSum            = 0,
        scwbBlnFullInputDate    = false,
        scwbPassEnabledDay      = new Array(),
        scwbSeedDate            = new Date(),
        scwbParmActiveToday     = true,
        scwbWeekStart           = scwbWeekStart%7,
        scwbToday,
        scwbDrag,
        scwbArrMonthNames,
        scwbArrWeekInits,
        scwbInvalidDateMsg,
        scwbOutOfRangeMsg,
        scwbDoesNotExistMsg,
        scwbInvalidAlert,
        scwbDateDisablingError,
        scwbRangeDisablingError;

    // Add a method to format a date into the required pattern

    Date.prototype.scwbFormat =
        function(scwbFormat)
            {var charCount = 0,
                 codeChar  = '',
                 result    = '';

             for (var i=0;i<=scwbFormat.length;i++)
                {if (i<scwbFormat.length && scwbFormat.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().
                                            scwbPadLeft(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().scwbPadLeft(charCount)
                                            :scwbArrMonthNames[this.getMonth()];
                                break;
                             case 'd': case 'D':
                                // If we find a D, get the date and format it
                                result += this.getDate().toString().
                                            scwbPadLeft(charCount);
                                break;
                             default:
                                // Copy any unrecognised characters across
                                while (charCount-- > 0) {result += codeChar;}
                            }

                         if (i<scwbFormat.length)
                            {// Store the character we have just worked on
                             codeChar  = scwbFormat.charAt(i);
                             charCount = 1;
                            }
                        }
                }
             return result;
            };

    // Add a method to left pad zeroes

    String.prototype.scwbPadLeft =
        function(padToLength)
            {var result = '';
             for (var i=0;i<(padToLength - this.length);i++) {result += '0';}
             return (result + this);
            };
            
            
    // Find the date and Strip space characters from start and
    // end of date input.

    var scwbDateValue = '';

    // 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.runsAfterscwb =
        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()==scwbTriggerEle)?func.apply(this, args):null;
                        };
                    };

    // Set up some shortcuts

    function scwbID(id)  {return document.getElementById(id);};

    // 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 scwbNextAction is not defined.

    var scwbNextActionReturn, scwbNextAction;

// ****************************************************************************
// Start of Function Library
//
//  Exposed functions:
//
//      scwbShow             Entry point for display of calendar,
//                              called in main page.
//      showCal             Legacy name of scwbShow:
//                              Passes only legacy arguments,
//                              not the optional day disabling arguments.
//
//      scwbShowMonth        Displays a month on the calendar,
//                              Called when a month is set or changed.
//
//      scwbBeginDrag        Controls calendar dragging.
//
//      scwbCancel           Called when the calendar background is clicked:
//                              Calls scwbStopPropagation and may call scwbHide.
//      scwbHide             Hides the calendar, called on various events.
//      scwbStopPropagation  Stops the propagation of an event.
//
// ****************************************************************************

    function showCal(scwbEle,scwbSourceEvent) {scwbShow(scwbEle,scwbSourceEvent);};
    function scwbShow(scwbEle,scwbSourceEvent)
        {if (!scwbSourceEvent) {scwbSourceEvent = window.event;}

         var scwbSourceEle = (scwbSourceEvent.target)
                                ?scwbSourceEvent.target
                                :scwbSourceEvent.srcElement;

         // Stop the click event that opens the calendar from bubbling up to
         // the document-level event handler that hides it!
         if (scwbSourceEvent.stopPropagation)
                {scwbSourceEvent.stopPropagation();}
         else   {scwbSourceEvent.cancelBubble = true;}

         scwbTriggerEle = scwbSourceEle;

         //   If no value is preset then the seed date is
         //      Today (when today is in range) OR
         //      The middle of the date range.

         scwbSeedDate = scwbDateNow;

         // Set the language-dependent elements

         scwbSetDefaultLanguage();

         scwbID('scwbDragText').innerHTML = scwbDrag;

         scwbID('scwbMonths').options.length = 0;
         for (var i=0;i<scwbArrMonthNames.length;i++)
            {scwbID('scwbMonths').options[i] = new Option(scwbArrMonthNames[i],scwbArrMonthNames[i]);}

         scwbID('scwbYears').options.length = 0;
         for (var i=0;i<scwbDropDownYears;i++)
            {scwbID('scwbYears').options[i] =  new Option((scwbBaseYear+i),(scwbBaseYear+i));}

         if (scwbID('scwbFoot'))
            {scwbID('scwbFoot').innerHTML = scwbToday + ' ' + scwbDateNow.scwbFormat(scwbDateDisplayFormat);}

         if (scwbDateValue.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.

             scwbBlnFullInputDate=false;

             if ((new Date(scwbBaseYear+scwbDropDownYears,0,0))<scwbSeedDate ||
                 (new Date(scwbBaseYear,0,1))                 >scwbSeedDate
                )
                {scwbSeedDate = new Date(scwbBaseYear + Math.floor(scwbDropDownYears / 2), 5, 1);}
            }
         else
            {function scwbInputFormat()
                {var scwbArrSeed = new Array(),
                     scwbArrInput = scwbDateValue.split(new RegExp('[\\'+scwbArrDelimiters.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 (scwbArrInput[0]!=null)
                    {if (scwbArrInput[0].length==0)                      {scwbArrInput.splice(0,1);}
                     if (scwbArrInput[scwbArrInput.length-1].length==0)   {scwbArrInput.splice(scwbArrInput.length-1,1);}
                    }

                 scwbBlnFullInputDate = false;

                 scwbDateOutputFormat = scwbDateOutputFormat.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 (scwbDateOutputFormat.search(template[i])>-1)
                        {result[scwbDateOutputFormat.search(template[i])] = template[i];}
                    }

                 var scwbDateSequence = result.join('');

                 // Separate the elements of the date input
                 switch (scwbArrInput.length)
                    {case 1:
                        {if (scwbDateOutputFormat.indexOf('Y')>-1 &&
                             scwbArrInput[0].length>scwbDateOutputFormat.lastIndexOf('Y'))
                            {scwbArrSeed[0] = parseInt(scwbArrInput[0].substring(scwbDateOutputFormat.indexOf('Y'),
                                                                               scwbDateOutputFormat.lastIndexOf('Y')+1),10);
                            }
                         else   {scwbArrSeed[0] = 0;}

                         if (scwbDateOutputFormat.indexOf('M')>-1 &&
                             scwbArrInput[0].length>scwbDateOutputFormat.lastIndexOf('M'))
                            {scwbArrSeed[1] = scwbArrInput[0].substring(scwbDateOutputFormat.indexOf('M'),
                                                                      scwbDateOutputFormat.lastIndexOf('M')+1);
                            }
                         else   {scwbArrSeed[1] = '6';}

                         if (scwbDateOutputFormat.indexOf('D')>-1 &&
                             scwbArrInput[0].length>scwbDateOutputFormat.lastIndexOf('D'))
                            {scwbArrSeed[2] = parseInt(scwbArrInput[0].substring(scwbDateOutputFormat.indexOf('D'),
                                                                               scwbDateOutputFormat.lastIndexOf('D')+1),10);
                            }
                         else   {scwbArrSeed[2] = 1;}

                         if (scwbArrInput[0].length==scwbDateOutputFormat.length) {scwbBlnFullInputDate = true;}
                         break;
                        }
                     case 2:
                        {// Year and Month entry
                         scwbArrSeed[0] =
                             parseInt(scwbArrInput[scwbDateSequence.
                                                    replace(/D/i,'').
                                                    search(/Y/i)],10);  // Year
                         scwbArrSeed[1] = scwbArrInput[scwbDateSequence.
                                                    replace(/D/i,'').
                                                    search(/M/i)];      // Month
                         scwbArrSeed[2] = 1;                             // Day
                         break;
                        }
                     case 3:
                        {// Day Month and Year entry

                         scwbArrSeed[0] =
                             parseInt(scwbArrInput[scwbDateSequence.
                                                    search(/Y/i)],10);  // Year
                         scwbArrSeed[1] = scwbArrInput[scwbDateSequence.
                                                    search(/M/i)];      // Month
                         scwbArrSeed[2] =
                             parseInt(scwbArrInput[scwbDateSequence.
                                                    search(/D/i)],10);  // Day

                         scwbBlnFullInputDate = true;
                         break;
                        }
                     default:
                        {// A stuff-up has led to more than three elements in
                         // the date.
                         scwbArrSeed[0] = 0;     // Year
                         scwbArrSeed[1] = 0;     // Month
                         scwbArrSeed[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 scwbExpValDay    = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'),
                     scwbExpValMonth  = new RegExp('^(0?[1-9]|1[0-2]|'        +
                                                  scwbArrMonthNames.join('|') +
                                                  ')$','i'),
                     scwbExpValYear   = new RegExp('^([0-9]{1,2}|[0-9]{4})$');

                 // Apply validation and report failures

                 if (scwbExpValYear.exec(scwbArrSeed[0])  == null ||
                     scwbExpValMonth.exec(scwbArrSeed[1]) == null ||
                     scwbExpValDay.exec(scwbArrSeed[2])   == null
                    )
                    {if (scwbShowInvalidDateMsg)
                        {alert(scwbInvalidDateMsg  +
                               scwbInvalidAlert[0] + scwbDateValue +
                               scwbInvalidAlert[1]);}
                     scwbBlnFullInputDate = false;
                     scwbArrSeed[0] = scwbBaseYear +
                                     Math.floor(scwbDropDownYears/2); // Year
                     scwbArrSeed[1] = '6';                            // Month
                     scwbArrSeed[2] = 1;                              // Day
                    }

                 // Return the  Year    in scwbArrSeed[0]
                 //             Month   in scwbArrSeed[1]
                 //             Day     in scwbArrSeed[2]

                 return scwbArrSeed;
                };

             // Parse the string into an array using the allowed delimiters

             scwbArrSeedDate = scwbInputFormat();

             // 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 (scwbArrSeedDate[0]<100) {scwbArrSeedDate[0] += (scwbArrSeedDate[0]>50)?1900:2000;}

             // Check whether the month is in digits or an abbreviation

             if (scwbArrSeedDate[1].search(/\d+/)!=0)
                {month = scwbArrMonthNames.join('|').toUpperCase().
                            search(scwbArrSeedDate[1].substr(0,3).
                                                    toUpperCase());
                 scwbArrSeedDate[1] = Math.floor(month/4)+1;
                }

             scwbSeedDate = new Date(scwbArrSeedDate[0],scwbArrSeedDate[1]-1,scwbArrSeedDate[2]);
            }

         // Test that we have arrived at a valid date

         if (isNaN(scwbSeedDate))
            {if (scwbShowInvalidDateMsg) {alert(scwbInvalidDateMsg + scwbInvalidAlert[0] + scwbDateValue + scwbInvalidAlert[1]);}
             scwbSeedDate = new Date(scwbBaseYear + Math.floor(scwbDropDownYears/2),5,1);
             scwbBlnFullInputDate=false;
            }
         else
            {// Test that the date is within range,
             // if not then set date to a sensible date in range.

             if ((new Date(scwbBaseYear,0,1)) > scwbSeedDate)
                {if (scwbBlnStrict && scwbShowOutOfRangeMsg) {alert(scwbOutOfRangeMsg);}
                 scwbSeedDate = new Date(scwbBaseYear,0,1);
                 scwbBlnFullInputDate=false;
                }
             else
                {if ((new Date(scwbBaseYear+scwbDropDownYears,0,0))<scwbSeedDate)
                    {if (scwbBlnStrict && scwbShowOutOfRangeMsg) {alert(scwbOutOfRangeMsg);}
                     scwbSeedDate = new Date(scwbBaseYear + Math.floor(scwbDropDownYears)-1,11,1);
                     scwbBlnFullInputDate=false;
                    }
                 else
                    {if (scwbBlnStrict && scwbBlnFullInputDate &&
                          (scwbSeedDate.getDate()      != scwbArrSeedDate[2] ||
                           (scwbSeedDate.getMonth()+1) != scwbArrSeedDate[1] ||
                           scwbSeedDate.getFullYear()  != scwbArrSeedDate[0]
                          )
                        )
                        {if (scwbShowDoesNotExistMsg) alert(scwbDoesNotExistMsg);
                         scwbSeedDate = new Date(scwbSeedDate.getFullYear(),scwbSeedDate.getMonth()-1,1);
                         scwbBlnFullInputDate=false;
                        }
                    }
                }
            }

         // Test the disabled dates for validity
         // Give error message if not valid.

         for (var i=0;i<scwbDisabledDates.length;i++)
            {if (!((typeof scwbDisabledDates[i] == 'object') && (scwbDisabledDates[i].constructor == Date)))
                {if ((typeof scwbDisabledDates[i] == 'object') && (scwbDisabledDates[i].constructor == Array))
                    {var scwbPass = true;

                     if (scwbDisabledDates[i].length !=2)
                        {if (scwbShowRangeDisablingError)
                            {alert(scwbRangeDisablingError[0] + scwbDisabledDates[i] + scwbRangeDisablingError[1]);}
                         scwbPass = false;
                        }
                     else
                        {for (var j=0;j<scwbDisabledDates[i].length;j++)
                            {if (!((typeof scwbDisabledDates[i][j] == 'object') && (scwbDisabledDates[i][j].constructor == Date)))
                                {if (scwbShowRangeDisablingError)
                                    {alert(  scwbDateDisablingError[0] + scwbDisabledDates[i][j] + scwbDateDisablingError[1]);}
                                 scwbPass = false;
                                }
                            }
                        }

                     if (scwbPass && (scwbDisabledDates[i][0] > scwbDisabledDates[i][1])) {scwbDisabledDates[i].reverse();}
                    }
                 else
                    {if (scwbShowRangeDisablingError) {alert(scwbDateDisablingError[0] + scwbDisabledDates[i] + scwbDateDisablingError[1]);}}
                }
            }

         // Calculate the number of months that the entered (or
         // defaulted) month is after the start of the allowed
         // date range.

         scwbMonthSum =  12*(scwbSeedDate.getFullYear()-scwbBaseYear)+scwbSeedDate.getMonth();

         scwbID('scwbYears' ).options.selectedIndex = Math.floor(scwbMonthSum/12);
         scwbID('scwbMonths').options.selectedIndex = (scwbMonthSum%12);

         // Display the month

         scwbShowMonth(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.

         scwbTargetEle=scwbEle;

         var offsetTop =parseInt(scwbEle.offsetTop ,10) + parseInt(scwbEle.offsetHeight,10),
             offsetLeft=parseInt(scwbEle.offsetLeft,10);

         if (!window.opera)
             {while (scwbEle.tagName!='BODY' && scwbEle.tagName!='HTML')
                 {offsetTop -=parseInt(scwbEle.scrollTop, 10);
                  offsetLeft-=parseInt(scwbEle.scrollLeft,10);
                  scwbEle=scwbEle.parentNode;
                 }
              scwbEle=scwbTargetEle;
             }

         do {scwbEle=scwbEle.offsetParent;
             offsetTop +=parseInt(scwbEle.offsetTop, 10);
             offsetLeft+=parseInt(scwbEle.offsetLeft,10);
            }
         while (scwbEle.tagName!='BODY' && scwbEle.tagName!='HTML');

         scwbID('scwb').style.top =offsetTop +'px';
         scwbID('scwb').style.left=offsetLeft+'px';

         scwbID('scwbIframe').style.top=offsetTop +'px';
         scwbID('scwbIframe').style.left=offsetLeft+'px';
         scwbID('scwbIframe').style.width=(scwbID('scwb').offsetWidth-(scwbID('scwbIE')?2:4))+'px';
         scwbID('scwbIframe').style.height=(scwbID('scwb').offsetHeight-(scwbID('scwbIE')?2:4))+'px';
         scwbID('scwbIframe').style.visibility='inherit';

         // Show it on the page
         scwbID('scwb').style.visibility='inherit';
        };

    function scwbHide()
        {scwbID('scwb').style.visibility='hidden';
         scwbID('scwbIframe').style.visibility='hidden';
         if (typeof scwbNextAction!='undefined' && scwbNextAction!=null)
             {scwbNextActionReturn = scwbNextAction();
              // Explicit null set to prevent closure causing memory leak
              scwbNextAction = null;
             }
        };

    function scwbCancel(scwbEvt)
        {if (scwbClickToHide) {scwbHide();}
         scwbStopPropagation(scwbEvt);
        };

    function scwbStopPropagation(scwbEvt)
        {if (scwbEvt.stopPropagation)
                {scwbEvt.stopPropagation();}     // Capture phase
         else   {scwbEvt.cancelBubble = true;}   // Bubbling phase
        };

    function scwbShowMonth(scwbBias)
        {// 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 scwbShowDate  = new Date(Date.parse(new Date().toDateString())),
             scwbStartDate = 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.

         scwbShowDate.setHours(12);

         scwbSelYears  = scwbID('scwbYears');
         scwbSelMonths = scwbID('scwbMonths');
         
         if (scwbSelYears.options.selectedIndex>-1)
            {scwbMonthSum=12*(scwbSelYears.options.selectedIndex)+scwbBias;
             if (scwbSelMonths.options.selectedIndex>-1) {scwbMonthSum+=scwbSelMonths.options.selectedIndex;}
            }
         else
            {if (scwbSelMonths.options.selectedIndex>-1) {scwbMonthSum+=scwbSelMonths.options.selectedIndex;}}

         scwbShowDate.setFullYear(scwbBaseYear + Math.floor(scwbMonthSum/12),(scwbMonthSum%12),1);

         // Opera has a bug with setting the selected index.
         // It requires the following work-around to force SELECTs to display correctly.
         if (window.opera)
            {scwbID('scwbMonths').style.display = 'inherit';
             scwbID('scwbYears' ).style.display = 'inherit';
           }

         // Set the drop down boxes.
         scwbTemp = (12*parseInt((scwbShowDate.getFullYear()-scwbBaseYear),10)) + parseInt(scwbShowDate.getMonth(),10);

         if (scwbTemp > -1 && scwbTemp < (12*scwbDropDownYears))
            {scwbSelYears.options.selectedIndex=Math.floor(scwbMonthSum/12);
             scwbSelMonths.options.selectedIndex=(scwbMonthSum%12);

             scwbCurMonth = scwbShowDate.getMonth();
             
             scwbShowDate.setDate(1);
             
             // This statement moved by Michael Cerveny to make version 3.55
             var scwbCompareDateValue = new Date(scwbShowDate.getFullYear(),
                                                scwbShowDate.getMonth(),
                                                scwbShowDate.getDate()).valueOf();
             
             scwbStartDate = new Date(scwbShowDate);

             if (scwbID('scwbFoot'))
                {var scwbFoot = scwbID('scwbFoot');
                 
                 
                 function scwbFootOutput() {scwbSetOutput(scwbDateNow);};

                 if (scwbDisabledDates.length==0)
                    {if (scwbActiveToday && scwbParmActiveToday)
                        {scwbFoot.onclick     = scwbFootOutput;
                         scwbFoot.className   = 'scwbFoot';

                         if (scwbID('scwbIE'))
                            {scwbFoot.onmouseover  = scwbChangeClass;
                             scwbFoot.onmouseout   = scwbChangeClass;
                            }

                        }
                     else
                        {scwbFoot.onclick     = null;
                         scwbFoot.className   = 'scwbFootDisabled';

                         if (scwbID('scwbIE'))
                            {scwbFoot.onmouseover  = null;
                             scwbFoot.onmouseout   = null;
                            }

                         if (document.addEventListener)
                                {scwbFoot.addEventListener('click',scwbStopPropagation,false);}
                         else   {scwbFoot.attachEvent('onclick',scwbStopPropagation);}
                        }
                    }
                 else
                    {for (var k=0;k<scwbDisabledDates.length;k++)
                        {if (!scwbActiveToday || !scwbParmActiveToday ||
                             ((typeof scwbDisabledDates[k] == 'object')                   &&
                                 (((scwbDisabledDates[k].constructor == Date)             &&
                                   scwbDateNow.valueOf() == scwbDisabledDates[k].valueOf()
                                  ) ||
                                  ((scwbDisabledDates[k].constructor == Array)               &&
                                   scwbDateNow.valueOf() >= scwbDisabledDates[k][0].valueOf() &&
                                   scwbDateNow.valueOf() <= scwbDisabledDates[k][1].valueOf()
                                  )
                                 )
                             )
                            )
                            {scwbFoot.onclick     = null;
                             scwbFoot.className   = 'scwbFootDisabled';

                             if (scwbID('scwbIE'))
                                {scwbFoot.onmouseover  = null;
                                 scwbFoot.onmouseout   = null;
                                }

                             if (document.addEventListener)
                                    {scwbFoot.addEventListener('click',scwbStopPropagation,false);}
                             else   {scwbFoot.attachEvent('onclick',scwbStopPropagation);}
                             break;
                            }
                         else
                            {scwbFoot.onclick=scwbFootOutput;
                             scwbFoot.className='scwbFoot';

                             if (scwbID('scwbIE'))
                                {scwbFoot.onmouseover  = scwbChangeClass;
                                 scwbFoot.onmouseout   = scwbChangeClass;
                                }
                            }
                        }
                    }
                }

             
             function scwbChangeClass(scwbEvt)
                {var scwbEle = scwbEventTrigger(scwbEvt);

                 if (scwbEle.nodeType==3) {scwbEle=scwbEle.parentNode;}

                 switch (scwbEle.className)
                    {case 'scwbFoot':
                        scwbEle.className = 'scwbFootHover';
                        break;
                     case 'scwbFootHover':
                        scwbEle.className = 'scwbFoot';
                        break;
                     case 'scwbInputDate':
                        scwbEle.className = 'scwbInputDateHover';
                        break;
                     case 'scwbInputDateHover':
                        scwbEle.className = 'scwbInputDate';
                    }

                 return true;
                }

          function scwbSetOutput(scwbOutputDate)
             {if (typeof scwbTargetEle.value == 'undefined')
                   {scwbTriggerEle.scwbTextNode.replaceData(0,scwbTriggerEle.scwbLength,scwbOutputDate.scwbFormat(scwbDateOutputFormat));}
              else {scwbTargetEle.value = scwbOutputDate.scwbFormat(scwbDateOutputFormat);}
              scwbHide();
             };

          function scwbCellOutput(scwbEvt)
             {var scwbEle = scwbEventTrigger(scwbEvt),
                  scwbOutputDate = new Date(scwbStartDate);

              scwbOutputDate.setDate(scwbStartDate.getDate());

              scwbSetOutput(scwbOutputDate);
             };
             
             function scwbEventTrigger(scwbEvt)
                {if (!scwbEvt) {scwbEvt = event;}
                 return scwbEvt.target||scwbEvt.srcElement;
                };


                var scwbOk = scwbID('scwbOk');
                scwbOk.onclick = scwbCellOutput;
                
         // 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)
            {scwbID('scwbMonths').style.display = 'inline';
             scwbID('scwbYears' ).style.display = 'inline';
             scwbID('scwb').style.visibility='hidden';
             scwbID('scwb').style.visibility='inherit';
           }
        }
    };

// *************************
//  End of Function Library
// *************************
// ***************************
// Start of Calendar structure
// ***************************

    document.writeln("<!--[if IE]><div id='scwbIE'></div><![endif]-->");
    document.writeln("<!--[if lt IE 7]><div id='scwbIElt7'></div><![endif]-->");
    document.write(
     "<iframe class='scwb' " + (scwbID('scwbIElt7')?"src='/scwbblank.html '":'') +
             "id='scwbIframe' name='scwbIframe' frameborder='0'>" +
     "</iframe>" +
     "<table id='scwb' class='scwb'>" +
       "<tr class='scwb'>" +
         "<td class='scwb'>" +
           "<table class='scwbHead' id='scwbHead' width='100%' " +
                    "cellspacing='0' cellpadding='0'>" +
            "<tr id='scwbDrag' style='display:none;'>" +
                "<td colspan='4' class='scwbDrag' " +
                    "onmousedown='scwbBeginDrag(event);'>" +
                    "<div id='scwbDragText'></div>" +
                "</td>" +
            "</tr>" +
            "<tr class='scwbHead' >" +
                 "<td class='scwbHead'>" +
                    "<input class='scwbHead' id='scwbHeadLeft' type='button' value='<' " +
                            "onclick='scwbShowMonth(-1);'  /></td>" +
                 "<td class='scwbHead'>" +
                    "<select id='scwbMonths' class='scwbHead' " +
                            "onchange='scwbShowMonth(0);'>" +
                    "</select>" +
                 "</td>" +
                 "<td class='scwbHead'>" +
                    "<select id='scwbYears' class='scwbHead' " +
                            "onchange='scwbShowMonth(0);'>" +
                    "</select>" +
                 "</td>" +
                 "<td class='scwbHead'>" +
                    "<input class='scwbHead' id='scwbHeadRight' type='button' value='>' " +
                            "onclick='scwbShowMonth(1);' /></td>" +
                 "<td class='scwbHead'>" +
                    "<input class='scwbOK' id='scwbOk' type='button' value='OK' /></td>" +
                "</tr>" +
              "</table>" +
            "</td>" +
          "</tr>");

    if ((new Date(scwbBaseYear + scwbDropDownYears, 0, 0)) > scwbDateNow &&
        (new Date(scwbBaseYear, 0, 0))                    < scwbDateNow)
        {document.write(
                  "<tfoot class='scwbFoot'>" +
                    "<tr class='scwbFoot'>" +
                      "<td class='scwbFoot' id='scwbFoot' colspan='8'>" +
                      "</td>" +
                    "</tr>" +
                  "</tfoot>");
        }

    document.write("</table>");

    if (document.addEventListener)
            {scwbID('scwb'         ).addEventListener('click',scwbCancel,false);
             scwbID('scwbHeadLeft' ).addEventListener('click',scwbStopPropagation,false);
             scwbID('scwbMonths'   ).addEventListener('click',scwbStopPropagation,false);
             scwbID('scwbMonths'   ).addEventListener('change',scwbStopPropagation,false);
             scwbID('scwbYears'    ).addEventListener('click',scwbStopPropagation,false);
             scwbID('scwbYears'    ).addEventListener('change',scwbStopPropagation,false);
             scwbID('scwbHeadRight').addEventListener('click',scwbStopPropagation,false);
            }
    else    {scwbID('scwb'         ).attachEvent('onclick',scwbCancel);
             scwbID('scwbHeadLeft' ).attachEvent('onclick',scwbStopPropagation);
             scwbID('scwbMonths'   ).attachEvent('onclick',scwbStopPropagation);
             scwbID('scwbMonths'   ).attachEvent('onchange',scwbStopPropagation);
             scwbID('scwbYears'    ).attachEvent('onclick',scwbStopPropagation);
             scwbID('scwbYears'    ).attachEvent('onchange',scwbStopPropagation);
             scwbID('scwbHeadRight').attachEvent('onclick',scwbStopPropagation);
            }

// ***************************
//  End of Calendar structure
// ***************************
// ****************************************
// Start of document level event definition
// ****************************************

    if (document.addEventListener)
            {document.addEventListener('click',scwbHide, false);}
    else    {document.attachEvent('onclick',scwbHide);}

// ****************************************
//  End of document level event definition
// ****************************************
// ************************************
//  End of Simple Calendar Widget Code
// ************************************