// On day click: Jump to calendar page for the selected day
function onDayClick(day, mon, year) {
      // Fix stupid year getYear() bug and get the REAL year
    var yearDecade = year % 100;
    yearDecade += (yearDecade < 38) ? 2000 : 1900;
    var realYear = yearDecade;
    var eventBox = '#event-box';
    hideEventPreview(eventBox);
    frameRedirect(CALENDAR_URL + '?SQ_CALENDAR_VIEW=day&SQ_CALENDAR_DATE=' + DateConvert2MySQL(day, mon, realYear));
}

// On week click: Jump to calendar page for the selected week
function onWeekClick(day, mon, year) {
    frameRedirect(CALENDAR_URL + '?SQ_CALENDAR_VIEW=week&SQ_CALENDAR_DATE=' + DateConvert2MySQL(day, mon, year));
}

// On month click: Jump to calendar page for the selected month
function onMonthClick(day, mon, year) {
    frameRedirect(CALENDAR_URL + '?SQ_CALENDAR_VIEW=month&SQ_CALENDAR_DATE=' + DateConvert2MySQL(day, mon, year));
}

// On year click: Jump to calendar page for the selected year
function onYearClick(day, mon, year) {
    frameRedirect(CALENDAR_URL + '?SQ_CALENDAR_VIEW=year&SQ_CALENDAR_DATE=' + DateConvert2MySQL(day, mon, year));
}

// After rendering calendar navigator: hide the event preview box and retrieve the event preview list
function onAfterDraw(day, mon, year) {
    // Hide the event box
    var eventBox = '#event-box';
    $(eventBox).hide();
    // Get raw event data
    loadEventPreviewList(js_calendar_cal, day, mon, year);
}

// On day mouseOver: change table cell style and show event preview box
function onDayMouseOver(day, mon, year, elementID) {

    // Cancel hiding Event Preview
    clearTimeout(this.hidePreview);

    // Event Preview details
    var selectedCell = '#' + elementID;
    var eventBox = '#event-box';
    var eventList = this.eventList;

    // Fix stupid year getYear() bug and get the REAL year
    var yearDecade = year % 100;
    yearDecade += (yearDecade < 38) ? 2000 : 1900;
    var realYear = yearDecade;

    // Remove current style
    $(selectedCell).removeClass('cal_day');
    $(selectedCell).removeClass('cal_hol');
    // Set hover style
    // Show Event Preview box if necessary
    if(this.isEventListReady) {
        $(selectedCell).addClass('cal_ovr');
        showEventPreview(day, mon, realYear, selectedCell, eventBox, eventList);
    }
    else {
        $(selectedCell).addClass('cal_ovr_loading');
    }
}

// On day mouseOut: restore styles and hide event preview box
function onDayMouseOut(day, mon, year, elementID, elementClass) {
    var dayCell = '#' + elementID;
    // Restore style
    $(dayCell).removeClass('cal_ovr');
    $(dayCell).removeClass('cal_ovr_loading');
    $(dayCell).addClass(elementClass);
    var eventBox = '#event-box';
    var functionHidePreview = 'hideEventPreview(\'' + eventBox + '\')';
    this.hidePreview = setTimeout(functionHidePreview, 500);
}

/**
 * Display the Event Preview box.
 * @param   integer         day         The selected day for the current calendar view.
 * @param   integer         mon         The selected month for the current calendar view.
 * @param   integer         year        The selected year for the current calendar view.
 * @param   anchorElement   string      The ID of the element to position the Event Box over.
 * @param   eventContainer  string      The ID of the Event Preview box.
 * @param   eventData       object      A list of events for the current calendar view. Must be correctly formatted.
 *
 * @author          Dianne Castillo
 *
 * @return  void
 */
