var initialtab  = [1, "page0"];

var DatePickers = new Array();

/* GLOBAL VARIABLES */
currentWeekIndex  = 0;
currentDayIndex   = 0;
currentEventID    = 0;
currentCal        = 1;
displayingWeek    = false;
displayingSearch  = false;
editingEvent      = false; // this variable is toggled by switching between
                           // the navigation and the editing calendar,
                           // i.e. by calling switchCal()

/* CONSTANTS */
calTab = { "day"  : { "id" : 1, "tab" : "tab0", "page" : "page0", "link" : "dayTabLink"},
           "week" : { "id" : 2, "tab" : "tab1", "page" : "page1", "link" : "weekTabLink"},
         "search" : { "id" : 3, "tab" : "tab2", "page" : "page2", "link" : "searchTabLink"},
      "template"  : { "id" : 1, "tab" : "tab0", "page" : "page0", "link" : "dayTabLink"}        // event templates are displayed in the day tab
          };

foreverYear       = 2020 /*new Date().getFullYear() + 14*/; // events that repeat forever actually
                                                            // repeat until December 31st, 2020
elemPerEvent      = 3; // there are elemPerEvent table cells (<td>) per row (<tr>)
                       // if the row is an event in an event table. This contant
                       // is used for highlighting table cells.
noErrors          = "have a nice day";
defaultTitle      = "Put Your Title Here";
defaultText       = "Put details here.";
defaultName       = "Untitled Template";
defaultVariable   = "calendar_event";

/********************************************************************************
EventCalendar.js
  For use with EventCalendarMgr.php & calendarList.html.
  Populates and manipulates the page outlined in calendarList.html.
  The page consists of a simple month calendar in the upper left hand corner
  and an event details window in the upper right hand corner.
  Beneath these are the tabs and the tab pages themselves.
  The tab pages are for displaying lists of events.

  ------ FUNCTIONS ------

  Functions are organized according to which of the page elements they deal
  the most with:

  1. General functions
      - loadPageDefaults

      - JumpToDay
      - SelectDate
      - SelectTemplate

      - showElem

  2. Simple calendar & tab functions
      - ChangeMonthYear
      - switchCal

      - SetToTab

      - HighlightCurrent
      - HighlightDay
      - HighlightWeek
      - HighlightSearch
      - HighlightTemplate

  3. Tab page functions
      - DisplayDay
      - DisplayWeek
      - DisplayResults
      - DisplayTemplate
      - getEventTable

      - HighlightEvent
      - dayHover
      - weekHover

  4. Event details window functions
      - SetDefaultEvent

      - AddEvent
      - SelectEvent
      - EditEvent
      - DeleteEvent

      - ApplyTemplate
      - ModifyTemplate

      - showFromTo
      - showRepeat
      - showUntil
      - hideDateTime

      - populateStart
      - populateEnd
      - getStart
      - getEnd
      - setStart
      - setEnd
      - setStartSuffix
      - setEndSuffix

      - getRepeatControls

      - clearDefault
      - ismaxlength
      - islegalvalue

  4. Status bar functions
      - MarkAsComplete
      - EraseMark

  5. Input validation functions
      - CheckInput
      - checkDate

  ------ DATA ------

Event data is organized into several arrays.
1. MonthEvents contains all events and event data for the month in order of
               week of month, day of week, and start time. Thus all month events
               can be specified by three array indices:
                   MonthEvents[whichWeek][whichDay][whichEvent]
               where whichWeek & whichDay & whichEvent are all > 0
               and whichDay <= 7
2. ListTemplates contains all template events ordered by start time and grouped
                 according to which template they belong to. It contains both data
                 on the templates themselves (name & description) as well as all
                 data on the events that belong to the templates.
                 So template events can be specified by
                     ListTemplates[whichTmpl][whichEvent]
                 where whichTmpl is the id of the event's parent template,
                 whichTmpl != 0 as template 0 is the calendar itself. Template events
                 can also be retrieved as
                     MonthEvents[0][whichTmpl][whichEvent]
                 because MonthEvents[0] = ListTemplates.

3. SearchResults is a list of found events organized according to date.
                     SearchResults[whichEvent]

4. EventsByID is for retrieving the first (weekOfMonth, dayOfWeek, eventOfDay) coordinate
              in the month, for an event with a particular calendar event id,
              to be used as indices on MonthEvents (i.e. MonthEvents[weekOfMonth][dayOfWeek][eventOfDay])
                  EventsByID[calendarID]
*********************************************************************************/

/////////////////////////////////////////                          /////////////////////////////////////////
/////////////////////////////////////////         GENERAL          /////////////////////////////////////////
/////////////////////////////////////////                          /////////////////////////////////////////

// this function is called when page is loaded
function loadPageDefaults() {
    do_onload();
    MonthEvents[0] = ListTemplates;
    displayingWeek = (SessionDate.view == "week"); // displayingWeek is a global variable
    SelectDate(SessionDate.week,SessionDate.weekday);
    if(SessionDate.view != "day" && SessionDate.view != "template") { // template & day use the first tab,
                                   // which is selected by default, so there's no need to call set to tab
        SetToTab(SessionDate.view);
    }
    if (SessionDate.view == "template") { // if true, switches to view template mode and selects a template event
        SelectTemplate(SessionDate.template);
        SelectEvent(0,SessionDate.template,SessionDate.event);
    } else {
        SelectEvent(SessionDate.week,SessionDate.weekday,SessionDate.event); // otherwise, selects a calendar event
    }
}

// selects a date within the month
// if the week is highlighted in the calendar, it unhighlights the week and highlights a day instead
// switches to the day tab
//    parameters: whichWeek is the week of the month to be selected
//                whichDay  is the day  of the week  to be selected
function JumpToDay(whichWeek, whichDay){
    SelectDate(whichWeek, whichDay);
    if (displayingWeek == true) {
        HighlightWeek(false);
        HighlightDay(true);
    }
    SetToTab("day");
}

// SelectDate:
//  Selects a date.
//  If not editing an event, sets default event.
//  If editing an event, updates the controls so that their are appropriate
//  to the changed date.
//    parameters: whichWeek is the week of the month to be selected
//                whichDay  is the day  of the week  to be selected
function SelectDate(whichWeek, whichDay) {
    theEventTemplate = document.calendarEvents.event_list;
    if(whichWeek == 0) { // if it's a template event...
        SelectTemplate(whichDay); // assume whichDay is whichTmpl
    // else if it's a calendar event, but we're not IN the calendar...
    } else if (theEventTemplate != null && theEventTemplate.value != 0) {
        currentWeekIndex = whichWeek;
        currentDayIndex  = whichDay;
        SelectTemplate(0); // select the calendar
    } else { // else if it's a calendar event and we ARE in the calendar...
        DisplayDay(whichWeek, whichDay);
        DisplayWeek(whichWeek, whichDay);

        HighlightCurrent(false);
        currentWeekIndex = whichWeek;
        currentDayIndex  = whichDay;
        HighlightCurrent(true);

        ThisDay  = MonthEvents[whichWeek][whichDay];
        document.calendarEvents.Y.value = ThisDay.year;
        document.calendarEvents.M.value = ThisDay.month;
        document.calendarEvents.D.value = ThisDay.day;

        if(editingEvent) {
            HighlightEvent(true);
            InitializeDatePicker("StartDate", ThisDay.year, ThisDay.month, ThisDay.day);
            if (!document.getElementById("foreverCheck").checked) {
                if (checkDate(noErrors) != noErrors) {
                    InitializeDatePicker("EndDate", ThisDay.year, ThisDay.month, ThisDay.day);
                }
            }
            if (document.getElementById("DAY") != null) {
                document.getElementById("DAY").innerHTML = ThisDay.day;
            }

//             if (document.getElementById("remindControls") != null) {
//                 showElem((ThisDay.today >= 1),"remindControls");
//                 if(ThisDay.today < 1) {
//                     document.calendarEvents.remind_in_advance.selectedIndex = 0;
//                 } else if (document.getElementById("setRemind").style.display != "none") {
//                     document.calendarEvents.remind_in_advance.selectedIndex = 1;
//                 }
//             }
        } else {
            SelectEvent(whichWeek, whichDay, 0);
        }
    }
}

// SelectTemplate:
//  whichTmpl = the template id
//    if whichTmpl is -1, then create a new template
//    if whichTmpl is 0, switch to viewing calendar
//    otherwise view the preexisting template specified
//    by whichTmpl, the template ID.
function SelectTemplate(whichTmpl) {
    document.calendarEvents.event_list.value = whichTmpl;
    showCal = (whichTmpl == 0); // show the calendar if whichTmpl is 0, hide the calendar if not.
    showElem(showCal, "cal" + currentCal);
    showElem(!showCal, "templateWindow"); // hide templateWindow if the calendar is visible, and vice versa
    showElem(showCal, calTab.week.tab); // hide the week tab
    showElem(showCal, calTab.search.tab); // if you want to add the ability to search templates,
                                          // commenting this line out would be a good place to start
    if(displayingWeek || displayingSearch) {
        if(showCal)
            SetToTab("week");
        else
            SetToTab("day");
    }
    if (whichTmpl != 0) { // if whichTmpl is not the calendar
        document.getElementById("templateTitle").innerHTML = ListTemplates[whichTmpl].name;
        document.getElementById("templateText").innerHTML  = ListTemplates[whichTmpl].description;
        DisplayTemplate(whichTmpl); // lists the template events
        HighlightTemplate(true);
        if(!editingEvent) {
            SetDefaultEvent();
        }
    } else { // else if we're switching to the calendar
        HighlightDay(true); // turn the template tab back into the day tab
        SelectDate(currentWeekIndex, currentDayIndex);
    }
    if(editingEvent) {
        templateDropDown = document.calendarEvents["calendar_event[event_list]"];
        if (templateDropDown.value != whichTmpl) {
            templateDropDown.value  = whichTmpl;
            hideDateTime(whichTmpl);
        }
        HighlightEvent(true);
    } else if (whichTmpl < 0) {// i.e. if whichTmpl is -1
        ModifyTemplate(whichTmpl);
    }
} // end SelectTemplate

