var moCalendarManager = new CalendarManager();
// Static date constants for today (not overwritten by functions)
var mcCalsToDisplay = 2;
var mcDisplayLimit  = 549;
var mcToday = new Date();
    mcToday         = new Date(mcToday.getFullYear(),mcToday.getMonth(),mcToday.getDate());
var mcStart         = new Date();
    mcStart         = new Date(mcStart.getFullYear(),mcStart.getMonth(),mcStart.getDate());
var mcEnd    = new Date();
    mcEnd    = mcEnd.setDate(mcStart.getDate() + mcDisplayLimit); //today + 549 days = 550 days to display

var moMonthDayCountArray = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

var moLeftArrow = new Image();
var moRightArrow = new Image();

/*  set up language object to display the correct strings on the cal for internationalization (can and should be overwritten on calling page)
    default to english and get populated on the page with the translated strings */
var moLanguageObj = {
        calendarMonthNameArray : ['January','February','March','April','May','June','July','August','September','October','November','December'],
        calendarShortMonthArray : ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'],
        calendarDayNameArray : ['Su','M','Tu','W','Th','F','Sa'],

        menuNotSelected : 'Not Selected',
        menuNoLOS : '--',
        menuTravelDatesTo : 'to',
        menuLOSUnit : 'nights',
        calendarClose : 'Close',
        calendarInstructionLabel :  '',
        calendarPrev : 'Previous',
        calendarNext : 'Next'
};

    // function to determine the offsetLeft of an element that is passed in
    function fnGetOffsetLeft (pElement) {
        var lsLeftOffset = pElement.offsetLeft;
        while ((pElement = pElement.offsetParent) != null){
            lsLeftOffset  += pElement.offsetLeft;
        }
        return lsLeftOffset;
    }
    // function to determine the offsetTop of an element that is passed in
    function fnGetOffsetTop (pElement) {
        var lsTopOffset = pElement.offsetTop;
        while ((pElement = pElement.offsetParent) != null){
            lsTopOffset +=pElement.offsetTop;
        }
        return lsTopOffset;
    }

    var moCalendarObj = null;

function CalendarManager(){
    this.calArray = new Array();
}
//Calendar Manager method to add a new calendar to the array
CalendarManager.prototype.addCalendar = function(pCalendarObj){
    this.calArray[pCalendarObj.calendarId] = pCalendarObj;
}

// Availability Calendar Constructor - takes in an id as a handle, a date string for ci and a date string for co in yyyy-mm-dd format
// added properties object
function multiDisplayCalendar(pCalendarId, valueDatesArray,parentElement){
    this.parentElement = parentElement || document.body;
    if(moCalendarManager.calArray[pCalendarId]){

        var loCalendarObj = moCalendarManager.calArray[pCalendarId];
        loCalendarObj.initializeObject();
        return loCalendarObj;
    }
    else{
        this.calendarId     	= pCalendarId;
        this.valueDatesArray = valueDatesArray;
        this.calStartDate   	= null;

        this.display = 'none';
        this.calendarDivMonth = new Array();
        this.calendarPrevious = null;
        this.calendarPreviousAction = null;
        this.calendarNext = null;
        this.calendarNextAction = null;

        this.initializeObject();

        this.calendarIframe = null;
        this.calendarContainer = this.createFramework();
        moCalendarManager.addCalendar(this);
    }
}

multiDisplayCalendar.prototype.initializeObject = function(){
    this.calStartDate = this.getCalStartDate();
}

multiDisplayCalendar.prototype.getCalStartDate = function(){
 	var loStartDate = new Date(mcToday.getFullYear(), mcToday.getMonth(), 1);
    return loStartDate;
}

multiDisplayCalendar.prototype.getDisplayMode = function(){
    return 0;
}

//Availability Calendar method to show and hide the coresponding div
multiDisplayCalendar.prototype.toggleDisplay = function(){
    this.display = (this.display == 'none') ? 'block' : 'none';
    this.calendarContainer.style.display = this.display;
}

