﻿/*********************************************************************************
 * timeslots.js
 * javascript functions for the clickable calendar and UI management 
 * of selected time-slots
 *********************************************************************************/
var IMPLEMENT_RECURRING = true;

// Color Constants
var TIME_SLOT_CLICKED = "#FEA813";
var TIME_SLOT_AVAILABLE = "#FFFFFF";
var TIME_SLOT_OVER = "#FDD56A";
var WEEKEND_AVAILABLE = "#F2F2F2";
var TIME_ROW_OVER = "#EEDEAB";
var TIME_ROW_NORMAL = "#EFEBDE";
var WEEKDAY_NORMAL = "#BACEFB";
var TIME_SLOT_UNAVAILABLE = "#E7E3D6";

// use case constants defined in page headers.
var SCHEDULE = 0;
var INDICATE = 1;

// global constants
var BY_DATES = 0;
var RECURRING = 1;
var SUNDAY = 0;
var SATURDAY = 6;
var SUNDAY_WEEK2 = 7;
var SATURDAY_WEEK2 = 13;

// these control times that get selected when the whole day is clicked.
var START_WORKDAY = 18;
var END_WORKDAY = 34;

// these are overriden from asp when we're updating the meeting
var meetingType = BY_DATES;
var doingUpdate = false;

var ONE_DAY = 1000 * 60 * 60 * 24;  // number of miliseconds
// time Cells grid
var timeCells = new Array(2);
var AVAILABLE = 0;
var CLICKED = 1;
var UNAVAILABLE = 2;
var LASTROW = 47;

// two arrays exist, one for each meeting type (recurring / one-time)
for (var t = 0; t < 2; t++) {
    timeCells[t] = new Array(14);
    for (var i = 0; i < 14; i++) {
        timeCells[t][i] = new Array(24 * 2); // this is how many 30 minute blocks there are per day
        // initialize timeCells
        for (var j = 0; j < 24 * 2; j++)
            timeCells[t][i][j] = AVAILABLE;
    }
}

// meeting time
// NOW setting this from asp
// var meetingTime = 2; 	// 2*30mins = 1 hour

var monthName = new Array("January", "Februrary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");

var timeSlots = new Array(2);   // array of selected time slots
var curSunday = new Array(2);   // sunday's date for currenly displayed 2 week period
for (var t = 0; t < 2; t++) 
{
    timeSlots[t] = new Array();
    curSunday[t] = new Date;
}

// function returns a date object set to the sunday immediately before date d (if weekBefore=0)
// or 1 week before that if weekBefore=1
function getSunday(d, weekBefore) {
    var sun = new Date(d);
    sun.setDate(d.getDate() - d.getDay());
    sun.setHours(0);
    sun.setMinutes(0);
    sun.setMilliseconds(0);
    sun.setSeconds(0);
    if (weekBefore)
        sun.setDate(sun.getDate() - 7);
    return sun;
}

// function is called on page load from master page, this is the local implementation for schedule and indicate pages
function body_onload() {
    // Need to avoid doing all this if we're on step1 because none of the elements exist,
    // probably a better way of handling this.
    if (USE_CASE == SCHEDULE && document.getElementById('step2') == null) {
        toggleIncludeMap(); // local function in schedule.aspx
        mapinitialize();
        return;
    }
     

    // disable submit button if no time slots are selected
    if (USE_CASE == SCHEDULE) {
        if (timeSlots[meetingType].length == 0)
            document.getElementById(submitButtonID).disabled = true;
        else
            document.getElementById(submitButtonID).disabled = false;
    }

    // initialize the current date to be whatever last sundays date was. For recurring we use a constant date
    curSunday[BY_DATES] = getSunday(new Date(), 0);
    curSunday[RECURRING]= getSunday(new Date("January 1, 2006"), 0);
    if (USE_CASE == INDICATE && availTimeSlots.length > 0) {
        // jump to first available dates in the future, or the last one if nothing is in the future
        var i = 0;
        while (availTimeSlots[i] < curSunday[meetingType] && i < availTimeSlots.length - 1) {
             i++;
        }
        curSunday[meetingType] = getSunday(availTimeSlots[i], 0);
    }
        
    fillInDates();

    if (USE_CASE == SCHEDULE && IMPLEMENT_RECURRING && !doingUpdate) {
        document.getElementById("RadioOnetime").checked = true;
        document.getElementById("RadioRecurring").checked = false;
    }
   
   // display the appropriate calendar. This also tells asp what type of meeting it is
   changeMeetingType(meetingType);
   
    refreshTimeCellDisplay();
    updateTimeSlotString();

    // scroll to 8am
    document.getElementById("timeSlotsDivByDate").scrollTop = 16 * 15;
    if (IMPLEMENT_RECURRING)
        document.getElementById("timeSlotsDiv").scrollTop = 16*15;
}
 
