//--********************************************************************-->
//--                                                                    -->
//--   Frontier Software Pty Ltd                                        -->
//--                                                                    -->
//--   File Name     : ftrcalen.js                                      -->
//--                                                                    -->
//--   History       :                                                  -->
//--   005876 - 02.07.00 - JavaScript Rewrite.                          -->
//--   008552 - 24.04.03 - Fix Previous Week button.                    -->
//--   008551 - 30.04.03 - SEARCH FOR DATE ON CALENDARS                 -->
//--   009349 - 28.01.04 - HR21: POP-UP CALENDAR REVAMPED               -->
//--   009347 - 19.12.03 - Expand Planner to show full month            -->
//--   009735 - 31.05.04 - Fix error in Planner on last day of month    -->
//--   009618 - 28.07.04 - Swap Heading Colours                         -->
//--   009983 - 05.08.04 - Set planner search date                      -->
//--   010104 - 10.09.04 - Calendar re-write                            -->
//--   010217 - 30.10.04 - Comments added                               -->
//--   010209 - 17.11.04 - Show work times in ecempcal                  -->
//--   010210 - 06.12.04 - Show time requests in melvepln               -->
//--   010063 - 17.12.04 - Opera (10062) & Mozilla (10063) supported    -->
//--   009584 - 07.12.04 - Show work hours in ecempcal and melvepln.    -->
//--   007775 - 06.12.04 - Search by Pay Period                         -->
//--   009745 - 07.04.05 - Allow default leave icon                     -->
//--   010765 - 12.05.05 - Date validation removed                      -->
//--   010119 - 30.06.05 - Lookup image conforms to C21                 -->
//--   011019 - 09.08.05 - Check sDesc before setting to avoid undefined-->
//--   011046 - 15.08.05 - Correct the date handling and the open window-->
//--                       id value                                     -->
//--   010889 - 16.08.05 - Training Request Form changes                -->
//--   010842 - 21.09.05 - Date search fields corrected                 -->
//--   011275 - 09.11.05 - Tidy up Date formats                         -->
//--   011560 - 22.02.06 - All dates in CCYY-MM-DD format               -->
//--   011899 - 17.05.06 - Notes Corrected for multiple codes           -->
//--   013738 - 06.03.07 - Use the ISO date format for all processing   -->
//--   013901 - 10.05.07 - loadPageCurrent function created             -->
//--   013985 - 07.06.07 - Planner mouse over and out corrected         -->
//--   014434 - 23.10.07 - Layout & Colour Enhancements                 -->
//--   014827 - 03.08.08 - Planner Dates Corrected                      -->
//--********************************************************************-->

var dCalDate = new Date();

var oCalDateField;

var dCalDateFormat = "dd/mm/yyyy";
if (sZone == "USA") dCalDateFormat = "mm/dd/yyyy";

var calDay;
var calDocBottom = new Object();
var aWeekEnd = new Array(); // loads weekend days

// GENERATE WEEKDAY headERS FOR THE CALENDAR
var aWeekDay = new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
var weekdays = calenCreateWeekDayList();

// 9347 - Generate Month Array for the Calendar and Pop-Up windows
var monthArray = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

// BUILD THE BLANK CELL ROWS
var blankCell = "<td align='center'></td>";

// *********************************************************************
// SET THE INITIAL value OF THE GLOBAL DATE FIELD
function calenSetDateField(dField) {
    // ASSIGN THE INCOMING FIELD OBJECT TO A GLOBAL VARIABLE
    oCalDateField = dField;
    // GET THE value OF THE INCOMING FIELD
    var dInput = (dField.value) ? dField.value : sToday;
    // SET dCalDate TO THE DATE IN THE INCOMING FIELD OR DEFAULT TO TODAY'S DATE
    calenSetInitialDate(dInput);
    return;
}

// *********************************************************************
// SET THE INITIAL CALENDAR DATE TO TODAY OR TO THE EXISTING value IN dateField
function calenSetInitialDate(dInput) {
    // Create new date
    switch (sZone) {
        case "USA":
            dCalDate = new Date(dInput);
            break;
        default:
            dCalDate = new Date(validDMYtoMDY(dInput));
            break;
    }
    // IF THE INCOMING DATE IS INVALID, USE THE CURRENT DATE
    if (isNaN(dCalDate)) {
        // ADD CUSTOM DATE PARSING HERE
        // IF IT FAILS, SIMPLY CREATE A NEW DATE OBJECT WHICH DEFAULTS TO THE CURRENT DATE
        dCalDate = new Date();
    }
    // KEEP trACK OF THE CURRENT DAY value
    calDay = dCalDate.getDate();
    // SET DAY value TO 1... TO AVOID JAVASCRIPT DATE CALCULATION ANOMALIES
    // (IF THE MONTH CHANGES TO FEB AND THE DAY IS 30, THE MONTH WOULD CHANGE TO MARCH
    //  AND THE DAY WOULD CHANGE TO 2.  SETTING THE DAY TO 1 WILL PREVENT THAT)
    dCalDate.setDate(1);
    return;
}

// *********************************************************************
// CREATE THE TOP CALENDAR FRAME
// 009349 - POP-UP CALENDAR REVAMPED
// 010063 - NOWRAP SET FOR MOZILLA
// 010119 - RE-ARRANGED FOR HTML BUTTONS
function calenBuildTop() {
    // CREATE THE TOP FRAME OF THE CALENDAR
    var sHtml = "";
    sHtml += "<table cellspacing='0' border='0' width='100%' bgcolor='" + hVertBG + "'>";
    sHtml += "<tr>";
    // 009349 - ADD THE 'PREVIOUS MONTH' NAVIGATION BUTTONS
    if (aDictDetail["sedrivew"]["prevmonth"]) {
        sHtml += "<td align='right' nowrap style='padding-left:1px;padding-right:3px;'><a href='javascript:void(0);'><img class='calImg' src='images/button/prev.png' alt='Previous Month' title='" + aDictDetail["sedrivew"]["prevmonth"].tooltip + "' onClick='oGlob.calenSetPreviousMonth();'></a></td>";
    }
    // 009349 - ADD THE DATE SELECT
    sHtml += "<td align='center' nowrap style='padding-top:7px;padding-bottom:7px;'>";
    sHtml += calenGetMonthSelect();
    sHtml += "<img src='" + loadPageResource("menu") + "pixel.png' width='5' height='1' alt=''>";
    sHtml += "<input name='year' value='" + dCalDate.getFullYear() + "' title='Type a year and click GO' type='text' size='4' class='calTop' maxlength='4' tabindex='-1' onChange='oGlob.calenSetCurrentYear(); return true;' onKeyPress='var charCode = (oGlob.is.moz) ? event.which : event.keyCode; if (charCode == 13) {oGlob.calenSetCurrentYear();return true;} '></td>";
    sHtml += "<td align='center'>";
    if (!bButtonHtml) sHtml += "<a href='javascript:void(0);' onMouseOver='locnImageSwap(\"dn\", \"gobl\", \"Search on a different year\"); return true;' onMouseOut='locnImageSwap(\"up\", \"gobl\", \"\"); return true;' ";
    else sHtml += "<input type='button' value='' tabindex='-1' class='goButton' title='Search on a different year' style='background:url(images/button/go_up.png);background-color:#D4D0C8;background-position:center;background-repeat:no-repeat;margin:0;' ";
    sHtml += " onClick='oGlob.calenSetCurrentYear(); return true;'>"
    if (!bButtonHtml) sHtml += "<img align='center' name='gobl' alt='Go' border='0' src='images/button/gobl_up.png' tabindex='-1'></a>";
    sHtml += "</td>";
    // 009349 - ADD THE 'NEXT MONTH' NAVIGATION BUTTON
    if (aDictDetail["sedrivew"]["nextmonth"]) {
        sHtml += "<td align='left' nowrap style='padding-left:3px;padding-right:2px'><a href='javascript:void(0);'><img class='calImg' src='images/button/next.png'  alt='Next Month' title='" + aDictDetail["sedrivew"]["nextmonth"].tooltip + "' onClick='oGlob.calenSetNextMonth();' tabindex='-1'></a></td>";
    }
    sHtml += "</tr>";
    // 009349 - ADD A COLOURED RULE
    sHtml += "<tr bgcolor=" + ((bHorizMenu) ? hHorizActive : hVertActive) + "><td height='3' colspan='10'></td></tr>";
    // 009349 - FINISH THE TABLE AND THE FRAME
    sHtml += "</table>";
    return sHtml;
}

