﻿/* *****************************************************************************
     JavaScript Advanced Calendar Script (JATS) - Cross-Browser pop-up calendar.

     Copyright (C) 2007-2008  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
*///*****************************************************************************

// ********************************************************
// Start of Javascript Advanced Time Script (JATS) Code
// based on Javascript Advanced Calenar Script (JACS) Code
// created by Imrich Szolik (30.10.2008)
// ********************************************************

lomtecRegisterNS("lomtec.Controls.UI.Script");

lomtec.Controls.UI.Script.JACS = new function()
    {// This date is used throughout to determine today's date.
     var dateNow = new Date(Date.parse(new Date().toDateString()));

     // This array keeps track of the defined calendars for the page.
     var cals = new Array();

     // This function shortens the code replacing
     // document.getElementById('myID') with getEl('myId')
     // everywhere in the script. It also tries to handle a common
     // error when calling the script: when the developer has only
     // set a NAME attribute value, so no ID attribute is set.
     function getEl(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( 'JACS' +
                                        ' \nCannot uniquely identify element named: ' + id +
                                        '.\nMore than one identical NAME attribute defined' +
                                        '.\nSolution: Assign the required element a unique ID attribute value.');
                                }
                        }
                }
           return null;
         };


     // This DIV inside an IE-only conditional comments is a
     // reliable way of setting up object testing for IE.
     document.writeln("<!--[if IE]><div id='jacsIE'></div><![endif]-->");
     document.writeln("<!--[if lt IE 7]><div id='jacsIElt7'></div><![endif]-->");

//******************************************************************************
//------------------------------------------------------------------------------
// Customisation section
//------------------------------------------------------------------------------
//******************************************************************************
     function calAttributes(cal)
        {
            cal.zIndex = 1;
            cal.baseYear = dateNow.getFullYear()-10;
            cal.dropDownYears = 30;
            cal.weekStart = 1;
            cal.weekNumberBaseDay = 4;
            cal.weekNumberDisplay = false;
            cal.defaultToCurrentMonth = true;

            try   {jacsSetLanguage(cal);}
            catch (exception)
                {// English
                 cal.language            = 'en';
                 cal.today               = 'Today:';
                 cal.clear               = 'Clear';
                 cal.drag                = 'click here to drag';
                 cal.monthNames          = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
                 cal.weekInits           = ['S','M','T','W','T','F','S'];
                 cal.invalidDateMsg      = 'The entered date is invalid.\n';
                 cal.outOfRangeMsg       = 'The entered date is out of range.';
                 cal.doesNotExistMsg     = 'The entered date does not exist.';
                 cal.invalidAlert        = ['Invalid date (',') ignored.'];
                 cal.dateSettingError    = ['Error ',' is not a Date object.'];
                 cal.rangeSettingError   = ['Error ',' should consist of two elements.'];
                }

            cal.showInvalidDateMsg      = false;
            cal.showOutOfRangeMsg       = false;
            cal.showDoesNotExistMsg     = false;
            cal.showInvalidAlert        = false;
            cal.showDateSettingError    = false;
            cal.showRangeSettingError   = false;
            cal.active = true;
            cal.delimiters = ['/','-','.',':',',',' '];
            cal.dateDisplayFormat = 'dd.mm.yyyy';    
            cal.dateFormat  = 'MM/DD/YYYY'; // e.g. 'MMM-DD-YYYY' for the US
            cal.strict = false;
            cal.clearButton = false;
            cal.valuesEnabled = false;
            cal.dayCells = [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];
            cal.range = null;
            cal.dates = new Array();
            cal.highlightDates = new Array();

            cal.outOfRangeDisable = true;
            cal.outOfMonthDisable = false;
            cal.outOfMonthHide    = false;

            cal.formatTodayCell = true;
            cal.todayCellBorderColour = '#f00'; // red
            cal.allowDrag = true;
            cal.onBlurMoveNext = false;
            cal.clickToHide = false;
            cal.xBase     = 'L';
            cal.yBase     = 'B';
            cal.xPosition = 'L';
            cal.yPosition = 'T';
            cal.autoPosition = true;

            cal.dateReturned  = false;
            cal.outputDate    = new Date(0);

            // Finally: The following attributes are used in calendar
            //          functions.  You need do nothing with them here.

            cal.seedDate      = new Date();
            cal.fullInputDate = false;
            cal.activeToday   = true;
            cal.monthSum      = 0;
            cal.days          = new Array();
            cal.triggerEle;
            cal.targetEle;
        };

     // Set up a closure so that any next function can be triggered after the calendar
     // has been closed AND that function can take arguments.

// **************************************
// Set up calendar events on calling page
// **************************************

     if (document.addEventListener)
          {window.addEventListener(  'load',jacsLoader,true);}
     else {window.attachEvent     ('onload',jacsLoader);}

     function jacsLoader()
        {// Define document level event to hide the calendar on click.

         if (document.addEventListener)
              {document.addEventListener('click',hide, false);}
         else {document.attachEvent('onclick',hide);}

         // Create an onBeforeUnload event to handle IE memory leaks.

         if (getEl('jacsIElt7')) {window.attachEvent('onbeforeunload',defeatLeaks);}

         function defeatLeaks()
            {for (var i=0;i<cals.length;i++)
                {// Display the week number column (header and row numbers).
                 getEl(cals[i]+'Week_').style.display='';

                 for (var j=0;j<6;j++) {getEl(cals[i]+'Week_'+j).style.display='';}

                 // Set events to null.

                 getEl(cals[i]+'Now').onclick         = null;
                 getEl(cals[i]+'Now').onmouseover     = null;
                 getEl(cals[i]+'Now').onmouseout      = null;
                 getEl(cals[i]+'ClearButton').onclick = null;

                 var cal    = getEl(cals[i]),
                     cells  = getEl(cals[i]+'Cells').childNodes;

                 for (var j=0;j<cells.length;j++)
                    {var rows = cells[j].childNodes;
                     for (var k=1;k<rows.length;k++)
                        {rows[k].onclick     = null;
                         rows[k].onmouseover = null;
                         rows[k].onmouseout  = null;
                        }
                    }

                 // Set calendar's leaky custom attributes to null.

                 cal.targetEle  = null;
                }
            };
        };