// a simple little function for showing and hiding page elements
function showElem(show,elemId) {
    theElem = document.getElementById(elemId);
    if (show) {
        theElem.style.display = "";
    } else {
        theElem.style.display = "none";
    }
} // end showElement

/////////////////////////////////////////                          /////////////////////////////////////////
/////////////////////////////////////////  SIMPLE CALENDAR / TABS  /////////////////////////////////////////
/////////////////////////////////////////                          /////////////////////////////////////////

// function called by the year and month drop downs on the simple calendar
// loads the calendar with a different month / year
function ChangeMonthYear(MonthAndYear) {
    ThisDay = MonthEvents[currentWeekIndex][currentDayIndex];
    if(displayingWeek) {
        viewText = "week";
    } else {
        viewText = "day";
    }
    window.location = PHXbaseURL + "/eventcalendar" + MonthAndYear + "D/" + ThisDay.day + "/view/" + viewText + "/";
}

// switches between the navigation calendar with the drop downs and next/prev month links
// and the editing calendar, which lacks the links and drop downs
// sets the global variable editingEvent based on which calendar is in use
// when viewing templates, neither calendar is shown.
function switchCal() {
    editingEvent = (currentCal == 1);
    showingCal   = (document.calendarEvents.event_list.value == 0);
    HighlightCurrent(false);
    showElem(!editingEvent && showingCal,  "cal1");
    showElem(editingEvent  && showingCal, "cal2");
    if(!editingEvent) {
        currentCal = 1;
    } else {
        currentCal = 2;
    }
    if (showingCal) {
        HighlightCurrent(true);
    } else {
        HighlightTemplate(true);
    }
}

// switches between tabs
// view = template, day, week, or search.
// note that the template and day tabs are one and the same
function SetToTab(whichView){
    ThisTab    = calTab[whichView];
    initialtab = [ThisTab.id, ThisTab.page];
    TabObj     = document.getElementById(ThisTab.link);
    expandcontent(ThisTab.page, TabObj);
    if (whichView == "search") {
        HighlightSearch(true);
        DisplayResults();
    }
}

/* HIGHLIGHT Functions.....
    for All highlight functions, the parameter
    'highlight' is either true or false.
    If it is true,  then the function highlights something.
    If it is false, then the function dehighlights that thing.
    Typically, dehighlighting undoes less than what highlighting does.
*/

/*
HighlightCurrent:
    Highlights the current day or week.
    If the calendar is displaying search results or a template,
    HighlightCurrent will switch the calendar to a day or week view.
*/
function HighlightCurrent(highlight) {
    if(displayingSearch) {
        if (highlight) {
            if (displayingWeek) {
                SetToTab("week");
            } else {
                SetToTab("day");
            }
            displayingSearch = false;
        }
    }
    if(displayingWeek) {
        originalState = displayingWeek;
        HighlightWeek(highlight);
        displayingWeek = originalState;
    } else {
        HighlightDay(highlight);
    }
}

/* HighlightDay:
    Highlights the current day in the simple calendar.
    Sets the day/template tab to be labelled 'Day' and
    to highlight the day in the calendar when clicked upon.
    Highlights the day/template tab.
*/
function HighlightDay(highlight) {
    if(highlight){
        document.calendarEvents.view.value = "day";
        var dayTabLink = document.getElementById("dayTabLink");
        dayTabLink.innerHTML      = "Day";
        dayTabLink.onclick        =        function () { HighlightWeek(false);
                                                         HighlightDay(true);
                                                         return expandcontent(calTab.day.page, dayTabLink)
                                                       };
        document.getElementById("dayTabLink").style.color    = "#184a84";
        document.getElementById("weekTabLink").style.color   = "#999999";
        document.getElementById("searchTabLink").style.color = "#999999";
    } else {
        document.getElementById("dayTabLink").style.color    = "#999999";
    }
    if ((currentWeekIndex != 0) && (currentDayIndex != 0)) {
        CalendarDay = document.getElementById("cal" + currentCal + "-week" + currentWeekIndex + "-day" + currentDayIndex);
        if (highlight) {
            CalendarDay.className = "selectedDay";
        } else {
            CalendarDay.className = "defaultDay";
        }
    }
} // end HighlightDay

/* HighlightWeek:
    Highlights the week tab.
    Highlights the current week in the simple calendar.
*/
function HighlightWeek(highlight) {
    displayingWeek = highlight;
    if(highlight){
        document.calendarEvents.view.value = "week";
        document.getElementById("dayTabLink").style.color    = "#999999";
        document.getElementById("weekTabLink").style.color   = "#781E7E";
        document.getElementById("searchTabLink").style.color = "#999999";
    } else {
        document.getElementById("weekTabLink").style.color   = "#999999";
    }
    if (currentWeekIndex != 0) {
        for (dayOfWeek = 1; dayOfWeek <= 7; dayOfWeek++) {
            if (SessionDate.month == MonthEvents[currentWeekIndex][dayOfWeek].month) {
                WeekDay = document.getElementById("cal" + currentCal + "-week" + currentWeekIndex + "-day" + dayOfWeek);
                if (highlight) {
                    if (dayOfWeek == currentDayIndex) {
                        WeekDay.className = "selectedDay";
                    } else {
                        WeekDay.className = "weekDay";
                    }
                } else {
                    WeekDay.className = "defaultDay";
                }
            }
        }// end for week loop
    }
}// end HighlightWeek

/* HighlightSearch:
    Highlights the search tab.
    Sets the action to search.
*/
function HighlightSearch(highlight) {
    if(highlight){
        displayingSearch = true;
        document.getElementById("action").value = "search";
        document.calendarEvents.view.value      = "search";
        document.getElementById("dayTabLink").style.color    = "#999999";
        document.getElementById("weekTabLink").style.color   = "#999999";
        document.getElementById("searchTabLink").style.color = "#00995A";
    } else {
        document.getElementById("searchTabLink").style.color = "#999999";
    }
}

/* HighlightTemplate:
    Sets the day/template tab to be labelled 'Template' and
    to highlight the template when clicked upon.
    Highlights the template tab.
*/
function HighlightTemplate(highlight) {
    if(highlight){
        document.calendarEvents.view.value = "template";
        tmplTabLink               = document.getElementById(calTab.template.link);
        tmplTabLink.innerHTML     = "Template";
        tmplTabLink.onclick       =        function () { HighlightTemplate(true);
                                                         return expandcontent(calTab.template.page, tmplTabLink)
                                                       };
        document.getElementById("dayTabLink").style.color = "#184a84";
    } else {
        document.getElementById("dayTabLink").style.color = "#999999";
    }
}

/////////////////////////////////////////                          /////////////////////////////////////////
/////////////////////////////////////////           PAGES          /////////////////////////////////////////
/////////////////////////////////////////                          /////////////////////////////////////////

/* DisplayDay:
    Lists the events for the selected day
*/
function DisplayDay(whichWeek, whichDay) {
    ThisDay    = MonthEvents[whichWeek][whichDay];

    if (ThisDay.today == 1) {
        TheTitle = "Today";
    } else {
        TheTitle = ThisDay.monthname + " " + ThisDay.day + ", " + ThisDay.year;
    }
    document.getElementById("DayView").innerHTML = getEventTable(TheTitle, whichWeek, whichDay);
}


/* DisplayWeek:
    Lists the events for the week, grouped by day
*/
function DisplayWeek(whichWeek, whichDay) {
    ThisWeek = MonthEvents[whichWeek];
    withNoEvents = "<tr><td colspan='2' Class='tabcontentTitle'>No events";
    withEvents   = "<tr><td colspan='2' Class='tabcontentTitle'>Events";
    Week         = " for the week of " + ThisWeek[1].monthname + " " + ThisWeek[1].day + ", " + ThisWeek[1].year + "</td></tr>";

    hasEvents  = false;
    tableBreak = "<tr><td>&nbsp</td></tr>";

    for (dayOfWeek = 1; dayOfWeek <= 7; dayOfWeek++) {
        if (ThisWeek[dayOfWeek].events != 0) {
            Week += tableBreak;
            hasEvents = true;
            Week += "<th width=26%>&nbsp " + ThisWeek[dayOfWeek].monthname + " " + ThisWeek[dayOfWeek].day + ", " + ThisWeek[dayOfWeek].year + "</th>" 
                  + "<th width=54%>&nbsp Events</th><th width=20%>&nbsp Status</th>";

            for (eventIndex = 1; eventIndex <= ThisWeek[dayOfWeek].events; eventIndex++) {
                if (eventIndex % 2 == 0) {
                    Week += "<tr class='PHX-row-light'>"
                } else {
                    Week += "<tr class='PHX-row-light'>"
                }
                eventID = ThisWeek[dayOfWeek][eventIndex].id;
                allDayStyle = "";
                if(ThisWeek[dayOfWeek][eventIndex].all_day) {
                    allDayStyle = "text-align: center";
                }
                if (whichDay == dayOfWeek) { // if the currently selected day is the day of the week this event is on,
                                             // there's no need to call SelectDate when the event gets clicked
                    eventOnClick = "SelectEvent(" + whichWeek + "," + dayOfWeek + "," + eventIndex + ")";
                } else if (SessionDate.month == ThisWeek[dayOfWeek].month) { // otherwise we select the event's day, the the event itself
                    eventOnClick = "SelectDate(" + whichWeek + "," + dayOfWeek + ");SelectEvent(" + whichWeek + "," + dayOfWeek + "," + eventIndex + ")";
                } else { // if the event's not in this month, we need to make a link to it
                    eventOnClick = "javascript:document.location.href=\"" + PHXbaseURL
                         + "/eventcalendar/action/list/Y/" + ThisWeek[dayOfWeek].year + "/M/" + ThisWeek[dayOfWeek].month 
                         + "/D/" + ThisWeek[dayOfWeek].day + "/frmCalendarEventId/" + ThisWeek[dayOfWeek][eventIndex].id
                         + "/view/week/\"";
                }

                // Event Duration
                Week += "<td id='event" + eventID + "-day" + dayOfWeek + "-1' onMouseOver='weekHover(true," + eventID + "," + dayOfWeek + ");'" 
                         + " onMouseOut='weekHover(false," + eventID + "," + dayOfWeek+ ");' class='calendarEvent' style='cursor:pointer;" + allDayStyle + "'"
                         + " onclick='" + eventOnClick + "'>" 
                             + ThisWeek[dayOfWeek][eventIndex].duration
                      + "</td>";

                // Event Title
                Week += "<td id='event" + eventID + "-day" + dayOfWeek + "-2' onMouseOver='weekHover(true," + eventID + "," + dayOfWeek + ");'" 
                         + " onMouseOut='weekHover(false," + eventID + "," + dayOfWeek + ");' class='calendarEvent'" 
                         + " style='font-weight:bold;cursor:pointer;color:#184a84'"
                         + " onclick='" + eventOnClick + "'>"
                             + ThisWeek[dayOfWeek][eventIndex].display_title
                      + "</td>";

                // Event Status
                Week += "<td id='event" + eventID + "-day" + dayOfWeek + "-3' onMouseOver='weekHover(true," + eventID + "," + dayOfWeek + ");'" 
                         + " onMouseOut='weekHover(false," + eventID + "," + dayOfWeek + ");' class='calendarEvent'" 
                         + " style='cursor:pointer;'"
                         + " onclick='" + eventOnClick + "'>" 
                             + ThisWeek[dayOfWeek][eventIndex].display_status
                      + "</td>";

                Week += "</tr>";
            }//end for one day's events loop
//            Week += "<tr><td class='calendarEvent'>&nbsp</td><td class='calendarEvent'>&nbsp</td></tr>";
//            Week += "<BR>";
        } // if has events
    } // end for week loop

    if(hasEvents) {
        Week = withEvents + Week;
    } else {
        Week = withNoEvents + Week;
    }

    var ClickedWeekView = document.getElementById("WeekView");
    ClickedWeekView.innerHTML = "<table width=100% valign=top>" + Week + "</table>";
}