// *********************************************************************
// CREATE THE BOTTOM CALENDAR FRAME
// (THE MONTHLY CALENDAR)
// 009349 - POP-UP CALENDAR REVAMPED 
// 010119 - RE-ARRANGED FOR HTML BUTTONS
function calenBuildBottom(bFirstRun) {       
    // START CALENDAR DOCUMENT by BUILDing WEEKDAY HEADINGS
    var calDoc = "<div id='calDiv'><center>" +
        "<table width='100%' cellpadding='0' cellspacing='1' border='0' bgcolor='" + hAlternate + "'>" +
        weekdays +
        "<tr>";
    // GET MONTH, AND YEAR FROM GLOBAL CALENDAR DATE
    month   = dCalDate.getMonth();
    year    = dCalDate.getFullYear();
    // GET GLOBALLY-trACKED DAY value (PREVENTS JAVASCRIPT DATE ANOMALIES)
    day     = calDay;
    var i   = 0;
    // DETERMINE THE NUMBER OF DAYS IN THE CURRENT MONTH
    var days = calenGetDaysInMonth();
    // IF GLOBAL DAY value IS > THAN DAYS IN MONTH, HIGHLIGHT LAST DAY IN MONTH
    if (day > days) {
        day = days;
    }
    // DETERMINE WHAT DAY OF THE WEEK THE CALENDAR STARTS ON
    var firstOfMonth = new Date (year, month, 1);
    // GET THE DAY OF THE WEEK THE FIRST DAY OF THE MONTH FALLS ON
    var startingPos  = firstOfMonth.getDay();
    days += startingPos;
    // KEEP trACK OF THE COLUMNS, START A NEW ROW AFTER EVERY 7 COLUMNS
    var iColumn = 0;
    // MAKE BEGINNING NON-DATE CELLS BLANK
    for (i = 0; i < startingPos; i++) {
        calDoc += blankCell;
        iColumn++;
    }
    // SET valueS FOR DAYS OF THE MONTH
    var iCurrDate = 0;
    var sDayType    = "weekday";
    // DATE CELLS CONTAIN A NUMBER
    for (i = startingPos; i < days; i++) {
        var paddingChar = "&nbsp;";
        // ADJUST SPACING SO THAT ALL LINKS HAVE RELATIVELY EQUAL WIDTHS
        if (i-startingPos+1 < 10) {
            padding = "&nbsp;&nbsp;";
        } else {
            padding = "&nbsp;";
        }
        // GET THE DAY CURRENTLY BEING WRITTEN
        iCurrDate = i-startingPos+1;
        // SET THE type OF DAY, THE focusDay GENERALLY APPEARS AS A DIFFERENT COLOR
        if (iCurrDate == day) {
            sDayType = "focusDay";
        } else if ((iColumn % 7 == 0) || (iColumn % 7 == 6)) {
            sDayType = "weekend";
        } else {
            sDayType = "weekDay";
        }
        // ADD THE DAY TO THE CALENDAR StrING
        calDoc += "<td align=center><a class='" + sDayType + "' href='javascript:oGlob.calenReturnDate(" + iCurrDate + ")'>" + padding + iCurrDate + paddingChar + "</a></td>";
        iColumn++;
        // START A NEW ROW WHEN NECESSARY
        if (iColumn % 7 == 0) {
            calDoc += "</tr><tr>";
        }
    }
    // MAKE REMAINING NON-DATE CELLS BLANK
    for (i=days; i<42; i++)  {
        calDoc += blankCell;
        iColumn++;
        // START A NEW ROW WHEN NECESSARY
        if (iColumn % 7 == 0) {
            calDoc += "</tr>";
            if (i<41) {
                calDoc += "<tr>";
            }
        }
    }
    calDoc += "</table><table cellpadding='2' cellspacing='0' border='0' width='100%' bgcolor='" + hAlternate + "'>";
    calDoc += "<tr><td colspan='10' height='2' style='padding:0'; class='horizRule'><img src='" + loadPageResource("menu", true) + "pixel.png' width='1' height='1' border='0' alt=''></td></tr><tr><td height='2'></td></tr>";
    // ADD 'TODAY' AND 'CLOSE' BUTTONS IF REQUIRED
    calDoc += "<tr>";
    if (aDictDetail["sedrivew"]["today"]) {
        calDoc += "<td align='left'>";
        if (!bButtonHtml) calDoc += "<a href='javascript:void(0);'><img name='tick' src='images/button/tick_up.png' class='calImg' alt='Today' onMouseOver='locnImageSwap(\"dn\", \"tick\", \"Today\"); return true;' onMouseOut='locnImageSwap(\"up\", \"tick\", \"\"); return true;' tabindex='-1' style='margin-left:2px;' ";
        else calDoc += "<input type='button' value='' tabindex='-1' class='goButton' title='Search for today' style='background:url(images/button/tick_dn.png);background-color:#D4D0C8;background-position:center;background-repeat:no-repeat;margin:1px;' ";
        calDoc += " title='" + aDictDetail["sedrivew"]["today"].tooltip + "' onClick='oGlob.calenSetToday();' ";
        if (!bButtonHtml) calDoc += "></a>";
        else calDoc += ">";
        calDoc += "</td><td class='heading' colspan='" + (aDictDetail["sedrivew"]["close"] ? 4 : 5) + "'><a href='javascript:oGlob.calenSetToday();' class='calImg'>Today:&nbsp;" + sToday + "</a></td>";
    }
    if (aDictDetail["sedrivew"]["back"]) {
        calDoc += "<td align='right' colspan='2'><input style='height:18px;font:9px;margin:3px;cursor:pointer;cursor:hand;' type='button' onClick='oGlob.oCalWin.close(); return true;' value='" + aDictDetail["sedrivew"]["back"].labeltext + "' title='" + aDictDetail["sedrivew"]["back"].tooltip + "'></td>";   
    }
    calDoc += "</tr>";
    // 10217 - ADD PAGE COMMENTS IF REQUIRED
    if (aDictDetail["sedrivew"]["i_comment"]) {
        calDoc += "<tr><td class='heading' style='padding:5;' colspan='8'>" + aDictDetail["sedrivew"]["i_comment"].comment + "</td></tr>";
    }
    calDoc += "</table></div>";
    // RETURN THE COMPLETED CALENDAR PAGE
    return calDoc;
}