//Availability Calendar method to show and hide the coresponding div
multiDisplayCalendar.prototype.show = function(event){
    this.initializeObject();
    this.renderCalDisplay();
    this.display = 'block';
    this.calendarContainer.style.display = this.display;
}

//Availability Calendar method to show and hide the coresponding div
multiDisplayCalendar.prototype.hide = function(event){
    this.display 							= 'none';
    this.calendarContainer.style.display 	= this.display;
}

multiDisplayCalendar.prototype.setCalendarPosition = function(pCalendarIcon){
    this.calendarContainer.style.top    = (fnGetOffsetTop(pCalendarIcon, this.calendarContainer) - this.calendarContainer.offsetHeight) + 'px';
    this.calendarContainer.style.left   = (fnGetOffsetLeft(pCalendarIcon, this.calendarContainer) - this.calendarContainer.offsetWidth) + 'px';
}


multiDisplayCalendar.prototype.createFramework = function(){
    var lsText;
    var loTextNode;

    // create main calendar div
    var loCalenderHolder = document.createElement("div");
        loCalenderHolder.style.zIndex = "2000";
        loCalenderHolder.className = "calendarHolder";
        loCalenderHolder.id = "calendarHolder";
        (this.parentElement || document.body).appendChild(loCalenderHolder);

    // create the main calendar portion
    var loCalendarContainer = document.createElement("div");
        loCalendarContainer.className = "calendarOuterContainer";
        // Prev button
        var loPreviousButton = document.createElement("div");
            loPreviousButton.className = "calendarNavigation";
            var loPrevActionHolder = document.createElement("div");
                loPrevActionHolder.id = "calendarNavigationPrev";
                var loPrevAction = document.createElement("a");
                    this.calendarPreviousAction = "javascript:fnChangeMonth('" + this.calendarId + "',-1);";
                    loPrevAction.className = "calendarNavigationPrevActive"
                    loPrevAction.href = this.calendarPreviousAction;
                    loPrevAction.title = moLanguageObj.calendarPrev;
                    this.calendarPrevious = loPrevAction;
                    var loPrevActionImg = document.createElement("img");
                        loPrevActionImg.src = moLeftArrow.src;
                        loPrevActionImg.border = '0';
                        loPrevActionImg.alt = moLanguageObj.calendarPrev;
                    loPrevAction.appendChild(loPrevActionImg);
                loPrevActionHolder.appendChild(loPrevAction);
            loPreviousButton.appendChild(loPrevActionHolder);
            loCalendarContainer.appendChild(loPreviousButton);
        // container
        var loCalendarInnerContainer = document.createElement("div");
            loCalendarInnerContainer.className = "calendarInnerContainer";
            /* ****************CAL BODY HERE******************* */
            // left cal
            var loLeftCal = document.createElement("div");
                loLeftCal.className = "calendarDiv";
                loCalendarInnerContainer.appendChild(loLeftCal);
                this.calendarDivMonth[0] = loLeftCal;
            // spacer div
            var loSpacerDiv = document.createElement("div");
                loSpacerDiv.className = "spacerDiv";
                loCalendarInnerContainer.appendChild(loSpacerDiv);
            // right cal
            var loRightCal = document.createElement("div");
                loRightCal.className = "calendarDiv";
                loCalendarInnerContainer.appendChild(loRightCal);
                this.calendarDivMonth[1] = loRightCal;
            // clear div
            var loClearDiv1 = document.createElement("div");
                loClearDiv1.className = "divClear";
                loCalendarInnerContainer.appendChild(loClearDiv1);
            loCalendarContainer.appendChild(loCalendarInnerContainer);
            /* ****************END CAL BODY******************** */
        // Next button
        var loNextButton = document.createElement("div");
            loNextButton.className = "calendarNavigation";
            var loNextActionHolder = document.createElement("div");
                loNextActionHolder.id = "calendarNavigationNext";
                var loNextAction = document.createElement("a");
                    this.calendarNextAction = "javascript:fnChangeMonth('" + this.calendarId + "',1);";
                    loNextAction.href = this.calendarNextAction;
                    loNextAction.className = "calendarNavigationNextActive"
                    loNextAction.title = moLanguageObj.calendarNext;
                    this.calendarNext = loNextAction;
                    var loNextActionImg = document.createElement("img");
                        loNextActionImg.src = moRightArrow.src;
                        loNextActionImg.border = '0';
                        loNextActionImg.alt = moLanguageObj.calendarNext;
                    loNextAction.appendChild(loNextActionImg);
                loNextActionHolder.appendChild(loNextAction);
            loNextButton.appendChild(loNextActionHolder);
            loCalendarContainer.appendChild(loNextButton);
        // clear div
        var loClearDiv2 = document.createElement("div");
            loClearDiv2.className = "divClear";
            loCalendarContainer.appendChild(loClearDiv2);
    loCalenderHolder.appendChild(loCalendarContainer);
    // create travel dates display
    var loMenuHolder = document.createElement("div");
        loMenuHolder.className = 'menuHolder';
        // create close button
        var loClearDiv4 = document.createElement("div");
            loClearDiv4.className = "divClear";
            loMenuHolder.appendChild(loClearDiv4);
    loCalenderHolder.appendChild(loMenuHolder);

    return loCalenderHolder;
}