// This function displays the dates for the current 2 week period
function fillInDates() {
	if (meetingType == RECURRING)
		return; // nothing to do
	
	var todaysDate = new Date();
	var tempDate;
	tempDate = new Date(curSunday[meetingType].getTime());
	// update the current month and year
	var curMonth = monthName[tempDate.getMonth()];
	document.getElementById('curYear').innerHTML = curMonth + ' ' + String(tempDate.getFullYear());
	for (var i = 0; i < 14; i++) {
	    // check if it is today's date
	    if (tempDate.getYear() == todaysDate.getYear() && tempDate.getMonth() == todaysDate.getMonth() &&
		    tempDate.getDate() == todaysDate.getDate()) {
	        document.getElementById('date' + String(i + 1)).style.background = "#FFFF88";
	    }
	    else {
	        document.getElementById('date' + String(i + 1)).style.background = WEEKDAY_NORMAL;
	    }
	    document.getElementById('date' + String(i + 1)).innerHTML = String(tempDate.getMonth() + 1) + '/' + String(tempDate.getDate());
	    tempDate.setDate(tempDate.getDate() + 1);
	}

    // determine if there are available time slots ahead or behind and disable / enable links accordingly
    if (USE_CASE == INDICATE) {
        // check previous available
        if (availTimeSlots.length == 0 || availTimeSlots[0] >= curSunday[meetingType]) {
            // disable previous link
            document.getElementById("prevCalendarLinks").innerHTML = "<span style=\"color:#777777\">&#60&#60 previous available</span> ";
        }
        else {
            document.getElementById("prevCalendarLinks").innerHTML = "<a href='' onclick='prevAvail();return false;'>&#60&#60 previous available</a> ";
        }
        // check next availble
        var sunday2Weeks = new Date(curSunday[meetingType].getTime());
        sunday2Weeks.setDate(curSunday[meetingType].getDate() + 14);
        if (availTimeSlots.length == 0 || availTimeSlots[availTimeSlots.length - 1] < sunday2Weeks) {
            // disable next link
            document.getElementById("nextCalendarLinks").innerHTML = "<span style=\"color:#777777\">next available &#62&#62</span>";
        }
        else {
            document.getElementById("nextCalendarLinks").innerHTML = "<a href='' onclick='nextAvail();return false;'>next available  &#62&#62</a>";
        }
    }
    else {
        // add next and previous 2 weeks links
        document.getElementById("prevCalendarLinks").innerHTML = "<a href='' onclick='prev2Weeks();return false;'>&#60&#60 2 Weeks </a>";
        document.getElementById("nextCalendarLinks").innerHTML = "<a href='' onclick='next2Weeks();return false;'>2 Weeks &#62&#62 </a>";
    }    
}
// This function increases the current date displayed by 2 weeks
function next2Weeks() {
    
    curSunday[meetingType].setDate(curSunday[meetingType].getDate() + 14);
    
    refreshTimeCellDisplay();
    
    // update the dates displayed on the calendar
    fillInDates();
}
// this funcion decreases the current date by 2 weeks
function prev2Weeks() {
    
    curSunday[meetingType].setDate(curSunday[meetingType].getDate() - 14);
  
    // make sure the updated timeCells are displayed
    refreshTimeCellDisplay();

    // update the dates displayed on the calendar
    fillInDates();
}
// this function jumps to the 2 week period containing the next available dates
function nextAvail() {
    // search through available timeslots and find the closest date
    // outside of this 2 week period.
    var sunday2Weeks = new Date(curSunday[meetingType].getTime());
    sunday2Weeks.setDate(curSunday[meetingType].getDate() + 14);
    var i = 0;
    while (availTimeSlots[i] < sunday2Weeks && i < availTimeSlots.length-1) {
            i++;
    }
    curSunday[meetingType] = getSunday(availTimeSlots[i],0);
    
    // make sure the updated timeCells are displayed
    refreshTimeCellDisplay();

    // update the dates displayed on the calendar
    fillInDates();
}
// this function jumps to the 2 week period containing the next available dates
function prevAvail() {
    // search through available timeslots and find the closest date
    // outside of this 2 week period.
    
    var i = availTimeSlots.length-1;
    while (availTimeSlots[i] >= curSunday[meetingType] && i > 0) {
        i--;
    }
    curSunday[meetingType] = getSunday(availTimeSlots[i],1);

    // make sure the updated timeCells are displayed
    refreshTimeCellDisplay();

    // update the dates displayed on the calendar
    fillInDates();
}