// *********************************************************************
// 009349 - POP-UP CALENDAR REVAMPED
function calenCheckKey(eKeyPress) {
    var charCode = (is.moz) ? eKeyPress.which : eKeyPress.keyCode;
    // '13' is the ASCII code for the 'Enter' button
    if (charCode == 13) calenSetCurrentYear();
    return;
}

// *********************************************************************
// WRITE THE MONTHLY CALENDAR TO THE BOTTOM CALENDAR FRAME
function calenWrite() {
    // CREATE THE NEW CALENDAR FOR THE SELECTED MONTH & YEAR
    calDocBottom = calenBuildBottom(true);
    // WRITE THE NEW CALENDAR TO THE BOTTOM FRAME
    oCalWin.document.getElementById("calDiv").innerHTML = calDocBottom;
    return;
}

// *********************************************************************
// SET THE CALENDAR TO TODAY'S DATE AND DISPLAY THE NEW CALENDAR
function calenSetToday() {
    // SET GLOBAL DATE TO TODAY'S DATE
    dCalDate = new Date();
    // SET DAY MONTH AND YEAR TO TODAY'S DATE
    var day = dCalDate.getDate();
    var month = dCalDate.getMonth();
    var year  = dCalDate.getFullYear();
    // SET MONTH IN DROP-DOWN LIST
    oCalWin.document.calControl.month.selectedIndex = month;
    // SET YEAR value
    oCalWin.document.calControl.year.value = year;
    // Return the date
    calenReturnDate(day);
    return;
}

// *********************************************************************
// SET THE GLOBAL DATE TO THE NEWLY ENTERED YEAR AND REDRAW THE CALENDAR
function calenSetCurrentYear() {
    // GET THE NEW YEAR value
    var year = oCalWin.document.calControl.year.value;
    var month = oCalWin.document.calControl.month.selectedIndex;
    // IF IT'S A FOUR-DIGIT YEAR THEN CHANGE THE CALENDAR
    if (calenIsFourDigitYear(year)) {
        dCalDate.setMonth(month);
        dCalDate.setFullYear(year);
        calenWrite();
    } else {
        // HIGHLIGHT THE YEAR IF THE YEAR IS NOT FOUR DIGITS IN LENGTH
        oCalWin.document.calControl.year.focus();
        oCalWin.document.calControl.year.select();
    }
    return;
}

// *********************************************************************
// SET THE GLOBAL DATE TO THE SELECTED MONTH AND REDRAW THE CALENDAR
function calenSetCurrentMonth() {
    // GET THE NEWLY SELECTED MONTH AND CHANGE THE CALENDAR ACCORDINGLY
    var month = oCalWin.document.calControl.month.selectedIndex;
    dCalDate.setMonth(month);
    calenWrite();
    return;
}

// *********************************************************************
// SET THE GLOBAL DATE TO THE PREVIOUS YEAR AND REDRAW THE CALENDAR
function calenSetPreviousYear() {
    var year = oCalWin.document.calControl.year.value;
    if (calenIsFourDigitYear(year) && year > 1000) {
        year--;
        dCalDate.setFullYear(year);
        oCalWin.document.calControl.year.value = year;
        calenWrite();
    }
    return;
}

// *********************************************************************
// SET THE GLOBAL DATE TO THE PREVIOUS MONTH AND REDRAW THE CALENDAR
function calenSetPreviousMonth() {
    var year = oCalWin.document.calControl.year.value;
    if (calenIsFourDigitYear(year)) {
        var month = oCalWin.document.calControl.month.selectedIndex;
        // IF MONTH IS JANUARY, SET MONTH TO DECEMBER AND DECREMENT THE YEAR
        if (month == 0) {
            month = 11;
            if (year > 1000) {
                year--;
                dCalDate.setFullYear(year);
                oCalWin.document.calControl.year.value = year;
            }
        } else {
            month--;
        }
        dCalDate.setMonth(month);
        oCalWin.document.calControl.month.selectedIndex = month;
        calenWrite();
    }
    return;
}

// *********************************************************************
// SET THE GLOBAL DATE TO THE NEXT MONTH AND REDRAW THE CALENDAR
function calenSetNextMonth() {
    var year = oCalWin.document.calControl.year.value;
    if (calenIsFourDigitYear(year)) {
        var month = oCalWin.document.calControl.month.selectedIndex;
        // IF MONTH IS DECEMBER, SET MONTH TO JANUARY AND INCREMENT THE YEAR
        if (month == 11) {
            month = 0;
            year++;
            dCalDate.setFullYear(year);
            oCalWin.document.calControl.year.value = year;
        } else {
            month++;
        }
        dCalDate.setMonth(month);
        oCalWin.document.calControl.month.selectedIndex = month;
        calenWrite();
    }
    return;
}

// *********************************************************************
// SET THE GLOBAL DATE TO THE NEXT YEAR AND REDRAW THE CALENDAR
function calenSetNextYear() {
    var year = oCalWin.document.calControl.year.value;
    if (calenIsFourDigitYear(year)) {
        year++;
        dCalDate.setFullYear(year);
        oCalWin.document.calControl.year.value = year;
        calenWrite();
    }
    return;
}

// *********************************************************************
// 11560 - All dates in CCYY-MM-DD format
// GET NUMBER OF DAYS IN MONTH
function calenGetDaysInMonth(dInput)  {
    if (!dInput) dInput = dCalDate;
    var days;
    var month = dInput.getMonth()+1;
    var year  = dInput.getFullYear();
    // RETURN 31 DAYS
    if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)  {
        days=31;
    }
    // RETURN 30 DAYS
    else if (month==4 || month==6 || month==9 || month==11) {
        days=30;
    }
    // RETURN 29 DAYS
    else if (month==2)  {
        if (calenIsLeapYear(year)) {
            days=29;
        }
        // RETURN 28 DAYS
        else {
            days=28;
        }
    }
    return (days);
}

// *********************************************************************
// CHECK TO SEE IF YEAR IS A LEAP YEAR
function calenIsLeapYear (Year) {
    if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) {
        return true;
    } else {
        return false;
    }
}

// *********************************************************************
// ENSURE THAT THE YEAR IS FOUR DIGITS IN LENGTH
function calenIsFourDigitYear(year) {
    if (year.length != 4) {
        oCalWin.document.calControl.year.value = dCalDate.getFullYear();
        oCalWin.document.calControl.year.select();
        oCalWin.document.calControl.year.focus();
    } else {
        return true;
    }
}