function showEventPreview(day, mon, year, anchorElement, eventContainer, eventData) {

    // Retrieve event preview for the selected day
    var currentEvent;
    var currentDay;
    var currentMonth;
    var currentYear;
    var eventDataLength = eventData.length;
    var selectedEvent;
    var i = 0;
    for (i=0; i < eventDataLength; i++) {
        currentEvent = eventData[i];
        currentDay = parseInt(currentEvent.selectedDay, 10);
        currentMonth = parseInt(currentEvent.selectedMonth, 10);
        currentYear = parseInt(currentEvent.selectedYear, 10);
        if (currentDay == day
        && currentMonth == mon
        && currentYear == year
        ) {
            selectedEvent = currentEvent;
            break;
        }
    }

    // The day was not found or the day has no events
    if(typeof(selectedEvent) == 'undefined'
    || !(selectedEvent.eventName)) {
        $(eventContainer).hide();
        return false;
    }
    else {
        // Define content sections
        var eventPreviewThumbnail = eventContainer + ' div.thumbnail';
        var eventPreviewDetails = eventContainer + ' div.details';
        // Clear the Event Box contents
        $(eventPreviewThumbnail).empty();
        $(eventPreviewDetails).children('p').empty();
        $(eventPreviewDetails).children('dd').empty();
        // Event details
        var selectedDateReadable = selectedEvent.selectedDateReadable;
        var eventName = selectedEvent.eventName;
        var eventURL = selectedEvent.eventURL;
        var eventThumbnailURL = selectedEvent.eventThumbnailURL;
        var eventDescription = selectedEvent.eventDescription;

        // Render event date
        var eventDateContainer = eventPreviewDetails + ' p.date';
        $(eventDateContainer).html(selectedDateReadable);
        // Render event name
        var eventNameLinked = '<a href="' + eventURL + '">' + eventName + '</a>';
        var eventTitleContainer = eventPreviewDetails + ' p.title';
        $(eventTitleContainer).html(eventNameLinked);
        // Render event thumbnail
        if (eventThumbnailURL) {
            var thumbnailTag = '<img src="' + eventThumbnailURL + '" width="50" height="50" alt="' + selectedEvent.eventName + '" />';
            var thumbnailLinked = '<a href="' + eventURL + '">' + thumbnailTag + '</a>';
            $(eventPreviewThumbnail).append(thumbnailLinked);
        }

        // Position the Event Box
        var anchorElementPosition = $(anchorElement).position();
        var eventBoxCoordX = anchorElementPosition.top - 26;
        var eventBoxCoordY = anchorElementPosition.left + 20;
        $(eventContainer).css({
            'position': 'absolute',
            'top': eventBoxCoordX,
            'left': eventBoxCoordY
        });

        // Display the Event Preview box
        $(eventContainer).show();
    }

}

// Hide the Event Preview box
function hideEventPreview(container) {
    var isPreviewActive = $(container).previewActive;
    $(container).hide();
}

/**
 * Load raw data for the selected month.
 * @param   object      calendar        The calendar to load events for.
 * @param   integer     day             The selected day for the current calendar view.
 * @param   integer     mon             The selected month for the current calendar view.
 * @param   integer     year            The selected year for the current calendar view.
 *
 * @author          Dianne Castillo
 *
 * @return  void
 */
function loadEventPreviewList(calendar, day, mon, year) {
    // Reset event list status
    calendar.isEventListReady = false;
    // Clear old data
    calendar.eventList = {};
    // Populate with new data
    var rawEventData = '';
    $.get(EVENT_PREVIEW_DETAILS_URL,
        {
            SQ_CALENDAR_VIEW: 'month',
            SQ_CALENDAR_DATE: DateConvert2MySQL(day, mon, year)
        },
        function(responseText) {
            rawEventData = responseText;
            // Parse the Matrix Calendar Page and build a list of events for preview purposes
            calendar.eventList = buildMonthEventList(rawEventData, day, mon, year);
            calendar.isEventListReady = true;
            // Highlight days with events
            renderEventDays(calendar, calendar.eventList);
        }
    );
}