function refreshTimeCellDisplay() {

    // if scheduling, set everything to available
    if (USE_CASE == SCHEDULE) {
        // clear timeCell array and add in info from timeSlots array
        for (var day = 0; day < 14; day++) {
            for (var cell = 0; cell < 48; cell++) {
                timeCells[meetingType][day][cell] = AVAILABLE;
            }
        }
    }
    // if indicating, then set cells accroding to availTimeSlots. This should be set by asp
    else {
        // clear timeCell array and add in info from timeSlots array
        for (var day = 0; day < 14; day++) {
            for (var cell = 0; cell < 48; cell++) {
                timeCells[meetingType][day][cell] = UNAVAILABLE;
            }
        }
        
        var sunday2Weeks = new Date(curSunday[meetingType].getTime());
        sunday2Weeks.setDate(curSunday[meetingType].getDate() + 14);
        var numAvailTimeSlots = availTimeSlots.length
        for (var i = 0; i < numAvailTimeSlots; i++) {
            if (availTimeSlots[i] >= curSunday[meetingType] && availTimeSlots[i] < sunday2Weeks) {
                var numDays = Math.floor((availTimeSlots[i].getTime() - curSunday[meetingType].getTime()) / ONE_DAY);
                var numRows = 2 * availTimeSlots[i].getHours() + Math.floor(availTimeSlots[i].getMinutes() / 30);
                for (j = 0; j < meetingTime; j++) {
                    timeCells[meetingType][numDays][numRows + j] = AVAILABLE;
                }
            }
        } 
          
    }
    // search for all timeslots that fall within this 2 week period and set timeCells array
    // for recurring meetings, all timeslots should fall within this range
    var sunday2Weeks = new Date(curSunday[meetingType].getTime());
    sunday2Weeks.setDate(curSunday[meetingType].getDate() + 14);
    var numTimeSlots = timeSlots[meetingType].length;
    for (var i = 0; i < numTimeSlots; i++) {
        if (timeSlots[meetingType][i] >= curSunday[meetingType] && timeSlots[meetingType][i] < sunday2Weeks) {
            var numDays = Math.floor((timeSlots[meetingType][i].getTime() - curSunday[meetingType].getTime()) / ONE_DAY);
            var numRows = timeSlots[meetingType][i].getHours() * 2 + Math.floor(timeSlots[meetingType][i].getMinutes() / 30);
            for (j = 0; j < meetingTime; j++) {
                timeCells[meetingType][numDays][numRows + j] = CLICKED;
            }
        }
    }

    // update display using timeCells array
    var final_day = (meetingType==RECURRING) ? 7 : 14;
    for (var day = 0; day < final_day; day++) {
        for (var row = 0; row < LASTROW+1; row++) {
            var id_str = String(day) + '-' + String(row) + (meetingType ? '' : '-D');
            // handle the weekends
            var is_weekend = (day == SUNDAY || day == SATURDAY || day == SUNDAY_WEEK2 || day == SATURDAY_WEEK2);
            if (timeCells[meetingType][day][row] == CLICKED)
                document.getElementById(id_str).style.background = TIME_SLOT_CLICKED;
            else if (timeCells[meetingType][day][row] == AVAILABLE)
                document.getElementById(id_str).style.background = (is_weekend) ? WEEKEND_AVAILABLE : TIME_SLOT_AVAILABLE;
            else
                document.getElementById(id_str).style.background = TIME_SLOT_UNAVAILABLE;
        }
    }
}
function updateTimeSlotString() {
    var timeSlotsStr = "";
    //var timeSlotsStrDbg = "";
    var aTimeSlot = "";
    var temp = new Date();
    var numTimeSlots = timeSlots[meetingType].length;
    for (var i = 0; i < numTimeSlots; i++) {
        aTimeSlot = timeSlots[meetingType][i].getFullYear() + "\\" + (timeSlots[meetingType][i].getMonth() + 1) + "\\" +
                        timeSlots[meetingType][i].getDate() + "\\" + timeSlots[meetingType][i].getHours() + "\\" + timeSlots[meetingType][i].getMinutes() + ";";
        timeSlotsStr += aTimeSlot;
        //timeSlotsStrDbg += aTimeSlot + " &nbsp ";                        
    }
    //document.getElementById('debugText').innerHTML = timeSlotsStrDbg;
    // hiddenTimesByDateID is set by asp backend page as the clientID of the time-string hidden field
    if (meetingType == RECURRING)
        document.getElementById(hiddenTimesRecurringID).value = timeSlotsStr;
    else
        document.getElementById(hiddenTimesByDateID).value = timeSlotsStr;
}
// function to add a time slot to the end of the timeSlots array
function addTimeSlot(day, cell) {
    var tempDate;
    tempDate = new Date(curSunday[meetingType].getTime());
    tempDate.setDate(curSunday[meetingType].getDate() + day);
    tempDate.setHours(cell/2);
    tempDate.setMinutes(30 * (cell % 2));
    timeSlots[meetingType].push(tempDate);
    updateTimeSlotString();
    
    // enable submit button if something is selected
    if (USE_CASE == SCHEDULE) {
        if (timeSlots[meetingType].length == 1) {
            document.getElementById(submitButtonID).disabled = false;
        }
    }
                             
}
// function to remove a timeslot from the timeslots array, using
// a day (0-14) and a cell (0-48)
function removeTimeSlot(day, cell) {
    tempDate = new Date(curSunday[meetingType].getTime());
    tempDate.setDate(curSunday[meetingType].getDate() + day);
    tempDate.setHours(cell / 2);
    tempDate.setMinutes(30 * (cell % 2));
    var numTimeSlots = timeSlots[meetingType].length;
    for (var i = 0; i < numTimeSlots; i++) {
        if (tempDate.getTime() == timeSlots[meetingType][i].getTime()) {
            // splice(i,n) removes n elements starting at index i
            timeSlots[meetingType].splice(i, 1);
            break;
        }
    }
    updateTimeSlotString();

    // disable submit button if something is selected
    if (USE_CASE == SCHEDULE) {
        if (timeSlots[meetingType].length == 0) {
            document.getElementById(submitButtonID).disabled = true;
        }
    }
}
// Function called when a time cell is clicked 
function clickTimeCell(day, curCell, override) {

    var previousState = timeCells[meetingType][day][curCell];

    // if the cell we just clicked is unavailable, then abort
    if (previousState == UNAVAILABLE)
        return;
    // add override case here
    // ... XXX is this needed?

    if (previousState == CLICKED) {
        // if this cell is at the top of an already clicked time-slot, remove it
        // otherwise add it as a new time slot
        var existingSlot = true;
        for (var i = 0; i < meetingTime; i++) {
            if (curCell + i > LASTROW || timeCells[meetingType][day][curCell + i] != CLICKED) {
                existingSlot = false;
                break;
            }
        }
        if (existingSlot) {
            // check if additional times are highlighted before and after this time. This is necessary to ensure that
            // only appropriate durations remain highlighted after removing a time slot.
            var beforeCells = 0;
            var afterCells = 0;
            var startRemove;
            var endRemove;
            var i = 0;
            while (i < meetingTime && curCell-1-i >= 0 && timeCells[meetingType][day][curCell-1-i] == CLICKED) {
                beforeCells++;
                i++;
            }
            if (beforeCells == 0)
                startRemove = 0;
            else if (beforeCells == meetingTime)
                startRemove = 0;
            else
                startRemove = meetingTime-beforeCells;
                
            i = 0;
            while (i < meetingTime && curCell+i+meetingTime <= LASTROW && timeCells[meetingType][day][curCell+meetingTime+i] == CLICKED) {
                afterCells++;
                i++;
            }
            if (afterCells == meetingTime)
                endRemove = meetingTime;
            else if (afterCells == 0)
                endRemove = meetingTime;
            else
                endRemove = afterCells;
            
            for (var i = startRemove; i < endRemove; i++) {
                timeCells[meetingType][day][curCell + i] = AVAILABLE;
                var id_str = String(day) + '-' + String(curCell + i) + (meetingType ? '' : '-D');
                if (day == SUNDAY || day == SATURDAY || day == SUNDAY_WEEK2 || day == SATURDAY_WEEK2)
                    document.getElementById(id_str).style.background = WEEKEND_AVAILABLE;
                else
                    document.getElementById(id_str).style.background = TIME_SLOT_AVAILABLE;
            }
            // remove this timeslot if its been unclicked
            if (startRemove < endRemove)
                removeTimeSlot(day, curCell);

            // remove all meetings going backward
            var i = 0;
            while (i < meetingTime - 1 && curCell - 1 - i >= 0 && timeCells[meetingType][day][curCell - 1 - i] == CLICKED &&
               timeCells[meetingType][day][curCell - 1 - i + meetingTime] != UNAVAILABLE) {
                // this is a valid slot, make sure it wasn't previously valid
                var foundNewSlot = false;
                for (var j = 0; j < meetingTime; j++) {
                    if (timeCells[meetingType][day][curCell - 1 - i + j] == AVAILABLE)
                        foundNewSlot = true;
                }
                if (foundNewSlot) {
                    removeTimeSlot(day, curCell - 1 - i);
                    
                }
                i++;
            }

            // remove all meetings going forward
            i = 0;
            while (i < meetingTime - 1 && timeCells[meetingType][day][curCell + 1 + i] != UNAVAILABLE &&
               curCell + 1 + i + meetingTime-1 <= LASTROW && timeCells[meetingType][day][curCell + 1 + i + meetingTime-1] == CLICKED) {
                // this is a valid slot, make sure it wasn't previously valid
                var foundNewSlot = false;
                for (var j = 0; j < meetingTime; j++) {
                    if (timeCells[meetingType][day][curCell + 1 + i + j] == AVAILABLE)
                        foundNewSlot = true;
                }
                if (foundNewSlot) {
                    removeTimeSlot(day, curCell + 1 + i);
                }
                i++;
            }
            
            return;
        }
    }
    // Add this time slot    
    // make sure there are enough consecutive available cells
    var enoughTime = true;
    for (var i = 0; i < meetingTime; i++) {
        if (curCell + i > LASTROW || timeCells[meetingType][day][curCell + i] == UNAVAILABLE) {
            enoughTime = false;
        }
    }
    if (enoughTime) {
        
        // add new timeslot to array of all timeSlots.
        addTimeSlot(day, curCell);
        
        // Also need to add all new time slots which may now exist because
        // of adjacent blocks coming together.
        var i = 0;

        // add all meetings going backwards
        // not sure why the unaivalable check is here...
        while (i < meetingTime - 1 && curCell - 1 - i >= 0 && timeCells[meetingType][day][curCell - 1 - i] == CLICKED &&
               timeCells[meetingType][day][curCell - 1 - i + meetingTime] != UNAVAILABLE) {
               // this is a valid slot, make sure it wasn't previously valid
               var foundNewSlot = false;
               for (var j = 0; j < meetingTime; j++) {
                   if (timeCells[meetingType][day][curCell - 1 - i + j] == AVAILABLE)
                    foundNewSlot = true;
            }
            if (foundNewSlot) {
                addTimeSlot(day, curCell - 1 - i);
            }
            i++;
        }
               
        // add all meetings going forward
        i = 0;
        while (i < meetingTime - 1 && timeCells[meetingType][day][curCell + 1 + i] != UNAVAILABLE &&
               curCell + 1 + i + meetingTime-1 <= LASTROW && timeCells[meetingType][day][curCell + 1 + i + meetingTime-1] == CLICKED) {
               // this is a valid slot, make sure it wasn't previously valid
               var foundNewSlot=false;
               for (var j=0;j < meetingTime; j++){
                   if (timeCells[meetingType][day][curCell + 1 + i + j] == AVAILABLE)
                        foundNewSlot=true;
               }
               if (foundNewSlot) {
                   addTimeSlot(day, curCell + 1 + i);
               }
               i++;
        }

        // select all cells for the meeting
        for (var i = 0; i < meetingTime; i++) {
            timeCells[meetingType][day][curCell + i] = CLICKED;
            var id_str = String(day) + '-' + String(curCell + i) + (meetingType ? '' : '-D');
            document.getElementById(id_str).style.background = TIME_SLOT_CLICKED;
        }
    }
}