// *********************************************************************
function calenCreateDay(dInput, iDay) {
    var sHtml = "";
    if ((oDataPage.oSearch) && (oDataPage.oSearch["i_date"])) {
        var activeDay = (iDay) ? iDay : dInput.getDate();
        sHtml += "<select name='i_day' class='Search' style='background-color:" + hSearch + ";'>";
        // Loop through the possible dates
        for (var iIndex=1;iIndex<=31;iIndex++) {
            if (iIndex == activeDay) {
                sHtml += "<option selected>" + iIndex.toString() + "</option>";
            } else {
                sHtml += "<option>" + iIndex.toString() + "</option>";
            }
        }
        sHtml += "</select>";
    }
    return sHtml;
}

// *********************************************************************
function calenCreateMonth(dInput, iMonth) {
    var sHtml = "";
    var activeMonth = (iMonth) ? iMonth : dCalDate.getMonth();
    if (((oDataPage.oSearch) && (oDataPage.oSearch["i_date"])) || ((oDataPage.oDict) && (oDataPage.oDict["i_month"]))) {
        sHtml += "<select name='i_month' class='Search' style='background-color:" + hSearch + ";'>";
    } else {
        sHtml += "<select name='month' class='calTop' onChange='oGlob.calenSetCurrentMonth();'>";
    }
    // Loop through the Month Array
    for (var iIndex in monthArray) {
        // show the correct month in the select object
        if (iIndex == activeMonth) {
            sHtml += "<option selected>" + monthArray[iIndex] + "</option>";
        } else {
            sHtml += "<option>" + monthArray[iIndex] + "</option>";
        }
    }
    sHtml += "</select>";
    return sHtml;
}

// *********************************************************************
// BUILD THE MONTH SELECT LIST
// 009349 - POP-UP CALENDAR REVAMPED
// 009347 - Day added to date search
function calenGetMonthSelect(iMonth, iDay) {
    // 9347: Default to current date
    if (!dCalDate) dCalDate = new Date();
    // Start Html select object
    var sHtml = "";
    switch (sZone) {
        case "USA":
            sHtml += calenCreateMonth(dCalDate, iMonth);
            sHtml += calenCreateDay(dCalDate, iDay);
            break;
        default:
            sHtml += calenCreateDay(dCalDate, iDay);
            sHtml += calenCreateMonth(dCalDate, iMonth);
            break;
    }
    return sHtml;
}

// *********************************************************************
// SET DAYS OF THE WEEK DEPENDING ON LANGUAGE
// 009349 - POP-UP CALENDAR REVAMPED
function calenCreateWeekDayList() {
    // START Html TO HOLD WEEKDAY nameS IN table formAT
    var sHtml = "<tr>";
    // LOOP THROUGH WEEKDAY ARRAY
    for (var i in aWeekDay) {
        sHtml += "<td class='Headings' align=center>" + aWeekDay[i] + "</td>";
    }
    sHtml += "</tr><tr><td colspan='10' height='2' class='horizRule'><img src='" + loadPageResource("menu", true) + "pixel.png' width='1' height='1' border='0' alt=''></td></tr>";
    // RETURN table ROW OF WEEKDAY ABBREVIATIONS TO DISPLAY ABOVE THE CALENDAR
    return sHtml;
}

// *********************************************************************
// REPLACE ALL INSTANCES OF find WITH replace
// inString: the string you want to convert
// find:     the value to search for
// replace:  the value to substitute
//
// usage:    calenReplace(inString, find, replace);
// example:  calenReplace("To be or not to be", "be", "ski");
//           result: "To ski or not to ski"
//
function calenReplace(inString, find, replace) {
    var outString = "";
    if (!inString) {
        return "";
    }
    // REPLACE ALL INSTANCES OF find WITH replace
    if (inString.indexOf(find) != -1) {
        // SEPARATE THE StrING INTO AN ARRAY OF StrINGS USING THE value IN find
        t = inString.split(find);
        // JOIN ALL ELEMENTS OF THE ARRAY, SEPARATED BY THE value IN replace
        return (t.join(replace));
    } else {
        return inString;
    }
}

// *********************************************************************
// ENSURE THAT value IS TWO DIGITS IN LENGTH
function calenMakeTwoDigit(inValue) {
    var numVal = parseInt(inValue,10);
    // value IS LESS THAN TWO DIGITS IN LENGTH
    if (numVal < 10) {
        // ADD A LEADING ZERO TO THE value AND RETURN IT
        return("0" + numVal);
    } else {
        return numVal;
    }
}

// *********************************************************************
// SET FIELD value TO THE DATE SELECTED AND CLOSE THE CALENDAR WINDOW
function calenReturnDate(inDay) {
    // inDay = THE DAY THE USER CLICKED ON
    dCalDate.setDate(inDay);
    // SET THE DATE RETURNED TO THE USER
    var day           = dCalDate.getDate();
    var month         = dCalDate.getMonth()+1;
    var year          = dCalDate.getFullYear();
    outDate = dCalDateFormat;
    // RETURN TWO DIGIT DAY
    if (dCalDateFormat.indexOf("dd") != -1) {
        day = calenMakeTwoDigit(day);
        outDate = calenReplace(outDate, "dd", day);
    }
    // RETURN TWO DIGIT MONTH
    if (dCalDateFormat.indexOf("mm") != -1) {
        month = calenMakeTwoDigit(month);
        outDate = calenReplace(outDate, "mm", month);
    }
    // RETURN FOUR-DIGIT YEAR
    if (dCalDateFormat.indexOf("yyyy") != -1) {
        outDate = calenReplace(outDate, "yyyy", year);
    }
    // SET THE value OF THE FIELD THAT WAS PASSED TO THE CALENDAR
    oCalDateField.value = outDate;
    // GIVE FOCUS BACK TO THE DATE FIELD
    oCalDateField.focus();
    // 010064 - FORM FIELD HAS BEEN MODIFIED
    if ((bModifyAlert) && (oDataPage.document.getElementById("updat"))) {
        bModified = true;
    }
    // CLOSE THE CALENDAR WINDOW
    oCalWin.close();
    return;
}

// *********************************************************************
// Frontier Additions for the Staff Calendar and Manager Planner
// *********************************************************************
var iMSPerDay = 1000 * 60 * 60 * 24;

// *********************************************************************
function calenTodayFocus() {
    if ((dCalDate.getMonth() == dToday.getMonth()) && (dCalDate.getFullYear() == dToday.getFullYear())) {
        var oDayElem = oDataPage.document.getElementById("day" + dToday.getDate());
        if (oDayElem) {
            if (oDayElem.className) {
                if (oDayElem.className.substr(0,5) != "today") {
                    calenChangeClass(dToday.getDate(),"today" + oDayElem.className);
                }
            } else {
                calenChangeClass(dToday.getDate(),"todayworkday");
            }
        }
    }
    return;
}

// *********************************************************************
function calenLinkBarMouse(sLinkType) {
    var sTemp = " onMouseOver='window.status=\"" + sLinkType + "\";return true;' onMouseOut='window.status=\"" + window.defaultStatus + "\";return true;'";
    return sTemp;
}