/* DisplayResults:
    Lists the events that matched the search query
*/
function DisplayResults() {
    var SearchView = document.getElementById("SearchView");
    if(SearchResults.events == 0) {
        SearchView.innerHTML = "<BR> &nbsp Sorry, we couldn't find any events that matched your search!";
    } else {
        Results  = "<BR><th width=54%>&nbsp Results</th><th width=23%>&nbsp Start</th><th width=23%>&nbsp End</th>";
        for (eventIndex = 1; eventIndex <= SearchResults.events; eventIndex++) {
            ThisEvent = SearchResults[eventIndex];
            if (eventIndex % 2 == 0) {
                Results += "<tr class='PHX-row-light'>"
            } else {
                Results += "<tr class='PHX-row-light'>"
            }
            if (SessionDate.month == ThisEvent.start.months) { // if the event's in this month, we don't have to reload the page to select it
                EventWhen = EventsByID[ThisEvent.id];
                eventOnClick = "JumpToDay("   + EventWhen.weekOfMonth + "," + EventWhen.dayOfWeek + ");"
                             + "SelectEvent(" + EventWhen.weekOfMonth + "," + EventWhen.dayOfWeek + "," + EventWhen.eventOfDay + ")";
            } else { // otherwise, we make a link to the event
                eventOnClick = "javascript:document.location.href=\"" + PHXbaseURL
                         + "/eventcalendar/action/list/Y/" + ThisEvent.start.years + "/M/" + ThisEvent.start.months 
                         + "/D/" + ThisEvent.start.days + "/frmCalendarEventId/" + ThisEvent.id
                         + "/view/day/\"";
            }

            // Event Title
            Results +=
                 "<td id='event" + ThisEvent.id + "-day0-2' onMouseOver='weekHover(true," + ThisEvent.id + ",0);' onMouseOut='weekHover(false,"
                 + ThisEvent.id + ",0);' class='calendarEvent' style='font-weight:bold;cursor:pointer;color:#184a84' "
                 + "onclick='" + eventOnClick + "'>&nbsp " + ThisEvent.display_title + "</td>";

            // Event Start Date
            Results += "<td id='event" + ThisEvent.id + "-day0-1' onMouseOver='weekHover(true," + ThisEvent.id + ",0);' onMouseOut='weekHover(false,"
                 + ThisEvent.id + ",0);' class='calendarEvent' style='cursor:pointer;text-align:right' "
                 + "onclick='" + eventOnClick + "'>" + ThisEvent.start.monthname + " " + ThisEvent.start.days + ", "
                 + ThisEvent.start.years + "</td>";

            // Event End Date
            Results += "<td id='event" + ThisEvent.id + "-day0-3' onMouseOver='weekHover(true," + ThisEvent.id + ",0);' onMouseOut='weekHover(false," 
                 + ThisEvent.id + ",0);' class='calendarEvent' style='cursor:pointer;text-align:right' " 
                 + "onclick='" + eventOnClick + "'>" + ThisEvent.end.monthname + " " + ThisEvent.end.days + ", "
                 + ThisEvent.end.years + "</td>";
            Results += "</tr>";
        }//end for all events loop
        SearchView.innerHTML = "<table width=100%>" + Results + "</table>";
    }
}

/* DisplayTemplate:
    Lists all the events in the event template
*/
function DisplayTemplate(whichTmpl) {
    document.getElementById("DayView").innerHTML = getEventTable(ListTemplates[whichTmpl].name, 0, whichTmpl);
}

/* getEventTable:
    Returns as a string the html for a table of events.
    The table contains all events found on whichWeek, whichDay
    and theTitle is the title that appears above the table
    after the words 'No events for' or 'Events for', depending.
*/
function getEventTable(TheTitle, whichWeek, whichDay) {
    TheEventList = MonthEvents[whichWeek][whichDay];

    tableBreak = "<tr><td>&nbsp</td></tr>";
    TheTable = "<tr><td colspan='2' Class='tabcontentTitle'>";
    if (TheEventList.events == 0) {
        TheTable += "No events";
    } else {
        TheTable += "Events";
    }
    TheTable += " for " + TheTitle;
//     if (TheEventList.events != 0) {
//         TheTable += " (click below for details)";
//     }
    TheTable += "</td></tr>";
    if (TheEventList.events != 0) {
        TheTable += tableBreak;
        TheTable += "<th width=26%>&nbsp Schedule</th><th width=54%>&nbsp Events</th><th width=20%>&nbsp Status</th>";
        for (eventIndex = 1; eventIndex <= TheEventList.events; eventIndex++) {
            if (eventIndex % 2 == 0) {
                TheTable += "<tr class='PHX-row-light'>"
            } else {
                TheTable += "<tr class='PHX-row-light'>"
            }
            allDayStyle = "";
            if(TheEventList[eventIndex].all_day) {
                    allDayStyle = "text-align:center";
            }
            eventID     = TheEventList[eventIndex].id;
            viewMode    = "day"; //document.calendarEvents.view.value;
            hoverEffect = "onMouseOver='" + viewMode + "Hover(true," + eventID + ");' onMouseOut='" + viewMode + "Hover(false," + eventID + ");'";

            // Event Duration
            TheTable += "<td id='event" + eventID + "-1' " + hoverEffect
                 + " class='calendarEvent' style='cursor:pointer;"   + allDayStyle + "' "
                 + "onclick='SelectEvent(" 
                 + whichWeek + "," + whichDay + "," + eventIndex + ")'>" + TheEventList[eventIndex].duration + "</td>";

            // Event Title
            TheTable += "<td id='event" + eventID + "-2' " + hoverEffect
                 + " class='calendarEvent' style='font-weight:bold;cursor:pointer;color:#184a84' "
                 + "onclick='SelectEvent(" 
                 + whichWeek + "," + whichDay + "," + eventIndex + ")'>" + TheEventList[eventIndex].display_title + "</td>";

            // Event Status
            TheTable += "<td id='event" + eventID + "-3' " + hoverEffect
                 + " class='calendarEvent' style='cursor:pointer;'"
                 + " onclick='SelectEvent("
                 + whichWeek + "," + whichDay + "," + eventIndex + ")'>" + TheEventList[eventIndex].display_status + "</td>";
            TheTable += "</tr>";
        }//end for all events loop
    }
    return "<table width=100%>" + TheTable + "</table>";
}

/* HighlightEvent:
    Highlights or dehighlights the table cells associated with the event,
    currentEventID, depending on whether highlight is true or false.
    Highlights table cells on the day page, the week page (1 <= dayOfWeek <= 7), and search page (dayOfWeek = 0).
    A lighter shade is used for occurences of the event that are not on the selected day, currentDayIndex.
*/
function HighlightEvent(highlight) {
    if(highlight) {
        eventClass     = "selectedEvent";   // darker selection shade
        associateClass = "associatedEvent"; // lighter selection shade
    } else {
        eventClass     = "calendarEvent";
        associateClass = "calendarEvent";
    }
    for(elem = 1; elem <= elemPerEvent; elem++) {
        dayEventElement = document.getElementById("event" + currentEventID + "-" + elem);
        if (dayEventElement != null) {
            dayEventElement.className = eventClass;
        }
        for (dayOfWeek = 0; dayOfWeek <= 7; dayOfWeek++) {
            weekEventElement = document.getElementById("event" + currentEventID + "-day" + dayOfWeek + "-" + elem);
            if(weekEventElement != null){
                if(dayOfWeek == currentDayIndex) {
                    weekEventElement.className = eventClass;
                } else {
                    weekEventElement.className = associateClass;
                }
            }
        }// end for week
    }// end for all elements of event
} // end HighlightEvent

