/// <reference path="../../references.js" />

rwthapp.util.initNamespace("templates.organisation");

rwthapp.templates.organisation.timetable = {

    nextWeek: 0,
    prevWeek: 0,

    minDate: new Date(new Date().getFullYear() - 1, 0, 1),
    maxDate: new Date(new Date().getFullYear() + 1, 11, 31),

    backProcessProceed: true,

    picker: null,

    load: function (template, parameters) {

        return this.fetchWeek(0).then(function (timetableHtmlAndDisplayDateFormat) {

            return {

                template: template,
                parameters: {
                    timetableHtml: timetableHtmlAndDisplayDateFormat.html,
                    isiOS: rwthapp.platformInfo.isIOS(),
                    isWindows: rwthapp.platformInfo.isWindowsUniversal() || rwthapp.platformInfo.isWP8()
                },
                title: rwthapp.localization.getLocalizedString("menu.organisation.schedule"),
                subTitle: timetableHtmlAndDisplayDateFormat.month + " " + timetableHtmlAndDisplayDateFormat.year,
                tabletMode: { position: 'right', mainView: true }
            };
        });
    },

    courseClick: function () {

        $(".loadCourse").unbind("click");
        $(".loadCourse").click(function () {
            rwthapp.navigator.gotoPage("campus.details.courses", { gguid: $(this).data("gguid") }, true);
        });
    },

    ready: function () {

        var me = this;

        rwthapp.util.addRightFeatureSpecificButtonToNavbar("timetable-today", "today", function () {

            me.scrollToRowByDate(new Date());
        });

        if ($('#timetable-content').height() <= $(window).height()) {

            var height = $(window).height() - $('#timetable-content').height() + 100;
            $('#week_body').append('<div id="spacer" style="height: ' + height + 'px;"/>');
        }

        var scrollValue = $('#scroll-up-btn').height() + parseInt($($('#week_body').children()[0]).css("margin-top")), me = this;

        $('#timetable-scroll-content').animate({ scrollTop: scrollValue }, 800, function () {

            me.registerScrollToFetchSpecificWeeks();
        });

        this.initDatePicker();

        var clickPicker = function (event) {

            if (me.picker) {

                me.picker.open();
                event.stopPropagation();
            }
        };

        $('#titleContainer').click(clickPicker);

        rwthapp.util.backButtonHook = function () {
            
            var result = me.backProcessProceed;
    
            if (me.picker) {

                // close inverts backProcessProceed
                me.picker.close();
            }

            return result;
        }

        rwthapp.util.orientationChangeHook = function () {

            if (!rwthapp.util.isLandscape()) {

                $('#titleContainer').unbind('click');
                $('#htmlPicker').remove();
                $('#timetable-today').css('display', 'none');
            }
            else {

                $('#titleContainer').click(clickPicker);
                me.initDatePicker();
                $('#timetable-today').css('display', '');
            }
        }

        this.picker.set('select', new Date());
    },

    initDatePicker: function() {

        $('#titleContainer').append('<div id="htmlPicker" style="display: none;"/>');

        var me = this;

        var pickerClose = function () {

            me.backProcessProceed = true;

            var pickedDate = this.get('select', 'yyyy-mm-dd');

            if (pickedDate !== '') {

                var date = new Date(pickedDate), firstDate = new Date($($('#week_body').children()[0]).data('date')),
                    lastDate = new Date($($('#week_body').children()[$('#week_body').children().length - 1]).data('date'));

                // when weeks in the past needs to be loaded
                if (date.getTime() < firstDate.getTime()) {

                    // set day of date to monday
                    date.setDate(date.getDate() - ((date.getDay() === 0 ? 7 : date.getDay()) - 1));
                    var weekCounter = 0;

                    while (date.toLocaleDateString() !== firstDate.toLocaleDateString()) {

                        // increase date for one day
                        date.setDate(date.getDate() + 1);

                        // when date is monday increase weekCounter
                        if (date.getDay() === 1) {

                            weekCounter++;
                        }
                    }

                    // it should be impossible that weekCounter has not been incresased here
                    if (weekCounter > 0) {

                        var prevWeekStateBefore = me.prevWeek;

                        me.prevWeek -= weekCounter;
                        me.addNewAppointmentsToWeekBody('up', weekCounter, new Date(pickedDate)).then(function (data) {

                            if (data && !data.error || !data) {

                                me.scrollToRowByDate(new Date(pickedDate));
                            }
                            else {

                                rwthapp.logging.logger.debug("Loading more than one week from server does not work as expected.", data.error);

                                me.prevWeek = prevWeekStateBefore;
                            }
                        });
                    }
                }
                    // when weeks in the future needs to be loaded
                else if (date.getTime() > lastDate.getTime()) {

                    // set day of date to Sunday
                    date.setDate(date.getDate() + (7 - (date.getDay() === 0 ? 7 : date.getDay())));
                    var weekCounter = 0;

                    while (date.toLocaleDateString() !== lastDate.toLocaleDateString()) {

                        // increase date for one day
                        lastDate.setDate(lastDate.getDate() + 1);

                        // when date is sunday increase weekCounter
                        if (lastDate.getDay() === 0) {

                            weekCounter++;
                        }
                    }

                    // it should be impossible that weekCounter has not been incresased here
                    if (weekCounter > 0) {

                        var nextWeekStateBefore = me.nextWeek;

                        me.nextWeek += 1;
                        me.addNewAppointmentsToWeekBody('down', weekCounter, new Date(pickedDate)).then(function (data) {

                            if (data && !data.error || !data) {

                                me.nextWeek += weekCounter - 1;
                                me.scrollToRowByDate(new Date(pickedDate));
                            }
                            else {

                                rwthapp.logging.logger.debug("Loading more than one week from server does not work as expected", data.error);

                                me.nextWeek = nextWeekStateBefore;
                            }

                        });
                    }
                }
                    // check if picked date is between the loaded weeks
                else {

                    me.scrollToRowByDate(new Date(pickedDate));
                }
            }
        },
        htmlPicker,
        onSet = function (setting) {

            if (!setting.highlight) {

                this.close();
            }
        },
        onOpen = function () {

            me.backProcessProceed = false;
        };

        if (rwthapp.localization.getCurrentLanguage() === 'de') {

            htmlPicker = $('#htmlPicker').pickadate({

                selectMonths: true,
                selectYears: 3,

                //The title label to use for the month nav buttons
                labelMonthNext: 'Nächster Monat',
                labelMonthPrev: 'Voriger Monat',
                //The title label to use for the dropdown selectors
                labelMonthSelect: 'Wähle einen Monat aus',
                labelYearSelect: 'Wähle ein Jahr aus',
                //Months and weekdays
                monthsFull: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
                monthsShort: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
                weekdaysFull: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
                weekdaysShort: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
                //Materialize modified
                weekdaysLetter: ['S', 'M', 'D', 'M', 'D', 'F', 'S'],
                //Today and clear
                today: 'Heute',
                clear: 'Löschen',
                close: '',
                firstDay: 1,

                format: 'mmmm',
                onClose: pickerClose,
                onSet: onSet,
                onOpen: onOpen,
                min: me.minDate,
                max: me.maxDate
            });
        }
        else {

            htmlPicker = $('#htmlPicker').pickadate({

                selectMonths: true,
                selectYears: 3,
                format: 'mmmm',
                onClose: pickerClose,
                onSet: onSet,
                onOpen: onOpen,
                close: '',
                onOpen: onOpen,
                min: me.minDate,
                max: me.maxDate
            });
        }

        this.picker = htmlPicker.pickadate('picker');
    },

    exit: function() {

        var subtitle = $('#title-sub').text();

        this.nextWeek = 0;
        this.prevWeek = 0;
        this.backProcessProceed = true;

        $('#title-sub').remove();
        $('#titleContainer').append('<p id="title-sub" class="truncate">' + subtitle + '</p>');

        $('#titleContainer').unbind('click');
        rwthapp.util.backButtonHook = undefined;
        rwthapp.util.orientationChangeHook = undefined;

        rwthapp.util.removeRightFeatureSpecificButtonFromNavbar("timetable-today");
    },

    scrollToRowByDate: function(dateToScrollTo, nonAnimated) {

        $('#title-sub').text(moment(dateToScrollTo).locale(rwthapp.localization.getCurrentLanguage()).format('MMMM') + " " + moment(dateToScrollTo).locale(rwthapp.localization.getCurrentLanguage()).format('YYYY'));

        // jump to selected day
        $('#timetable-scroll-content').scrollTop()

        var rows = $('#week_body').children(), height = 0, rowCounter = 0;

        while (new Date($(rows[rowCounter]).data('date')).toLocaleDateString() !== dateToScrollTo.toLocaleDateString() && rowCounter !== rows.length - 1) {

            height += $(rows[rowCounter]).height() + parseInt($(rows[rowCounter]).css("margin-top")) + parseInt($(rows[rowCounter]).css("margin-bottom"));
            rowCounter++;
        }

        height += $('#scroll-up-btn').height();

        $('#timetable-scroll-content').animate({ scrollTop: height }, nonAnimated ? 0 : 800);
    },

    registerScrollToFetchSpecificWeeks: function () {

        var me = this;

        $('#timetable-scroll-content').scroll(function (event) {

            event = $(event.currentTarget);

            var direction, count = 1, nextWeekStateBefore = me.nextWeek, prevWeekStateBefore = me.prevWeek;

            if (event[0].scrollHeight - event.scrollTop() - event.outerHeight() === 0)
            {
                rwthapp.logging.logger.debug("perform request on scroll down");

                direction = 'down';

                me.nextWeek++;
            }
            else if ($('#timetable-scroll-content').scrollTop() === 0) {

                rwthapp.logging.logger.debug("perform request on scroll up");

                direction = 'up';

                me.prevWeek--;
            }

            if (direction) {

                me.addNewAppointmentsToWeekBody(direction, count).then(function (data) {

                    if (data && data.error) {

                        rwthapp.logging.logger.debug("Infinite scrolling do not work properly.", data.error);

                        me.nextWeek = nextWeekStateBefore;
                        me.prevWeek = prevWeekStateBefore;
                    }
                });;
            }
        });
    },

    addNewAppointmentsToWeekBody: function (direction, count, pickedDate) {

        var up = false, markedRow = $('#week_body').children()[0], me = this, backupSubtitle = $('#title-sub').text(), restore = function () {

            if (!pickedDate) {

                $('#scroll-' + direction + '-btn').css("display", "block");
                $('#loading-' + direction).empty();
                $('#title-sub').text(backupSubtitle);
            }
            else {

                rwthapp.util.hideLoadingScreen();
            }

            me.registerScrollToFetchSpecificWeeks();
        };

        $('#timetable-scroll-content').unbind('scroll');

        if (!pickedDate) {

            $('#scroll-' + direction + '-btn').css("display", "none");
            rwthapp.util.showLoadingScreenInSpecificDiv($('#loading-' + direction), { color: 'blue' });
            $('#loading-' + direction).width($($('#loading-' + direction).children()[0]).width());
        }
        else {

            rwthapp.util.showLoadingScreen();
        }

        if (direction === 'down') {
            
            // sunday in every case
            var possibleLastDate = new Date($($('#week_body').children()[$('#week_body').children().length -1]).data('date'));

            possibleLastDate.setDate(possibleLastDate.getDate() + (7 * count));

            if (possibleLastDate.getTime() > this.maxDate.getTime()) {

                return Promise.resolve().then(function () {

                    restore();

                    rwthapp.notifications.showToast(rwthapp.langStrings.timetable.outOfRangeMax, 5000);

                    return { error: rwthapp.langStrings.timetable.outOfRangeMax };
                });
            }
        }
        else {

            var possibleFirstDate = new Date($($('#week_body').children()[0]).data('date'));

            possibleFirstDate.setDate(possibleFirstDate.getDate() - (7 * count));
            possibleFirstDate.setDate(possibleFirstDate.getDate() - (possibleFirstDate.getDay() === 0 ? -1 : possibleFirstDate.getDay() - 1));

            if (possibleFirstDate.getTime() < this.minDate.getTime()) {

                return Promise.resolve().then(function () {

                    restore();

                    rwthapp.notifications.showToast(rwthapp.langStrings.timetable.outOfRangeMin, 5000);

                    return { error: rwthapp.langStrings.timetable.outOfRangeMin };
                });
            }
        }

        return rwthapp.connection.api.campus.getTimetableWeeks(direction === 'down' ? this.nextWeek : this.prevWeek, count).then(function (timetableData) {

            if (timetableData) {

                var timetableHtmlAndAndDisplayDateFormat = me.getTimetableHtmlAndDisplayDateFormat(timetableData, pickedDate);

                $('#title-sub').text(timetableHtmlAndAndDisplayDateFormat.month + " " + timetableHtmlAndAndDisplayDateFormat.year);

                if (direction === 'down') {

                    $('#week_body').append(timetableHtmlAndAndDisplayDateFormat.html);
                }
                else if (direction === 'up') {

                    $('#week_body').prepend(timetableHtmlAndAndDisplayDateFormat.html);
                    $('#week_body')

                    up = true;
                }

                if ($('#timetable-content').height() - 100 > $(window).height()) {

                    $('#spacer').remove();
                }

                if (!pickedDate) {

                    $('#scroll-' + direction + '-btn').css("display", "block");
                    $('#loading-' + direction).empty();
                }
                else {

                    rwthapp.util.hideLoadingScreen();
                }

                if (up) {

                    me.scrollToRowByDate(new Date($(markedRow).data('date')), true);
                }
            }
            else {

                rwthapp.logging.logger.debug("No data has been submitted from timetable service.");
            }

            me.registerScrollToFetchSpecificWeeks();
        }).catch(function (error) {

            restore();

            return {
            
                error: error
            }
        });
    },

    fetchWeek: function (week) {

        var me = this;

        return new Promise(function (resolve, reject) {

            return rwthapp.connection.api.campus.getTimetableWeeks(week, 2).then(function (data) {

                resolve(me.getTimetableHtmlAndDisplayDateFormat(data));

            }).catch(function (e) {

                reject(e);
            });
        });

    },

    getTimetableHtmlAndDisplayDateFormat: function (timetableData, date) {

        var simpleDate;

        if (!date) {

            date = timetableData[0].date;
        }

        $.each(timetableData, function (index, timetableEntry) {

            if (!simpleDate || simpleDate !== timetableEntry.date) {

                timetableEntry.firstAppointmentOfDay = true;
                timetableEntry.day = timetableEntry.date.split("-")[2];
                timetableEntry.month = moment(new Date(timetableEntry.date)).locale(rwthapp.localization.getCurrentLanguage()).format('MMM');
                timetableEntry.w_day = moment(new Date(timetableEntry.date)).locale(rwthapp.localization.getCurrentLanguage()).format('ddd');
            }

            simpleDate = timetableEntry.date;
        });

        var html = rwthapp.templateRenderer.fetch("organisation.timetable.partial", { entries: timetableData });

        return { html: html, month: moment(date).locale(rwthapp.localization.getCurrentLanguage()).format('MMMM'), year: moment(date).locale(rwthapp.localization.getCurrentLanguage()).format('YYYY') };
    }
};