// *********************************************************************
//  sets the Calendar Options row on Calendar/Planner page
//  'Previous Week' calls new function calenCalcPrevWeek() - ZBG 7019
function calenLinkBar(sRange) {
    var sCalData = "<table border='0' cellpadding='0' cellspacing='0' align='center' width='100%'>";
    sCalData += hdftHeadingCreate();
    if (sRange != "planner") sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='goCal(oGlob.dCalDate.getFullYear()-1,oGlob.dCalDate.getMonth()); return false;' " + calenLinkBarMouse("Previous Year") + ">Previous Year</a></td>";
    sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='goCal(oGlob.dCalDate.getFullYear(),oGlob.dCalDate.getMonth()-1,oGlob.dCalDate.getDate()); return false;'" + calenLinkBarMouse("Previous Month") + ">Previous Month</a></td>";
    if (sRange == "planner") sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='oGlob.calenCalcPrevWeek(); return false;'" + calenLinkBarMouse("Previous Week") + ">Previous Week</a></td>";
    sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='initPage(); return false;'" + calenLinkBarMouse("Today") + ">Today</a></td>";
    if (sRange == "planner") sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='goCal(oGlob.dCalDate.getFullYear(),oGlob.dCalDate.getMonth(),oGlob.dCalDate.getDate()+7); return false;'" + calenLinkBarMouse("Next Week") + ">Next Week</a></td>";
    sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='goCal(oGlob.dCalDate.getFullYear(),oGlob.dCalDate.getMonth()+1,oGlob.dCalDate.getDate()); return false;'" + calenLinkBarMouse("Next Month") + ">Next Month</a></td>";
    if (sRange != "planner") sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='goCal(oGlob.dCalDate.getFullYear()+1,oGlob.dCalDate.getMonth()); return false;'" + calenLinkBarMouse("Next Year") + ">Next Year</a></td>";
    sCalData += "<td class='Headings'><a href='javascript:void(0)' class='Headings' onClick='oGlob.calenLegendShow(); return false;'" + calenLinkBarMouse("Legend") + ">Legend</a></td>";
    sCalData += "</tr></table><br>";
    return sCalData;
}

// *********************************************************************
function calenChangeClass(iWkDay,sEvent,sNo) {
    var sTempPage = loadPageCurrent();
    var bPlanMode = (sNo && (sNo != "")) ? true : false;
    var oDayElem = oDataPage.document.getElementById(((bPlanMode) ? sNo + "_" : "day") + iWkDay);
    if (oDayElem) {
        for (var sIndex in aDictDetail[sTempPage]) {
            if (aDictDetail[sTempPage][sIndex] && aDictDetail[sTempPage][sIndex]["appendix"] && aDictDetail[sTempPage][sIndex]["appendix"][0] && aDictDetail[sTempPage][sIndex]["label"] == sEvent) {
                // 010765 - If the day is already set as a holiday, then we don't want to clobber it with another event type
                if (oDayElem.eventType != "holiday") {
                    oDayElem.style.background = aDictDetail[sTempPage][sIndex]["appendix"][0];
                    //9347 - Set the event type
                    oDayElem.eventType = sEvent.toLowerCase();
                }
                break;
            }
        }
    }
    return;
}

// *********************************************************************
function calenLegendShow() {
    var oTemp = oDataPage.document.getElementById("legendDiv");
    if (oTemp) {
        oTemp.style.visibility = "visible";
    }
    return;
}

// *********************************************************************
function calenLegendHide() {
    var oTemp = oDataPage.document.getElementById("legendDiv");
    if (oTemp) {
        oTemp.style.visibility = "hidden";
    }
    return;
}

// *********************************************************************
function calenLegend() {
    var sLeg = "<table border='1'><tr><th>Legend</th></tr>";
    var sTempPage = loadPageCurrent();
    for (var sIndex in aDictDetail[sTempPage]) {
        if (aDictDetail[sTempPage][sIndex] && aDictDetail[sTempPage][sIndex]["title"] && aDictDetail[sTempPage][sIndex]["appendix"] && aDictDetail[sTempPage][sIndex]["appendix"][0]) {
            sLeg += "<tr><td style='background:" + aDictDetail[sTempPage][sIndex]["appendix"][0] + ";font-size:8pt;padding:6px'>" + aDictDetail[sTempPage][sIndex]["title"] + "</td></tr>";
        }
    }
    sLeg += "</table><p align='center' style='font-size:8pt;padding:6px'>Click legend to hide</p>";
    return(sLeg);
}

// *********************************************************************
// 9347 - Allow the type phol to display an icon
// 9745 - Default all leave icons to 'leave' if 'i_default' entered
// 11019 - Check sDesc before setting to avoid undefined when mouseover
function calenEventInsert(linkRef,linkText,nDays,iWkDay,sNo,sCode,sDesc) {
    // Set up whether this is called from the normal or planner view
    var bPlanMode = (sNo && (sNo != "")) ? true : false;
    var iWeekendNum = 0; 
    // must be modified to select table cell by staff number and weekday number
    var linkHtml = linkGraphic = "";
    if (linkText != "holiday") {
        // Set up the drill down if available
        if (linkRef && (linkRef != "")) {
            switch (linkText.toLowerCase()) {
                case "wfc":
                    if (!sDesc) sDesc = "WorkFlow Request";
                    linkGraphic = (sCode) ? sCode.toLowerCase() : "workflow";
                    break;
                case "lve":
                    if (!sDesc) sDesc = "Approved Leave";
                    if (oDataPage.oDict["i_default"]) linkGraphic = "leave"; 
                    else linkGraphic = (sCode) ? sCode.toLowerCase() : "leave";
                    break;
                case "lap":
                    if (!sDesc) sDesc = "Leave Application";
                    if (oDataPage.oDict["i_default"]) linkGraphic = "leave"; 
                    else linkGraphic = (sCode) ? sCode.toLowerCase() : "leave";
                    break;
                case "trh":
                    if (!sDesc) sDesc = "Approved Training";
                    linkGraphic = "training";
                    break;
                case "dri":
                    if (!sDesc) sDesc = "Diary";
                    linkGraphic = "diary";
                    break;
                case "phol":
                    if (!sDesc) sDesc = "Public Holiday";
                    linkGraphic = "phol";
                    break;
                // 10209 - show work times
                case "ekp":
                    linkText = sDesc;
                    sDesc = "Time Booking";
                    linkGraphic = "shif";
                    break;
                // 10210 - show time requests
                case "swt":
                    sDesc = "Time Request";
                    linkGraphic = "shif";
                    break;
                default:
                    if (!sDesc) sDesc = "Unknown Calendar Event";
                    break;
            }
            // 9347 - Display the description on the message bar
            // 10063 - onClick event used for Mozilla/Opera
            linkHtml += "<a href='" + linkRef + ";'";
            if (sDesc) {
                linkHtml += " title='" + sDesc + "' onMouseOver='window.status=\"" + sDesc + "\";return true;'";
            } else {
                linkHtml += " onMouseOver='window.status=\"Approved Leave\";return true;'";
            }
            linkHtml += " onMouseOut='window.status=\"" + window.defaultStatus + "\";return true;'>";
            // Do an image (with tool tip) in preference to the label
            if (linkGraphic) {
                linkHtml += "<img src='" + loadPageResource("calendar") + linkGraphic.toLowerCase() + ".png' border='0' style='width:20px;height:20px;'";
                if (sDesc) linkHtml += " alt='" + sDesc + "'";
                linkHtml += ">";
            } else {
                linkHtml += sDesc;
            }
            // 10209 - Add the string for the work times
            if (sDesc == "Time Booking") linkHtml += "<font size='1'>" + linkText + "</font>";
            // Close the drill down if available
            linkHtml += "</a>&nbsp;";
        } else {
            linkHtml += linkText;
        }
    } else {
        linkHtml += "<a>" + linkRef + "</a>";
        var oTemp = oDataPage.document.getElementById(((bPlanMode) ? sNo + "_" : "day") + iWkDay);
        if (oTemp) {
            oTemp.eventType = linkText;
        }
    }
    var bCase7 = false;
    var iCounter = 0;
    var iWeekendCounter = 0;
    if (nDays && (!isNaN(nDays))) {
        //nDays is the number of days off
        for (var iDay = parseInt(iWkDay,10); iDay < (parseInt(iWkDay,10) + parseInt(nDays,10)); iDay++) {
            var iAtDay = (iDay + iWeekendCounter);
            //iWkDay is the start day of the leave
            for (iWeekendNum = 0; iWeekendNum < aWeekEnd.length;iWeekendNum++) {
                if ((aWeekEnd[iWeekendNum] == iAtDay) && (linkText.toLowerCase() == "lve")) {
                    iCounter++;
                    iWeekendCounter += 2; //else first weekend day
                    iAtDay += iWeekendCounter;  
                }
                switch (iCounter) { 
                    case 3:
                        iAtDay = (iDay + 4);
                        break;
                    case 4:
                        iAtDay = (iDay + 6);
                        break;
                    case 5:
                        iAtDay = (iDay + 8);
                        break;
                }
            }
            //iDay = start day and start day + num of days by 1
            var oTemp = oDataPage.document.getElementById(((bPlanMode) ? sNo + "_" : "day") + iAtDay);
            if (oTemp) {
                oTemp.innerHTML += linkHtml;
                if (sDesc) oTemp.title = sDesc;
                oTemp.eventType = linkText.toLowerCase();
            }
        }
    } else {
        var oTemp = oDataPage.document.getElementById(((bPlanMode) ? sNo + "_" : "day") + iWkDay);
        if (oTemp) {
            oTemp.innerHTML += linkHtml;
            if (sDesc) oTemp.title = sDesc;
            oTemp.eventType = linkText.toLowerCase();
        }
    }
    return;
}