// This function handles what happens when the mouse moves over a time slot cell.
// If the cell can be clicked the function returns 1, otherwise 0.
function onMouseOverTimeCell(day, curCell) {
    // if the cell we just moved over is unavailable, then abort
    if (timeCells[meetingType][day][curCell] == UNAVAILABLE)
        return 0;

    var id_str;
    
    // loop through the number of cells in meetingTime
    for (var i = 0; i < meetingTime; i++) {

        // get id of this cell
        id_str = String(day) + '-' + String(curCell + i) + (meetingType ? '' : '-D');
        
        // make sure we aren't trying to mess with a cell that doesn't exist.
        if (curCell + i > LASTROW)
            break;

        // first check if this cell was clicked or unclicked
        var previousState = timeCells[meetingType][day][curCell + i];
        
        // check if the cell is unavailable, if so then we don't need to go any further.
        if (previousState == UNAVAILABLE)
            break;

        // check if the time cell was previously clicked
        if (previousState == AVAILABLE) {
            // wasn't previously clicked
            document.getElementById(id_str).style.background = TIME_SLOT_OVER;
        }
    }

    //change the cursor only if clicking on this cell actually does anything
    id_str = String(day) + '-' + String(curCell) + (meetingType ? '' : '-D');
    if (i == meetingTime) {
        document.getElementById(id_str).style.cursor = 'pointer';
        return 1;
    }
    return 0;
}