//Availability Calendar method to render the calendar, different results are shown based on the display mode
multiDisplayCalendar.prototype.renderCalendar = function(){
    for(var calIndex=0; calIndex<mcCalsToDisplay; calIndex++){
        var lsOutput        = '';
        var lvColumnIndex   = 0;
        var lvWorkingDate   = new Date(this.calStartDate);
        lvWorkingDate       = new Date(lvWorkingDate.setMonth(lvWorkingDate.getMonth() + calIndex));
        var loCurrentMonth  = lvWorkingDate.getMonth();
        var loCurrentYear   = lvWorkingDate.getFullYear();
        var lvCurrentDay    = new Date(loCurrentYear,loCurrentMonth,1).getDay();

        // Construct calendar table
        lsOutput += '<div class="CalendarTable">'
            // Header
        lsOutput += '<div class="month">' + moLanguageObj.calendarMonthNameArray[loCurrentMonth];
        lsOutput += ' ' + loCurrentYear;
        lsOutput += '</div>';
            // Day Names
        lsOutput += '<div class="CalendarTableInner">';
        for (i=0; i<7; i++){
            lsOutput += '<div class="daysoftheweek">'+ moLanguageObj.calendarDayNameArray[i] +'</div>';
        }
        // Calendar Days
        lsOutput += '<div class="divClear">&nbsp;</div>';
        // Figure out if it is a leap year and set accordingly
        moMonthDayCountArray[1] = (((loCurrentYear % 4 == 0) && (loCurrentYear % 100 != 0)) || (loCurrentYear % 400 == 0)) ? 29 : 28;
        for (i=0; i<lvCurrentDay; i++, lvColumnIndex++){
            lsOutput += '<div class="emptyDay">&nbsp;</div>';
        }

        for (var i=0; i<=moMonthDayCountArray[loCurrentMonth]-1; i++, lvColumnIndex++) {
            var loCurrentDate = new Date(loCurrentYear,loCurrentMonth,1);
            loCurrentDate = new Date(loCurrentDate.setDate(loCurrentDate.getDate() + i));
            var lsTempOutput = '';
            var myDate=new Date()
            if(loCurrentDate < mcEnd) // day is valid
                    {
                        lsTempOutput = '<div class="available" >' + loCurrentDate.getDate() +'</div>';
                    }
            else    { //day is past the book limit
                        lsTempOutput = '<div class="emptyDay">' + loCurrentDate.getDate() +'</div>';
                    }

            if (inArray(loCurrentDate, valueDates)) {
                         lsTempOutput = '<div class="vdate">' + loCurrentDate.getDate() + '</div>';
                    }

            lsOutput += lsTempOutput;
            if (lvColumnIndex == 6) {
                        lsOutput += '<div class="divClear">&nbsp;</div>';
                        lvColumnIndex = -1;
            }
        }


        if (lvColumnIndex > 0) {
            for (i=1; lvColumnIndex<7; i++, lvColumnIndex++){
                lsOutput += '<div class="emptyDay">&nbsp;</div>';
            }
        }
        lsOutput += '</div></div>';
        //Write the newly constructed table to the div on the page
        this.calendarDivMonth[calIndex].innerHTML = lsOutput;
    }
}

