function showCalendar( button, rooturl ) {
    return showCalendar( button, "en", "", "default" );
}

function showCalendar( button, lang, rootURL, rootTemplate ) {

    appLang = lang;
    appRootURL = rootURL;
    appRootTemplate = rootTemplate;

    if ( appLang=="de" ) {

          CAL_monthNames = new Array(
            "Januar", "Februar", "M&auml;rz", "April", "Mai", "Juni", "Juli",
            "August", "September", "Oktober", "November", "Dezember" );

          CAL_weekDayNames = new Array(
            "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So" );

    } else if ( appLang=="ru" ) {

          CAL_monthNames = new Array(
            "&#1071;&#1085;&#1074;&#1072;&#1088;&#1100;", "&#1060;&#1077;&#1074;&#1088;&#1072;&#1083;&#1100;",
            "&#1052;&#1072;&#1088;&#1090;", "&#1040;&#1087;&#1088;&#1077;&#1083;&#1100;",
            "&#1052;&#1072;&#1081;", "&#1048;&#1102;&#1085;&#1100;",
            "&#1048;&#1102;&#1083;&#1100;", "&#1040;&#1074;&#1075;&#1091;&#1089;&#1090;",
            "&#1057;&#1077;&#1085;&#1090;&#1103;&#1073;&#1088;&#1100;", "&#1054;&#1082;&#1090;&#1103;&#1073;&#1088;&#1100;",
            "&#1053;&#1086;&#1103;&#1073;&#1088;&#1100;", "&#1044;&#1077;&#1082;&#1072;&#1073;&#1088;&#1100;" );

          CAL_weekDayNames = new Array(
            "&#1055;&#1085;", "&#1042;&#1090;", "&#67;&#112;", "&#1063;&#1090;", "&#1055;&#1090;", "&#1057;&#1073;", "&#66;&#99;" );

    } else {
          CAL_monthNames = new Array(
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "October", "November", "December" );

          CAL_weekDayNames = new Array(
            "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" );
    }

    currentCalendar = CAL_getCalendar( button );
    currentCalendar.show();
    return false;
}

function hideCalendar() {

    if ( currentCalendar ) {
        if ( currentCalendar.visible ) {
            currentCalendar.hide();
            currentCalendar = null;
        }
    }
}

var CAL_monthNames = new Array();
var CAL_weekDayNames = new Array();

var CAL_monthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var CAL_dayBeforeMonth = true;
var CAL_datePattern = /^(\d{1,2})\D(\d{1,2})\D(\d{1,4})$/;
var CAL_timePattern = /^(\d{1,2})\D(\d{1,2})$/;
var CAL_window = new CalendarWindow ();

// for different visualizes of saturday, sunday, holidays (implemented not yet)
// one entry per day
var cssCtrlArr = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

/******************************************/

/**
 * CalendarWindow
 *      Calendar class definition
 */
function CalendarWindow ()
{
    this.open = CAL_windowOpen;
    this.close = CAL_windowClose;
    this.writeBodyContent = CAL_windowWriteBodyContent;
    this.window = null;
    this.calendars;
    this.title  = 'Kalender';
    this.width  = '250';
    this.height = '210';

    var leftPos  = screen.width  ? (screen.width-this.width)/2  : 0;
    var topPos   = screen.height ? (screen.height-this.height)/2 : 0;
    this.options = 'resizable=no,alwaysRaised=yes,top=' + topPos + ',left=' + leftPos;
}

/**
 * set the date of a calendar. argument must
 * have format "dd.mm.yyyy"
 */
function CAL_setDate( dateString )
{
    date = CAL_parseDate( dateString );
    if ( !date ) date = new Date();

    currentCalendar.setYear( date.getYear() );
    currentCalendar.setMonth( date.getMonth() );
    currentCalendar.setDayOfMonth( date.getDate() );
}

function CAL_windowOpen ()
{
    optionString = 'width=' + this.width + ',height=' + this.height;

    if (this.options && this.options.length > 0)
        optionString += ',' + this.options;

    this.window = open ('about:blank', 'Calendar', optionString);
    if (this.window.focus)
    {
        this.window.focus();
    }
}

function CAL_windowClose ()
{
    if(this.window && !this.window.closed) {
        this.window.close();
    }
}

/**
 * CAL_initCalendar  -- initializes calendar
 *  param - element  -> a text field, which is to fill with selected calendar dates
 */