// ****************************************************************************
// Start of Main Private Function Library
// ****************************************************************************

     function showMonth(bias,calId)
        {// 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 cal       = getEl(calId),
             showDate  = new Date(Date.parse(new Date().toDateString())),
             startDate = 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.

         showDate.setHours(12);

         selYears  = getEl(calId+'Years');
         selMonths = getEl(calId+'Months');

         if ( selYears.options.selectedIndex>-1) {cal.monthSum =12*(selYears.options.selectedIndex)+bias;}
         if (selMonths.options.selectedIndex>-1) {cal.monthSum+=selMonths.options.selectedIndex;}

         showDate.setFullYear(cal.baseYear+Math.floor(cal.monthSum/12),(cal.monthSum%12),1);

         // If the Week numbers are displayed, shift the week day names to the right.

         getEl(calId+'Week_').style.display = (cal.weekNumberDisplay)?'':'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)
            {selMonths.style.display = 'inherit';
              selYears.style.display = 'inherit';
            }

         tmp = (12*parseInt((showDate.getFullYear()-cal.baseYear),10)) + parseInt(showDate.getMonth(),10);

         if (tmp > -1 && tmp < (12*cal.dropDownYears))
            {selYears.options.selectedIndex  = Math.floor(cal.monthSum/12);
             selMonths.options.selectedIndex = (cal.monthSum%12);

             curMonth = showDate.getMonth();

             showDate.setDate((((showDate.getDay()-cal.weekStart)<0)?-6:1)+cal.weekStart-showDate.getDay());

             var compareDateValue = new Date(showDate.getFullYear(),showDate.getMonth(),showDate.getDate()).valueOf();

             startDate = new Date(showDate);

             var now = getEl(calId+'Now');

             function nowOutput() {setOutput(dateNow,calId);};

             if (cal.dates.length==0)
                {if (cal.active && cal.activeToday)
                    {now.onclick   = nowOutput;
                     now.className = 'jacsNow';

                     if (getEl('jacsIE'))
                        {now.onmouseover = changeClass;
                         now.onmouseout  = changeClass;
                        }

                     if (document.removeEventListener)
                            {now.removeEventListener('click',stopPropagation,false);}
                     else   {now.detachEvent(      'onclick',stopPropagation);}
                    }
                 else
                    {now.onclick   = null;
                     now.className = 'jacsNowDisabled';

                     if (getEl('jacsIE'))
                        {now.onmouseover = null;
                         now.onmouseout  = null;
                        }

                     if (document.addEventListener)
                            {now.addEventListener('click',stopPropagation,false);}
                     else   {now.attachEvent(   'onclick',stopPropagation);}
                    }
                }
             else
                {for (var k=0;k<cal.dates.length;k++)
                    {if (!cal.activeToday ||
                         (typeof cal.dates[k]=='object' &&
                              ((cal.dates[k].constructor==Date  && dateNow.valueOf() == cal.dates[k].valueOf()) ||
                               (cal.dates[k].constructor==Array && dateNow.valueOf() >= cal.dates[k][0].valueOf() &&
                                                                   dateNow.valueOf() <= cal.dates[k][1].valueOf()
                               )
                              )
                         )
                        )
                        {now.onclick   = (cal.active && cal.valuesEnabled)?nowOutput:null;
                         now.className = (cal.active && cal.valuesEnabled)?'jacsNow':'jacsNowDisabled';

                         if (getEl('jacsIE'))
                            {now.onmouseover = (cal.active && cal.valuesEnabled)?changeClass:null;
                             now.onmouseout  = (cal.active && cal.valuesEnabled)?changeClass:null;
                            }

                         if (cal.active && cal.valuesEnabled)
                            {if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);}
                             else                              {now.detachEvent(      'onclick',stopPropagation);}
                            }
                         else
                            {if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);}
                             else                           {now.attachEvent(   'onclick',stopPropagation);}
                            }

                         break;
                        }
                     else
                        {now.onclick   = (cal.active && cal.valuesEnabled)?null:nowOutput;
                         now.className = (cal.active && cal.valuesEnabled)?'jacsNowDisabled':'jacsNow';

                         if (getEl('jacsIE'))
                            {now.onmouseover = (cal.active && cal.valuesEnabled)?null:changeClass;
                             now.onmouseout  = (cal.active && cal.valuesEnabled)?null:changeClass;
                            }

                         if (cal.active && cal.valuesEnabled)
                            {if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);}
                             else                           {now.attachEvent(   'onclick',stopPropagation);}
                            }
                         else
                            {if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);}
                             else                              {now.detachEvent(      'onclick',stopPropagation);}
                            }
                        }
                    }
                }

             function setOutput(outputDate,calId)
                {
                 var cal = getEl(calId);

                 cal.dateReturned = true;
                 cal.outputDate   = outputDate;
                 
                 cal.lomtecDateTimePicker.setCalendarValue(outputDate);

                 if (cal.dynamic) {hide(calId);}

                 if (cal.onBlurMoveNext)
                    {// if the target element has a tabIndex look for tabIndex+1
                     // if that exists then set the focus to it

                     var tagsToFind = 'INPUT;A;SELECT;TEXTAREA;BUTTON;AREA;OBJECT',
                         found      = false;

                     if (cal.ele.tabIndex>0)
                        {var tags = tagsToFind.split(';');

                         tagsOuterLoop:
                         for (var i=0;tags.length;i++)
                            {elementsByTag = document.getElementsByTagName(tags[i]);

                             for (var j=0;j<elementsByTag.length;j++)
                                {if (elementsByTag[j].tabIndex==(cal.ele.tabIndex+1) && !elementsByTag[j].disabled &&
                                     elementsByTag[j].type!='hidden' && elementsByTag[j].style.display!='none' &&
                                     elementsByTag[j].style.visibility!='hidden')
                                    {elementsByTag[j].focus();
                                     found = true;
                                     break tagsOuterLoop;
                                    }
                                }
                            }
                        }

                     // else do the full search to find the next element

                     if (!found)
                        {// find element tabIndices
                         function orderElements()
                            {var tabOrder  = new Array,
                                 unordered = new Array;

                             function elementArrays(ele)
                                {for (var i=0;i<ele.childNodes.length;i++)
                                    {var tempEle = ele.childNodes[i];
                                     if (tempEle.nodeType==1 && tempEle.style.display!='none' &&
                                         !tempEle.disabled   && tempEle.type!='hidden' &&
                                         tempEle.style.visibility!='hidden')
                                        {if (tagsToFind.indexOf(tempEle.tagName)>-1)
                                            {if (tempEle.tabIndex>0) {tabOrder[tempEle.tabIndex]  = tempEle}
                                             else                    {unordered[unordered.length] = tempEle}
                                            }
                                         elementArrays(tempEle);
                                        }
                                    }
                                };

                             elementArrays(document.body);

                             while (tabOrder.length>0 && tabOrder[0]==null) {tabOrder.shift();}

                             return tabOrder.concat(unordered);
                            };

                         var tabSequenced = orderElements();

                         // find the current element in tabIndex ordered array
                         // and set focus to the next element (or the first if
                         // the current is the last)

                         for (var i=0;i<tabSequenced.length;i++)
                            {if (tabSequenced[i]==cal.targetEle)
                                {if (i<(tabSequenced.length-1)) {tabSequenced[i+1].focus()}
                                 else                           {tabSequenced[0].focus()}
                                 break;
                                }
                            }
                        }
                    }
                 else
                    {if (!cal.targetEle.disabled      && cal.targetEle.style.display!='none' &&
                         cal.targetEle.type!='hidden' && cal.targetEle.style.visibility!='hidden')
                        {cal.targetEle.focus();}
                    }
                };

             function changeClass(evt)
                {var ele = eventTrigger(evt);

                 if (ele.nodeType==3) {ele=ele.parentNode;}

                 if (((evt)?evt.type:event.type)=='mouseover')
                    {switch (ele.className)
                        {case 'jacsCells':
                            ele.className = 'jacsCellsHover';        break;
                         case 'jacsCellsHighlighted':
                            ele.className = 'jacsCellsHighlightedHover';        break;
                         case 'jacsCellsExMonth':
                            ele.className = 'jacsCellsExMonthHover'; break;
                         case 'jacsCellsWeekend':
                            ele.className = 'jacsCellsWeekendHover'; break;
                         case 'jacsCellsHighlightedWeekend':
                            ele.className = 'jacsCellsHighlightedWeekendHover'; break;
                         case 'jacsNow':
                            ele.className = 'jacsNowHover';         break;
                         case 'jacsInputDate':
                            ele.className = 'jacsInputDateHover';
                        }
                    }
                 else
                    {switch (ele.className)
                        {case 'jacsCellsHover':
                            ele.className = 'jacsCells';             break;
                         case 'jacsCellsHighlightedHover':
                            ele.className = 'jacsCellsHighlighted';  break;
                         case 'jacsCellsExMonthHover':
                            ele.className = 'jacsCellsExMonth';      break;
                         case 'jacsCellsWeekendHover':
                            ele.className = 'jacsCellsWeekend';      break;
                         case 'jacsCellsHighlightedWeekendHover':
                            ele.className = 'jacsCellsHighlightedWeekend';      break;
                         case 'jacsNowHover':
                            ele.className = 'jacsNow';              break;
                         case 'jacsInputDateHover':
                            ele.className = 'jacsInputDate';
                        }
                    }
                 return true;
                };

             function eventTrigger(evt)
                {if (!evt) {evt = event;}
                 return evt.target||evt.srcElement;
                };

             function weekNumber(inDate)
                {// The base day in the week of the input date
                 var inDateWeekBase = new Date(inDate);

                 inDateWeekBase.setDate(inDateWeekBase.getDate() - inDateWeekBase.getDay() + cal.weekNumberBaseDay +
                                            ((inDate.getDay() > cal.weekNumberBaseDay)?7:0));

                 // The first Base Day in the year
                 var firstBaseDay = new Date(inDateWeekBase.getFullYear(),0,1);

                 firstBaseDay.setDate(firstBaseDay.getDate() - firstBaseDay.getDay() + cal.weekNumberBaseDay);

                 if (firstBaseDay<new Date(inDateWeekBase.getFullYear(),0,1))
                    {firstBaseDay.setDate(firstBaseDay.getDate()+7);}

                 // Start of Week 01
                 var startWeekOne = new Date(firstBaseDay - cal.weekNumberBaseDay + inDate.getDay());

                 if (startWeekOne>firstBaseDay) {startWeekOne.setDate(startWeekOne.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 weekNo = '0'+(Math.round((inDateWeekBase - firstBaseDay)/604800000,0)+1);

                 // Return the last two characters in the week number string

                 return weekNo.substring(weekNo.length-2,weekNo.length);
                };

             // walk the DOM to display the dates.

             var cells = getEl(calId+'Cells').childNodes;

             for (var i=0;i<cells.length;i++)
                {var rows = cells[i];
                 if (rows.nodeType==1 && rows.tagName=='TR')
                    {tmpEl = rows.childNodes[0];
                     if (cal.weekNumberDisplay)
                          {//Calculate the week number using showDate
                           tmpEl.innerHTML = weekNumber(showDate);
                           tmpEl.style.borderColor =
                               (tmpEl.currentStyle)
                                    ?tmpEl.currentStyle['backgroundColor']
                                    :(document.defaultView.getComputedStyle)
                                        ?document.defaultView.getComputedStyle(tmpEl,null).backgroundColor
                                        :'';
                           tmpEl.style.display = '';
                          }
                     else  {tmpEl.style.display='none';}

                     for (var j=1;j<rows.childNodes.length;j++)
                        {var cols = rows.childNodes[j];
                         if (cols.nodeType==1 && cols.tagName=='TD')
                            {rows.childNodes[j].innerHTML = showDate.getDate();

                             var cell = rows.childNodes[j];

                             cell.style.visibility = (cal.outOfMonthHide &&
                                                      (showDate < (new Date(showDate.getFullYear(),curMonth,1,showDate.getHours())) ||
                                                       showDate > (new Date(showDate.getFullYear(),curMonth+1,0,showDate.getHours()))
                                                      )
                                                     )?'hidden':'inherit';

                             // Disable if the outOfRangeDisable option has been set and the current date
                             // is out of range or the cal.valuesEnabled option is true.
                             var disabled = cal.valuesEnabled;

                             if ( cal.range!=null ){
                                 if ( cal.range.length==2 && compareDateValue < cal.range[0].valueOf() || compareDateValue >= cal.range[1].valueOf() ) disabled = true;
                             }
                             if ((cal.outOfRangeDisable && (showDate < (new Date(cal.baseYear,0,1,12)) ||
                                                            showDate > (new Date(cal.baseYear+cal.dropDownYears,0,0,12))
                                                           )
                                 ) ||
                                 (cal.outOfMonthDisable && (showDate < (new Date(showDate.getFullYear(),curMonth,1,showDate.getHours())) ||
                                                            showDate > (new Date(showDate.getFullYear(),curMonth+1,0,showDate.getHours()))
                                                           )
                                 )
                                ) {disabled = true;}
                             else
                                {if ((cal.days.join().search(((j-1+(7*(i*cells.length/6))+cal.weekStart)%7))>-1) ||
                                      !cal.dayCells[j-1+(7*((i*cells.length)/6))]
                                    )   {disabled = !cal.valuesEnabled;} // Set (Disable or Enable) if the day is passed as a parameter of JACS.show
                                 else   {for (var k=0;k<cal.dates.length;k++)
                                            {if (typeof cal.dates[k]=='object' &&
                                                 ((cal.dates[k].constructor==Date  && compareDateValue == cal.dates[k].valueOf()) ||
                                                  (cal.dates[k].constructor==Array && compareDateValue >= cal.dates[k][0].valueOf() &&
                                                                                      compareDateValue <= cal.dates[k][1].valueOf()
                                                  )
                                                 )
                                                )
                                                {disabled = !cal.valuesEnabled;
                                                 break;
                                                }
                                            }
                                        }
                                }

                             if (disabled)
                                {rows.childNodes[j].onclick = null;

                                 if (getEl('jacsIE'))
                                    {rows.childNodes[j].onmouseover = null;
                                     rows.childNodes[j].onmouseout  = null;
                                    }

                                 cell.className=
                                    (showDate.getMonth()!=curMonth)
                                        ?'jacsCellsExMonthDisabled'
                                        :(cal.fullInputDate &&
                                          compareDateValue==
                                          cal.seedDate.valueOf())
                                            ?'jacsInputDateDisabled'
                                            :(showDate.getDay()%6==0)
                                                ?'jacsCellsWeekendDisabled'
                                                :'jacsCellsDisabled';

                                 cell.style.borderColor =
                                     (cal.formatTodayCell && showDate.toDateString()==dateNow.toDateString())
                                        ?cal.todayCellBorderColour
                                        :(cell.currentStyle)
                                            ?cell.currentStyle['backgroundColor']
                                            :(document.defaultView.getComputedStyle)
                                                ?document.defaultView.getComputedStyle(cell,null).backgroundColor
                                                :'';
                                }
                             else
                                {function cellOutput(evt)
                                    {var ele = eventTrigger(evt),
                                         outputDate = new Date(startDate);

                                     if (ele.nodeType==3) ele=ele.parentNode;

                                     outputDate.setDate(startDate.getDate() +
                                        parseInt(ele.id.substr(calId.length+5),10));

                                     setOutput(outputDate,calId);
                                    };

                                 if (cal.active)
                                    {rows.childNodes[j].onclick=cellOutput;}

                                 if (getEl('jacsIE'))
                                    {rows.childNodes[j].onmouseover = changeClass;
                                     rows.childNodes[j].onmouseout  = changeClass;
                                    }

                                 var highlighted = false;

                                 for (var k=0;k<cal.highlightDates.length;k++)
                                    {if (typeof cal.highlightDates[k]=='object' &&
                                         ((cal.highlightDates[k].constructor==Date  &&
                                           compareDateValue == cal.highlightDates[k].valueOf()) ||
                                          (cal.highlightDates[k].constructor==Array &&
                                           compareDateValue >= cal.highlightDates[k][0].valueOf() &&
                                           compareDateValue <= cal.highlightDates[k][1].valueOf()
                                          )
                                         )
                                        )
                                        {highlighted = true;
                                         break;
                                        }
                                    }

                                 cell.className=
                                     (showDate.getMonth()!=curMonth)
                                        ?'jacsCellsExMonth'
                                        :(cal.fullInputDate &&
                                          compareDateValue==
                                          cal.seedDate.valueOf())
                                            ?'jacsInputDate'
                                            :(showDate.getDay()%6==0)
                                                ?(highlighted)?'jacsCellsHighlightedWeekend':'jacsCellsWeekend'
                                                :(highlighted)?'jacsCellsHighlighted':'jacsCells';

                                 cell.style.borderColor =
                                     (cal.formatTodayCell && showDate.toDateString()==dateNow.toDateString())
                                        ?cal.todayCellBorderColour
                                        :(cell.currentStyle)
                                            ?cell.currentStyle['backgroundColor']
                                            :(document.defaultView.getComputedStyle)
                                                ?document.defaultView.getComputedStyle(cell,null).backgroundColor
                                                :'';
                               }

                             showDate.setDate(showDate.getDate()+1);
                             compareDateValue = new Date(showDate.getFullYear(),
                                                         showDate.getMonth(),
                                                         showDate.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)
            {selMonths.style.display = 'inline';
              selYears.style.display = 'inline';
             cal.style.visibility = 'hidden';
             cal.style.visibility = 'inherit';
            }
        };

     function hide(instanceID)
        {if (typeof instanceID=='object')
                {for (var i=0;i<cals.length;i++) {hideOne(cals[i]);}}
         else   {hideOne(instanceID);}

         function hideOne(id)
            {cal = getEl(id);

             if (cal!=null && cal.dynamic)
                {cal.style.visibility = 'hidden';
                 getEl(id+'Iframe').style.visibility='hidden';
                }
            };
        };

     function stopPropagation(evt)
       {
        if (evt.stopPropagation)
             {if (evt.target!=evt.currentTarget) {evt.stopPropagation(); evt.preventDefault();}}
        else {evt.cancelBubble = true;}
       };

// *********************************
//   End of Private Function Library
// *********************************
// Start of Public  Function Library
// *********************************

     return {show: function(element,src)
                {// Check the type of any additional parameters.
                 // The optional string parameter is a calendar ID,
                 // Take any remaining parameters as day numbers to be handled
                 // (enabled/disabled) according to the setting of the
                 // calendar's  valuesEnabled  attribute.
                 // 0 = Sunday through to 6 = Saturday.

                 //modification from using this object from lomtecDateTimePicker
                     var ele = element.getCalendarControl();
                     
                     var dynamic = true;
                     var calId = 'jacs';
                     var min = 2;
                     
                     // Stop the click event that opens the calendar
                     // from bubbling up to the document-level event
                     // handler that hides it!

                     var source = src;
                     if (!source) {source = window.event;}

                     if (source.tagName)    // Second parameter isn't an event it's an element
                        {var sourceEle = source;
                         if (getEl('jacsIE'))  {window.event.cancelBubble = true;}
                         else {sourceEle.parentNode.addEventListener('click',stopPropagation,false);}
                        }
                     else   // Second parameter is an event
                        {var event = source;
                         // Stop the click event that opens the calendar from bubbling up to
                         // the document-level event handler that hides it!
                         var sourceEle = (event.target)?event.target:event.srcElement;
                         if (event.stopPropagation) {event.stopPropagation();}
                         else                       {event.cancelBubble = true;}
                        }
                     


                 // Add event handlers to the return element and its parent.
                 // This helps the script to support tab sequences and focus events.

                 if (document.addEventListener)
                        {ele.addEventListener('keydown',hideOnTab,false);
                         ele.parentNode.addEventListener('click',stopPropagation,false);}
                 else   {ele.attachEvent('onkeydown',hideOnTab);
                         if (ele.parentNode!=document.body)
                            {ele.parentNode.attachEvent('onclick',stopPropagation);}
                        }

                 function hideOnTab(evt)
                    {if (!evt) { evt = window.event;}
                     if ((evt.keyCode||evt.which)==9) {hide(calId);}
                    };

                 // Create the calendar structure. One is enough unless you want more
                 // than one calendar visible on the page at one time.  If you DO need
                 // more, you can create as many as you like but each must have a unique
                 // ID.

                 // The first parameter of JACS.make is the ID of the calendar. The
                 // second is a boolean that determines whether the calendar is to be
                 // static on the page (assigned to a single input field and always
                 // visible) or dynamic (shown and hidden on events and can be assigned
                 // to any number of input fields).

                 if (!getEl(calId)) {lomtec.Controls.UI.Script.JACS.make(calId,dynamic);}

                 cal = getEl(calId);

                 // If the calendar has been triggered using an onfocus event,
                 // and the script actively returns the focus to the target
                 // element (i.e. when cal.onBlurMoveNext = false). We need
                 // to kill the event.

                 if (event)
                    {if (event.type == 'focus' && cal.dateReturned && !cal.onBlurMoveNext && cal.prevEventType == 'focus')
                        {stopPropagation(event); cal.prevEventType = ''; cal.dateReturned = false; return false;}
                     cal.prevEventType = event.type;
                    }

                 cal.triggerEle = sourceEle;

                 cal.dateReturned = false;
                 cal.activeToday  = true;

                 //set LomtecDateTimePicker to object 
                 cal.lomtecDateTimePicker = element;

                 // Set calendar range
                 var dateRange = element.getDateRange();  
                 if(dateRange != null) {
                    cal.range = dateRange;
                    if (dateNow.valueOf() < cal.range[0].valueOf() || dateNow.valueOf() >= cal.range[1].valueOf()){
                          cal.activeToday = false;
                    }
                    
                    cal.baseYear  = cal.range[0].getFullYear();
                    cal.dropDownYears = cal.range[1].getFullYear() - cal.range[0].getFullYear();
                    if(cal.dropDownYears < 1 ) cal.dropDownYears = 1;
                 }

                 
                 // Set enabled/disabled days
                 var disabledDays = element.getDisabledDays();  
                 if(disabledDays != null) cal.days  = disabledDays; 
                
                 // Set disabled Dates
                 var disabledDates = element.getDisabledDates();  
                 if(disabledDates != null) cal.dates = disabledDates;
                
                 //Set highlight Dates 
                 var highlightDates = element.getHighlightDates();
                 if (highlightDates != null) cal.highlightDates = highlightDates;
                 
                 for (var i=0;i<cal.days.length;i++)
                    {if (dateNow.getDay()==cal.days[i]%7) {cal.activeToday = false; break;}}

                 //   If no value is preset then the seed date is
                 //      Today (when today is in range) OR
                 //      The middle of the date range.

                 cal.seedDate = dateNow;

                 // Find the date and Strip space characters from start and
                 // end of date input.

                 var dateValue = '';
                 dateValue = element.getCalendarValue();
                 
                 // Set the year range
                 var yearOptions = getEl(calId+'Years').options;

                 if (yearOptions.length==0 || yearOptions[0].value!=cal.baseYear)
                    {yearOptions.length = 0;
                     for (var i=0;i<cal.dropDownYears;i++) {yearOptions[i] = new Option((cal.baseYear+i),(cal.baseYear+i));}
                    }

                 if (dateValue.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.
                     cal.fullInputDate=false;
                     if (cal.range != null && cal.range.length==2){
                        if( dateNow.valueOf() >= cal.range[0].valueOf() && dateNow.valueOf() <= cal.range[1].valueOf() ) cal.seedDate = dateNow;
                        else cal.seedDate = cal.range[0];
                     }
                     else if ((new Date(cal.baseYear+cal.dropDownYears,0,0))<cal.seedDate ||
                         (new Date(cal.baseYear,0,1))                  >cal.seedDate
                        )
                        {cal.seedDate = new Date(cal.baseYear+Math.floor(cal.dropDownYears / 2), 5, 1);}
                    }
                 else
                    {function inputFormat()
                        {var seed = new Array(),
                             input = dateValue.split(new RegExp('[\\'+cal.delimiters.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 (input[0]!=null)
                            {if (input[0].length==0)              {input.splice(0,1);}
                             if (input[input.length-1].length==0) {input.splice(input.length-1,1);}
                            }

                         cal.fullInputDate = false;

                         cal.dateFormat = cal.dateFormat.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 (cal.dateFormat.search(template[i])>-1)
                                {result[cal.dateFormat.search(template[i])] = template[i];}
                            }

                         cal.dateSequence = result.join('');

                         // Separate the elements of the date input
                         switch (input.length)
                            {case 1:
                                {// Year only entry or undelimited date format

                                 if (cal.dateFormat.indexOf('Y')>-1 &&
                                     input[0].length>cal.dateFormat.lastIndexOf('Y'))
                                    {seed[0] = parseInt(input[0].substring(cal.dateFormat.indexOf('Y'),
                                                                           cal.dateFormat.lastIndexOf('Y')+1),10);
                                    }
                                 else   {seed[0] = parseInt(input[0],10);}

                                 if (cal.dateFormat.indexOf('M')>-1 &&
                                     input[0].length>cal.dateFormat.lastIndexOf('M'))
                                    {seed[1] = input[0].substring(cal.dateFormat.indexOf('M'),
                                                                  cal.dateFormat.lastIndexOf('M')+1);
                                    }
                                 else   {seed[1] = cal.defaultToCurrentMonth?(dateNow.getMonth()+1).toString():'6';}

                                 if (cal.dateFormat.indexOf('D')>-1 &&
                                     input[0].length>cal.dateFormat.lastIndexOf('D'))
                                    {seed[2] = parseInt(input[0].substring(cal.dateFormat.indexOf('D'),
                                                                           cal.dateFormat.lastIndexOf('D')+1),10);
                                    }
                                 else   {seed[2] = 1;}

                                 if (input[0].length==cal.dateFormat.length)    {cal.fullInputDate = true;}
                                 break;
                                }
                             case 2:
                                {// Year and Month entry
                                 seed[0] = parseInt(input[cal.dateSequence.replace(/D/i,'').search(/Y/i)],10);  // Year
                                 seed[1] = input[cal.dateSequence.replace(/D/i,'').search(/M/i)];               // Month
                                 seed[2] = 1;                                                                        // Day
                                 break;
                                }
                             case 3:
                                {// Day Month and Year entry
                                 seed[0] = parseInt(input[cal.dateSequence.search(/Y/i)],10);  // Year
                                 seed[1] = input[cal.dateSequence.search(/M/i)];               // Month
                                 seed[2] = parseInt(input[cal.dateSequence.search(/D/i)],10);  // Day
                                 cal.fullInputDate = true;
                                 break;
                                }
                             default:
                                {// A stuff-up has led to more than three elements in the date.
                                 seed[0] = 0;     // Year
                                 seed[1] = 0;     // Month
                                 seed[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 expValDay    = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'),
                             expValMonth  = new RegExp('^(0?[1-9]|1[0-2]|'+cal.monthNames.join('|')+')$','i'),
                             expValYear   = new RegExp('^([0-9]{1,2}|[0-9]{4})$');

                         // Apply validation and report failures

                         if (expValYear.exec(seed[0]) ==null ||
                             expValMonth.exec(seed[1])==null ||
                             expValDay.exec(seed[2])  ==null
                            )
                            {if (cal.showInvalidDateMsg)
                                {alert(cal.invalidDateMsg + cal.invalidAlert[0] + dateValue + cal.invalidAlert[1]);}
                             seed[0] = cal.baseYear + Math.floor(cal.dropDownYears/2);                   // Year
                             seed[1] = cal.defaultToCurrentMonth?(dateNow.getMonth()+1).toString():'6';  // Month
                             seed[2] = 1;                                                                // Day
                             cal.fullInputDate = false;
                            }

                         // Return the Year  in seed[0]
                         //            Month in seed[1]
                         //            Day   in seed[2]

                         return seed;
                        };

                     // Parse the string into an array using the allowed delimiters

                     seedDate = inputFormat();

                     // 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 (seedDate[0]<100) {seedDate[0] += (seedDate[0]>50)?1900:2000;}

                     // Check whether the month is in digits or an abbreviation

                     if (seedDate[1].search(/\d+/)<0)
                        {for (i=0;i<cal.monthNames.length;i++)
                            {if (seedDate[1].toUpperCase()==cal.monthNames[i].toUpperCase())
                                {seedDate[1]=i+1;
                                 break;
                                }
                            }
                        }

                     cal.seedDate = new Date(seedDate[0],seedDate[1]-1,seedDate[2]);
                    }

                 // Test that we have arrived at a valid date

                 if (isNaN(cal.seedDate))
                    {if (cal.showInvalidDateMsg)
                        {alert(cal.invalidDateMsg + cal.invalidAlert[0] + dateValue + cal.invalidAlert[1]);}
                     cal.seedDate = new Date(cal.baseYear + Math.floor(cal.dropDownYears/2),5,1);
                     cal.fullInputDate = false;
                    }
                 else
                    {// Test that the date is within range,
                     // if not then set date to a sensible date in range.

                     if ((new Date(cal.baseYear,0,1))>cal.seedDate)
                        {if (cal.strict && cal.showOutOfRangeMsg) {alert(cal.outOfRangeMsg);}
                         cal.seedDate = new Date(cal.baseYear,0,1);
                         cal.fullInputDate=false;
                        }
                     else
                        {if ((new Date(cal.baseYear+cal.dropDownYears,0,0))<cal.seedDate)
                            {if (cal.strict && cal.showOutOfRangeMsg) {alert(cal.outOfRangeMsg);}
                             cal.seedDate = new Date(cal.baseYear + Math.floor(cal.dropDownYears),-1,1);
                             cal.fullInputDate=false;
                            }
                         else
                            {if (cal.strict && cal.fullInputDate &&
                                  (cal.seedDate.getDate()     !=seedDate[2] ||
                                   (cal.seedDate.getMonth()+1)!=seedDate[1] ||
                                   cal.seedDate.getFullYear() !=seedDate[0]
                                  )
                                )
                                {if (cal.showDoesNotExistMsg) {alert(cal.doesNotExistMsg);}
                                 cal.seedDate = new Date(cal.seedDate.getFullYear(),cal.seedDate.getMonth()-1,1);
                                 cal.fullInputDate=false;
                                }
                            }
                        }
                    }

                 // Test the chosen dates for validity
                 // Give error message if not valid

                 for (var i=0;i<cal.dates.length;i++)
                    {if (!((typeof cal.dates[i]=='object') && (cal.dates[i].constructor==Date)))
                        {if ((typeof cal.dates[i]=='object') && (cal.dates[i].constructor==Array))
                            {var pass = true;

                             if (cal.dates[i].length!=2)
                                {if (cal.showRangeSettingError)
                                    {alert(cal.rangeSettingError[0] + cal.dates[i] + cal.rangeSettingError[1]);}
                                 pass = false;
                                }
                             else
                                {for (var j=0;j<cal.dates[i].length;j++)
                                    if (!((typeof cal.dates[i][j]=='object') && (cal.dates[i][j].constructor==Date)))
                                        {if (cal.showRangeSettingError)
                                            {alert(cal.dateSettingError[0] + cal.dates[i][j] + cal.dateSettingError[1]);}
                                         pass = false;
                                        }
                                }

                             if (pass && (cal.dates[i][0]>cal.dates[i][1])) {cal.dates[i].reverse();}
                            }
                         else
                            {if (cal.showRangeSettingError)
                                {alert(cal.dateSettingError[0] + cal.dates[i] + cal.dateSettingError[1]);}
                            }
                        }
                    }

                 // Set language-dependent values

                 getEl(calId+'DragText').innerHTML = cal.drag;

                 var monthOptions = getEl(calId+'Months').options,  months = '';

                 if (monthOptions.length>0) {for (var i=0;i<monthOptions.length;i++) {months += monthOptions[i].value+',';}}

                 if (monthOptions.length==0 || (cal.monthNames.join()+',')!=months)
                    {monthOptions.length = 0;

                     if (cal.monthNames.length<monthOptions.length) {monthOptions.length = cal.monthNames.length;}

                     for (var i=0;i<cal.monthNames.length;i++)
                        {if (i>monthOptions.length-1)
                              {monthOptions[i] = new Option(cal.monthNames[i],cal.monthNames[i]);}
                         else {monthOptions[i].innerHTML = cal.monthNames[i];}
                        }
                    }

                 for (var i=0;i<cal.weekInits.length;i++)
                    {getEl(calId+'WeekInit'+i).innerHTML = cal.weekInits[(i+cal.weekStart)%cal.weekInits.length];}

                 if (((new Date(cal.baseYear + cal.dropDownYears, 0, 0)) > dateNow &&
                      (new Date(cal.baseYear, 0, 0))                     < dateNow) ||
                     (cal.clearButton && (ele.readOnly || ele.disabled))
                    )   {getEl(calId+'Now').innerHTML = cal.today+' '+dateNow.jacsFormat(cal.dateDisplayFormat,cal.monthNames);
                         getEl(calId+'ClearButton').value   = cal.clear;
                         getEl(calId+'Foot').style.display = '';

                         if ((new Date(cal.baseYear + cal.dropDownYears, 0, 0)) > dateNow &&
                             (new Date(cal.baseYear, 0, 0))                     < dateNow)
                                {getEl(calId+'Now').style.display = '';
                                 if (cal.clearButton && (ele.readOnly || ele.disabled))
                                        {getEl(calId+'Clear').style.display   = '';
                                         getEl(calId+'Clear').style.textAlign = 'left';
                                         getEl(calId+'Now'  ).style.textAlign = 'right';
                                        }
                                 else   {getEl(calId+'Clear').style.display   = 'none';
                                         getEl(calId+'Now'  ).style.textAlign = 'center';
                                        }
                                }
                         else   {getEl(calId+'Clear').style.textAlign = 'center';
                                 getEl(calId+'Clear').style.display   = '';
                                 getEl(calId+'Now'  ).style.display   = 'none';
                                }
                        }
                 else   {getEl(calId+'Foot').style.display = 'none';}

                 // Calculate the number of months that the entered (or
                 // defaulted) month is after the start of the allowed
                 // date range.
                 cal.monthSum =  12*(cal.seedDate.getFullYear() - cal.baseYear) + cal.seedDate.getMonth();

                 // Set the drop down boxes.
                 getEl(calId+'Years').options.selectedIndex  = Math.floor(cal.monthSum/12);
                 getEl(calId+'Months').options.selectedIndex = (cal.monthSum%12);

                 getEl(calId).ele = ele;

                 // Display the month
                 showMonth(0,calId);

                 // Remember the Element
                 cal.targetEle = ele;

                 // Position the calendar box.
                 if (dynamic)
                    {// Check whether or not dragging is allowed and display drag handle if necessary
                     getEl(calId+'Drag').style.display = (cal.allowDrag)?'':'none';

                     var offsetTop  = parseInt(ele.offsetTop ,10),
                         offsetLeft = parseInt(ele.offsetLeft,10);

                     // 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.
                     if (!window.opera)
                         {while (ele.tagName!='BODY' && ele.tagName!='HTML')
                             {offsetTop  -= parseInt(ele.scrollTop, 10);
                              offsetLeft -= parseInt(ele.scrollLeft,10);
                              ele = ele.parentNode;
                             }
                          ele = cal.targetEle;
                         }

                     while (ele.tagName!='BODY' && ele.tagName!='HTML')
                        {ele = ele.offsetParent;
                         offsetTop  += parseInt(ele.offsetTop, 10);
                         offsetLeft += parseInt(ele.offsetLeft,10);
                        }

                     ele = cal.targetEle;

                     var eleOffsetTop  = offsetTop,
                         eleOffsetLeft = offsetLeft;

                     if (cal.xBase.length>0)
                            {if (isNaN(cal.xBase))
                                    {cal.xBase = cal.xBase.toUpperCase();
                                     offsetLeft += (cal.xBase=='R')
                                                        ?parseInt(ele.offsetWidth,10)
                                                        :(cal.xBase=='M')?Math.round(parseInt(ele.offsetWidth,10)/2):0;
                                    }
                             else   {offsetLeft += parseInt(cal.xBase,10);}
                            }

                     if (cal.yBase.length>0)
                            {if (isNaN(cal.yBase))
                                    {cal.yBase  = cal.yBase.toUpperCase();
                                     offsetTop += (cal.yBase=='B')
                                                    ?parseInt(ele.offsetHeight,10)
                                                    :(cal.yBase=='M')?Math.round(parseInt(ele.offsetHeight,10)/2):0;
                                    }
                             else   {offsetTop += parseInt(cal.yBase,10);}
                            }
                     else   {offsetTop += parseInt(ele.offsetHeight,10);}

                     if (cal.xPosition.length>0)
                            {if (isNaN(cal.xPosition))
                                    {cal.xPosition = cal.xPosition.toUpperCase();
                                     offsetLeft -= (cal.xPosition=='R')
                                                        ?parseInt(cal.offsetWidth,10)
                                                        :(cal.xPosition=='M')?Math.round(parseInt(cal.offsetWidth,10)/2):0;
                                    }
                             else   {offsetLeft += parseInt(cal.xPosition,10);}
                            }

                     if (cal.yPosition.length>0)
                            {if (isNaN(cal.yPosition))
                                    {cal.yPosition = cal.yPosition.toUpperCase();

                                     offsetTop -= (cal.yPosition=='B')
                                                        ?parseInt(cal.offsetHeight,10)
                                                        :(cal.yPosition=='M')?Math.round((parseInt(cal.offsetHeight,10))/2):0;
                                    }
                             else   {offsetTop += parseInt(cal.yPosition,10);}
                            }

                     if (cal.autoPosition)
                        {var width      = parseInt(cal.offsetWidth, 10),
                             height     = parseInt(cal.offsetHeight,10),
                             windowLeft =
                                 (document.body && document.body.scrollLeft)
                                      ?document.body.scrollLeft                  //DOM compliant
                                      :(document.documentElement && document.documentElement.scrollLeft)
                                          ?document.documentElement.scrollLeft   //IE6+ standards compliant
                                          :0,                                    //Failed
                             windowWidth =
                                  (typeof(innerWidth) == 'number')
                                      ?innerWidth                                //DOM compliant
                                      :(document.documentElement && document.documentElement.clientWidth)
                                          ?document.documentElement.clientWidth  //IE6+ standards compliant
                                          :(document.body && document.body.clientWidth)
                                              ?document.body.clientWidth         //IE non-compliant
                                              :0,                                //Failed
                             windowTop =
                                  (document.body && document.body.scrollTop)
                                      ?document.body.scrollTop                   //DOM compliant
                                      :(document.documentElement && document.documentElement.scrollTop)
                                          ?document.documentElement.scrollTop    //IE6+ standards compliant
                                          :0,                                    //Failed
                             windowHeight =
                                  (typeof(innerHeight) == 'number')
                                      ?innerHeight                               //DOM compliant
                                      :(document.documentElement && document.documentElement.clientHeight)
                                          ?document.documentElement.clientHeight //IE6+ standards compliant
                                          :(document.body && document.body.clientHeight)
                                              ?document.body.clientHeight        //IE non-compliant
                                              :0;                                //Failed

                         if (eleOffsetLeft + parseInt(ele.offsetWidth,10) - width >= windowLeft &&
                             offsetLeft + width > windowLeft + windowWidth
                            )       {offsetLeft = eleOffsetLeft + parseInt(ele.offsetWidth,10) - width;}
                         else if (eleOffsetLeft >= windowLeft && offsetLeft < windowLeft
                                 )  {offsetLeft = eleOffsetLeft;}

                         if (eleOffsetTop - height >= windowTop &&
                             offsetTop + height > windowTop + windowHeight
                            )       {offsetTop = eleOffsetTop - height;}
                         else if (offsetTop + height <= windowTop + windowHeight && offsetTop < windowTop)
                                    {offsetTop = eleOffsetTop + parseInt(ele.offsetHeight,10);}
                        }

                     cal.style.top  = offsetTop+'px';
                     cal.style.left = offsetLeft+'px';

                     getEl(calId+'Iframe').style.top    = offsetTop +'px';
                     getEl(calId+'Iframe').style.left   = offsetLeft+'px';

                     getEl(calId+'Iframe').style.width  = (cal.offsetWidth -(getEl('jacsIE')?2:4))+'px';
                     getEl(calId+'Iframe').style.height = (cal.offsetHeight-(getEl('jacsIE')?2:4))+'px';
                     getEl(calId+'Iframe').style.visibility = 'inherit';
                    }

                 // Show it on the page
                 cal.style.visibility = 'inherit';
                },

             make: function (calId)
                {cals.push(calId);

                 var dynamic = (typeof arguments[1]=='boolean')?arguments[1]:true;

                 TABLEjacs           = document.createElement('table');
                 TABLEjacs.id        = calId;
                 TABLEjacs.dynamic   = dynamic;
                 TABLEjacs.className = (dynamic)?'jacs':'jacsStatic';

                 calAttributes(TABLEjacs);

                 if (dynamic) {TABLEjacs.style.zIndex = TABLEjacs.zIndex+1;}

                 function cancel(evt)
                    {if (TABLEjacs.clickToHide) {hide(calId);}
                     stopPropagation(evt);
                    };

                 TBODYjacs                 = document.createElement('tbody');
                 TRjacs1                   = document.createElement('tr');
                 TRjacs1.className         = 'jacs';
                 TDjacs1                   = document.createElement('td');
                 TDjacs1.className         = 'jacs';
                 TABLEjacsHead             = document.createElement('table');
                 TABLEjacsHead.id          = calId+'Head';
                 TABLEjacsHead.cellSpacing = '0';
                 TABLEjacsHead.cellPadding = '0';
                 TABLEjacsHead.className   = 'jacsHead';
                 TABLEjacsHead.width       = '100%';

                 TBODYjacsHead             = document.createElement('tbody');

                 TRjacsDrag                = document.createElement('tr');
                 TRjacsDrag.id             = calId+'Drag';
                 TRjacsDrag.style.display  = 'none';

                 TDjacsDrag                = document.createElement('td');
                 TDjacsDrag.className      = 'jacsDrag';
                 TDjacsDrag.colSpan        = '4';

                 function beginDrag(evt)
                    {var elToDrag = getEl(calId);

                     var deltaX    = evt.clientX,
                         deltaY    = evt.clientY,
                         offsetEle = elToDrag;

                     while (offsetEle.tagName!='BODY' && offsetEle.tagName!='HTML')
                        {deltaX   -= parseInt(offsetEle.offsetLeft,10);
                         deltaY   -= parseInt(offsetEle.offsetTop ,10);
                         offsetEle = offsetEle.offsetParent;
                        }

                     if (document.addEventListener)
                            {elToDrag.addEventListener('mousemove',moveHandler,true);
                             elToDrag.addEventListener('mouseup',    upHandler,true);
                            }
                     else   {elToDrag.attachEvent('onmousemove', moveHandler);
                             elToDrag.attachEvent('onmouseup',     upHandler);
                             elToDrag.setCapture();
                            }

                     stopPropagation(evt);

                     function moveHandler(evt)
                        {if (!evt) {evt = window.event;}

                         elToDrag.style.left = (evt.clientX-deltaX)+'px';
                         elToDrag.style.top  = (evt.clientY-deltaY)+'px';

                         getEl(calId+'Iframe').style.left = (evt.clientX-deltaX)+'px';
                         getEl(calId+'Iframe').style.top  = (evt.clientY-deltaY)+'px';

                         stopPropagation(evt);
                        };

                     function upHandler(evt)
                        {if (!evt) {evt = window.event;}

                         if (document.removeEventListener)
                                {elToDrag.removeEventListener('mousemove',moveHandler,true);
                                 elToDrag.removeEventListener(  'mouseup',  upHandler,true);
                                }
                         else   {elToDrag.detachEvent('onmouseup',    upHandler);
                                 elToDrag.detachEvent('onmousemove',moveHandler);
                                 elToDrag.releaseCapture();
                                }

                         stopPropagation(evt);
                        };
                    };

                 DIVjacsDragText           = document.createElement('span');
                 DIVjacsDragText.id        = calId+'DragText';

                 TRjacsHead                = document.createElement('tr');
                 TRjacsHead.className      = 'jacsHead';

                 TDjacsHead1               = document.createElement('td');
                 TDjacsHead1.className     = 'jacsHead';

                 INPUTjacsHead1            = document.createElement('input');
                 INPUTjacsHead1.className  = 'jacsHead';
                 INPUTjacsHead1.id         = calId+'HeadLeft';
                 INPUTjacsHead1.type       = 'button';
                 INPUTjacsHead1.tabIndex   = '-1';
                 INPUTjacsHead1.value      = '<';
                 INPUTjacsHead1.onclick    = function() {showMonth(-1,calId);}

                 TDjacsHead2               = document.createElement('td');
                 TDjacsHead2.className     = 'jacsHead';

                 SELECTjacsHead2           = document.createElement('select');
                 SELECTjacsHead2.className = 'jacsHead';
                 SELECTjacsHead2.id        = calId+'Months';
                 SELECTjacsHead2.tabIndex  = '-1';
                 SELECTjacsHead2.onchange  = function() {showMonth(0,calId);}

                 TDjacsHead3               = document.createElement('td');
                 TDjacsHead3.className     = 'jacsHead';

                 SELECTjacsHead3           = document.createElement('select');
                 SELECTjacsHead3.className = 'jacsHead';
                 SELECTjacsHead3.id        = calId+'Years';
                 SELECTjacsHead3.tabIndex  = '-1';
                 SELECTjacsHead3.onchange  = function() {showMonth(0,calId);}

                 TDjacsHead4               = document.createElement('td');
                 TDjacsHead4.className     = 'jacsHead';

                 INPUTjacsHead4            = document.createElement('input');
                 INPUTjacsHead4.className  = 'jacsHead';
                 INPUTjacsHead4.id         = calId+'HeadRight';
                 INPUTjacsHead4.type       = 'button';
                 INPUTjacsHead4.tabIndex   = '-1';
                 INPUTjacsHead4.value      = '>';
                 INPUTjacsHead4.onclick    = function() {showMonth(1,calId);}

                 TRjacs2                   = document.createElement('tr');
                 TRjacs2.className         = 'jacs';

                 TDjacs2                   = document.createElement('td');
                 TDjacs2.className         = 'jacs';

                 TABLEjacsCells            = document.createElement('table');
                 TABLEjacsCells.className  = 'jacsCells';
                 TABLEjacsCells.align      = 'center';
                 TABLEjacsCells.width      = '100%';

                 THEADjacsCells            = document.createElement('thead');
                 TRjacsCells               = document.createElement('tr');
                 TDjacsCells               = document.createElement('td');
                 TDjacsCells.className     = 'jacsWeekNumberHead';
                 TDjacsCells.id            = calId+'Week_';

                 TABLEjacs.appendChild(TBODYjacs);
                 TBODYjacs.appendChild(TRjacs1);
                    TRjacs1.appendChild(TDjacs1);
                        TDjacs1.appendChild(TABLEjacsHead);
                            TABLEjacsHead.appendChild(TBODYjacsHead);
                                 TBODYjacsHead.appendChild(TRjacsDrag);
                                    TRjacsDrag.appendChild(TDjacsDrag);
                                        TDjacsDrag.appendChild(DIVjacsDragText);
                                 TBODYjacsHead.appendChild(TRjacsHead);
                                    TRjacsHead.appendChild(TDjacsHead1);
                                        TDjacsHead1.appendChild(INPUTjacsHead1);
                                    TRjacsHead.appendChild(TDjacsHead2);
                                        TDjacsHead2.appendChild(SELECTjacsHead2);
                                    TRjacsHead.appendChild(TDjacsHead3);
                                        TDjacsHead3.appendChild(SELECTjacsHead3);
                                    TRjacsHead.appendChild(TDjacsHead4);
                                        TDjacsHead4.appendChild(INPUTjacsHead4);
                 TBODYjacs.appendChild(TRjacs2);
                    TRjacs2.appendChild(TDjacs2);
                        TDjacs2.appendChild(TABLEjacsCells);
                            TABLEjacsCells.appendChild(THEADjacsCells);
                                THEADjacsCells.appendChild(TRjacsCells);
                                    TRjacsCells.appendChild(TDjacsCells);

                                    for (var i=0;i<7;i++)
                                        {TDjacsCells           = document.createElement('td');
                                         TDjacsCells.className = 'jacsWeek';
                                         TDjacsCells.id        = calId+'WeekInit'+i;
                                         TRjacsCells.appendChild(TDjacsCells);
                                        }

                            TBODYjacsCells    = document.createElement('tbody');
                            TBODYjacsCells.id = calId+'Cells';

                            TABLEjacsCells.appendChild(TBODYjacsCells);

                            for (var i=0;i<6;i++)
                                {TRjacsCells              = document.createElement('tr');
                                 TBODYjacsCells.appendChild(TRjacsCells);

                                    TDjacsCells           = document.createElement('td');
                                    TDjacsCells.className = 'jacsWeekNo';
                                    TDjacsCells.id        = calId+'Week_'+i;
                                    TRjacsCells.appendChild(TDjacsCells);

                                    for (var j=0;j<7;j++)
                                        {TDjacsCells           = document.createElement('td');
                                         TDjacsCells.className = 'jacsCells';
                                         TDjacsCells.id        = calId+'Cell_'+(j+(i*7));
                                         TRjacsCells.appendChild(TDjacsCells);
                                        }
                                }

                 TFOOTjacsFoot           = document.createElement('tfoot');
                 TABLEjacsCells.appendChild(TFOOTjacsFoot);

                    TRjacsFoot              = document.createElement('tr');
                    TRjacsFoot.id           = calId+'Foot';
                    TFOOTjacsFoot.appendChild(TRjacsFoot);

                    TDjacsFoot               = document.createElement('td');
                    TDjacsFoot.colSpan       = '8';
                    TDjacsFoot.style.padding = '0px';
                    TRjacsFoot.appendChild(TDjacsFoot);

                        TABLEjacsFootDetail = document.createElement('table');
                        TABLEjacsFootDetail.style.width = '100%';
                        TABLEjacsFootDetail.cellSpacing = '0';
                        TABLEjacsFootDetail.cellPadding = '0';
                        TDjacsFoot.appendChild(TABLEjacsFootDetail);

                            TBODYjacsFootDetail = document.createElement('tbody');
                            TABLEjacsFootDetail.appendChild(TBODYjacsFootDetail);

                                TRjacsFootDetail = document.createElement('tr');
                                TBODYjacsFootDetail.appendChild(TRjacsFootDetail);

                                    TDjacsFootDetail           = document.createElement('td');
                                    TDjacsFootDetail.className = 'jacsClear';
                                    TDjacsFootDetail.id        = calId+'Clear';
                                    TDjacsFootDetail.style.padding = '0px';
                                    TRjacsFootDetail.appendChild(TDjacsFootDetail);

                                        INPUTjacsClearButton           = document.createElement('input');
                                        INPUTjacsClearButton.type      = 'button';
                                        INPUTjacsClearButton.id        = calId+'ClearButton';
                                        INPUTjacsClearButton.className = 'Clear';
                                        INPUTjacsClearButton.style.textAlign = 'center';
                                        INPUTjacsClearButton.onclick   = function() {cal.targetEle.value='';hide(calId);};
                                        TDjacsFootDetail.appendChild(INPUTjacsClearButton);

                                    TDjacsNow                 = document.createElement('td');
                                    TDjacsNow.className       = 'jacsNow';
                                    TDjacsNow.id              = calId+'Now';
                                    TDjacsNow.style.padding   = '0px';
                                    TRjacsFootDetail.appendChild(TDjacsNow);

                 if (TABLEjacs.clickToHide)
                    {if (document.addEventListener)
                            {      TABLEjacs.addEventListener('click',    cancel,         false);
                                   TABLEjacs.addEventListener('change',   cancel,         false);
                                  TDjacsDrag.addEventListener('mousedown',beginDrag,      false);
                              INPUTjacsHead1.addEventListener('click',    stopPropagation,false);
                             SELECTjacsHead2.addEventListener('click',    stopPropagation,false);
                             SELECTjacsHead2.addEventListener('change',   stopPropagation,false);
                             SELECTjacsHead3.addEventListener('click',    stopPropagation,false);
                             SELECTjacsHead3.addEventListener('change',   stopPropagation,false);
                              INPUTjacsHead4.addEventListener('click',    stopPropagation,false);
                              TBODYjacsCells.addEventListener('click',    stopPropagation,false);
                            }
                     else   {      TABLEjacs.attachEvent('onclick',    cancel);
                                   TABLEjacs.attachEvent('onchange',   cancel);
                                  TDjacsDrag.attachEvent('onmousedown',beginDrag);
                              INPUTjacsHead1.attachEvent('onclick',    stopPropagation);
                             SELECTjacsHead2.attachEvent('onclick',    stopPropagation);
                             SELECTjacsHead2.attachEvent('onchange',   stopPropagation);
                             SELECTjacsHead3.attachEvent('onclick',    stopPropagation);
                             SELECTjacsHead3.attachEvent('onchange',   stopPropagation);
                              INPUTjacsHead4.attachEvent('onclick',    stopPropagation);
                              TBODYjacsCells.attachEvent('onclick',    stopPropagation);
                            }
                    }
                 else
                    {if (document.addEventListener)
                        {      TABLEjacs.addEventListener('click',    stopPropagation,false);
                               TABLEjacs.addEventListener('change',   stopPropagation,false);
                              TDjacsDrag.addEventListener('mousedown',beginDrag,      false);
                        }
                     else
                        {      TABLEjacs.attachEvent('onclick',    stopPropagation);
                               TABLEjacs.attachEvent('onchange',   stopPropagation);
                              TDjacsDrag.attachEvent('onmousedown',beginDrag);
                        }
                    }

                 if (dynamic)
                        {iFrame = document.createElement('iframe');

                         iFrame.className    = 'jacs';
                         iFrame.id           = calId+'Iframe';
                         if (getEl('jacsIElt7')) {iFrame.src = '/jacsblank.html';}
                         iFrame.name         = 'jacsIframe';
                         iFrame.frameborder  = '0';
                         iFrame.style.zIndex = TABLEjacs.zIndex;

                         document.body.insertBefore(iFrame, document.body.firstChild);
                         document.body.insertBefore(TABLEjacs, iFrame);
                        }
                 else   {if (!getEl('jacsSpan'+calId)) {document.writeln("<span id='jacsSpan"+calId+"'></span>");}
                         getEl('jacsSpan'+calId).appendChild(TABLEjacs);
                        }
                },

             hide:  function()   {
                           var calId = 'jacs';
                           hide(calId);
               },
               
             cals: function ()  {return cals;}
             
            };
    };

lomtec.Controls.UI.Script.JATS = new function()
    {

     // This array keeps track of the defined calendars for the page.
     var times = new Array();

     // This function shortens the code replacing
     // document.getElementById('myID') with getEl('myId')
     // everywhere in the script. It also tries to handle a common
     // error when calling the script: when the developer has only
     // set a NAME attribute value, so no ID attribute is set.
     function getEl(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( 'JATS' +
                                        ' \nCannot uniquely identify element named: ' + id +
                                        '.\nMore than one identical NAME attribute defined' +
                                        '.\nSolution: Assign the required element a unique ID attribute value.');
                                }
                        }
                }
           return null;
         };


     // This DIV inside an IE-only conditional comments is a
     // reliable way of setting up object testing for IE.
     document.writeln("<!--[if IE]><div id='jatsIE'></div><![endif]-->");
     document.writeln("<!--[if lt IE 7]><div id='jatsIElt7'></div><![endif]-->");

//******************************************************************************
//------------------------------------------------------------------------------
// Customisation section
//------------------------------------------------------------------------------
//******************************************************************************
     function timeAttributes(time)
        {
            time.zIndex = 1;
            
            try   {jacsSetLanguage(time);}
            catch (exception)
                {// English
                 time.language            = 'en';
                 time.drag                = 'click here to drag';
                }

            time.active = true;
            time.allowDrag = true;
            
            time.clickToHide = false;
            time.xBase     = 'L';
            time.yBase     = 'B';
            time.xPosition = 'L';
            time.yPosition = 'T';
            time.autoPosition = true;

            time.dateReturned  = false;
            time.outputTime = null;
            
            time.workDayStart = '09:00';
            time.workDayEnd   = '18:00';

            // Finally: The following attributes are used in calendar
            //          functions.  You need do nothing with them here.

            time.triggerEle;
            time.targetEle;
        };

//******************************************************************************
//------------------------------------------------------------------------------
// End of customisation section
//------------------------------------------------------------------------------
//******************************************************************************

// **************************************
// Set up calendar events on calling page
// **************************************

     if (document.addEventListener)
          {window.addEventListener(  'load',jacsLoader,true);}
     else {window.attachEvent     ('onload',jacsLoader);}

     function jacsLoader()
        {// Define document level event to hide the calendar on click.

         if (document.addEventListener)
              {document.addEventListener('click',hide, false);}
         else {document.attachEvent('onclick',hide);}

         // Create an onBeforeUnload event to handle IE memory leaks.

         if (getEl('jatsIElt7')) {window.attachEvent('onbeforeunload',defeatLeaks);}

         function defeatLeaks()
            {for (var i=0;i<times.length;i++)
                {
                 var time    = getEl(times[i]),
                     cells  = getEl(times[i]+'Cells').childNodes;

                 for (var j=0;j<cells.length;j++)
                    {var rows = cells[j].childNodes;
                     for (var k=1;k<rows.length;k++)
                        {rows[k].onclick     = null;
                         rows[k].onmouseover = null;
                         rows[k].onmouseout  = null;
                        }
                    }

                 // Set calendar's leaky custom attributes to null.

                 time.targetEle  = null;
                }
            };
        };

// ****************************************************************************
// Start of Main Private Function Library
// ****************************************************************************
       function setDisplay(timeId,time){
            var data = getEl(timeId+'Cells');
            if (data == null) return;
            
            var start = null;
            var end   = null;
            
            if ( time.lomtecDateTimePicker != null && time.lomtecDateTimePicker.getTimeSettings() != null){
                start = time.lomtecDateTimePicker.getTimeSettings().start;
                end   = time.lomtecDateTimePicker.getTimeSettings().end;
            }
            
            for(var i =0;i< data.childNodes.length; i++){
                var parent = data.childNodes[i];
                
                for (var j=0;j< parent.childNodes.length;j++){
                        var child = parent.childNodes[j];
                        var value = child.innerHTML + ':00';
                        if(value == time.outputTime)              child.className = 'jatsCellsActual'; 
                        else if(value < start || value > end)    child.className = 'jatsCellsDeactive'; 
                        else                                     child.className = 'jatsCells';                              
                } 
            }
       }

       function setOutput(outputTime,timeId)
        {
         var tmp = outputTime.split(':');
         if(tmp.length !=2 ) return;
        
         var time = getEl(timeId);
         time.dateReturned = true;
         time.outputTime   = outputTime;
         
         var t = new Date(0,0,0,tmp[0].lomtecParseInt(),tmp[1].lomtecParseInt(),0);
         time.lomtecDateTimePicker.setTimeValue(t);

         if (time.dynamic) {hide(timeId);}
     };

     function changeClass(evt)
        {var ele = eventTrigger(evt);

         if (ele.nodeType==3) {ele=ele.parentNode;}

         if (((evt)?evt.type:event.type)=='mouseover')
            {switch (ele.className)
                {case 'jatsCells':
                     ele.className = 'jatsCellsHover';    break;
                 case 'jatsCellsDeactive':
                     ele.className = 'jatsCellsDeactiveHover'; break;
                 case 'jatsCellsActual':
                     ele.className = 'jatsCellsActualHover'; break;

                }
            }
         else
            {switch (ele.className)
                {case 'jatsCellsHover':
                    ele.className = 'jatsCells';     break;
                 case 'jatsCellsDeactiveHover':
                     ele.className = 'jatsCellsDeactive'; break;
                 case 'jatsCellsActualHover':
                     ele.className = 'jatsCellsActual'; break;

                }
            }
         return true;
      };

     function eventTrigger(evt)
        {if (!evt) {evt = event;}
         return evt.target||evt.srcElement;
     };

     function hide(instanceID)
        {if (typeof instanceID=='object')
                {for (var i=0;i<times.length;i++) {hideOne(times[i]);}}
         else   {hideOne(instanceID);}

         function hideOne(id)
            {time = getEl(id);

             if (time!=null && time.dynamic)
                {time.style.visibility = 'hidden';
                 getEl(id+'Iframe').style.visibility='hidden';
                }
            };
        };

     function stopPropagation(evt)
       {
        if (evt.stopPropagation)
             {if (evt.target!=evt.currentTarget) {evt.stopPropagation(); evt.preventDefault();}}
        else {evt.cancelBubble = true;}
       };

// *********************************
//   End of Private Function Library
// *********************************
// Start of Public  Function Library
// *********************************

     return {show: function(element,src)
                {// Check the type of any additional parameters.
                 // The optional string parameter is a calendar ID,
                 // Take any remaining parameters as day numbers to be handled
                 // (enabled/disabled) according to the setting of the
                 // calendar's  valuesEnabled  attribute.
                 // 0 = Sunday through to 6 = Saturday.

                 //modification from using this object from lomtecDateTimePicker
                     var ele = element.getTimeControl();
                     
                     var dynamic = true;
                     var timeId = 'jats';
                     
                     // Stop the click event that opens the calendar
                     // from bubbling up to the document-level event
                     // handler that hides it!

                     var source = src;
                     if (!source) {source = window.event;}

                     if (source.tagName)    // Second parameter isn't an event it's an element
                        {var sourceEle = source;
                         if (getEl('jatsIE'))  {window.event.cancelBubble = true;}
                         else {sourceEle.parentNode.addEventListener('click',stopPropagation,false);}
                        }
                     else   // Second parameter is an event
                        {var event = source;
                         // Stop the click event that opens the calendar from bubbling up to
                         // the document-level event handler that hides it!
                         var sourceEle = (event.target)?event.target:event.srcElement;
                         if (event.stopPropagation) {event.stopPropagation();}
                         else                       {event.cancelBubble = true;}
                        }
                     


                 // Add event handlers to the return element and its parent.
                 // This helps the script to support tab sequences and focus events.

                 if (document.addEventListener)
                        {ele.addEventListener('keydown',hideOnTab,false);
                         ele.parentNode.addEventListener('click',stopPropagation,false);}
                 else   {ele.attachEvent('onkeydown',hideOnTab);
                         if (ele.parentNode!=document.body)
                            {ele.parentNode.attachEvent('onclick',stopPropagation);}
                        }

                 function hideOnTab(evt)
                    {if (!evt) { evt = window.event;}
                     if ((evt.keyCode||evt.which)==9) {hide(timeId);}
                    };

                 // Create the calendar structure. One is enough unless you want more
                 // than one calendar visible on the page at one time.  If you DO need
                 // more, you can create as many as you like but each must have a unique
                 // ID.

                 // The first parameter of JATS.make is the ID of the calendar. The
                 // second is a boolean that determines whether the calendar is to be
                 // static on the page (assigned to a single input field and always
                 // visible) or dynamic (shown and hidden on events and can be assigned
                 // to any number of input fields).

                 if (!getEl(timeId)) {lomtec.Controls.UI.Script.JATS.make(timeId,dynamic);}

                 time = getEl(timeId);

                 time.triggerEle = sourceEle;

                 time.dateReturned = false;

                 //set LomtecDateTimePicker to object 
                 time.lomtecDateTimePicker = element;
                 
                 // Set language-dependent values
                 getEl(timeId+'DragText').innerHTML = time.drag;
                 getEl(timeId).ele = ele;

                 // Display the time
                 time.outputTime = element.getTimeValue();
                 setDisplay(timeId,time);
                 
                 // Remember the Element
                 time.targetEle = ele;

                 // Position the calendar box.
                 if (dynamic)
                    {// Check whether or not dragging is allowed and display drag handle if necessary
                     getEl(timeId+'Drag').style.display = (time.allowDrag)?'':'none';

                     var offsetTop  = parseInt(ele.offsetTop ,10),
                         offsetLeft = parseInt(ele.offsetLeft,10);

                     // 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.
                     if (!window.opera)
                         {while (ele.tagName!='BODY' && ele.tagName!='HTML')
                             {offsetTop  -= parseInt(ele.scrollTop, 10);
                              offsetLeft -= parseInt(ele.scrollLeft,10);
                              ele = ele.parentNode;
                             }
                          ele = time.targetEle;
                         }

                     while (ele.tagName!='BODY' && ele.tagName!='HTML')
                        {ele = ele.offsetParent;
                         offsetTop  += parseInt(ele.offsetTop, 10);
                         offsetLeft += parseInt(ele.offsetLeft,10);
                        }

                     ele = time.targetEle;

                     var eleOffsetTop  = offsetTop,
                         eleOffsetLeft = offsetLeft;

                     if (time.xBase.length>0)
                            {if (isNaN(time.xBase))
                                    {time.xBase = time.xBase.toUpperCase();
                                     offsetLeft += (time.xBase=='R')
                                                        ?parseInt(ele.offsetWidth,10)
                                                        :(time.xBase=='M')?Math.round(parseInt(ele.offsetWidth,10)/2):0;
                                    }
                             else   {offsetLeft += parseInt(time.xBase,10);}
                            }

                     if (time.yBase.length>0)
                            {if (isNaN(time.yBase))
                                    {time.yBase  = time.yBase.toUpperCase();
                                     offsetTop += (time.yBase=='B')
                                                    ?parseInt(ele.offsetHeight,10)
                                                    :(time.yBase=='M')?Math.round(parseInt(ele.offsetHeight,10)/2):0;
                                    }
                             else   {offsetTop += parseInt(time.yBase,10);}
                            }
                     else   {offsetTop += parseInt(ele.offsetHeight,10);}

                     if (time.xPosition.length>0)
                            {if (isNaN(time.xPosition))
                                    {time.xPosition = time.xPosition.toUpperCase();
                                     offsetLeft -= (time.xPosition=='R')
                                                        ?parseInt(time.offsetWidth,10)
                                                        :(time.xPosition=='M')?Math.round(parseInt(time.offsetWidth,10)/2):0;
                                    }
                             else   {offsetLeft += parseInt(time.xPosition,10);}
                            }

                     if (time.yPosition.length>0)
                            {if (isNaN(time.yPosition))
                                    {time.yPosition = time.yPosition.toUpperCase();

                                     offsetTop -= (time.yPosition=='B')
                                                        ?parseInt(time.offsetHeight,10)
                                                        :(time.yPosition=='M')?Math.round((parseInt(time.offsetHeight,10))/2):0;
                                    }
                             else   {offsetTop += parseInt(time.yPosition,10);}
                            }

                     if (time.autoPosition)
                        {var width      = parseInt(time.offsetWidth, 10),
                             height     = parseInt(time.offsetHeight,10),
                             windowLeft =
                                 (document.body && document.body.scrollLeft)
                                      ?document.body.scrollLeft                  //DOM compliant
                                      :(document.documentElement && document.documentElement.scrollLeft)
                                          ?document.documentElement.scrollLeft   //IE6+ standards compliant
                                          :0,                                    //Failed
                             windowWidth =
                                  (typeof(innerWidth) == 'number')
                                      ?innerWidth                                //DOM compliant
                                      :(document.documentElement && document.documentElement.clientWidth)
                                          ?document.documentElement.clientWidth  //IE6+ standards compliant
                                          :(document.body && document.body.clientWidth)
                                              ?document.body.clientWidth         //IE non-compliant
                                              :0,                                //Failed
                             windowTop =
                                  (document.body && document.body.scrollTop)
                                      ?document.body.scrollTop                   //DOM compliant
                                      :(document.documentElement && document.documentElement.scrollTop)
                                          ?document.documentElement.scrollTop    //IE6+ standards compliant
                                          :0,                                    //Failed
                             windowHeight =
                                  (typeof(innerHeight) == 'number')
                                      ?innerHeight                               //DOM compliant
                                      :(document.documentElement && document.documentElement.clientHeight)
                                          ?document.documentElement.clientHeight //IE6+ standards compliant
                                          :(document.body && document.body.clientHeight)
                                              ?document.body.clientHeight        //IE non-compliant
                                              :0;                                //Failed

                         if (eleOffsetLeft + parseInt(ele.offsetWidth,10) - width >= windowLeft &&
                             offsetLeft + width > windowLeft + windowWidth
                            )       {offsetLeft = eleOffsetLeft + parseInt(ele.offsetWidth,10) - width;}
                         else if (eleOffsetLeft >= windowLeft && offsetLeft < windowLeft
                                 )  {offsetLeft = eleOffsetLeft;}

                         if (eleOffsetTop - height >= windowTop &&
                             offsetTop + height > windowTop + windowHeight
                            )       {offsetTop = eleOffsetTop - height;}
                         else if (offsetTop + height <= windowTop + windowHeight && offsetTop < windowTop)
                                    {offsetTop = eleOffsetTop + parseInt(ele.offsetHeight,10);}
                        }

                     time.style.top  = offsetTop+'px';
                     time.style.left = offsetLeft+'px';

                     getEl(timeId+'Iframe').style.top    = offsetTop +'px';
                     getEl(timeId+'Iframe').style.left   = offsetLeft+'px';

                     getEl(timeId+'Iframe').style.width  = (time.offsetWidth -(getEl('jatsIE')?2:4))+'px';
                     getEl(timeId+'Iframe').style.height = (time.offsetHeight-(getEl('jatsIE')?2:4))+'px';
                     getEl(timeId+'Iframe').style.visibility = 'inherit';
                    }

                 // Show it on the page
                 time.style.visibility = 'inherit';
                },

             make: function (timeId)
                {times.push(timeId);
                
                 var dynamic      = (typeof arguments[1]=='boolean')   ? arguments[1]:true;

                 TABLEjacs           = document.createElement('table');
                 TABLEjacs.id        = timeId;
                 TABLEjacs.dynamic   = dynamic;
                 TABLEjacs.className = (dynamic)?'jacs':'jacsStatic';

                 timeAttributes(TABLEjacs);

                 if (dynamic) {TABLEjacs.style.zIndex = TABLEjacs.zIndex+1;}

                 function cancel(evt)
                    {if (TABLEjacs.clickToHide) {hide(timeId);}
                     stopPropagation(evt);
                    };
                    
                 function cellOutput(evt)
                    {
                        var ele = eventTrigger(evt);
                        if (ele.nodeType==3) ele=ele.parentNode;
                        
                        setOutput(ele.innerHTML,timeId);
                    };
                    
                 TBODYjacs                 = document.createElement('tbody');
                 TRjacs1                   = document.createElement('tr');
                 TRjacs1.className         = 'jacs';
                 TDjacs1                   = document.createElement('td');
                 TDjacs1.className         = 'jacs';
                 TABLEjacsHead             = document.createElement('table');
                 TABLEjacsHead.id          = timeId+'Head';
                 TABLEjacsHead.cellSpacing = '0';
                 TABLEjacsHead.cellPadding = '0';
                 TABLEjacsHead.className   = 'jacsHead';
                 TABLEjacsHead.width       = '100%';

                 TBODYjacsHead             = document.createElement('tbody');

                 TRjacsDrag                = document.createElement('tr');
                 TRjacsDrag.id             = timeId+'Drag';
                 TRjacsDrag.style.display  = 'none';

                 TDjacsDrag                = document.createElement('td');
                 TDjacsDrag.className      = 'jacsDrag';
                 TDjacsDrag.colSpan        = '4';

                 function beginDrag(evt)
                    {var elToDrag = getEl(timeId);

                     var deltaX    = evt.clientX,
                         deltaY    = evt.clientY,
                         offsetEle = elToDrag;

                     while (offsetEle.tagName!='BODY' && offsetEle.tagName!='HTML')
                        {deltaX   -= parseInt(offsetEle.offsetLeft,10);
                         deltaY   -= parseInt(offsetEle.offsetTop ,10);
                         offsetEle = offsetEle.offsetParent;
                        }

                     if (document.addEventListener)
                            {elToDrag.addEventListener('mousemove',moveHandler,true);
                             elToDrag.addEventListener('mouseup',    upHandler,true);
                            }
                     else   {elToDrag.attachEvent('onmousemove', moveHandler);
                             elToDrag.attachEvent('onmouseup',     upHandler);
                             elToDrag.setCapture();
                            }

                     stopPropagation(evt);

                     function moveHandler(evt)
                        {if (!evt) {evt = window.event;}

                         elToDrag.style.left = (evt.clientX-deltaX)+'px';
                         elToDrag.style.top  = (evt.clientY-deltaY)+'px';

                         getEl(timeId+'Iframe').style.left = (evt.clientX-deltaX)+'px';
                         getEl(timeId+'Iframe').style.top  = (evt.clientY-deltaY)+'px';

                         stopPropagation(evt);
                        };

                     function upHandler(evt)
                        {if (!evt) {evt = window.event;}

                         if (document.removeEventListener)
                                {elToDrag.removeEventListener('mousemove',moveHandler,true);
                                 elToDrag.removeEventListener(  'mouseup',  upHandler,true);
                                }
                         else   {elToDrag.detachEvent('onmouseup',    upHandler);
                                 elToDrag.detachEvent('onmousemove',moveHandler);
                                 elToDrag.releaseCapture();
                                }

                         stopPropagation(evt);
                        };
                    };

                 DIVjacsDragText           = document.createElement('span');
                 DIVjacsDragText.id        = timeId+'DragText';

                 TRjacsHead                = document.createElement('tr');
                 TRjacsHead.className      = 'jacsHead';

                 TRjacs2                   = document.createElement('tr');
                 TRjacs2.className         = 'jacs';

                 TDjacs2                   = document.createElement('td');
                 TDjacs2.className         = 'jacs';

                 TABLEjacsCells            = document.createElement('table');
                 TABLEjacsCells.className  = 'jacsCells';
                 TABLEjacsCells.align      = 'center';
                 TABLEjacsCells.width      = '100%';

                 THEADjacsCells            = document.createElement('thead');

                 TABLEjacs.appendChild(TBODYjacs);
                 TBODYjacs.appendChild(TRjacs1);
                    TRjacs1.appendChild(TDjacs1);
                        TDjacs1.appendChild(TABLEjacsHead);
                            TABLEjacsHead.appendChild(TBODYjacsHead);
                                 TBODYjacsHead.appendChild(TRjacsDrag);
                                    TRjacsDrag.appendChild(TDjacsDrag);
                                        TDjacsDrag.appendChild(DIVjacsDragText);
                 TBODYjacs.appendChild(TRjacs2);
                    TRjacs2.appendChild(TDjacs2);
                        TDjacs2.appendChild(TABLEjacsCells);
                           
                            TBODYjacsCells    = document.createElement('tbody');
                            TBODYjacsCells.id = timeId+'Cells';

                            TABLEjacsCells.appendChild(TBODYjacsCells);

                            var hour = 0;
                            var min  = 0;
                            var IE   = getEl('jatsIE');
                            
                            for (var i=0;i<8;i++)
                                {TRjacsCells              = document.createElement('tr');
                                 TBODYjacsCells.appendChild(TRjacsCells);

                                    for (var j=0;j<6;j++)
                                        {TDjacsCells           = document.createElement('td');
                                         TDjacsCells.id        = timeId+'Cell_'+(j+(i*6));
                                         TDjacsCells.className = 'jatsCells';
                                         if (IE){ TDjacsCells.onmouseover = changeClass;  TDjacsCells.onmouseout  = changeClass;  }
                                         TDjacsCells.onclick = cellOutput;

                                         TDjacsCells.innerHTML = hour.toString().lomtecPadLeft(2) + ":" + min.toString().lomtecPadLeft(2)
                                         TRjacsCells.appendChild(TDjacsCells);                                         

                                         min = min + 30;
                                         if(min == 60) {hour++;min=0;}
                                        }
                                }

                 if (TABLEjacs.clickToHide)
                    {if (document.addEventListener)
                            {      TABLEjacs.addEventListener('click',    cancel,         false);
                                   TABLEjacs.addEventListener('change',   cancel,         false);
                                  TDjacsDrag.addEventListener('mousedown',beginDrag,      false);
                              TBODYjacsCells.addEventListener('click',    stopPropagation,false);
                            }
                     else   {      TABLEjacs.attachEvent('onclick',    cancel);
                                   TABLEjacs.attachEvent('onchange',   cancel);
                                  TDjacsDrag.attachEvent('onmousedown',beginDrag);
                              TBODYjacsCells.attachEvent('onclick',    stopPropagation);
                            }
                    }
                 else
                    {if (document.addEventListener)
                        {      TABLEjacs.addEventListener('click',    stopPropagation,false);
                               TABLEjacs.addEventListener('change',   stopPropagation,false);
                              TDjacsDrag.addEventListener('mousedown',beginDrag,      false);
                        }
                     else
                        {      TABLEjacs.attachEvent('onclick',    stopPropagation);
                               TABLEjacs.attachEvent('onchange',   stopPropagation);
                               TDjacsDrag.attachEvent('onmousedown',beginDrag);
                        }
                    }

                 if (dynamic)
                        {iFrame = document.createElement('iframe');

                         iFrame.className    = 'jacs';
                         iFrame.id           = timeId+'Iframe';
                         if (getEl('jatsIElt7')) {iFrame.src = '/jacsblank.html';}
                         iFrame.name         = 'jacsIframe';
                         iFrame.frameborder  = '0';
                         iFrame.style.zIndex = TABLEjacs.zIndex;

                         document.body.insertBefore(iFrame, document.body.firstChild);
                         document.body.insertBefore(TABLEjacs, iFrame);
                        }
                 else   {if (!getEl('jatsSpan'+timeId)) {document.writeln("<span id='jatsSpan"+timeId+"'></span>");}
                         getEl('jatsSpan'+timeId).appendChild(TABLEjacs);
                        }
                },
                
             hide:  function()   {
                         var timeId = 'jats';
                         hide(timeId);
                },

             times: function ()  {return times;}
             
            };
    }

// ******************************
// End of Public Function Library
// ******************************************************
// End of Javascript Advanced Time Script (JATS) Code
// ******************************************************


//******************************************************************************
//------------------------------------------------------------------------------
// End of customisation section
//------------------------------------------------------------------------------
//******************************************************************************

// *******************************************************
// Custom methods for Date, String and Function prototypes
// *******************************************************

// Format a date into the required pattern

Date.prototype.jacsFormat = function(format,monthNames)
    {var charCount = 0,
         codeChar  = '',
         result    = '';

     for (var i=0;i<=format.length;i++)
        {if (i<format.length && format.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().lomtecPadLeft(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().lomtecPadLeft(charCount)
                                    :monthNames[this.getMonth()];
                        break;
                     case 'd': case 'D':
                        // If we find a D, get the date and format it
                        result += this.getDate().toString().lomtecPadLeft(charCount);
                        break;
                     default:
                        // Copy any unrecognised characters across
                        while (charCount-->0) {result += codeChar;}
                    }

                 if (i<format.length)
                    {// Store the character we have just worked on
                     codeChar  = format.charAt(i);
                     charCount = 1;
                    }
                }
        }
     return result;
};

lomtec.Controls.UI.DateTimePicker = function(id,dSettings,tSettings){

    var ctrlID = id;
    
    //controlers (initialized only if I need)
    var parentCtrl  = null;
    var hfValueCtrl = null;
    var tbDayCtrl = null;
    var tbMonthCtrl = null;
    var tbYearCtrl = null;
    var tbHourCtrl = null;
    var tbMinuteCtrl = null;

    //optional parameters
    var dateSettings  = { range : null    , dates : null   , days  : null  ,  highlight : null};
    var timeSettings  = { begin : "09:00" , start: "09:00" , end : "18:00" };
    
    //initialize optional parameters    
    if(typeof(dSettings)!= 'undefined' && dSettings != null ) dateSettings = dSettings;
    if(typeof(tSettings)!= 'undefined' && tSettings != null ) timeSettings = tSettings;

    //optional parameter
    var timeRounding =  null;
    //storage this
    var self = this;    
    //===============================================
    //    
    //events
    //
    //===============================================
    this.onChange = null;
    //
    //===============================================
    //    
    //members  
    //
    //===============================================
    this.getID  = function() {  return ctrlID; };
    this.getCtrl  = function() {  return parentCtrl; };

    this.getDisabledDates  = function(){
        if(typeof(dateSettings) == 'undefined' || dateSettings == null || typeof(dateSettings.dates) == 'undefined' ) return null;
        return dateSettings.dates; 
        
    };
    this.getDisabledDays  = function(){
        if(typeof(dateSettings) == 'undefined' || dateSettings == null || typeof(dateSettings.days) == 'undefined' ) return null;
        return dateSettings.days; 
    };
    this.getHighlightDates = function(){ 
        if(typeof(dateSettings) == 'undefined' || dateSettings == null || typeof(dateSettings.highlight) == 'undefined' ) return null;    
        return dateSettings.highlight; 
    };
    
    this.getDateRange  = function(){ 
        if(typeof(dateSettings) == 'undefined' || dateSettings == null || typeof(dateSettings.range) == 'undefined' ) return null;
        if(dateSettings.range != null && dateSettings.range.length == 2)  return dateSettings.range;  
        return null; 
    };

    this.getTimeSettings = function(){ return timeSettings; };

    this.getValue = getValue;
       
    this.setText = function(value, format){  
             var input = value.split(new RegExp('[/.,: ]+','g'));

             if (input[0]!=null){
                if (input[0].length==0)                {input.splice(0,1);}
                if (input[input.length-1].length==0)   {input.splice(input.length-1,1);}
             }

             var format = format.toUpperCase();
             var template = ['D','M','Y', 'H' , 'I'];

             var result = new Array();
             for (var i=0;i<template.length;i++){
                if (format.search(template[i])>-1) {result[format.search(template[i])] = template[i];}
             }
             var sequence = result.join('');
             
             var year = 0;
             var month = 0;
             var day = 0;
             var hour = 0;
             var min = 0;

             switch (input.length){
                case 1:  
                      if (format.indexOf('Y')>-1 && input[0].length>format.lastIndexOf('Y')) {
                         year = parseInt(input[0].substring(format.indexOf('Y'), format.lastIndexOf('Y')+1),10);
                      }

                      if (format.indexOf('M')>-1 && input[0].length>format.lastIndexOf('M')) {
                          month = input[0].substring(format.indexOf('M'),format.lastIndexOf('M')+1); 
                      }

                      if (format.indexOf('D')>-1 && input[0].length>format.lastIndexOf('D')) {
                          day = parseInt(input[0].substring(format.indexOf('D'),format.lastIndexOf('D')+1),10);
                      }

                      if (format.indexOf('H')>-1 && input[0].length>format.lastIndexOf('H')) {
                          hour = parseInt(input[0].substring(format.indexOf('H'),format.lastIndexOf('H')+1),10);
                      }

                      if (format.indexOf('I')>-1 && input[0].length>format.lastIndexOf('I')) {
                          min = parseInt(input[0].substring(format.indexOf('I'),format.lastIndexOf('I')+1),10);
                      }
                      break;

                 case 3:
                 
                     year = parseInt(input[sequence.search(/Y/i)],10);  // Year
                     month = parseInt(input[sequence.search(/M/i)],10);   // Month
                     day = parseInt(input[sequence.search(/D/i)],10);  // Day
                     break;

                 case 5:
                     year = parseInt(input[sequence.search(/Y/i)],10);  // Year
                     month = parseInt(input[sequence.search(/M/i)],10);   // Month
                     day = parseInt(input[sequence.search(/D/i)],10);   // Day
                     hour = parseInt(input[sequence.search(/H/i)],10);   // Hour
                     min = parseInt(input[sequence.search(/I/i)],10);   // Min
                     break;
             }

             var expValDay    = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$');
             var expValMonth  = new RegExp('^(0?[1-9]|1[0-2])$');
             var expValYear   = new RegExp('^([0-9]{1,2}|[0-9]{4})$');
             var expValHour   = new RegExp('^([0-9]|1[0-9]|2[0-3])$');
             var expValMinute = new RegExp('^([0-9]|[1-5][0-9])$');

             if (expValYear.exec(year)  == null ||  expValMonth.exec(month) == null || expValDay.exec(day) == null || expValHour.exec(hour) == null || expValMinute.exec(min) == null ){
                 year = 0; month = 0; day = 0; hour = 0; min = 0;
             }
             
            var result = month.toString().lomtecPadLeft(2) + '/' + day.toString().lomtecPadLeft(2) + '/' + year.toString().lomtecPadLeft(4) + ' ' + hour.toString().lomtecPadLeft(2) + ':' +  min.toString().lomtecPadLeft(2) + ':00';
            setTextValue(result,true);
     };


       
        
    this.setValue = function(value,valid){
        //set value
        if(value == null) { 
            this.clear();
            return; 
        }
    
        var result = (value.getMonth() + 1).toString().lomtecPadLeft(2) + '/' + 
                value.getDate().toString().lomtecPadLeft(2) + '/' + 
                value.getFullYear().toString().lomtecPadLeft(4) + ' ' +
                value.getHours().toString().lomtecPadLeft(2) + ':' + 
                value.getMinutes().toString().lomtecPadLeft(2) + ':' + 
                value.getSeconds().toString().lomtecPadLeft(2);
                
        if(typeof(valid) == 'undefined')    valid=true;
        
        setTextValue(result,true,valid);
    };

    this.getCalendarControl = function(){  return tbYearCtrl; };
    
    this.getCalendarValue = function(){
        //get calendar value for JACS (date without time)
        var tmp = getTextValue();   if( tmp == '') return '';
        var tmp = tmp.split(' ');  
        if( tmp.length == 2 && tmp[0].indexOf('01/01/0001') != 0) return tmp[0]; 
        return '';
    };
    
    this.setCalendarValue = function(value){
        //set calendar value from JACS
        if (value == null) return ;
        
        var day = value.getDate().toString().lomtecPadLeft(2);
        var month = (value.getMonth() + 1).toString().lomtecPadLeft(2);
        var year = value.getFullYear().toString().lomtecPadLeft(4);
                 
        var oldValue = getTextValue();
        var date = oldValue.split(' ');
        var newValue = month + '/' + day + '/' + year;
        
        //set value to controls , no validate...
        if(date.length == 2 )  setTextValue(newValue + ' ' + date[1],true);
        else {
            if(isTimeShow() && timeSettings != null && typeof(timeSettings.begin) != 'undefined' && timeSettings.begin.length==5) setTextValue(newValue + ' ' + timeSettings.begin + ':00',true);
            else setTextValue(newValue + ' 00:00:00',true);
        }
    };

    this.getTimeControl = function(){  return tbMinuteCtrl; };
    
    this.getTimeValue = function(){
        //get time (do data)
        var tmp = getTextValue();   if( tmp == '') return '';
        var tmp = tmp.split(' ');    if( tmp.length == 2 ){  return tmp[1]; }
        return '';
    };

    this.setTimeValue = function(value){
        if (value == null) return ;
        
        var hour = value.getHours().toString().lomtecPadLeft(2);
        var minute = value.getMinutes().toString().lomtecPadLeft(2);
                 
        var oldValue = getTextValue();
        var date = oldValue.split(' ');
        var newValue = hour + ':' + minute + ':00';
         
        if(date.length == 2 )  setTextValue(date[0] + ' ' + newValue,true);
        else setTextValue('00/00/0000 ' + newValue,true);
    };

    //===============================================
    //    
    //private functions
    //
    //===============================================    
    function getDateValue(value){
        var all = value.split(' ');                   if(all.length!=2)  return null ;
        var date = all[0].split('/');                 if(date.length!=3) return null ;
        var time = all[1].split(':');                 if(time.length!=3) return null ;  
        try {
            for (var i=0;i < 3; i++)  {
                date[i] = date[i].lomtecParseInt();  if( isNaN(date[i]) ) return null;
                time[i] = time[i].lomtecParseInt();  if( isNaN(time[i]) ) return null; 
            }
            var n = new Date(date[2],date[0]-1,date[1],time[0],time[1],time[2]);
            return n;
        }
        catch(e){
        }
        return null;
    };
    
    function isTimeShow(){
        if(tbHourCtrl == null || tbMinuteCtrl==null) return false;
        return true;
    };
    function getValue(){
        //get value and 
        return getDateValue(getTextValue());
    };  
    function getTextValue(){
        //get value and remove valid flag :-)
        return hfValueCtrl.value.replace(/!/g,'');
    };

    function setTextValue(value,controls,valid,isvalid){
        //
        if(typeof(controls) == 'undefined') controls=true;
        if(typeof(valid)    == 'undefined') valid=true;
        if(typeof(isvalid) == 'undefined')  isvalid=true;

        //update controls (for manual edit it is not need        
        if(controls){
            var all=value.split(' ');            

            if(all.length==2)  {
                var date = all[0].split('/');          
                if(date.length==3){ 
                    if( date[1]!= '00')  tbDayCtrl.value = date[1];
                    else                 tbDayCtrl.value = '';
                    if( date[0]!= '00')  tbMonthCtrl.value = date[0];
                    else                 tbMonthCtrl.value = '';   
                    if( date[2]!= '0000')tbYearCtrl.value = date[2];
                    else                 tbYearCtrl.value = '';   
                }
                var time = all[1].split(':');           
                if(isTimeShow() && time.length==3) {
                    tbHourCtrl.value = time[0];
                    tbMinuteCtrl.value = time[1];
                }
            }
        }
        var test = isvalid;
        //valdiate data... for clear is not need
        if(valid) test = validate(value);

        //send event if valid      
        if(getTextValue() != value && test && (Function.prototype.eventDateTimePickerDateChanged != null || self.onChange != null) ){
            var n = getDateValue(value);        
            var o = getValue();
        
            try{    
                if(n == null || o == null) {
                       if(self.onChange != null) self.onChange(self,n,o,null);
                       if(Function.prototype.eventDateTimePickerDateChanged != null) Function.eventDateTimePickerDateChanged(self,n,o,null);
                }
                else{
                       var delta = n-o;
                       //local event
                       if(self.onChange != null) self.onChange(self,n,o,delta);
                       //global event
                       if(Function.prototype.eventDateTimePickerDateChanged != null) Function.eventDateTimePickerDateChanged(self,n,o,delta);
                }
            }
            catch(e){
            }
        }    
       
        //update hf to new value
        if(test == false ) hfValueCtrl.value = '!' + value;
        else hfValueCtrl.value = value;
    };
    
    
    //change css for control (to signalize error)
    function changeCSS(ctrl,error){
       if( ctrl == null ) return;

       if(error){
           if( ctrl.className.indexOf('-error') < 0 ) ctrl.className = ctrl.className + '-error';
       }
       else{
           var index = ctrl.className.indexOf('-error');
           if( index > 0 ) ctrl.className = ctrl.className.substr(0,index);
       }
    };
    
    //report bad date format (set css for my controlers)
    function badDate(type){
        switch(type){
            case 'A':   changeCSS(tbHourCtrl,true);
                        changeCSS(tbMinuteCtrl,true);
                        changeCSS(tbDayCtrl,true);
                        changeCSS(tbMonthCtrl,true);
                        changeCSS(tbYearCtrl,true);
                        break;
            case 'D':   changeCSS(tbDayCtrl,true);
                        changeCSS(tbMonthCtrl,true);
                        changeCSS(tbYearCtrl,true);
                        break;
            case 'T':   changeCSS(tbHourCtrl,true);
                        changeCSS(tbMinuteCtrl,true);
                        break;
            case 'm':   changeCSS(tbMonthCtrl,true);
                        break;
            case 'd':   changeCSS(tbDayCtrl,true);
                        break;
            case 'y':   changeCSS(tbYearCtrl,true);
                        break;
            case 'h':   changeCSS(tbHourCtrl,true);
                        break;
            case 't':   changeCSS(tbMinuteCtrl,true);
                        break;
            default:    changeCSS(tbHourCtrl,false);
                        changeCSS(tbMinuteCtrl,false);
                        changeCSS(tbDayCtrl,false);
                        changeCSS(tbMonthCtrl,false);
                        changeCSS(tbYearCtrl,false);
                        break;
        }
    };
    
    //validate control
    function validate(result){
       var range = true;
    
       function validateDate(value) {
            var all = value.split(' ');                   if(all.length!=2)  return 'A' ;
            var date = all[0].split('/');                 if(date.length!=3) return 'D' ;
            var time = all[1].split(':');                 if(time.length!=3) return 'T' ;  
            try {
                for (var i=0;i < 3; i++)  {
                    date[i] = date[i].lomtecParseInt();  if( isNaN(date[i]) ) return 'D' ;
                    time[i] = time[i].lomtecParseInt();  if( isNaN(time[i]) ) return 'T' ;
                }
                var n = new Date(date[2],date[0]-1,date[1],time[0],time[1],time[2]);
                
                if (date[2] == n.getFullYear() && date[0] == (n.getMonth() + 1) && date[1] == n.getDate() &&
                    time[0] == n.getHours() && time[1] == n.getMinutes() && time[2] == n.getSeconds())
                            return null;
            }
            catch(e){
            }
            return 'A';
       };
    
       var test = validateDate(result)
       if(test != null) { badDate(test); return false; }
    
       var n = getDateValue(result);        
       var nval = n.valueOf();
    
       if(typeof(dateSettings) != 'undefined' && dateSettings != null){
       
           if(typeof(dateSettings.range) != 'undefined' && dateSettings.range!=null) {
               var rangeDates = dateSettings.range;
               if( rangeDates.length ==2 && ( nval < rangeDates[0].valueOf() || nval > rangeDates[1].valueOf() ) ) range = false;
           }
           else{
                var test = new Date();  test.setFullYear(1900,0,1);
                if( nval < test.valueOf() ) range = false;
                test.setFullYear(2100,0,1);
                if( nval > test.valueOf() ) range = false;
           }

           //disable dates validation
           if(range && typeof(dateSettings.days) != 'undefined' && dateSettings.days!=null){
                 var disabledDays = dateSettings.days;
                 if( disabledDays.join(',').indexOf( n.getDay().toString() ) > -1) range = false;
           }
            
           //disabled days validation
           if(range && typeof(dateSettings.dates) != 'undefined' && dateSettings.dates!=null){
                var disabledDates = dateSettings.dates;
                for(var i = 0; i < disabledDates.length ; i++){
                    if( typeof(disabledDates[i]) == 'object') {
                        if(disabledDates[i].constructor==Date && disabledDates[i].getFullYear()==n.getFullYear() && disabledDates[i].getMonth()==n.getMonth() && disabledDates[i].getDate()==n.getDate())  { 
                            range = false; break; 
                        }
                        
                        else if( disabledDates[i].constructor==Array && disabledDates[i].length == 2 && disabledDates[i][0].constructor==Date &&  disabledDates[i][1].constructor==Date && nval >= disabledDates[i][0].valueOf() && nval <= disabledDates[i][0].valueOf() ) { 
                            range = false; break; 
                        }
                    }
               }
           }
       }
       //report status
       if(!range) badDate('A');
       else badDate();
       return range;
    };

    //===============================================
    //    
    //public functions
    //
    //===============================================        

    //initialize members
    this.initialize = function (){
        if(parentCtrl == null && ctrlID != null ) {
            parentCtrl = document.getElementById(ctrlID);
            //controls to show values
            tbDayCtrl   = lomtec.Utility.UI.findChildrenByName(parentCtrl,'tbDay');
            tbMonthCtrl = lomtec.Utility.UI.findChildrenByName(parentCtrl,'tbMonth');
            tbYearCtrl  = lomtec.Utility.UI.findChildrenByName(parentCtrl,'tbYear');
            tbHourCtrl  = lomtec.Utility.UI.findChildrenByName(parentCtrl,'tbHour');
            tbMinuteCtrl= lomtec.Utility.UI.findChildrenByName(parentCtrl,'tbMinute');
            //value
            hfValueCtrl = lomtec.Utility.UI.findChildrenByName(parentCtrl,'hfValue');
        }
        //partial test for this control
        if(parentCtrl != null && hfValueCtrl != null) return 0;
        return 1;
    };

    //setting focus and signalize data status
    this.setFocus = function(ctrl) {
       if(ctrl == null) return;
       
       function validateInput(p,min,max) {
            if(p == '') return '';
        
            for(var i = 0; i<p.length ; i++) {
                if ( p[i] < '0'  || p[i] > '9' ) return null;
            }
            
            var val = p.toString().lomtecParseInt();
            if( isNaN(val) ) return null;
            if( typeof(min) != 'undefined' &&  val < min ) return null;
            if( typeof(max) != 'undefined' &&  val > max ) return null;    
            return val;
       };
       
       var newctrl = null, value = null;
    
       //get values and test range
       var day  = validateInput(tbDayCtrl.value,1,31);
       var mon  = validateInput(tbMonthCtrl.value,1,12);
       var year = validateInput(tbYearCtrl.value,1900,2100);
       var hour = null, min  = null;
       if(isTimeShow())   {
            hour = validateInput(tbHourCtrl.value,0,23);
            min = validateInput(tbMinuteCtrl.value,0,59);
       }
       //copy value to store
       if (ctrl.id.indexOf("tbDay")  >0)       {  value = day;  newctrl = tbMonthCtrl;   }
       else if(ctrl.id.indexOf("tbMonth")>0)   {  value = mon;  newctrl = tbYearCtrl;    }
       else if(ctrl.id.indexOf("tbYear") >0)   {  value = year; newctrl = tbHourCtrl;    }
       else if(ctrl.id.indexOf("tbHour") >0)   {  value = hour; newctrl = tbMinuteCtrl;  }
       else if(ctrl.id.indexOf("tbMinute") >0) {  value = min;                           }
       //display error
       var error = false;
       if(day  == null)   { error = true; badDate('d'); }
       if(mon  == null)   { error = true; badDate('m'); }
       if(year == null)   { error = true; badDate('y'); }
       if(isTimeShow()){
         if(hour == null) { error = true; badDate('h'); }
         if(min  == null) { error = true; badDate('t'); }
       }
       //create values to hidden field       
       day  = day  == null ? '00'   : day.toString().lomtecPadLeft(2);
       mon  = mon  == null ? '00'   : mon.toString().lomtecPadLeft(2);
       year = year == null ? '0000' : year.toString().lomtecPadLeft(4);
       hour = hour == null ? '00'   : hour.toString().lomtecPadLeft(2);
       min  = min  == null ? '00'   : min.toString().lomtecPadLeft(2);

       var result = mon + '/' + day  + '/' +  year + ' ' +  hour + ':' + min + ':00'; 

       setTextValue(result,false,!error,false);

       //set new focus
       if (ctrl.value.length == ctrl.maxLength && ctrl.readOnly == false && ctrl.defaultValue != ctrl.value ) {
            ctrl.defaultValue = value;
            if( newctrl != null && value != null){  newctrl.focus();  newctrl.select();  }
       }
       
    };
    
    //clear event
    this.clear = function(){
            //date
            tbDayCtrl.value = '';
            tbMonthCtrl.value = '';
            tbYearCtrl.value = '';
            //time
            if(isTimeShow())   {
                tbHourCtrl.value = '';
                tbMinuteCtrl.value = '';
            }
            //values
            var old = getValue();    
            setTextValue('',false,false);
            badDate();
            
            try{    
                 //local event
                 if(self.onChange != null) self.onChange(this,null,old,null);
                 //global event
                 if(Function.prototype.eventDateTimePickerDateChanged != null) Function.eventDateTimePickerDateChanged(this,null,old,null);
            }
            catch(e){
            }
    };
    
    //show
    this.showCalendar = function(eve){
        lomtec.Controls.UI.Script.JACS.show(self,eve);
    };

    this.showTime = function(eve){
        lomtec.Controls.UI.Script.JATS.show(self,eve);
    };

    //hide
    this.hide = function(){
        lomtec.Controls.UI.Script.JACS.hide();
        lomtec.Controls.UI.Script.JATS.hide();
    };

};
   