/**
 * Parse raw HTML response and create a tidy list of the first event for each day of the selected month.
 * @param   string      rawEventData    The raw HTML response.
 * @param   integer     day             The selected day for the current calendar view.
 * @param   integer     mon             The selected month for the current calendar view.
 * @param   integer     year            The selected year for the current calendar view.
 *
 * @author          Dianne Castillo
 *
 * @return  void
 */
function buildMonthEventList(rawEventData, day, mon, year) {

    var eventList = [];

    // No data - bail out
    if (typeof(rawEventData) != 'string') {
        return eventList;
    }

    // Inject raw data into temporary div for processing
    var tempContainer = document.createElement('div');
    var tempID = 'temp-event-list';
    tempContainer.id = tempID;
    tempContainer.innerHTML = rawEventData;
    var tempEventList = $(tempContainer).children('div#event-preview-list');
    // Strip out extraneous content and markup from Event Preview List
    var tempElements = $(tempEventList).children();
    var tempElementsLength = tempElements.length;
    var currentElement;
    var currentElementTag;
    var currentElementClass;
    for (i=0; i < tempElementsLength; i++) {
        currentElement = tempElements[i];
        currentElementTag = currentElement.tagName;
        currentElementClass = currentElement.className;
        switch(currentElementTag) {
            // Don't strip these elements
            case 'DIV':
                if (currentElementClass == 'event-preview') {
                    continue;
                }
                else {
                    $(currentElement).remove();
                }
            case 'H1':
            case 'H3':
                continue;
                break;
            // Strip these elements
            default:
                $(currentElement).remove();
                break;
        }
    }
    // Get the position of all of the Day headings within the containing Preview List div
    var currentEventListElementTag;
    var dayHeadingPositions = [];
    var eventPreviewDataAll = [];
    tempEventList.children().each(function(i, el) {
        currentEventListElementTag = el.tagName;
        if (currentEventListElementTag == 'H3') {
            dayHeadingPositions.push(i);
        }
        eventPreviewDataAll.push(el);
    });
    // Grab the Day headings and the first event for each day and insert into a new array
    var countEventPreviewDays = dayHeadingPositions.length;
    var currentDayPosition;
    var currentEventPosition;
    var eventPreviewDataRaw = [];
    var currentDayDate;
    var currentDayEventElement;
    var currentPreviewData;
    for (i=0; i < countEventPreviewDays; i++) {
        currentDayPosition = dayHeadingPositions[i];
        currentEventPosition = currentDayPosition + 1;
        // <h3> contains the date (hardcoded into Matrix)
        currentDayDate = eventPreviewDataAll[currentDayPosition];
        // If no element exists beyond the last heading
        if (typeof(eventPreviewDataAll[currentEventPosition]) == 'undefined') {
            currentDayEventElement = null;
        }
        // Check existing elements immediately following a <h3>
        else {
            // If the next element is a div with a class of "event-preview", use it as the first event
            if (eventPreviewDataAll[currentEventPosition].tagName == 'DIV'
            && eventPreviewDataAll[currentEventPosition].className == 'event-preview') {
                currentDayEventElement = eventPreviewDataAll[currentEventPosition];
            }
            // Otherwise there is no first event for the day
            else {
                currentDayEventElement = null;
            }
        }
        currentPreviewData = {
            'date': currentDayDate,
            'firstEvent': currentDayEventElement
        };
        eventPreviewDataRaw.push(currentPreviewData);
    }

    // Extract event data
    var eventPreviewDataRawLength = eventPreviewDataRaw.length;
    var dayCount = 0;

    for (dayCount = 0; dayCount < eventPreviewDataRawLength; dayCount++) {

        // Initialise date and event details
        var selectedDay = '';
        var selectedMonth = '';
        var selectedYear = '';
        var selectedDateReadable = '';
        var selectedDayURL = '';
        var eventName = '';
        var eventURL = '';
        var eventThumbnailURL = '';
        var eventDescription = '';

        // Current Preview Event Date
        var currentPreviewEventDateEl = $(eventPreviewDataRaw[dayCount].date);
        var selectedDateReadable = currentPreviewEventDateEl.text();
        var selectedDayURL = currentPreviewEventDateEl.children('a:first').attr('href');

        // Get full date from calendar URL
        var selectedDayURLQuery = selectedDayURL.split('?')[1];
        var selectedDayURLParams = selectedDayURLQuery.split('&');
        var selectedDayURLParamsLength = selectedDayURLParams.length;
        var currentURLQuery;
        var currentURLQuerySplit;
        var currentURLQueryKey;
        var currentURLQueryValue;
        var selectedDateFull = '';

        for (i=0; i < selectedDayURLParamsLength; i++) {
            currentURLQuery = selectedDayURLParams[i];
            currentURLQuerySplit = currentURLQuery.split('=');
            currentURLQueryKey = currentURLQuerySplit[0];
            currentURLQueryValue = currentURLQuerySplit[1];
            if (currentURLQueryKey == 'SQ_CALENDAR_DATE') {
                selectedDateFull = currentURLQueryValue;
                break;
            }
            else {
                continue;
            }       
        }

        // Get date components from URL
        var selectedDateSplit = selectedDateFull.split('-');
        var selectedYear = selectedDateSplit[0];
        var selectedMonth = selectedDateSplit[1];
        var selectedDay = selectedDateSplit[2];

        // Does the current day have events?
        if (eventPreviewDataRaw[dayCount].firstEvent) {

            var currentPreviewEventEl = $(eventPreviewDataRaw[dayCount].firstEvent);
            var eventDetails = currentPreviewEventEl.children('ul:first').children('li');
            var currentEventDetailClass;

            // Retrieve event details for first event of the day
            var eventName = null;
            var eventURL = null;
            var eventThumbnailURL = null;
            var eventDescription = null;

            $(eventDetails).each(function(i, el) {
                currentEventDetailClass = el.className;
                switch(currentEventDetailClass) {
                    case 'eventName':
                        eventName = $(el).text();
                        break;
                    case 'eventURL':
                        eventURL = $(el).text();
                        break;
                    case 'eventThumbnailURL':
                        eventThumbnailURL = $(el).text();
                        break;
                    case 'eventDescription':
                        eventDescription = $(el).html();
                        break;
                    default:
                        break;
                }
            });

        }
        // Current day has no events
        else {
            eventName = null;
            eventURL = null;
            eventThumbnailURL = null;
            eventDescription = null;
        }

        // Final object with tidy list of all event previews
        eventList.push({
            'selectedDay': selectedDay,
            'selectedMonth': selectedMonth,
            'selectedYear': selectedYear,
            'selectedDateReadable': selectedDateReadable,
            'selectedDayURL': selectedDayURL,
            'eventName': eventName,
            'eventURL': eventURL,
            'eventThumbnailURL': eventThumbnailURL,
            'eventDescription': eventDescription
        });

    }

    return eventList;

}

/**
 * Indicate days on the calendar which have events.
 * @param   string      calendar        The ID of the calendar container.
 * @param   object      eventList       A list of events for the current calendar view. Must be correctly formatted.
 *
 * @author          Dianne Castillo
 *
 * @return  object      An array of days with events.
 */
function renderEventDays(calendar, eventList) {

    var containerID = '#' + calendar.divname;
    var calendarLinkName = calendar.varname;

    // Container doesn't exist
    if($(containerID).length < 1) {
        return;
    }
    // Event list is empty
    if(eventList.length < 1) {
        return;
    }

    // Get calendar table element
    var calendarTable = containerID + ' table';
    var calendarCells = calendarTable + ' td';
    var currentDayEvent;
    var eventListLength = eventList.length;
    var i = 0;
    var currentDay;
    var dayCell;
    for(i=0; i < eventListLength; i++) {
        currentDayEvent = eventList[i].eventName;
        // This day has an event
        if(currentDayEvent) {
            currentDay = parseInt(eventList[i].selectedDay, 10);
            dayCell = '#' + calendarLinkName + '_td_' + currentDay;
            $(dayCell).addClass('cal_event');
        }
    }

}