// *********************************************************************
function calenEventEdit(linkRef,linkText,nDays,iWkDay) {
    var existingDiv = oDataPage.document.getElementById(linkText.toLowerCase() + nDays);
    if (existingDiv) {
        var linkHtml = linkGraphic = sDesc = "";
        // Set up the drill down if available
        if (linkRef && (linkRef != "")) {
            linkHtml += "<a href='" + linkRef + "'>";
            switch (linkText.toLowerCase()) {
                case "wfc":
                    sDesc = "WorkFlow Request";
                    linkGraphic = "workflow";
                    break;
                case "dri":
                    sDesc == "Diary";
                    linkGraphic = "diary";
                    break;
                case "lve":
                    sDesc = "Approved Leave";
                    linkGraphic = "leave";
                    break;
                case "lap":
                    sDesc = "Leave Application";
                    linkGraphic = "leave";
                    break;
                case "trh":
                    sDesc = "Approved Training";
                    linkGraphic = "training";
                    break;
                default:
                    sDesc = "Unknown Calendar Event";
                    break;
            }
            // Do an image (with tool tip) in preference to the label
            if (linkGraphic) {
                linkHtml += "<img src='" + loadPageResource("calendar") + linkGraphic.toLowerCase() + ".png' border='0' style='width:20px;height:20px;'";
                if (sDesc) linkHtml += " alt='" + sDesc + "'";
                linkHtml += ">";
            } else {
                linkHtml += sDesc;
            }
            // Close the drill down if available
            linkHtml += "</a>";
        } else {
            linkHtml += linkText;
        }
        existingDiv.innerHTML = linkHtml;
    }
    return;
}

// *********************************************************************
// 11560 - All dates in CCYY-MM-DD format
function calenSetDateFrom(dInput, bFirst) { 
    var sDateFrom = "";
    if (!dInput) dInput = dCalDate;
    sDateFrom += dInput.getFullYear() + "-";
    var iMonth = (dInput.getMonth() + 1).toString();
    if (iMonth < 10) sDateFrom += "0";
    if (bFirst) sDateFrom += iMonth + "-01";
    else sDateFrom += iMonth + "-" + dInput.getDate();
    return sDateFrom;
}

// *********************************************************************
// 11560 - All dates in CCYY-MM-DD format
function calenSetDateTo(dInput, bFullMonth) { 
    var sDateTo = "";
    if (!dInput) dInput = dCalDate;
    sDateTo += dInput.getFullYear() + "-";
    var iMonth = (dInput.getMonth() + 1).toString();
    if (iMonth < 10) sDateTo += "0";
    sDateTo += iMonth + "-"
    if (bFullMonth) sDateTo += calenGetDaysInMonth(dInput);
    else sDateTo += dInput.getDate();
    return sDateTo;
}

// *********************************************************************
// 11560 - All dates in CCYY-MM-DD format
// Accepts a string in the format dd/mm/ccyy, and returns an object with the day,
// month and year seperated out as attributes.
function calenSplitDateString(sDate) {
    var oReturnDate = new Object();
    var aTemp = sDate.split("/");
    if (aTemp && aTemp.length == 3) {
        if (sZone == "USA") {
            oReturnDate.day = parseInt(aTemp[1],10);
            oReturnDate.month = aTemp[0];
        } else {
            oReturnDate.day = parseInt(aTemp[0],10);
            oReturnDate.month = aTemp[1];
        } 
        oReturnDate.year = aTemp[2];
    }
    return oReturnDate;
}

// *********************************************************************
// 8551 - Set search date field
// 9347 - Add the Day to the date search
// 9983 - Set the planner date search
// 10842 - Day value set correctly
function calenSetSearchDate(sYear,iMonth,iDay) { 
    var sSearchDate = "";
    if (oDataPage.document.detForm.i_day) {
        // 10842 - Don't change this conditional.
        if (isNaN(iDay)) iDay = dCalDate.getDate()-1;
        else iDay = iDay-1;
        oDataPage.document.detForm.i_day.selectedIndex = iDay;
        var iDD = iDay + 1;
        if (iDD < 10) iDD = "0" + iDD;
        sSearchDate += iDD;
    }
    if (oDataPage.document.detForm.i_month) {
        if (isNaN(iMonth)) iMonth = dCalDate.getMonth();
        oDataPage.document.detForm.i_month.selectedIndex = iMonth;
        var iMM = iMonth + 1;
        if (iMM < 10) iMM = "0" + iMM;
        sSearchDate += "/" + iMM;
    }
    if (oDataPage.document.detForm.i_date) {
        sYear = ((sYear) ? sYear : dCalDate.getFullYear());
        oDataPage.document.detForm.i_date.value = sYear;
        sSearchDate += "/" + sYear;
    }
    return sSearchDate;
}