// This function handles what happens when the mouse moves out of a time slot cell
function onMouseOutTimeCell(day, curCell) {
    // if the cell we just moved off of is unavailable, then abort
    if (timeCells[meetingType][day][curCell] == UNAVAILABLE)
        return;

    for (var i = 0; i < meetingTime; i++) {
        // first check if this cell was clicked or unclicked and
        // store this in a var
        var previousState = timeCells[meetingType][day][curCell + i];

        // make sure we aren't trying to mess with a cell that doesn't exist.
        if (curCell + i > LASTROW)
            break;

        // check if the cell is unavailable, if so then we don't need to go any further.
        if (timeCells[meetingType][day][curCell + i] == UNAVAILABLE)
            break;

        // check if the time cell was previously selected
        var id_str = String(day) + '-' + String(curCell + i) + (meetingType ? '' : '-D');
        if (previousState == CLICKED)
                document.getElementById(id_str).style.background = TIME_SLOT_CLICKED;
        else {
            // check if sunday or saturday
            if (day == SUNDAY || day == SATURDAY || day == SUNDAY_WEEK2 || day == SATURDAY_WEEK2) {
                document.getElementById(id_str).style.background = WEEKEND_AVAILABLE;
            }
            else {
                document.getElementById(id_str).style.background = 'white';
            }
        }
    }
}