function CAL_initCalendar (element, state)
{
    currentCalendar = CAL_getCalendar(element);
    currentCalendar.state = state;
    if (!currentCalendar.inputField.value.length > 0)
    {
        currentCalendar.display();
        currentCalendar.inputField.select();
    }
}

function CAL_windowWriteBodyContent (content)
{
    var doc = this.window.document;
    doc.open('text/html');
    doc.write( '<HTML>\n' );
    doc.write( '<HEAD>\n' );
    doc.write( '<TITLE>' + this.title + '</TITLE>\n' );
    doc.write( '<STYLE TYPE="text/css">\n' );

    doc.write( 'a.cal {\n' );
    doc.write( '        color: #FFcc00;\n' );
    doc.write( '        text-decoration: none;\n' );
    doc.write( '}\n' );

    doc.write( '.cal0 {\n' );
    doc.write( '        text-align: center;\n' );
    doc.write( '        font-weight: bold;\n' );
    doc.write( '        color:blue;\n' );
    doc.write( '        font-family: Arial,Helvetica,sans-serif;\n' );
    doc.write( '        font-size: 12px;\n' );
    doc.write( '        text-decoration: none;\n' );
    doc.write( '}\n' );

    doc.write( '.cal1 {\n' );
    doc.write( '        text-align: center;\n' );
    doc.write( '        font-weight: 600;\n' );
    doc.write( '        color:green;\n' );
    doc.write( '        font-family: Arial,Helvetica,sans-serif;\n' );
    doc.write( '        font-size: 12px;\n' );
    doc.write( '        text-decoration: none;\n' );
    doc.write( '}\n' );

    doc.write( '.cal2 {\n' );
    doc.write( '        text-align: center;\n' );
    doc.write( '        font-weight: 600;\n' );
    doc.write( '        color: blue;\n' );
    doc.write( '        font-family: Arial,Helvetica,sans-serif;\n' );
    doc.write( '        font-size: 12px;\n' );
    doc.write( '        text-decoration: none;\n' );
    doc.write( '}\n' );

    doc.write( '.cal3 {\n' );
    doc.write( '        text-align: center;\n' );
    doc.write( '        font-weight: 600;\n' );
    doc.write( '        color: cyan;\n' );
    doc.write( '        font-family: Arial, Helvetica, sans-serif;\n' );
    doc.write( '        font-size: 12px;\n' );
    doc.write( '        text-decoration: none;\n' );
    doc.write( '}\n' );

    doc.write( '.pfeil {\n' );
    doc.write( '    text-align: center;\n' );
    doc.write( '    font-weight: 900;\n' );
    doc.write( '    color: #CC3300;\n' );
    doc.write( '    font-family: Arial, Helvetica, sans-serif;\n' );
    doc.write( '    font-size: 16px;\n' );
    doc.write( '    text-decoration: none;\n' );
    doc.write( '}\n' );

    doc.write( 'td.cal {\n' );
    doc.write( '    text-align: center;\n' );
    doc.write( '    font-family: Arial, Helvetica, sans-serif;\n' );
    doc.write( '    font-size: 12px;\n' );
    doc.write( '    font-weight: 600;\n' );
    doc.write( '    color: #000000;\n' );
    doc.write( '}\n' );

    doc.write( 'x.calhead {\n' );
    doc.write( '    text-align: center;\n' );
    doc.write( '    font-family: Arial, Helvetica, sans-serif;\n' );
    doc.write( '    font-size: 12px;\n' );
    doc.write( '    font-weight: normal;\n' );
    doc.write( '    color: #000000;\n' );
    doc.write( '}\n' );

    doc.write( '.calhead {\n' );
    doc.write( '    text-align: center;\n' );
    doc.write( '    font-family: Arial, Helvetica, sans-serif;\n' );
    doc.write( '    font-size: 12px;\n' );
    doc.write( '    font-weight: normal;\n' );
    doc.write( '    color: #000000;\n' );
    doc.write( '}\n' );

    doc.write( '.calday {\n' );
    doc.write( '    text-align: center;\n' );
    doc.write( '    font-family: Arial, Helvetica, sans-serif;\n' );
    doc.write( '    font-size: 11px;\n' );
    doc.write( '    color: #000000;\n' );
    doc.write( '}\n' );

    doc.write( 'b { font-weight: 600; }\n' );
    doc.write( '</STYLE>\n' );
    doc.write( '</HEAD>\n' );
    doc.write( content );
    doc.write( '</HTML>\n' );
    doc.close();
}