/* Darkens the colour of an unselected event in the table as the mouse hovers over it. (highlight = true) */
/* Lightens the colour as the mouse leaves (highlight = false) */
function dayHover(highlight, whichID) {
  if(whichID != currentEventID) {
    if(highlight) {
        eventClass     = "hoverEvent";
    } else {
        eventClass     = "calendarEvent";
    }
    for(elem = 1; elem <= elemPerEvent; elem++) {
        document.getElementById("event" + whichID + "-" + elem).className = eventClass;
    }
  }
}

/* Darkens the colour of an unselected event in the table as the mouse hovers over it. (highlight = true) */
/* Lightens the colour as the mouse leaves (highlight = false) */
function weekHover(highlight, whichID, whichDay) {
    eventClass = "";
    if(whichID != currentEventID) {
        if(highlight) {
            eventClass     = "hoverEvent";
        } else {
            eventClass     = "calendarEvent";
        }
    } else if (whichDay != currentDayIndex) {
        if(highlight) {
            eventClass = "selectedEvent";
        } else {
            eventClass = "associatedEvent";
        }
    }
    if (eventClass != "") {
        for(elem = 1; elem <= elemPerEvent; elem++) {
            document.getElementById("event" + whichID + "-day" + whichDay + "-" + elem).className = eventClass;
        }
    }
}

/////////////////////////////////////////                          /////////////////////////////////////////
/////////////////////////////////////////   EVENT DETAILS WINDOW   /////////////////////////////////////////
/////////////////////////////////////////                          /////////////////////////////////////////

// Determines what the Event Details Window displays when no events are selected
// as well as what buttons appear when no events are selected.
// Content for the Calendar Default Event and the Template Default Event is quite different.
function SetDefaultEvent() {
    currentEventID                           = 0;
    document.getElementById("ID").value      = "";
    document.getElementById("frmID").value   = "";
    if (currentCal == 2) {
        switchCal();
    }
    viewingTemplates = (document.calendarEvents.view.value == "template")
    if (viewingTemplates) { // Default Event for Templates
        currentTmplID = document.calendarEvents.event_list.value;
        document.calendarEvents.action.value                  = "clear";
        document.getElementById("windowTitleCell").className  = "defaultTitle";
        document.getElementById("windowTitle").innerHTML      = ListTemplates[currentTmplID].name;
        document.getElementById("windowSubTitle").innerHTML   = "my template";
        document.getElementById("windowInfo").innerHTML       = "<b>&nbsp Click on an event from the list below to select it.</b>";
        document.getElementById("windowText").innerHTML       = ListTemplates[currentTmplID].description;
    } else { // Default Event for Calendar
        showElem(true, calTab.search.tab);
        document.calendarEvents.action.value                  = "cancel";
        document.getElementById("windowTitleCell").className  = "defaultTitle";
        document.getElementById("windowTitle").innerHTML      = "Event Calendar: View and Post Public Events <br>(you must login to post an event)";
        document.getElementById("windowSubTitle").innerHTML   = "event details window";
        document.getElementById("windowInfo").innerHTML       = "<b>&nbsp Click on a date to view that day's events below.</b>";
        document.getElementById("windowText").innerHTML       = "&nbsp Events are displayed below.";
        if(MonthEvents[currentWeekIndex][currentDayIndex].events > 0) {
            document.getElementById("windowText").innerHTML       += "<HR><b>&nbsp Click on an event from the list to select it.</b>";
        }
    }
    if(MonthEvents.buttons){                      /* DEFAULT BUTTONS */
        StatusBar = document.getElementById("statusBar");
        ButtonBar = document.getElementById("buttonBar");
        ButtonBarContent = "";
        StatusBarContent = "";
        if(TemplateApply != 0 && !viewingTemplates) { // if there are any templates to apply AND we're in the calendar, show the apply button
            ButtonBarContent = "<input type='button' class='wideButton' value='apply template' onclick='ApplyTemplate("
                                    + currentWeekIndex + "," + currentDayIndex + ")' title='Apply a template to this day'/>";
        }
        if(viewingTemplates) { // if we're viewing templates
            StatusBarContent  = "<input type='submit' name='submitted' class='veryNarrowButton' value='clear'"
                             +      " title='Clear events and delete template'/>";
            StatusBarContent += "<input type='button' class='veryNarrowButton' value='rename' onclick='ModifyTemplate("
                                    + currentTmplID + ")' title=\"Modify template's name and description\"/>";
            xx = 0;
            yy = currentTmplID;
        } else { // if we're in the calendar
            xx = currentWeekIndex;
            yy = currentDayIndex;
        }
        ButtonBarContent += "<input type='button' class='wideButton' value='add event' onclick='AddEvent("
                                + xx + "," + yy + ")' title='Add a new event'/>";
        ButtonBar.innerHTML = ButtonBarContent;
        StatusBar.innerHTML = StatusBarContent;
    }
} // END SetDefaultEvent



// Function for selecting & highlighting events and displaying their information in the event details window.
// Causes the status drop down and the edit/delete buttons to appear.
// Sets the globabl variable currentEventID.
// If given whichEvent = 0, it calls SetDefaultEvent.
// If whichEvent is already selected, it deselects that event, i.e. calls SetDefaultEvent, except when in editing mode.
// Otherwise, it selects the specified event.
function SelectEvent(whichWeek, whichDay, whichEvent) {
  EventParent = MonthEvents[whichWeek][whichDay];
  if (whichEvent == 0) { // if no event is selected, set to default event
      HighlightEvent(false);
      SetDefaultEvent();
  } else if (EventParent[whichEvent].id == currentEventID) { // if event is already selected...
    if (!editingEvent) {
        HighlightEvent(false);
        SetDefaultEvent(); // deselect event or, if editing, do nothing.
    }
  } else { // otherwise, select the specified event...
    if (currentCal == 2) {
        switchCal();
    }
    if(currentEventID != 0){
        HighlightEvent(false);
    }

    ThisAction = document.calendarEvents.action;
    ViewMode   = document.calendarEvents.view.value;
    if(ThisAction.value != "cancel") {
        ThisAction.value = "cancel";
        if(ViewMode != "template") {
            showElem(true, calTab.search.tab);
        }
    }

    ThisEvent      = EventParent[whichEvent];
    ThisDay        = EventParent;
    currentEventID                         = ThisEvent.id;
    document.getElementById("ID").value    = ThisEvent.id;
    document.getElementById("frmID").value = ThisEvent.id;
    HighlightEvent(true);

    // Get eventRepeat and moreInfo
    moreInfo = "";
    if (!ThisEvent.repeats) {
        eventRepeat = " never";
    } else {
        eventRepeat = " once every " + ThisEvent.repeat_interval + " " + ThisEvent.repeat_unit;
        if (thisIsForever(ThisEvent.end.years, ThisEvent.end.months, ThisEvent.end.days)) {
            untilDate = "forever";
        } else {
            untilDate = ThisEvent.end.monthname + " " + ThisEvent.end.days + ", " + ThisEvent.end.years;
        }
        moreInfo    = "<tr>"
                        + "<td align=right><b>from&nbsp</b></td>" 
                        + "<td align=left>" + ThisEvent.start.monthname + " " + ThisEvent.start.days + ", " + ThisEvent.start.years + "</td>"
                        + "<td align=right><b>until&nbsp</b></td>" 
                        + "<td align=left>" + untilDate + "</td>"
                    + "</tr>";
    }

    if(ThisEvent.all_day) {
        eventDuration = "all day";
    } else {
        eventDuration = ThisEvent.start.hours + ":" + ThisEvent.start.minutes + " " + ThisEvent.start.suffix 
               + " to " + ThisEvent.end.hours + ":" + ThisEvent.end.minutes   + " " + ThisEvent.end.suffix;
    }

    infoWindow = document.getElementById("windowInfo");
    infoWindow.innerHTML = "<table width=100%>"
                             + "<tr>"
                                 + "<td align=right style='width:15%'><b>Duration&nbsp</b></td>"
                                 + "<td align=left  style='width:40%'>" + eventDuration
                                 + "</td>"
                                 + "<td align=right style='width:5%'><b>Repeat&nbsp</b></td>"
                                 + "<td align=left  style='width:40%'>" + eventRepeat + "</td>"
                             + "</tr>"
                             + moreInfo
                         + "</table>";

    document.getElementById("windowTitleCell").className   = "selectedTitle";
    document.getElementById("windowTitle").innerHTML       = ThisEvent.title;
    document.getElementById("windowSubTitle").innerHTML    = ThisEvent.display_privacy;
//    document.getElementById("windowInfo").innerHTML        = ThisEvent.duration + ", " + eventRepeat;
    document.getElementById("windowText").innerHTML        = ThisEvent.text;
    ButtonBar = document.getElementById("buttonBar");
    StatusBar = document.getElementById("statusBar");
    if(MonthEvents.buttons){ // if the user is logged in
            statusContents = "<b>&nbsp Status:&nbsp</b>";
            if(ThisEvent.completeable) { // if this event is completeable, i.e. is 'not complete' as opposed to 'complete', 'planned', 'hidden', etc.
                statusContents += MarkSelect; // drop down for marking an event as complete
            } else if(ThisEvent.marked) { // else if the event has an event instance object (or 'mark')
                statusContents += EraseSelect; // drop down for erasing marks / event instances
            } else {
                statusContents += ThisEvent.display_status; // otherwise, don't give them options, just display the status
            }
            barContents = "&nbsp";
            if (ThisEvent.editable) {                   /* EDIT AND DELETE BUTTONS */
                barContents += "<input type='button' class='veryNarrowButton' value='edit' onclick='EditEvent(" 
                                 + whichWeek + "," + whichDay + "," + whichEvent + ");' title='Edit the selected event'/>";
                barContents += "<input type='button' class='veryNarrowButton' value='delete' onclick='DeleteEvent(" 
                                 + whichWeek + "," + whichDay + "," + whichEvent + ");' title='Delete the selected event'/>";
            } // end if editable
            StatusBar.innerHTML = statusContents;
            ButtonBar.innerHTML = barContents;
            ButtonBar.innerHTML += "&nbsp;<input type='button' class='wideButton' value='add event' onclick='AddEvent(" 
                                + whichWeek + "," + whichDay + ")' title='Add a new event'/>";
    } // end if has buttons
  } // end if select the event
}// END SelectEvent