multiDisplayCalendar.prototype.setNavigation = function(){
    var lvWorkingDate   = new Date(this.calStartDate);
        lvWorkingDate   = new Date(lvWorkingDate.setMonth(lvWorkingDate.getMonth() + 1));
    var loMaxDisplay    = new Date(mcEnd);
    var loDisableArray = new Array(false, false);

    // Prev button
    if(this.calStartDate.getMonth() == mcStart.getMonth() && this.calStartDate.getFullYear() == mcStart.getFullYear()){
        this.calendarPrevious.className = 'calendarNavigationPrevDisabled';
        this.calendarPrevious.href = "javascript:void(0);";
    }
    else{
        this.calendarPrevious.className = 'calendarNavigationPrevActive';
        this.calendarPrevious.href = this.calendarPreviousAction;
    }
    // next button
    if(lvWorkingDate.getMonth() >= loMaxDisplay.getMonth() && lvWorkingDate.getFullYear() >= loMaxDisplay.getFullYear()){
        this.calendarNext.className = 'calendarNavigationNextDisabled';
        this.calendarNext.href = "javascript:void(0);";
    }
    else{
        this.calendarNext.className = 'calendarNavigationNextActive';
        this.calendarNext.href = this.calendarNextAction;
    }
}

multiDisplayCalendar.prototype.renderCalDisplay = function(){
    this.renderCalendar();
    this.setNavigation();
}

multiDisplayCalendar.prototype.formatDateOnImport = function(pDate){
    var loDateObj = null;
    if(pDate != ''){
        var lsDateString = pDate;
        var loDateArray = new Array();
        loDateArray = lsDateString.split("-");
        loDateObj = new Date(loDateArray[1] + "/" + loDateArray[2] + "/" + new Number(loDateArray[0]));
    }
    return loDateObj;
}


function fnCloseCalendar(pCalendarId){
    var loCalendarObj = moCalendarManager.calArray[pCalendarId];
    loCalendarObj.toggleDisplay();
}

// function to change the month.  The month buttons pass pDirection to tell the function to move up or down one month and a new calendar is drawn
function fnChangeMonth(pCalendarId,pDirection){
    var loCalendarObj = moCalendarManager.calArray[pCalendarId];
    var loNewStart = new Date(loCalendarObj.calStartDate);
    loCalendarObj.calStartDate = new Date(loNewStart.setMonth(loNewStart.getMonth() + pDirection));
    loCalendarObj.renderCalDisplay();
}

function fnGetDisplayDate(pDateToFormat){
    var lsFormatDate = null;
    if(pDateToFormat){
        var loDate = new Date(pDateToFormat);
        var lsYear = loDate.getFullYear();
        var lsMonth = moLanguageObj.calendarShortMonthArray[loDate.getMonth()]
        lsFormatDate = loDate.getDate() + ' ' + lsMonth + ' ' + lsYear;
    }
    return lsFormatDate;
}


function fnFormatForExport(pDateToFormat){
    var loFormatDate = new Date(pDateToFormat);
    if(!isNaN(loFormatDate)){
        var lsDateString = loFormatDate.getFullYear() + '-' + padZero(loFormatDate.getMonth() +1) + '-' + padZero(loFormatDate.getDate());
        return lsDateString;
    }
}

function padZero(pNumber) {
    return (pNumber<0 || pNumber>9 ? "" : "0") + pNumber;
}

function inArray(needle, haystack) {
    for (h in haystack) {
        if ( (haystack[h].getDate() == needle.getDate() )
             &&
             (haystack[h].getMonth() == needle.getMonth() )
             &&
             (haystack[h].getFullYear() == needle.getFullYear() )
            )
        {
          return true;
        }
    }

    return false;
}