function fillWithNulls(number, length)
{
    s = new String();
    numberString = new String(number);
    for (i = 0; i < length - numberString.length; i ++)
        s += '0';
    s += number;
    return s;
}

function CAL_getCalendarByName (calendarName)
{
    if (!window.calendars)
        window.calendars = new Array();

    if (window.calendars[calendarName])
    {
        c = window.calendars[calendarName];
        return c;
    }
    return null;
}

function CAL_getCalendar (element)
{
    calendarName = CAL_getCalendarName(element.name);

    if (!window.calendars)
        window.calendars = new Array();

    if (window.calendars[calendarName])
    {
        return window.calendars[calendarName];
    }
    else
    {
        window.calendars[calendarName] = new CAL_Calendar(element);
        return window.calendars[calendarName];
    }
}

function CAL_getCalendarName(name)
{
    return (name.substring(0, 4) == 'btn_') ? name.substring(4, name.length) : name;
}

function CAL_doOnCalendarClick (calendarName, dayOfMonth)
{
    currentCalendar = CAL_getCalendarByName(calendarName);
    if (currentCalendar)
    {
        currentCalendar.setDayOfMonth(dayOfMonth);
        currentCalendar.display();
    }
}

function CAL_goPrevYear(calendarName)
{
    currentCalendar = CAL_getCalendarByName(calendarName);
    if (currentCalendar) {
        currentCalendar.setYear(currentCalendar.getYear() - 1);
        currentCalendar.show();
    }
}

function CAL_goNextYear(calendarName)
{
    currentCalendar = CAL_getCalendarByName(calendarName);
    if (currentCalendar) {
        currentCalendar.setYear(currentCalendar.getYear() + 1);
        currentCalendar.show();
    }
}

function CAL_goPrevMonth(calendarName)
{
    currentCalendar = CAL_getCalendarByName(calendarName);
    if (currentCalendar) {
        if (currentCalendar.getMonth() < 1) {
            currentCalendar.setYear(currentCalendar.getYear() - 1);
            currentCalendar.setMonth(11);
        } else {
            currentCalendar.setMonth(currentCalendar.getMonth() - 1);
        }
        currentCalendar.show();
    }
}

function CAL_goNextMonth(calendarName)
{
    currentCalendar = CAL_getCalendarByName(calendarName);
    if (currentCalendar) {
        if (currentCalendar.getMonth() > 10) {
            currentCalendar.setYear(currentCalendar.getYear() + 1);
            currentCalendar.setMonth(0);
        } else {
            currentCalendar.setMonth(currentCalendar.getMonth() + 1);
        }
        currentCalendar.show();
    }
}

function CAL_validateCalendar (element, alertMsg)
{
    currentCalendar = CAL_getCalendar(element);
    if (currentCalendar.inputField.value.length > 0)
    {
        return currentCalendar.validate(alertMsg);
    }
    return false;
}

function CAL_showCalendar (element, state)
{
    currentCalendar = CAL_getCalendar(element);
    currentCalendar.state = state;
    currentCalendar.show();
    return currentCalendar;
}

function CAL_correctYear (year)
{
    year = year % 100;
    year = ((year < 70) ? (2000 + year) : (1900 + year));
    return year;
}

function CAL_getMonthDays (month, year)
{
    if (month != 1)
        return CAL_monthDays[month];
    return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? 29 : 28;
}

function CAL_setWeekDayNames (weekDayNames)
{
    CAL_weekDayNames = weekDayNames;
}
function CAL_getWeekDayNames ()
{
    return CAL_weekDayNames;
}

function CAL_setMonthNames (monthNames)
{
    CAL_monthNames = monthNames;
}
function CAL_getMonthNames ()
{
    return CAL_monthNames;
}

function CAL_parseDate (dateString)
{
  if (dateString.length > 0)
  {
    if (CAL_datePattern.exec(dateString))
    {
      currentDay = (CAL_dayBeforeMonth) ? RegExp.$1 : RegExp.$2;
      currentMonth = (CAL_dayBeforeMonth) ? RegExp.$2 : RegExp.$1;
      currentYear = CAL_correctYear(RegExp.$3);
      date = new Date(currentYear, currentMonth - 1, currentDay);
      return (date.getDate() == currentDay && date.getMonth() == currentMonth - 1) ? date : null;
    }
  }
  return null;
}

