


// Calendar control in Javascript
//
// Copyright (C) Ampersand Corporation, 1999-2001
// All rights reserved
//
// M. A. Sridhar, April 27th, 2000
//
// Modified Aug 4th, 2001, to use iframe instead of div, and remove the
// dragging facility, so that the calendar can obscure any combo boxes it
// intersects with.
//


// Public methods:
//    attach (aTextBox)   --  Attach this calendar to the given text
//                            box. The effect will be to display the
//                            calendar next to the box.
//    isAttached ()       --  Tell whether this calendar is currently
//                            attached.
//    hide ()             --  Hide this calendar.
//
//    show ()             --  Show this calendar.
//
// This control currently only works with IE. Only one instance of this
// control may be created on a page, but it can be attached to multiple date
// boxes on demand.


// Constants:
var Calendar__Name      = "__zc__Calendar";
var CALENDAR_BOX_WIDTH  = 150;
var CALENDAR_BOX_HEIGHT = 160;

// Constructor: Create a calendar control that initially displays the given
// month and year.
// This is just like a C++ or Java class.
//

var calendarIframeStyle = "background-color: #bbbbbb; " +
    "border: 2; " +
    "border-style: outset; " +
    "position: absolute; " +
    "display: none";

var calendarOuterTableStyle = "background-color: #bbbbbb; " +
    "font-size: 7pt; " +
    "font-family: Tahoma";

var calendarInnerTableStyle = "background-color: #bbbbbb; " +
    "font-size: 7pt; " +
    "font-family: Tahoma";



function CalendarControl () {
    var calendarName      = Calendar__Name;
    this.calendarHtml     = _Calendar__calendarHtml;
    this.attach           = _Calendar__attach;
    this.isAttached       = _Calendar__isAttached;
    this.hide             = _Calendar__hide;
    this.show             = _Calendar__show;
    this.setMonth         = _Calendar__setMonth;
    this.moveTo           = _Calendar__moveTo;
    this.name             = Calendar__Name;
    if (document[calendarName]) {
        alert ("calendar.js: Attempt to create duplicate calendar " +
               " with name '" + calendarName + "'");
    } else {
        document[calendarName] = this;
    }
    if (document.all) {
        document.body.insertAdjacentHTML
            ("beforeEnd",
             "<iframe name=\"" + Calendar__Name + "\" id=\"" +
             Calendar__Name + "\" style=\"" + calendarIframeStyle + "\" " +
             "class=calendarIframeClass marginwidth=0 marginheight=0 " +
             " onclick=\"parent._Calendar__documentClick('" + calendarName
             + "')\"" +
             " src=\"javascript:parent.Calendar__setBox (document)\" " +
             "scrolling=no framespacing=0 frameborder=no " +
             "width=\"" + CALENDAR_BOX_WIDTH + "\" height=\"" +
             CALENDAR_BOX_HEIGHT + "\"></iframe>");
        // Do this only in IE
        document.body.onclick = _Calendar__documentClick;

        this.hide();
    }
    return this;
}




/* -------------------------------------------------------------------------*/
/* Everything below is private to the calendar control, and should not be   */
/* used by code external to this file.                                      */
/* -------------------------------------------------------------------------*/


var _Calendar_wkDays       = ["S", "M", "T", "W", "T", "F", "S"];
var _Calendar_daysInMonth  = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var _Calendar_monthNames   = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
                              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];



var _calendarIframeBox = null;

function Calendar__setBox (documentElt) {
    _calendarIframeBox = documentElt;
    documentElt.onclick = _Calendar__documentClick;
    return "";
}


function _Calendar__hide () {
    document.all (Calendar__Name).style.display = "none";
}


function _Calendar__show () {
    var box = document.all (Calendar__Name);
    box.style.display = "block";
}


function _Calendar__documentClick () {
    var elt = _calendarIframeBox;
    if (elt) {
        calendar.hide();
    }
}

    
function Debug (s) {
    var debugDiv = document.all ("Debug");
    if (debugDiv) {
        debugDiv.insertAdjacentText ("beforeEnd", s);
    }
}


