Source: calendar_util.js

/**
* A general calendar utility object that is used by other modules to perform
* calendar related tasks.
*
* @module calendar_util
* @author Joonas Konki
* @author Anu Koskela
* @author Mikko Kuhno
* @author Henrik Paananen
* @author Atte Räty
* @license BSD 3-clause, see LICENSE for more details.
* @copyright 2015 Kepler project authors
*/
calUtil = (function(){

var colorPalette = {
    lightBlue: '#9BCCF5',
    defaultBlue: '#337ab7',
    borderBlue: '#46b8da',
    clickedGreen: '#89e894',
    lightGrey: '#e6e6e6',
    reservedGrey: '#8E948F',
    warningRed: '#ff9696',
    black: 'black',
    orange: '#c7410a',
    //'#5EAFF2'
};

var eventColorScheme = {
    reservation: colorPalette.reservedGrey,
    external: colorPalette.lightGrey,
    time_slot: colorPalette.lightBlue,
    supervisor_time_slot: colorPalette.defaultBlue,
};

/**
 * Makes a calendar event from the event received from the Kepler API calls
 * get_calendar_events or get_time_slot_events.
 * @memberof module:calendar_util
 * @param event The Kepler event that contains the information about the event.
 */
function makeCalendarEvent(event, colorScheme) {
    if(colorScheme === undefined){
        colorScheme = eventColorScheme;
    }
    if(event.reservation !== undefined){
        if(event.reservation.status === "superuser_canceled_id"){
            event.content =
                kepler.translate('content.reservations_cancelled_time_slot');
            colorScheme.reservation = "#ff9696";
        }
    }

    var calEvent = {};
    calEvent.title = event.title;
    calEvent.start = event.start_time;
    calEvent.end = event.end_time;
    calEvent.textColor = 'black';
    calEvent.className = "cal-event";
    calEvent.k = {};

    // Custom attributes
    calEvent.k.event_type = event.type;
    calEvent.k.content = event.content;
    calEvent.k.reservation = event.reservation;
    calEvent.k.event = event;
    calEvent.k.selectedColor = colorPalette.clickedGreen;
    calEvent.k.color = colorPalette.defaultBlue;

    if(calEvent.k.event_type){
        if (colorScheme[calEvent.k.event_type] === undefined){
            calEvent.k.color = eventColorScheme[calEvent.k.event_type];
        } else{
            calEvent.k.color = colorScheme[calEvent.k.event_type];
        }
    }

    calEvent.k.pointer = false;
    calEvent.k.selected = false;

    calEvent.color = calEvent.k.color;
    return calEvent;
}

/**
 * Sets the default event rendering callback function for FullCalendar events.
 * @memberof module:calendar_util
 * @param event - Contains the event information.
 * @param element - Contains information of what kind of
 *                  element the clicked event is.
 * @param view - Contains the viewmode in which the element is shown.
 */
function defaultEventRender(event, element, view) {
    if (event.k.content) {
        var content = $("<div>").addClass("cal-event-content");
        content.text(event.k.content);
        element.append(content);
    }
    if (event.k.reservation) {
        var group = $("<div>").addClass("cal-event-content");
        var groupText = "";
        if (event.k.reservation.is_personal) {
            groupText = kepler.translate('reservation.personal');
        } else {
            groupText = kepler.translate('reservation.shared') +
                ": " + event.k.reservation.user_group_name;
        }
        group.text(groupText);
        element.append(group);
    }
    if (event.k.event_type == "supervisor_time_slot") {
        var content = $("<div>").addClass("cal-event-content");
        var contentText = kepler.translate('time_slot.supervisors') + ": ";
        var supervisors = event.k.event.supervisors;
        for (var i in supervisors) {
            if (i > 0) contentText += ", ";
            contentText += supervisors[i].first_names;
        }
        content.text(contentText);
        element.append(content);
    }
    if (event.k.selected) {
        var selectedDiv = $("<div>").addClass("cal-event-content selected");
        selectedDiv.text(kepler.translate('calendar.event.selected'));
        element.append(selectedDiv);
        element.css('background-color', event.k.selectedColor);
    }else {
        element.css('background-color', event.k.color);
    }
}

/**
 * Initialises the FullCalendar calendar widget.
 * @memberof module:calendar_util
 * @param clickCallback The click event handler for clicking calendar events.
 * @param renderCallback An optional callback to customise calendar events to
 *                       suit each module's purpose.
 * @returns The jQuery object of the calendar widget.
 */
function initCal(clickCallback, renderCallback) {
    var cal = $('#calendar');

    if (!renderCallback)
        renderCallback = defaultEventRender;

    cal.fullCalendar({

        eventClick: clickCallback,

        lang: _locale,

        header: {
            left: 'agendaDay, agendaWeek, month',
            center: 'title',
            right: ' today, prev, next,',
        },

        eventMouseover: function(event, element, view) {
            if (event.k.pointer !== undefined && event.k.pointer === true)
                $('html,body').css('cursor', 'pointer');
        },
        eventMouseout: function(event, element, view) {
            if (event.k.pointer !== undefined && event.k.pointer === true)
                $('html,body').css('cursor', 'default');
        },

        eventRender: renderCallback,

        height: 'auto',
        // aspectRatio: 2.0,
        // handleWindowResize: true,
        allDaySlot: false,
        slotDuration: '01:00:00',

        //Change the view options of Agenda view styles
        //like agendaWeek and agendaDay
        views: {
            agendaWeek: {
                type: 'agenda',
                duration: { days: 7 },
                weekends: false,
                minTime: "08:00:00",
                maxTime: "20:00:00",
            },

            agendaDay: {
                type: 'agenda',
                minTime: "08:00:00",
                maxTime: "20:00:00",
            }
        },

        //Set the default view
        firstDay: 1,
        //Set the default view to week instead of month
        defaultView: 'agendaWeek',
        //Changes the title format
        titleFormat: 'D.M.YYYY',
        // Changes the axis format to legit numerals instead of AM - PM
        axisFormat: 'H:mm',
        columnFormat: {
            month: 'ddd',
            week: 'ddd - DD.MM',
            day: 'ddd - DD.MM',
        },

    });

    return cal;
}


/**
 * Initialises the default calendar with the event source of kepler
 * calendar events.
 * @memberof module:calendar_util
 * @param clickCallback The click event handler for clicking calendar events.
 * @param renderCallback An optional callback to customise calendar events.
 * @param eventFilter An optional function that can filter out events.
 * @returns The jQuery object of the calendar widget.
 */
function initDefaultCal(clickCallback, renderCallback, eventFilter) {
    var cal = initCal(clickCallback, renderCallback);

    cal.fullCalendar('addEventSource', {
        events: function(start, end, timezone, callback) {
            var params = {
                'start_time': start.toISOString(),
                'end_time': end.toISOString()
            };
            kepler.getCalendarEvents(params, function(data) {
                var events = [];
                for (var i = 0; i < data.events.length; i++) {
                    var event = data.events[i];

                    if (eventFilter === undefined || !eventFilter(event))
                        continue;

                    calEvent = makeCalendarEvent(event);
                    events.push(calEvent);
                }
                callback(events);
            });
        }
    });

    return cal;
}

// Return the calUtil object.
return {
    initCal: initCal,
    initDefaultCal: initDefaultCal,
    colorPalette: colorPalette,
    defaultEventRender: defaultEventRender,
    makeCalendarEvent: makeCalendarEvent
};

})();