// Sets the default values for a new event,
// then calls edit event.
// The new event is stored temporarily as the 0th event of the day.
function AddEvent(whichWeek, whichDay) {
    viewMode = document.calendarEvents.view.value;
    if(viewMode == "week" || viewMode == "search") {
        JumpToDay(whichWeek, whichDay);
    }
    FrmDay            = MonthEvents[currentWeekIndex][currentDayIndex];
    defaultStart      = {"monthname"  : FrmDay.monthname,
                              "years" : FrmDay.year,
                             "months" : FrmDay.month,
                               "days" : FrmDay.day,
                              "hours" : "12",
                            "minutes" : "00",
                             "suffix" : "AM"
                        };
    defaultEnd        = {"monthname"  : FrmDay.monthname,
                              "years" : FrmDay.year,
                             "months" : FrmDay.month,
                               "days" : FrmDay.day,
                              "hours" : "11",
                            "minutes" : "59",
                             "suffix" : "PM"
                        };    ThisDay    = MonthEvents[whichWeek][whichDay];
    ThisDay[0] = { "title" : defaultTitle,
                    "text" : defaultText,
                "editable" : 1,
              "visibility" : 0,
             "repeat_unit" : "days",
         "repeat_interval" : 0,
                      "id" : -1,
                   "start" : defaultStart,
                     "end" : defaultEnd,
                  "remind" : 0,
                 "all_day" : 1
                 };
    EditEvent(whichWeek, whichDay, 0);
} // END AddEvent


// Fills the event details window with the controls for editing an event.
// Creates the action select drop down and the save cancel buttons that appear below the window.
// Switches to editing mode.
function EditEvent(whichWeek, whichDay, whichEvent) {
    ThisEvent  = MonthEvents[whichWeek][whichDay][whichEvent];
    ThisDay    = MonthEvents[whichWeek][whichDay];

    switchCal();

    if (ThisEvent.id == 0) {
        statusDropDown = StatusSelect;
    } else {
        statusDropDown = "";
    }
    if (ThisEvent.start.suffix == "PM") {
        startSuffixSelect = " selected='selected'";
    } else {
        startSuffixSelect = "";
    }
    if (ThisEvent.end.suffix == "PM") {
        endSuffixSelect = " selected='selected'";
    } else {
        endSuffixSelect = "";
    }
    if (ThisEvent.all_day) {
        selectCheck = "checked='on'";
    } else {
        selectCheck = "";
    }

    allDayCheck  = "<input name='all_day' type='checkbox' onclick='showFromTo(!this.checked)' value='1' " + selectCheck + ">";

    inputNewList = "<input size='18' autocomplete='off' name='calendar_event_list[name]' maxlength='18'"
                 + " value='"+ defaultName +"' onclick='clearDefault(this,\""+ defaultName +"\")'/>";

    document.getElementById("windowTitleCell").className  = "defaultTitle";


                                                                     /* UPPERMOST CONTROLS */
    document.getElementById("windowInfo").innerHTML       = "<table width=100%>"
                                      + "<tr valign='bottom'>"
                                              + "<td align='right'><b>Event title &nbsp</b></td>"
                                              + "<td align='left'>&nbsp<input size='30' style='font-weight:bold;' maxlength='100'"
                                                         +" id='inputTitle' type='text' name='calendar_event[event_title]' value=\""
                                                         +  ThisEvent.title + "\" autocomplete='off' onclick='clearDefault(this,\""+ defaultTitle +"\")'>"
                                              + "</td></tr>"
                                      + "<tr><td colspan=2><HR></td></tr>"
                                      + statusDropDown 

                                      + "<tr style='display:none'>"
                                              + "<td align='right' style='width:20%'><b>Event for &nbsp</b></td>"
                                              + "<td style='width:80%'>&nbsp" + TemplateSelect + "&nbsp"
                                                  + "<span id='setNewList' style='display:none'>" + inputNewList + "</span></td></tr>"

                                                                     /* DATETIME CONTROLS */
                                      + "<tr id='setDate' valign='bottom'>"
                                              + "<td align='right' style='padding-top:5px'><b>on &nbsp</b></td>"
                                              + "<td style='padding-top:5px'>&nbsp" + getStart() + "<b>&nbsp all day </b>" + allDayCheck + "</td></tr>"
                                      + "<tr id='setTime' valign='bottom'>"
                                          + "<td align='right' style='padding-top:5px'><b>from &nbsp</b></td><td style='padding-top:5px'>&nbsp"
                                              + "<input style='text-align:right' type='text' size='2' maxlength='2' name='start_time[hours]'"
                                              + " maxvalue='12' minvalue='0' onkeyup='return islegalvalue(this)' value="
                                              + ThisEvent.start.hours + "><b>:</b><input type='text' size='2' maxlength='2' name='start_time[minutes]'"
                                              + " maxvalue='59' minvalue='0' onkeyup='return islegalvalue(this)' value="
                                              + ThisEvent.start.minutes + "> <select name='start_time[suffix]' onChange='setEndSuffix()'>" 
                                              + "<option value='AM'>AM</option><option value='PM'" + startSuffixSelect + ">PM</option></select>"
                                              + "<b> to </b><input style='text-align:right' type='text' size='2' maxlength='2' name='end_time[hours]'"
                                              + " maxvalue='12' minvalue='0' onkeyup='return islegalvalue(this)' value=" 
                                              + ThisEvent.end.hours + "><b>:</b><input type='text' size='2' maxlength='2' name='end_time[minutes]'"
                                              + " maxvalue='59' minvalue='0' onkeyup='return islegalvalue(this)' value=" 
                                              + ThisEvent.end.minutes + "> <select name='end_time[suffix]' onChange='setStartSuffix()'>" 
                                              + "<option value='AM'>AM</option><option value='PM'"
                                              + endSuffixSelect + ">PM</option></select></td></tr>"
                               + "</table>"
                                                                     /* REPEAT CONTROLS */
                               + getRepeatControls(defaultVariable, whichWeek, whichDay, whichEvent);

    selectRemind     = "";
    selectDaysBefore = "";
    inAdvance        = 1;
    if(ThisEvent.reminder) {
        selectRemind   = "selected";
        inAdvance      = ThisEvent.reminder.time;
        if(ThisEvent.reminder.units == "days") {
            selectDaysBefore = "selected";
        }
    }                                                        /* REMINDER CONTROLS */
    remindSelect   = "<select name='remind_in_advance' onChange='showElem(parseInt(this.options[selectedIndex].value,10),\"setRemind\");'>"
                   +     "<option value='0'>never</option>"
                   +     "<option " + selectRemind + " value='1'>by email</option>"
                   + "</select>";
    remindUnitDrop = "<select name='units_in_advance'>"
                   +      "<option value='hours'>hours before</option>";
    remindUnitDrop +=     "<option " + selectDaysBefore + " value='days'>days before</option>";
    remindUnitDrop += "</select>";
    document.getElementById("windowInfo").innerHTML +=
                               "<table width=100% id='remindControls'><tr><td colspan=2><HR></td></tr>"
                               +     "<tr valign='bottom'><td style='width:20%' align='right'><b>Remind &nbsp</b></td>"
                               +         "<td>&nbsp" + remindSelect + "<span id='setRemind'>"
                               +             "<input style='text-align:right' type='text' size='2' maxlength='2' maxvalue='999' minvalue='0' " 
                               +                 "onkeyup='return islegalvalue(this)' name='time_in_advance' value='" + inAdvance + "'>&nbsp" 
                               +                 remindUnitDrop + "</span></td></tr>"
                               + "</table>";
    if(!ThisEvent.reminder) {
        showElem(false,"setRemind");
    }
//    if(ThisDay.today < 1) {
        showElem(false,"remindControls");
//    }
                                                                  /* EVENT DETAILS TEXTAREA */
    TextAreaContents = ThisEvent.text.replace(/<br>/g, "\n");
    document.getElementById("windowText").innerHTML       = "<table width=100%><tr><td align='right' style='width:20%'><b>Details &nbsp</b></td>"
                                                          + "<td style='width:80%' align='right'>&nbsp</td></tr></table>"
                                                          + "<textarea maxlength='2000' onkeyup='return ismaxlength(this)'"
                                                          + " onclick='clearDefault(this,\""+ defaultText +"\")'"
                                                          + " style='margin-bottom:2%; margin-left:1%; margin-right:2%; width:97%;' rows='10'" 
                                                          + " id='inputText' name='calendar_event[event_text]'>" + TextAreaContents + "</textarea>";

                                                                 /* BUTTONS: SAVE AND CANCEL */

    document.getElementById("buttonBar").innerHTML        = "<input class='veryNarrowButton' type='submit' name='submitted' value='save'/>"
         + "<input class='veryNarrowButton' type='button' name='cancel' value='cancel'"
         + "onclick='SelectDate(" + whichWeek + "," + whichDay + "); SetDefaultEvent(); SelectEvent(" + whichWeek + "," + whichDay + "," + whichEvent + ")'/>";

    /* Initialize date, time, repeat, and visibility */
    setStart();
    setEnd();

    InitializeDatePicker("StartDate", ThisDay.year, ThisDay.month, ThisDay.day);
    InitializeDatePicker("EndDate", ThisEvent.end.years, ThisEvent.end.months, ThisEvent.end.days);

   // selectedVisibility = document.getElementById(ThisEvent.visibility + "/" + ThisEvent.role);
    //if (selectedVisibility != null) {
      //  selectedVisibility.selected = true;
    //}

    showElem(!ThisEvent.all_day,"setTime");
    showRepeat(ThisEvent.repeats, whichWeek, whichDay, whichEvent);
    showUntil(ThisEvent.repeats && !isForever(), whichWeek, whichDay, whichEvent);
    if(isForever()) {
        document.getElementById("foreverCheck").checked = true;
    }

    /* Set to the current template */
    currentTmplID = document.calendarEvents.event_list.value;
    document.calendarEvents["calendar_event[event_list]"].value = currentTmplID
    hideDateTime(currentTmplID);

    showElem(false, calTab.search.tab); // hide search tab while editing


                                                                 /* ACTION SPECIFIC CODE: ADD (insert) & EDIT (update, split, override) */
    if (ThisEvent.id == -1) { // if we're adding an event...
        document.getElementById("action").value = "insert";
        document.getElementById("statusBar").innerHTML = "";
        document.getElementById("windowSubTitle").innerHTML   = /*"adding a new event"*/"";
        document.getElementById("windowTitle").innerHTML      = "Post Public Event: <br>Complete the information below and your posted event will show up on the AutismConnects Event Calendar within 2 business days pending approval.";
    } else { // else we are editing an event...
        document.getElementById("action").value = "update";
        statusContents = "<b>&nbsp Edit:&nbsp</b>"
        if(ThisEvent.repeats) {
            statusContents += "<select onChange='document.calendarEvents.action.value=this.options[selectedIndex].value;"
                                              + "showRepeat((this.options[selectedIndex].value != \"override\")," 
                                                             + whichWeek + "," + whichDay + "," + whichEvent + ");"
                                              + "document.getElementById(\"repeatSelect\").selectedIndex = (this.options[selectedIndex].value != \"override\");'>";
            if ( (ThisEvent.start.years == ThisDay.year) && (ThisEvent.start.months == ThisDay.month) && (ThisEvent.start.days == ThisDay.day) ) {
                statusContents += "<option value='update'>all occurrences</option>";
            } else {
                statusContents += "<option value='split'>from now on</option>";
                document.getElementById("action").value = "split";
            }
            statusContents += "<option value='override'>only this occurrence</option>";
            statusContents += "</select>";
        } else { // if it does not repeat
            statusContents += "all occurences";
        }
        document.getElementById("statusBar").innerHTML = statusContents;
        document.getElementById("windowSubTitle").innerHTML   = /*"editing an event"*/"";
        document.getElementById("windowTitle").innerHTML      = "Editing event: <span style='color:#184a84'>" + ThisEvent.display_title + "</span>";
        //document.getElementById("selectedStatus").innerHTML   = ThisEvent.display_status;
    }
} // END EditEvent