function _Calendar__isAttached () {
    return this._dateBox != null;
}


function _Calendar__setMonth (month, year) {
    _calendarIframeBox.body.innerHTML = this.calendarHtml (month, year);
}


function _Calendar__attach (dateBox) {
    if (typeof (dateBox) == "string") {
        dateBox = document.all (dateBox);
    }
    var dateBoxValue = dateBox.value;
    var dateBoxContentDate = null;
    var month, year;
    if (dateBoxValue && (dateBoxValue.length > 0)) {
        // The box seems to have a date in it.
        var mSec = Date.parse (dateBoxValue);
        if (mSec == 0 || isNaN (mSec)) {
            dateBoxContentDate = new Date();
        } else {
            dateBoxContentDate = new Date (mSec);
        }
        month = dateBoxContentDate.getMonth();
        year  = dateBoxContentDate.getYear();
        if (year < 100) {
            year += 1900;
        }
    } else {
        // No date in the box, so use today's date.
        var today = new Date();
        month = today.getMonth();
        year  = today.getYear();
    }
    
    // Position the calendar box
    var rect = dateBox.getBoundingClientRect();
    // var style = _calendarIframeBox.style;
    var style = document.all(Calendar__Name).style;
    style.top  = rect.bottom  + 1 + document.body.scrollTop;
    style.left = rect.left + document.body.scrollLeft;
    
    // Fill it out with the appropriate HTML
    _calendarIframeBox.body.innerHTML = this.calendarHtml (month, year);

    // Make it visible
    this.show ();

    // Remember the box to which we're attached.
    this._dateBox = dateBox;

    // Inhibit event bubbling
    event.cancelBubble = true;

}


function _Calendar__moveTo (left, top) {
    var style = document.all(Calendar__Name).style;
    style.top  = top;
    style.left = left;
}



function _Calendar_updateDisplay (calendarName, month, year) {
    var html = calendar.calendarHtml (month, year);
    _calendarIframeBox.body.innerHTML = html;
}



function _isLeapYear (year) {
    return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
}


function _daysInMonth (month, year) {
    return (_isLeapYear (year) && month == 1) ? 29 :
        _Calendar_daysInMonth[month];
}


function _Calendar_noop () {
}


function _Calendar__prefix0 (x) {
    x = "" + x; // Convert to string
    return (x.length > 1) ? x : ("0" + x);
}

function _Calendar_updateBox (calendarName, mo, day, year) {
    if (calendar && calendar._dateBox) {
        calendar._dateBox.value = _Calendar__prefix0 (mo) + "/" +
            _Calendar__prefix0 (day) + "/" + year;
        calendar.hide ();
    }
}