// this function handles what happens when the mouse is position over the weekday heading
// we want to highlight the day's time slots from 9 - 5
function onMouseOverWeekday(day) {
    // make sure there is at least one time slot available in the range we're considering
    // for the day
    var atLeastOneAvailable = false;

    for (var row = START_WORKDAY; row < END_WORKDAY; row++) {
        // check if there is at least on cell available so we know if we should highlight the
        // day of the week heading for this column.
        if (timeCells[meetingType][day][row] != UNAVAILABLE)
            atLeastOneAvailable = true;

        if (timeCells[meetingType][day][row] == AVAILABLE)
            if (meetingType==RECURRING)
                document.getElementById(String(day) + '-' + String(row)).style.background = TIME_SLOT_OVER;
            else
                document.getElementById(String(day) + '-' + String(row) + '-D').style.background = TIME_SLOT_OVER;
    }
    if (atLeastOneAvailable) {
        if (meetingType == RECURRING) {
            //change the cursor and background while we're hover over the weekday
            document.getElementById('weekday-' + String(day)).style.background = TIME_ROW_OVER;
            document.getElementById('weekday-' + String(day)).style.cursor = 'pointer';
        }
        else {
            //change the cursor and background while we're hover over the weekday
            document.getElementById('weekday-' + String(day) + '-D').style.background = TIME_ROW_OVER;
            document.getElementById('weekday-' + String(day) + '-D').style.cursor = 'pointer';
        }
    }

}
// this function handles what happens when we move the mouse out of the weekday heading
function onMouseOutWeekday(day) {
    var id_str = 'weekday-' + String(day) + (meetingType ? '' : '-D');
    document.getElementById(id_str).style.background = WEEKDAY_NORMAL;
    document.getElementById(id_str).style.background = WEEKDAY_NORMAL;
    
    for (var row = START_WORKDAY; row < END_WORKDAY; row++) {
        var id_str = String(day) + '-' + String(row) + (meetingType ? '' : '-D');
        if (timeCells[meetingType][day][row] == CLICKED)
            document.getElementById(id_str).style.background = TIME_SLOT_CLICKED;
        else if (timeCells[meetingType][day][row] == AVAILABLE) {
            if (day == SUNDAY || day == SATURDAY || day == SUNDAY_WEEK2 || day == SATURDAY_WEEK2)
                document.getElementById(id_str).style.background = WEEKEND_AVAILABLE;
            else
                document.getElementById(id_str).style.background = 'white';
        }
    }
}
// this function handles what happens when we click a week day heading
function clickWeekday(day) {
    // first check if any of the cells from 9-5 are unclicked, if they are, 
    // then we're going to select (click) them all.
    var anyUnclicked = false;

    for (var row = START_WORKDAY; row < END_WORKDAY; row++) {
        if (timeCells[meetingType][day][row] == AVAILABLE) {
            anyUnclicked = true;
            break;
        }
    }

    // now either click or unclick them all
    if (anyUnclicked) {
        for (var row = START_WORKDAY; row < END_WORKDAY - meetingTime+1; row++) {
            if (timeCells[meetingType][day][row] != UNAVAILABLE)
            {
                var clickThisOne=false;
                // only click it if it will add new time slots
                for (var j=0; j < meetingTime; j++)
                {
                    if (timeCells[meetingType][day][row+j]==AVAILABLE) {
                        clickThisOne=true;
                        break;
                    }
                }
                if (clickThisOne)
                    clickTimeCell(day, row, 0);    
            }
        }
    }
    else {
        for (var row = START_WORKDAY; row < END_WORKDAY - meetingTime+1; row++) {
            if (timeCells[meetingType][day][row] == CLICKED)
                clickTimeCell(day, row, 0);
        }
    }
}
// This function handles what happens when the user clicks a time Row i.e the actual 
// time eg. 8:00 am, which indicates the user wants to select the entire row.
function clickTimeRow(row, week) {
    // figure out if there are any available cells
    var anyAvailable = false;
    var startDay = (week ? 7 : 0);  // handles week 0 or week 1
    var endDay = (week ? 14 : 7);
    var day = startDay;
    while (!anyAvailable && day < endDay) {
        if (timeCells[meetingType][day][row] == AVAILABLE) {
            // assume available for now
            anyAvailable = true;
            for (var j = 1; j < meetingTime; j++) {
                if (row + j > LASTROW) {
                    anyAvailable = false;
                    break;
                }
                if (timeCells[meetingType][day][row + j] == UNAVAILABLE) {
                    anyAvailable = false;
                    break;
                }
            }
        }
        day++;
    }
    if (anyAvailable) {
        for (day = startDay; day < endDay; day++) {
            // only click this cell if it will add a new timeslot
            var clickThisOne = false;
            for (var j = 0; j < meetingTime; j++) {
                if (timeCells[meetingType][day][row + j] == AVAILABLE) {
                    clickThisOne = true;
                    break;
                }
            }
            if (clickThisOne)
                clickTimeCell(day, row, 0);
        }
    }
    else {
        // unselect the cells across the whole row
        for (day = startDay; day < endDay; day++) {
            clickTimeCell(day, row, 0);
        }
    }
}