function CAL_Calendar (element)
{
  this.setYear = CAL_setYear;
  this.getYear = CAL_getYear;
  this.setMonth = CAL_setMonth;
  this.getMonth = CAL_getMonth;
  this.setDayOfMonth = CAL_setDayOfMonth;
  this.getDayOfMonth = CAL_getDayOfMonth;
  this.validate = CAL_validate;
  this.display = CAL_displayDate;
  this.show = CAL_show;
  this.hide = CAL_hide;
  this.setDate = CAL_setDate;

  this.name = CAL_getCalendarName(element.name);
  this.window = CAL_window;
  this.inputForm = element.form;
  this.inputField = CAL_getInputField(this);
  this.selectedDate = CAL_parseDate(this.inputField.value);
  if (!this.selectedDate) this.selectedDate = new Date();
  this.setYear(this.selectedDate.getYear());
  this.setMonth(this.selectedDate.getMonth());
  this.setDayOfMonth(this.selectedDate.getDate());
  this.state = 0;
  this.visible = false;
}

function CAL_validate (alertMsg)
{
  dateString = this.inputField.value;
  if (dateString.length == 0)
      return true;
  date = CAL_parseDate(dateString);
  if (date != null)
  {
    this.setDayOfMonth(date.getDate());
    this.setMonth(date.getMonth());
    this.setYear(date.getYear());
    this.display();
    return true;
  }
  else
  {
    CAL_DisplayError(alertMsg, this.inputField);
    this.inputField.focus();
    this.inputField.select();
    return false;
  }
}

function CAL_setDayOfMonth (dayOfMonth)
{
  dayOfMonth = new String(dayOfMonth);
  dayOfMonth = eval(dayOfMonth.replace('/^0*/', ''));
  this.dayOfMonth = dayOfMonth;
}
function CAL_getDayOfMonth ()
{
  return this.dayOfMonth;
}

function CAL_setMonth (month)
{
  month = new String(month);
  month = eval(month.replace('/^0*/', ''));
  this.month = month;
}
function CAL_getMonth ()
{
  return this.month;
}

function CAL_setYear (year)
{
    this.year = CAL_correctYear(year);
}
function CAL_getYear ()
{
    return this.year;
}

function CAL_getInputField (calendar)
{
    for (i = 0; i < calendar.inputForm.elements.length; i ++)
    {
        current = calendar.inputForm.elements[i];
        if (current.name == calendar.name)
            return current;
    }
}

function CAL_displayDate ()
{
    dateString = fillWithNulls(this.getDayOfMonth(), 2);
    dateString += '.' + fillWithNulls(this.getMonth() + 1, 2);
    dateString += '.' + this.getYear();
    this.inputField.value = dateString;

    if ( this.inputField.callback ) {
        // user has registered a callback function for the field
        // displaying the selected date. So we will evaluate it
        eval( this.inputField.callback );
    }

    this.hide();
}

function CAL_hide ()
{
    this.window.close();
    this.visible = false;
}