// *********************************************************************
function calenWriteEmp(sYear,sMonth) {
    // N.B. sMonth range is 0 (January) to 11 (December)
    if ((!isNaN(sYear)) && (!isNaN(sMonth))) {
        sMonth = parseInt(sMonth,10);
        sYear = parseInt(sYear,10);
        if (sMonth < 0) {
            sMonth+=12;
            sYear--;
        } else if (sMonth > 11) {
            sMonth-=12;
            sYear++;
        }
        //  CALCULATES NEXT MONTH - ZBG 7019
        var iTempMonth = dCalDate.getMonth();
        if(sMonth == (iTempMonth + 1)) dCalDate.setDate(1);
        dCalDate.setMonth(sMonth);
        dCalDate.setFullYear(sYear);
    }
    // 9347 - Add the Day to the date search
    var day = dCalDate.getDate();
    var month = dCalDate.getMonth();
    var year = dCalDate.getFullYear();
    // Set the search year and month
    if (oDataPage && oDataPage.oSearch && oDataPage.oSearch["i_date"]) calenSetSearchDate(year,month,day);
    // Controls for Calendar
    var sCalData = calenLinkBar("calendar");
    // begin table and include WEEKDAY headINGS
    sCalData += "<table width='100%' cellpadding='0' cellspacing='1' border='1' align='center'>" + weekdays + "<tr>";
    // GET MONTH, AND YEAR FROM GLOBAL CALENDAR DATE
    // DETERMINE THE NUMBER OF DAYS IN THE CURRENT MONTH
    var days = calenGetDaysInMonth();
    // DETERMINE WHAT DAY OF THE WEEK THE CALENDAR STARTS ON
    var firstOfMonth = new Date(year, month, 1);
    // GET THE DAY OF THE WEEK THE FIRST DAY OF THE MONTH FALLS ON
    var startingPos  = firstOfMonth.getDay();
    days += startingPos;
    // KEEP trACK OF THE COLUMNS, START A NEW ROW AFTER EVERY 7 COLUMNS
    var iColumn = 0;
    // MAKE BEGINNING NON-DATE CELLS BLANK
    for (var i = 0; i < startingPos; i++) {
        sCalData += blankCell;
        iColumn++;
    }
    // SET valueS FOR DAYS OF THE MONTH
    var iCurrDate = 0;
    var sDayType = "workday";
    var sDayPerc = "16%";
    // DATE CELLS CONTAIN A NUMBER
    for (var i = startingPos; i < days; i++) {
        // GET THE DAY CURRENTLY BEING WRITTEN
        iCurrDate = i-startingPos+1;
        // SET THE type OF DAY, THE focusDay GENERALLY APPEARS AS A DIFFERENT COLOR
        if ((iColumn % 7 == 0) || (iColumn % 7 == 6)) {
            sDayType = "nonworkday";
            sDayPerc = "10%";
        } else {
            sDayType = "workday";
            sDayPerc = "16%";
        }
        // ADD THE DAY TO THE CALENDAR StrING
        sCalData += "<td class='" + sDayType + "' id='day" + iCurrDate + "' align='right' valign='top' width='" + sDayPerc +"' height='50'>" + iCurrDate + "<br></td>";
        // Increment the column count
        iColumn++;
        // START A NEW ROW WHEN NECESSARY
        if (iColumn % 7 == 0) sCalData += "</tr><tr>";
    }
    // MAKE REMAINING NON-DATE CELLS BLANK
    var iTotalCells = 42;
    while (days<=iTotalCells-7) {
        iTotalCells-=7;
    }
    for (var i=days; i<iTotalCells; i++)  {
        sCalData += blankCell;
        iColumn++;
        // START A NEW ROW WHEN NECESSARY
        if (iColumn % 7 == 0) {
            sCalData += "</tr>";
            if (i<iTotalCells-1) sCalData += "<tr>";
        }
    }
    sCalData += "</table>";
    // Write the HTML
    oDataPage.document.getElementById("calDiv").innerHTML = sCalData;
    // Set focus to today
    calenTodayFocus();
    // Debug Window
    if (gDHTMLDebug) loadPageDebug("calenWriteEmp:\n" + sCalData + "\n");
    return;
}

// *********************************************************************
// 9347 - Allow Planner to be of variable length (iCalenLen)
// 9735 - Set day to 1 before subtracting a month and restore later
function calenWritePlanner(aStaffList,iCalenLen,sYear,sMonth,sDay) {
    dCalDate.setHours(0);
    dCalDate.setMinutes(0);
    dCalDate.setSeconds(0);
    dCalDate.setMilliseconds(0);
    // build and insert table as follows:
    /*
    |Staff      |S |M |T |W |T |F |S |
    |Number     |15|16|17|18|19|20|21|
    ==================================
    |500100     |**|**|**|**|**|**|**|
    |500200     |**|**|**|**|**|**|**|
    |500300     |**|**|**|**|**|**|**|
    ** = <div id='<empno>_<weekday-number>'></div>
    */
    // N.B. sMonth range is 0 (January) to 11 (December)
    if ((!isNaN(sYear)) && (!isNaN(sMonth)) && (!isNaN(sDay))) {
        sMonth = parseInt(sMonth,10);
        sYear = parseInt(sYear,10);
        sDay = parseInt(sDay,10);
        dCalDate.setMonth(sMonth);
        if (sDay < 0) {
            sMonth--;
            dCalDate.setMonth(sMonth);
            sDay += calenGetDaysInMonth();
        } else if (sDay > calenGetDaysInMonth()) {
            sDay -= calenGetDaysInMonth();
            sMonth++;
        }
        if (sMonth < 0) {
            sMonth+=12;
            sYear--;
        } else if (sMonth > 11) {
            sMonth-=12;
            sYear++;
        }
        dCalDate.setDate(sDay);
        dCalDate.setMonth(sMonth);
        dCalDate.setFullYear(sYear);
    }
    // GET MONTH, AND YEAR FROM GLOBAL CALENDAR DATE
    var iDate = dCalDate.getDate();
    var iMonth = dCalDate.getMonth();
    var iYear = dCalDate.getFullYear();
    // get days in last month in case we go back a month
    iMonth--;
    if (iMonth < 0) {
        iMonth += 12;
        iYear--;
    }
    dCalDate.setDate(1);
    dCalDate.setMonth(iMonth);
    dCalDate.setFullYear(iYear);
    var daysLastMonth = calenGetDaysInMonth();
    iMonth++;
    if (iMonth > 11) {
        iMonth -= 12;
        iYear++;
    }
    // 014827
	dCalDate = new Date();
    dCalDate.setDate(iDate);
    dCalDate.setMonth(iMonth);
    dCalDate.setFullYear(iYear);
    var iDaysThisMonth = calenGetDaysInMonth();
    // determine date of Sunday immediately preceding or equal to today
    var iCurrDate = dCalDate.getDay();
    var iSunDate = iDate - iCurrDate;
    if (iSunDate < 1) {
        iSunDate += daysLastMonth;
        iMonth--;
        if (iMonth < 0) {
            iMonth += 12;
            iYear--;
        }
        dCalDate.setMonth(iMonth);
        dCalDate.setFullYear(iYear);
    }
    dCalDate.setDate(iSunDate);
    // Controls for Calendar
    var sCalData = "<br>" + calenLinkBar("planner");
    // 9347 - START Html TO HOLD WEEKDAY nameS IN table formAT
    var sHtml = "";
    // LOOP THROUGH WEEKDAY ARRAY
    for (var iDayCount=0;iDayCount<iCalenLen;iDayCount++) {
        var iIndex = iDayCount%7;
        sHtml += "<td class='heading' align=center>" + aWeekDay[iIndex] + "</td>";
    }
    // begin table and include WEEKDAY headINGS
    sCalData += "<table width='100%' cellpadding='0' cellspacing='1' border='1' align='center'><tr><td class='heading' align='left' rowspan='2'>Name</td>" + sHtml + "</tr>";
    // date now set to Sunday on or before date passed to function
    // write row of dates
    var thisDate = new Date();
    for (var d=0;d<iCalenLen;d++) {
        thisDate.setTime(Date.UTC(dCalDate.getFullYear(), dCalDate.getMonth(), dCalDate.getDate()) + (d * iMSPerDay));
        sCalData += "<td class='heading' align='center'>" + thisDate.getDate() + "/" + parseInt(thisDate.getMonth() + 1,10).toString() + "</td>";
    }
    sCalData += "</tr>";
    var sDayType = "workday";
    // for each staff, write row with name and all day cells
    for (var iStaffList in aStaffList) {
        if (aStaffList[iStaffList]["checked"]) {
            sCalData += "<tr><td title='Staff Number: " + aStaffList[iStaffList]["wfeempno"] + "'>" + aStaffList[iStaffList]["wfesurinit"] + "</td>";
            for (var iDayType=0;iDayType<iCalenLen;iDayType++) {
                sDayType = ((iDayType % 7 == 0) || (iDayType % 7 == 6)) ? "nonworkday" : "workday";
                thisDate.setTime(dCalDate.getTime() + (iDayType * iMSPerDay));
                sCalData += "<td class='" + sDayType + "' id='" + aStaffList[iStaffList]["wfeempno"] + "_" + iDayType + "'></td>";
            }
            sCalData += "</tr>";
        }
    }
    sCalData += "</table>";
    // Write the HTML
    var oTemp = oDataPage.document.getElementById("calDiv");
    if (oTemp) {
        oTemp.innerHTML = sCalData;
    }
    // Debug Window
    if (gDHTMLDebug) loadPageDebug("calenWritePlanner:\n" + sCalData + "\n");
    return;
}