// Provides the deletion controls including the action selection radio button and okay/cancel buttons.
function DeleteEvent(whichWeek, whichDay, whichEvent) {
    ThisEvent = MonthEvents[whichWeek][whichDay][whichEvent];
    ThisDay   = MonthEvents[whichWeek][whichDay];

    document.getElementById("windowTitleCell").className  = "defaultTitle";
    document.getElementById("windowTitle").innerHTML =
    "<span style='color:#DA0000'>Deleting event: </span>'" + ThisEvent.display_title + "'";
    document.getElementById("windowSubTitle").innerHTML += "<input type='hidden' name='frmDelete' value='" + ThisEvent.id + "'/>";

    //Create action drop down and set action field
    document.getElementById("action").value = "delete";
    showElem(false, calTab.search.tab);
    deleteContents = ""
    if(ThisEvent.repeats) {
        if ( (ThisEvent.start.years == ThisDay.year) && (ThisEvent.start.months == ThisDay.month) && (ThisEvent.start.days == ThisDay.day) ) {
            deleteContents += "<input type='radio' value='delete' name='deletePicker' onClick='document.calendarEvents.action.value=this.value;' checked>"
                           + "Delete all occurrences <BR>";
            alternative = "advance";
        } else {
            deleteContents += "<input type='radio' value='curtail' name='deletePicker' onClick='document.calendarEvents.action.value=this.value;' checked>"
                           + "Delete this and all future occurences<BR>";
            document.getElementById("action").value = "curtail";
            alternative = "hide";
        }
        deleteContents += "<input type='radio' value='" + alternative + "' name='deletePicker' onClick='document.calendarEvents.action.value=this.value;'>"
                       + "Delete only this occurrence";
    } else { // if it does not repeat
        deleteContents += "<input type='radio' value='delete' name='deletePicker' onClick='document.calendarEvents.action.value=this.value;' checked>"
                       + "Delete all occurrences <BR>";
    }
    document.getElementById("windowText").innerHTML = deleteContents;
    document.getElementById("statusBar").innerHTML = "";
    //Create buttons
    document.getElementById("buttonBar").innerHTML = "<input class='veryNarrowButton' type='submit' name='submitted' value='okay'/>"
                                                   + "<input class='veryNarrowButton' type='button' name='cancel' value='cancel'"
                                 + "onclick='SetDefaultEvent(); SelectEvent(" + whichWeek + "," + whichDay + "," + whichEvent + ")'/>";
} // END DeleteEvent


// Provides the apply template controls.
// Switches calendar to editing mode.
function ApplyTemplate(whichWeek, whichDay) {
    ThisDay      = MonthEvents[whichWeek][whichDay];

    switchCal();

    document.getElementById("windowTitleCell").className  = "defaultTitle";
    document.getElementById("windowTitle").innerHTML      = "Applying Template to " 
        + ThisDay.monthname + " <span id='DAY'>" + ThisDay.day + "</span>, " + ThisDay.year;
    document.getElementById("windowSubTitle").innerHTML   = "";
    document.getElementById("windowText").innerHTML       = "";

    document.getElementById("action").value = "apply";
    showElem(false, calTab.search.tab);
    document.getElementById("buttonBar").innerHTML = "<input class='veryNarrowButton' type='submit' name='submitted' value='okay'/>"
                                                   + "<input class='veryNarrowButton' type='button' name='cancel' value='cancel'"
                                                          + "onclick='SetDefaultEvent();'/>";
    defaultTime       = {"monthname"  : ThisDay.monthname,
                              "years" : ThisDay.year,
                             "months" : ThisDay.month,
                               "days" : ThisDay.day,
                              "hours" : "00",
                            "minutes" : "00",
                             "suffix" : "AM"
                        };
    ThisDay[0] = {
             "repeat_unit" : "days",
         "repeat_interval" : 0,
                     "end" : defaultTime
                 };

    startSelect = getStart();

    document.getElementById("windowInfo").innerHTML = "<table width=100%>"
                                                        + "<tr>"
                                                            + "<td align='right' style='width:20%'><b>Apply &nbsp</b></td>"
                                                            + "<td style='width:80%'>&nbsp" + TemplateApply + "</td></tr>"
                                                        + "<tr valign='bottom'>"
                                                            + "<td align='right' style='padding-top:5px'><b>to &nbsp</b></td>"
                                                            + "<td style='padding-top:5px'>&nbsp" + startSelect + "</td></tr>"
                                                    + getRepeatControls("applied_events", whichWeek, whichDay, 0);
    setStart();
    setEnd();

    InitializeDatePicker("StartDate", ThisDay.year, ThisDay.month, ThisDay.day);
    InitializeDatePicker("EndDate",   ThisDay.year, ThisDay.month, ThisDay.day);

    showRepeat(false, whichWeek, whichDay, 0);
    showUntil(false, whichWeek, whichDay, 0);
    document.getElementById("foreverCheck").checked = true;
}

// Provides controls for modifying the name & description of an event list / template.
function ModifyTemplate(whichTmpl) {
    ThisTmpl = ListTemplates[whichTmpl];

    TitleFieldContents = ThisTmpl.name;
    if(TitleFieldContents.length < 1) {
        TitleFieldContents = defaultName;
    }
    /*document.getElementById("windowTitle").innerHTML      = "<input style='width:60%; text-align:center; font-weight:bold;' maxlength='18'" 
                                                          + " type='text' name='calendar_event_list[name]' value=\""
                                                          + TitleFieldContents + "\" autocomplete='off' onclick='clearDefault(this,\""+ defaultName +"\")'>";
    */
    TextAreaContents = ThisTmpl.description.replace(/<br>/g, "\n");
    if(TextAreaContents.length < 1) {
        TextAreaContents = defaultText;
    }

    document.getElementById("windowSubTitle").innerHTML = "editing my template";
    //document.getElementById("windowInfo").innerHTML       = "<b>&nbsp Editing name and description.</b>";
    document.getElementById("windowInfo").innerHTML       = "<table width=100%><tr>"
                                                          + "<td align=right style='width:25%'><b>Name &nbsp</b></td><td style='width:75%'>"
                                                          + "<input size='25' style='font-weight:bold;' maxlength='18'" 
                                                          + " type='text' name='calendar_event_list[name]' value=\""
                                                          + TitleFieldContents + "\" autocomplete='off' onclick='clearDefault(this,\""+ defaultName +"\")'>"
                                                          + "</td></tr></table>";

    document.getElementById("windowText").innerHTML       = "<table width=100%><tr><td align='right' style='width:25%'><b>Description &nbsp</b></td>"
                                                          + "<td style='width:75%' align='right'>&nbsp</td></tr></table>"
                                                          + "<textarea maxlength='90' onkeyup='return ismaxlength(this)'"
                                                          + " onclick='clearDefault(this,\""+ defaultText +"\")'"
                                                          + " style='margin-bottom:2%; margin-left:1%; margin-right:2%; width:97%;' rows='3'" 
                                                          + " id='inputText' name='calendar_event_list[description]'>" + TextAreaContents + "</textarea>";
    document.calendarEvents.action.value = "modify";
    if(whichTmpl > 0) {
        theCancelFunction = "SetDefaultEvent();"
    } else if (whichTmpl < 0) {
        theCancelFunction = "SelectTemplate(0);"
    }
    document.getElementById("statusBar").innerHTML        = "";
    document.getElementById("buttonBar").innerHTML        = "<input class='veryNarrowButton' type='submit' name='submitted' value='save'/>"
         + "<input class='veryNarrowButton' type='button' name='cancel' value='cancel' onclick='" + theCancelFunction + "'/>";
} // end ModifyTemplate