// This function handles what happens when the user moves the mouse over a the time
// on the side of the table, indicating that he/she might select the entire row
function onMouseOverTimeRow(row, week) {
// XXX TODO if nothing is available don't highlight the row
    if (week == null) week = 0;
    // change the background of the times that we're hovering over
    var id_str;
    
    for (var i = 0; i < meetingTime; i++) {
        // make sure we aren't trying to mess with a row that doesn't exist.
        if (row + i > LASTROW)
            break;
        id_str = 'Row-' + String(row + i) + (meetingType ? '' : (week ? 'B-D' : 'A-D'));
        document.getElementById(id_str).style.background = TIME_ROW_OVER;
    }

    // loop through all the cells in the row and call the mouse over function
    // for each one, if something can be clicked, this returns true.
    var canBeClicked = 0;
    var startDay = (week ? 7 : 0);
    var endDay = (week ? 14 : 7);
    for (var day = startDay; day < endDay; day++) {
        canBeClicked += onMouseOverTimeCell(day, row);
    }
    // change cursor if something can be clicked
    if (canBeClicked) {
        id_str = 'Row-' + String(row) + (meetingType ? '' : (week ? 'B-D' : 'A-D'));
        document.getElementById(id_str).style.cursor = 'pointer';
    }
}

// This function handles what happens when the user moves the mouse out of a time
// on the side of the table.
function onMouseOutTimeRow(row, week) {
   // change the background of the times that we're hovering over
    for (var i = 0; i < meetingTime; i++) {
        // make sure we aren't trying to mess with a row that doesn't exist.
        if (row + i > LASTROW)
            break;
        var id_str = 'Row-' + String(row + i) + (meetingType ? '' : (week ? 'B-D' : 'A-D'));
        document.getElementById(id_str).style.background = TIME_ROW_NORMAL;
    }
    // loop through all the cells in the row and call the click function 
    // for each one
    var startDay = (week ? 7 : 0);
    var endDay = (week ? 14 : 7);
    for (var day = startDay; day < endDay; day++) {
        onMouseOutTimeCell(day, row)
    }

}

function changeMeetingType(recurring) {
    if (recurring == 1) {
        document.getElementById("recurringDiv").style.visibility = "visible";
        document.getElementById("onetimeDiv").style.visibility = "hidden";
        document.getElementById("calendarCenter").style.width = "515px";
        meetingType = RECURRING;
    }
    else {
        document.getElementById("recurringDiv").style.visibility = "hidden";
        document.getElementById("onetimeDiv").style.visibility = "visible";
        document.getElementById("calendarCenter").style.width = "635px";
        meetingType = BY_DATES;
    }
    if (USE_CASE==SCHEDULE)
        document.getElementById(hiddenMeetingTypeID).value = meetingType;
}