function CAL_show ()
{
    emptyFirstRow = false;
    firstDay = (new Date(this.getYear(), this.getMonth(), 1).getDay());
    if (firstDay == 0)
    {
        firstDay += 7;
    }
    monthDays = CAL_getMonthDays(this.getMonth(), this.getYear());
    html = '';
    html += '<HEAD>';        // EEEEAA
    html += '<BODY bgcolor="#f2f2f2" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">';
    html += '<CENTER>';
    html += '<TABLE background="' + appRootURL + '/templates/' + appRootTemplate + '/gfx/header-bg.gif" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="8" ALIGN="center" VALIGN="top">';
    html += '<TR>';
    html += '<TD align=center><A HREF="javascript:opener.CAL_goPrevYear(\''  + this.name + '\');" class="pfeil"><img src="' + appRootURL + '/common/images/rewind.gif"      border="0"></A></TD>';
    html += '<TD align=center><A HREF="javascript:opener.CAL_goPrevMonth(\'' + this.name + '\');" class="pfeil"><img src="' + appRootURL + '/common/images/arrow-left.gif"  border="0"></A></TD>';
    html += '<TD align=center width="100%" nowrap><font class="calhead"><b>';
    html += CAL_getMonthNames()[this.getMonth()] + '&nbsp;' + this.getYear();
    html += '</b></font></TD>';
    html += '<TD align=center><A HREF="javascript:opener.CAL_goNextMonth(\'' + this.name + '\');" class="pfeil"><img src="' + appRootURL + '/common/images/arrow-right.gif" border="0"></A></TD>';
    html += '<TD align=center><A HREF="javascript:opener.CAL_goNextYear(\''  + this.name + '\');" class="pfeil"><img src="' + appRootURL + '/common/images/skip.gif"        border="0"></A></TD>';
    html += '</TR>';
    html += '</TABLE>';
    html += '<TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">';
    html += '<tr><td bgcolor=#808080><img src="' + appRootURL + '/common/images/void.gif" alt="" height=1 width=1></td></tr>';
    html += '</TABLE>';

    html += '<TABLE WIDTH="100%" BORDER=0 CELLPADDING="10" ALIGN="center" VALIGN="top">';
    html += '<TR><TD WIDTH="100%" ALIGN="CENTER" VALIGN="top">';
    html += '<TABLE width="100%" BORDER="0" CELLSPACING="5" CELLPADDING="0">';
    html += '<TR>';
    for (cols = 0; cols < 7; cols ++)
    {
        html += '<TD WIDTH="10%" align=center>' + '<font CLASS="calday">' + '<b>'
                 + CAL_getWeekDayNames()[cols] + '</b>' + '</font>' + '</TD>';
    }
    html += '</TR>';
    if (emptyFirstRow)
    {
        html += '<TR>';
        for (cols = 0; cols < 7; cols ++)
        {
            html += '<TD WIDTH="10%" CLASS="cal">&nbsp;&nbsp;</TD>';
        }
        html += '</TR>';
    }

    var cssDayVar = 'cal0';
    var dayStr;
    for (rows = 0; rows < 6; rows ++)
    {
        if (rows > 0 && nextEmpty)
            break;
        html += '<TR>';
        for (cols = 0; cols < 7; cols ++)
        {
            day = (rows * 7 + cols) - firstDay + 2;
            dayStr = ""+day;
            if (day < 10)
            {
                dayStr = "&nbsp;" + day;
            }
            cssDayVar = 'cal0';
            if (cssCtrlArr[day-1])
            {
               cssDayVar = 'cal' + cssCtrlArr[day-1];
            }

            if ((day > 0) && (day <= monthDays))
            {
                html += '<TD WIDTH="10%" align=center> '
                        + '<A HREF="javascript:opener.CAL_doOnCalendarClick(\''
                        + this.name + '\',' + day + ');" class=' + cssDayVar + '>'
                        + dayStr + '</A></TD>';
                nextEmpty = !((day + 1) <= monthDays);
            }
            else
            {
                html += '<TD WIDTH="10%">&nbsp;&nbsp;</TD>';
                nextEmpty = true;
            }
        }
        html += '</TR>';
    }
    html += '</TABLE><br class="calday">';
    html += '</TD></TR></TABLE>';
    html += '</BODY>';
    if (!this.visible || this.window.window.closed)
        this.window.open();
    this.visible = true;
    this.window.writeBodyContent(html);
}


function CAL_DisplayError(errorMessage, element)
{
    alert(errorMessage);
    if (element)
    {
        element.focus()
        element.select();
    }
}

/*************************************
 * TIME
 *************************************/

function CAL_initTime (element)
{
    if (!element.value.length > 0) {
        date = new Date();
        element.value = fillWithNulls(date.getHours(), 2) + ':'
                                       + fillWithNulls(date.getMinutes(), 2);
        element.select();
    }
}

function CAL_validateTime (element, alertTimeFmt, alertTimeVal)
{
    if (element.value.length > 0) {
        if (CAL_timePattern.exec(element.value)) {
            currentHours = RegExp.$1;
            currentMinutes = RegExp.$2;
            if (currentHours < 0 || currentHours > 23) {
                CAL_DisplayError(alertTimeVal, element);
            } else if (currentMinutes < 0 || currentMinutes > 59) {
                CAL_DisplayError(alertTimeVal, element);
            } else {
                element.value = fillWithNulls(currentHours, 2) + ':'
                                              + fillWithNulls(currentMinutes, 2);
            }
        } else {
            CAL_DisplayError(alertTimeFmt, element);
        }
    }
}