// Show/hides the start ane end time hour, minute, and suffix fields.
function showFromTo(show) {
    showElem(show,"setTime");
}

// Shows/hides the repeat interval field, repeat unit drop down (day, week, month, year), and 'repeat until' date controls.
function showRepeat(show, whichWeek, whichDay, whichEvent) {
    if (!show) {
        show = parseInt(show,10);
    } else if (show == "0") {
        show = false;
    }
    showElem(show,"repeatCell");
    ThisEvent = MonthEvents[whichWeek][whichDay][whichEvent];
    if (show) {
        showElem(!document.getElementById("foreverCheck").checked,"untilCell");
        if(ThisEvent.repeat_interval == 0) {
            document.getElementById("repeatInterval").value = 1;
        } else {
            document.getElementById("repeatInterval").value = ThisEvent.repeat_interval;
        }
    } else {
        showElem(false,"untilCell");
        document.getElementById("repeatInterval").value = 0;
    }
} // end showRepeat

/* Function for showing and hiding the month, year, and day drop downs for the repeat until date */
function showUntil(show, whichWeek, whichDay, whichEvent) {
    showElem(show,"untilCell");
    ThisEvent = MonthEvents[whichWeek][whichDay][whichEvent];
    FrmDay    = MonthEvents[currentWeekIndex][currentDayIndex];
    if (show) { // if show the until date drop downs
        // if the until date is forever, set the until date to this date
        if(thisIsForever(ThisEvent.end.years, ThisEvent.end.months, ThisEvent.end.days)) {
            InitializeDatePicker("EndDate", FrmDay.year, FrmDay.month, FrmDay.day);
        } else { // else set the until date to the end date...
            InitializeDatePicker("EndDate", ThisEvent.end.years, ThisEvent.end.months, ThisEvent.end.days);
            if (checkDate(noErrors) != noErrors) { //... unless the end date is invalid, in which case we set the until date to this date
                InitializeDatePicker("EndDate", FrmDay.year, FrmDay.month, FrmDay.day);
            }
        }
    } else {
        InitializeDatePicker("EndDate", foreverYear, 12, 31);
    }
} // end showUntil

// given hideVal (the template id)
// determines whether to hide or show the entirety of the repeat controls
// as well as the start date drop downs and all day check box.
// If 0, (false, i.e. calendar template) it will show the date & repeat controls.
// Otherwise it will hide those controls.
// If -1, it will provide a field for creating a new template's name.
function hideDateTime(hideVal) {
    show  = false;
    showT = true; // display time select
    ask   = false;
    if (hideVal == 0 || !hideVal) {
        show  = true;
        showT = !document.calendarEvents["all_day"].checked; // show the time if all day is NOT checked
    } else if (hideVal == -1) {
        ask  = true;
    }
    showElem(show,  "repeatControls");
    showElem(show,  "setDate");
    showElem(showT, "setTime");
    showElem(ask,   "setNewList");
    if (document.calendarEvents.event_list.value != hideVal) {
        SelectTemplate(hideVal);
    }
}

// determines if the currently selected end time is 'forever'.
function isForever() {
    return thisIsForever( document.calendarEvents["end_time[years]"].value,
                          document.calendarEvents["end_time[months]"].value,
                          document.calendarEvents["end_time[days]"].value
                        );
}

// determines if a given theYear, theMonth, theDay combination represents 'forever'.
function thisIsForever(theYear, theMonth, theDay) {
    //alert(theYear +"/"+ theMonth +"/"+ theDay);
    //alert(foreverYear +"/"+ 12 +"/"+ 31);
    return ( (theYear  == foreverYear)
          && (theMonth == 12)
          && (theDay   == 31)
           );
}

// populates the start date drop downs
// with data
function populateStart(){
    populate("StartDate");
}

// populates the end date drop downs
// with data
function populateEnd(){
    populate("EndDate");
}

// creates the start date drop downs
function getStart(){
    return "<select name='start_time[months]' onChange='populateStart();'></select>"
         + "<select name='start_time[days]'></select><b>,</b>"
         + "<select name='start_time[years]' onChange='populateStart();'></select>";
}

// creates the end date drop downs
function getEnd(){
    return "<select name='end_time[months]' onChange='populateEnd();'></select>"
         + "<select name='end_time[days]'></select><b>,</b>"
         + "<select name='end_time[years]' onChange='populateEnd();'></select>";
}

function setStart(){
    DatePickers["StartDate"]          = new Array();
    DatePickers["StartDate"]["year"]  = document.calendarEvents.elements["start_time[years]"];
    DatePickers["StartDate"]["month"] = document.calendarEvents.elements["start_time[months]"];
    DatePickers["StartDate"]["day"]   = document.calendarEvents.elements["start_time[days]"];
}

function setEnd(){
    DatePickers["EndDate"]          = new Array();
    DatePickers["EndDate"]["year"]  = document.calendarEvents.elements["end_time[years]"];
    DatePickers["EndDate"]["month"] = document.calendarEvents.elements["end_time[months]"];
    DatePickers["EndDate"]["day"]   = document.calendarEvents.elements["end_time[days]"];
}

// if the end time's suffix is AM then the start time's suffix must be AM
function setStartSuffix(){
    if (document.calendarEvents["end_time[suffix]"].value == "AM") {
        document.calendarEvents["start_time[suffix]"].value = "AM";
    }
}

// if the start time's suffix is PM then the end time's suffix must be PM
function setEndSuffix(){
    if (document.calendarEvents["start_time[suffix]"].value == "PM") {
        document.calendarEvents["end_time[suffix]"].value = "PM";
    }
}

// returns, as a string, the HTML for the repeat controls
// where theVariable is the object that is repeating
// e.g. a calendar_event.
function getRepeatControls(theVariable, whichWeek, whichDay, whichEvent) {
    ThisEvent = MonthEvents[whichWeek][whichDay][whichEvent];

    if (ThisEvent.repeats) {
        selectEver = "selected";
    } else {
        selectEver = "";
    }
    repeatSelect = "<select id='repeatSelect' onChange='showRepeat(this.options[selectedIndex].value," 
                                                      + whichWeek + "," + whichDay + "," + whichEvent + ")'>"
                 +     "<option value='0'>never</option>"
                 +     "<option " + selectEver + " value='1'>every...</option>"
                 + "</select>";

    foreverCheck = "<b>&nbsp forever </b><input id='foreverCheck' type='checkbox' onclick='showUntil(!this.checked," +
                                          whichWeek + "," + whichDay + "," + whichEvent + ")'>";

    selectedUnit = { "days"   : "",
                     "weeks"  : "",
                     "months" : "",
                     "years"  : "" 
                   };
    selectedUnit[ThisEvent.repeat_unit] = "selected";
    unitDropDown =  "<select name='" + theVariable + "[repeat_unit]'>\n";
    unitDropDown +=     "<option " + selectedUnit["days"]   + " value='days'>days</option>\n";
    unitDropDown +=     "<option " + selectedUnit["weeks"]  + " value='weeks'>weeks</option>\n";
    unitDropDown +=     "<option " + selectedUnit["months"] + " value='months'>months</option>\n";
    unitDropDown +=     "<option " + selectedUnit["years"]  + " value='years'>years</option>\n";
    unitDropDown += "</select>";

    endSelect   = getEnd();

    return "<table width=100% id='repeatControls'>"
     +     "<tr><td colspan=2><HR></td></tr>"
     +     "<tr valign='bottom'><td style='width:20%' align='right'><b>Repeat &nbsp</b></td>"
     +         "<td>&nbsp" + repeatSelect + "<span id='repeatCell'>"
     +             "<input id='repeatInterval' style='text-align:right' type='text' size='2' maxlength='2'"
     +                 " maxvalue='999' minvalue='0' onkeyup='return islegalvalue(this)'"
     +                 "name='" + theVariable + "[repeat_interval]' value='" + ThisEvent.repeat_interval + "'>&nbsp" 
     +             unitDropDown + foreverCheck + "</span></td></tr>"
     +     "<tr id='untilCell' valign='bottom'>"
     +         "<td align='right' style='padding-top:5px'><b>until &nbsp</b></td>" 
     +         "<td style='padding-top:5px'>&nbsp" + endSelect
     + "</td></tr></table>";
}

// if the object obj's value is the default value defaultVal then
// clear obj's contents.
function clearDefault(obj, defaultVal) {
    if(obj.value == defaultVal) {
        obj.value = "";
    }
}

// if obj's value is more than maximum length, the value is curtailed to the maximum lenght
function ismaxlength(obj){
    var mlength=obj.getAttribute? parseInt(obj.getAttribute("maxlength")) : ""
    if (obj.getAttribute && obj.value.length>mlength)
        obj.value=obj.value.substring(0,mlength)
}

// checks to see if the value of the obj is legal (between the maximum and minimum allowable values)
function islegalvalue(obj){
    if (obj.getAttribute && obj.value != "") {
        var maxval = parseInt(obj.getAttribute("maxvalue"));
        var minval = parseInt(obj.getAttribute("minvalue"));
        var valend = parseInt(obj.value.substring(obj.value.length - 1, obj.value.length));
        if (!(valend <= maxval && valend >= minval)) { // if the end character of the value is not legal
            obj.value = obj.value.substring(0, obj.value.length - 1) + "0"; // drop the end character
        }
        var valstart = parseInt(obj.value);
        if (!(valstart == "" || (valstart <= maxval && valstart >= minval))) { // if the value of the object is still not legal...
            obj.value = "0" + obj.value.substring(1, obj.value.length); // ...replace the first character with a zero
        }
    }
}

/////////////////////////////////////////                          /////////////////////////////////////////
/////////////////////////////////////////        STATUS BAR        /////////////////////////////////////////
/////////////////////////////////////////                          /////////////////////////////////////////