// *********************************************************************
function calenDrillPage(iLS,redirPage) {
    iListSelected = iLS;
    oDataPage.location.replace(loadPagePath(redirPage));
    return;
}

// *********************************************************************
var oEmpCalWin;
var aCalData = new Array();

// *********************************************************************
// Find date type and change the format to the iso 8601 standard
function calenISOFormat(sDate) {
    if ((sDate.indexOf("/") != -1) && (sDate.length <= 10)) {
        var aTemp = sDate.split("/");
        if (aTemp.length && aTemp.length == 3) {
            for (var date in aTemp) if (isNaN(aTemp[date])) return sValue;
            aTemp[0] = parseInt(aTemp[0],10);
            if (aTemp[0] < 10) aTemp[0] = "0" + aTemp[0];
            aTemp[1] = parseInt(aTemp[1],10);
            if (aTemp[1] < 10) aTemp[1] = "0" + aTemp[1];
            switch (sZone) {
                case "USA":
                    sDate = aTemp[2] + "-" + aTemp[0] + "-" + aTemp[1];
                    break;
                default:
                    sDate = aTemp[2] + "-" + aTemp[1] + "-" + aTemp[0];
                    break;
            }
        }
    }
    return sDate;
}

// *********************************************************************
// 9347 - The date is passed in as the number of milliseconds
// 11046 Correct the date handling and the open window id value
// 13738 Use the ISO date format for all processing
function calenWindow(sDate,iDay,sType) {
    if (oEmpCalWin && (!oEmpCalWin.closed)) {
        oEmpCalWin.close();
    }
    oEmpCalWin = window.parent.open("","CalendarDetails",sNewWindow,true);
    if (!oEmpCalWin.opener) {
        oEmpCalWin.opener = window;
    }
    var weekdayList  = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
    var sCalHtml = "<html><head><title>";
    switch (sType) {
        case "dri":
            sCalHtml += "Diary Reminder";
            break;
        case "lve":
            sCalHtml += "Approved Leave";
            break;
        case "lap":
            sCalHtml += "Leave Application";
            break;
        case "trh":
            sCalHtml += "Approved Training";
            break;
        default:
            sCalHtml += "Unknown Event";
            break;
    }
    // If sDate is numeric then we have been passed a millisecond value, 
    // otherwise this is a date format with forward slashes present
    var dThisDate = new Date();
    if (isNaN(sDate)) {
        sDate = calenISOFormat(sDate);
        dThisDate.setFullYear(sDate.substring(0,4));
        dThisDate.setMonth(sDate.substring(5,7)-1);
        dThisDate.setDate(sDate.substring(8,10));
    } else {
        var iDate = parseInt(sDate,10);
        dThisDate = new Date(iDate);
    }
    sCalHtml += "</title></head><body><h4>";
    // Day of Week
    sCalHtml += weekdayList[dThisDate.getDay()];
    sCalHtml += ", ";
    // String for Month
    sCalHtml += monthArray[dThisDate.getMonth()];
    sCalHtml += " "; 
    // Date of the Month
    sCalHtml += dThisDate.getDate();
    sCalHtml += ", ";
    // Year
    sCalHtml += dThisDate.getFullYear();
    sCalHtml += "</h4><ul>" + aCalData[parseInt(iDay,10)] + "</ul>";
    sCalHtml += "<div align='center'><form><input type='button' name='Close' value='Close' onClick='self.close()' tabindex='0'></form></div></body></html>";
    if (oEmpCalWin) {
        oEmpCalWin.document.write(sCalHtml);
        oEmpCalWin.document.body.style.backgroundColor = (hWindowBG) ? hWindowBG : "#FFFFDE";
        oEmpCalWin.document.close();
    }
    return;
}

// *********************************************************************
//  CALCULATES PREVIOUS WEEK - ZBG 7019
function calenCalcPrevWeek() {
    var iOneMinute = 60 * 1000;
    var iOneHour = iOneMinute * 60;
    var iOneDay = iOneHour * 24;
    var iOneWeek = iOneDay * 7;
    var dTargetDate = new Date();
    var dDateInMs = dCalDate.getTime();
    dDateInMs -= iOneWeek;
    dTargetDate.setTime(dDateInMs);
    // 008552 - Fix Previous Week button
    oDataPage.goCal(dTargetDate.getFullYear(),dTargetDate.getMonth(),dTargetDate.getDate());
    return;
}

// *********************************************************************
//  CALCULATES NEXT MONTH - ZBG 7019
function calenCalcNextMonth() {
    var dTargetDate = new Date();
    dTargetDate = dCalDate;
    dTargetDate.setDate(1);
    var iMonth = dTargetDate.getMonth();
    iMonth++;
    dTargetDate.setMonth(iMonth);
    oDataPage.goCal(dTargetDate.getFullYear(),dTargetDate.getMonth());
    return;
}

// *********************************************************************