function _Calendar__calendarHtml (month, year) {
    // Return the HTML representation for a calendar for the given month and
    // year.
    var today = new Date();
    var html = "<html>\n" +
        "<body >\n" +
        "<table cellpadding=2 cellspacing=1 border=0 align=center width=\"100%\"; height=\"100%\" " +
        "style=\"" + calendarOuterTableStyle + "\">\n";

    // Create the first line containing month and year:
    html +=
        "<tr>\n" +
        "  <td colspan=7>\n" +
        "    <table  style=\"" + calendarInnerTableStyle + "\" >\n" +
        "      <tr >\n" +
        "       <td width=10% class=calendarArrowClass >" +
        "<a href=\"javascript:parent._Calendar_noop()\" " +
        'style="text-decoration: none" title="Previous year" ' +
        "onclick=\"parent._Calendar_updateDisplay('" + this.name + "', " +
        month + ", " + (year-1) + ")\">" +
        '<span style="font-family: Webdings">7</span>' +
        "</a></td>" +
        "       <td width=10% class=calendarArrowClass >";
    var prevMonth = month - 1, prevYear = year;
    if (prevMonth < 0) {
        prevMonth = 11;
        prevYear --;
    }
    html +=
        "<a href=\"javascript:parent._Calendar_noop()\" " +
        'style="text-decoration: none" title="Previous month"  ' +
        "onclick=\"parent._Calendar_updateDisplay('" + this.name + "', " +
        prevMonth + ", " + prevYear + ")\">" +
        '<span style="font-family: Webdings">3</span>' +
        "</a></td>" +
        "       <td align=center width=90% class=calendarArrowClass >" +
        _makeMonthSelector (month, year) +
        "</td>\n" +
        "       <td width=10% class=calendarArrowClass >";
    var nextMonth = month + 1, nextYear = year;
    if (nextMonth > 11) {
        nextMonth = 0;
        nextYear ++;
    }
    html +=
        "<a href=\"javascript:parent._Calendar_noop()\" " +
        'style="text-decoration: none" title="Next month"  ' +
        "onclick=\"parent._Calendar_updateDisplay('" + this.name + "', " + 
        nextMonth + ", " + nextYear + ")\"> " +
        '<span style="font-family: Webdings">4</span>' +
        "</a></td>\n" +
        "       <td width=10% class=calendarArrowClass >" +
        "<a href=\"javascript:parent._Calendar_noop()\" " +
        'style="text-decoration: none" title="Next year"  ' +
        "onclick=\"parent._Calendar_updateDisplay('" + this.name + "', " + 
        month + ", " + (year+1) + ")\">" +
        '<span style="font-family: Webdings">8</span>' +
        "</a></td>\n" +
        "      </tr>\n" +
        "    </table>\n" +
        "  </td>\n" +
        "</tr>\n";

    // Create the second line containing the days of the week:
    html += "<tr>\n";
    for (var i = 0; i < 7; i++) {
        html += "<td align=center>" + _Calendar_wkDays[i] + "</td>\n";
    }
    html += "</tr>\n";

    // Find the weekday of the first day of the given month:
    var firstDayInt = new Date (year, month, 1).getDay();

    // Create the subsequent lines containing the dates:
    var daysInThisMonth = _daysInMonth (month, year);
    var count = daysInThisMonth + firstDayInt;
    html += "<tr>\n";
    var todaysDate  = today.getDate();
    var todaysMonth = today.getMonth();
    var thisYear    = today.getYear();
    for (var i = 0; i < count; i++) {
        html += "  <td align=right style=\"background-color: #dddddd\">";
        var dayOfMonth = i - firstDayInt + 1;
        if (dayOfMonth > 0) {
            html += "\n    <a href=\"javascript:parent._Calendar_noop()\" " +
                "onclick=\"parent._Calendar_updateBox ('" + this.name + "', " +
                (month+1) + ", " + dayOfMonth + ", " + year + ")\">";
            if (dayOfMonth == todaysDate && month == todaysMonth &&
                year == thisYear) {
                html += "<font color=red>";
            }
            html += dayOfMonth;
            if (dayOfMonth == todaysDate && month == todaysMonth &&
                year == thisYear) {
                html += "</font>";
            }
            html += "</a>";
            html += "\n";
        }
        html += "  </td>\n";
        if ((i+1) % 7 == 0) {
            html += "</tr>\n";
            if (i < count) {
                html += "<tr>\n";
            }
        }
    }
    if (i % 7 == 0) {
        html += "</tr>\n";
    }
    

    html += "</table>\n</body>\n</html>\n";
    return html;
}



function _makeMonthSelector (month, year) {
    // This was an attempt to make the month and year choosable from a
    // dropdown, but to work this, we must ensure that clicking the dropdown
    // doesn't make the calendar disappear. So this is incomplete.
    // MAS 3/28/2002
//     var strg =  '<select name="chooseMonth" style="font-size: 7pt">';
//     for (var i = 0; i < _Calendar_monthNames.length; i++) {
//         strg += '<option value=' + i + '>' + _Calendar_monthNames[i] +
//             '</option>\n';
//     }
//     strg += '</select> &nbsp;' + year;
//     return strg;

    return "<b>" + _Calendar_monthNames [month] + " " + year + "</b>";
}