/*   MarkAsComplete:
calls the mark action to create an instance object for this event
and date which will mark the event as completed for this day
*/
function MarkAsComplete(statusLabel) {
    eventTitle = document.getElementById("event" + currentEventID + "-" + 2).innerHTML;
    ThisDay   = MonthEvents[currentWeekIndex][currentDayIndex];
    if(displayingWeek) {
        viewText = "week";
    } else {
        viewText = "day";
    }
    var agree = confirm("Have you " + statusLabel + " the event '" + eventTitle + "' for " 
                        + ThisDay.monthname + " " + ThisDay.day + ", " + ThisDay.year + "?");
    if (agree) {
        document.location.href = PHXbaseURL + "/eventcalendar/action/mark/frmCalendarEventId/" 
                                 + currentEventID +  "/Y/" + ThisDay.year + "/M/" + ThisDay.month + "/D/" + ThisDay.day + "/view/" + viewText + "/";
    } else {
        document.getElementById("statusChange").selectedIndex = 0;
    }
}

/*   EraseMark:
calls the erase action to delete an instance object tied to the event,
therebye returning the event to its default status (usually- not complete)
*/
function EraseMark(statusLabel) {
    eventTitle = document.getElementById("event" + currentEventID + "-" + 2).innerHTML;
    ThisDay   = MonthEvents[currentWeekIndex][currentDayIndex];
    if(displayingWeek) {
        viewText = "week";
    } else {
        viewText = "day";
    }
    var agree = confirm("Do you wish to reset '" + eventTitle + "' to a '" + statusLabel + "' status for " 
                        + ThisDay.monthname + " " + ThisDay.day + ", " + ThisDay.year + "?");
    if (agree) {
        document.location.href = PHXbaseURL + "/eventcalendar/action/erase/frmCalendarEventId/" 
                                 + currentEventID +  "/Y/" + ThisDay.year + "/M/" + ThisDay.month + "/D/" + ThisDay.day + "/view/" + viewText + "/";
    } else {
        document.getElementById("statusChange").selectedIndex = 1;
    }
}

/////////////////////////////////////////                          /////////////////////////////////////////
/////////////////////////////////////////     INPUT VALIDATION     /////////////////////////////////////////
/////////////////////////////////////////                          /////////////////////////////////////////

/*   CheckInput:
called on submit
checks the input for errors
makes changes or warns the user if neccesary
returns false if the input isn't valid
(or can't be made valid)
*/
function CheckInput() {
    actionName   = document.calendarEvents.action.value;
    viewMode     = document.calendarEvents.view.value;
    var variableName = defaultVariable;

    if (actionName == "cancel") {
        if (viewMode == "search") {
            document.calendarEvents.action.value = "search";
            actionName = "search";
        } else {
            alert("cancel!");
            return false;
        }
    }
    if (actionName == "apply") {
        variableName = "applied_events";
        inCalendar   = true;

    } else if (actionName == "clear") {
        theTemplateName = ListTemplates[document.calendarEvents.event_list.value].name;
        return confirm("Are you sure you want to clear all events from the template '" + theTemplateName + "' and delete the template?");

    } else if (actionName == "modify") {
        modifiedName    = document.calendarEvents["calendar_event_list[name]"].value;
        tmplDescField   = document.calendarEvents["calendar_event_list[description]"];
        if (tmplDescField.value == defaultText) {
            tmplDescField.value = "";
        }
        theTemplateName = ListTemplates[document.calendarEvents.event_list.value].name;
        theTemplateDesc = ListTemplates[document.calendarEvents.event_list.value].description;
        if (theTemplateName == modifiedName && theTemplateDesc == tmplDescField.value) { // if no changes have been made
            SetDefaultEvent();
            return false;
        }
        nameIsValid  = !((modifiedName == null) || (modifiedName.length == 0) || (modifiedName < " "));
        if (!nameIsValid) alert("Please give the template a name.");
        return nameIsValid;

    } else if (actionName == "search") {
        searchField = document.calendarEvents.search_string.value;
        return !((searchField == null) || (searchField.length == 0) || (searchField < " "));

    } else if ( (actionName == "delete") || (actionName == "curtail") || (actionName == "hide") || (actionName == "advance") ) { // event deletion actions
       theEventTitle = document.getElementById("event" + document.calendarEvents.frmDelete.value + "-" + 2).innerHTML;
       monthName  = MonthEvents[2][1].monthname;
       dayNum     = document.calendarEvents.D.value;
       yearNum    = document.calendarEvents.Y.value;
       if (actionName == "delete") {
           return confirm("Are you sure you want to delete all occurrences of the event '" + theEventTitle + "'?");
       } else if (actionName == "curtail") {
           return confirm("Are you sure you want to delete all occurrences of the event '" 
                        + theEventTitle + "' after and including " + monthName + " " + dayNum + ", " + yearNum + "?");
       } else if ((actionName == "hide") || (actionName == "advance")) {
           return confirm("Are you sure you want to delete the event '" + theEventTitle + "' for " + monthName + " " + dayNum + ", " + yearNum + "?");
       }
    }

    errorMessage = noErrors;

    // um, let's change the input a wee bit here...

    repeatInterval = parseInt(document.getElementById("repeatInterval").value, 10);

    if(!(repeatInterval > 0)) {
        document.getElementById("repeatInterval").value = 0;
    }
    if (repeatInterval == 0) {
        document.calendarEvents["end_time[years]"].value  = document.calendarEvents["start_time[years]"].value;
        document.calendarEvents["end_time[months]"].value = document.calendarEvents["start_time[months]"].value;
        document.calendarEvents["end_time[days]"].value   = document.calendarEvents["start_time[days]"].value;
    }

    if (variableName == defaultVariable) {

        remindAdvance  = parseInt(document.calendarEvents["time_in_advance"].value, 10);

        if(!(remindAdvance > 0)) {
            document.calendarEvents["time_in_advance"].value = 0;
        }

        textField = document.getElementById("inputText");
        if (textField.value == defaultText) { // no sense in storing the default string in the database
            textField.value = ""; 
        }

        //okay, now let's do error checking.

        titleField = document.calendarEvents["calendar_event[event_title]"].value;

        // make sure the event has a title
        if( (titleField == null) || (titleField.length == 0) || (titleField <= " ") || (titleField == defaultTitle)) {
            errorMessage = "fill in a title";
        }

        listID = parseInt(document.calendarEvents["calendar_event[event_list]"].value, 10);
        if (listID < 0 || listID > 0) {
            inCalendar = false;
        } else {
            inCalendar = true;
        }

	// make sure that the event is either an all day event in the calendar or has appropriate start and end times
	allDay = document.calendarEvents["all_day"].checked;
	if (!allDay || !inCalendar) {
		startHours = parseInt(document.calendarEvents["start_time[hours]"].value, 10);
		endHours   = parseInt(document.calendarEvents["end_time[hours]"].value, 10);
		if( !((startHours <= 12) && (startHours >= 1)) ) {
			errorMessage = "fill in a start time between 12:00 AM and 11:59 PM";
		} else if( !((endHours <= 12) && (endHours >= 1)) ) {
			errorMessage = "fill in an end time between 12:00 AM and 11:59 PM";
		}
		
		startMinutes = parseInt(document.calendarEvents["start_time[minutes]"].value, 10);
		endMinutes   = parseInt(document.calendarEvents["end_time[minutes]"].value, 10);
		
		if( !((startMinutes <= 59) && (startMinutes >= 0) && (endMinutes <= 59) && (endMinutes >= 0)) ) {
			errorMessage = "remember, there are between 0 and 59 minutes in an hour";
		}
		
		startSuffix = document.calendarEvents["start_time[suffix]"].value;
		endSuffix   = document.calendarEvents["end_time[suffix]"].value;
		
		if(errorMessage == noErrors) {
		
			start24Hours = startHours;
			if(startHours == 12) {
				start24Hours = 0;
			}
			if(startSuffix == "PM") {
				start24Hours = start24Hours + 12;
			}
			start24Hours = (start24Hours * 100) + startMinutes;
		
			end24Hours = endHours;
			if(endHours == 12) {
				end24Hours = 0;
			}
			if(endSuffix == "PM") {
				end24Hours = end24Hours + 12;
			}
			end24Hours = (end24Hours * 100) + endMinutes;
		
			if(end24Hours < start24Hours) {
				errorMessage = "choose an end time that comes after the start time";
			}
		}
	} // end if not all day
    } // end if variable is the default

    if (inCalendar) { // only check for these errors if it's an event in the calendar
        errorMessage = checkDate(errorMessage);
    }

    if(errorMessage != noErrors) {
        alert("Please " + errorMessage + ".");
        return false;
    } else {
        return true;
    }
} // end CheckInput


/*   checkDate:
Checks to see if the the end date comes after the start date.
If the end date comes before the start date, that's an error.
Returns the passed in value of errorMessage if there aren't any errors.
Returns a different message if there is an error.
*/
function checkDate(errorMessage) {
    startYear  = parseInt(document.calendarEvents["start_time[years]"].value, 10);
    startMonth = parseInt(document.calendarEvents["start_time[months]"].value, 10);
    startDay   = parseInt(document.calendarEvents["start_time[days]"].value, 10);

    endYear  =  parseInt(document.calendarEvents["end_time[years]"].value, 10);
    endMonth =  parseInt(document.calendarEvents["end_time[months]"].value, 10);
    endDay   =  parseInt(document.calendarEvents["end_time[days]"].value, 10);

    //alert(startYear + "/" + startMonth + "/" + startDay + " " + endYear + "/" + endMonth + "/" + endDay);
    //alert(startDay > endDay);
    //alert(startDay + endDay);

    if (startYear > endYear) {
        errorMessage = "choose a later end date or an earlier start date.\nTry changing the year";
    } else if (startYear == endYear) {
        if (startMonth > endMonth) {
            errorMessage = "choose a later end date or an earlier start date.\nTry changing the month or year";
        } else if (startMonth == endMonth){
            if (startDay > endDay) {
                errorMessage = "choose a later end date or an earlier start date.\nTry changing the day, month, or year";
            }
        }
    }
    return errorMessage;
}