Source: utils.js

define('application/utils', [
    'rofl/lib/l10n',
    'rofl/lib/utils',
    'application/models/configuration',
    'antie/runtimecontext',
    'application/managers/feature',
    'application/managers/session',
    'application/constants'
], function (
    L10N,
    Utils,
    KPNConfig,
    RuntimeContext,
    FeatureManager,
    SessionManager,
    Constants
) {

    'use strict';

    var l10n = L10N.getInstance(),
        app;

    return {

        /**
         * Randomises an array.
         *
         * @param {Array} items - The items to randomise.
         * @returns {Array} - The items randomised.
         */
        randomiseArray: function (items) {
            var i,
                j,
                temp;

            for (i = items.length - 1; i > 0; i--) {
                j = Math.floor(Math.random() * (i + 1));
                temp = items[i];
                items[i] = items[j];
                items[j] = temp;
            }

            return items;
        },

        /**
         * Returns the subtitle.
         *
         * @param {Date} startTime - The start time.
         * @param {Date} endTime - The end time.
         * @param {number} duration - The duration.
         * @returns {string} - The subtitle string.
         * @private
         */
        getAssetDateSubtitle: function (startTime, endTime, duration) {
            var subtitle;

            subtitle = this.getDate(startTime, endTime);

            subtitle += ' | ' + Math.floor(duration / 60) + 'm';

            return subtitle;
        },

        /**
         * Returns the duration in hh:mm format ("Nu 1u 05m" | "1u" | "05m" | "15m").
         *
         * @param {Date} startTime - The start time.
         * @param {Date} endTime - The end time.
         * @param {number} duration - The duration.
         * @returns {string} - The subtitle string.
         * @private
         */
        getSearchAssetDateSubtitle: function (startTime, endTime, duration) {
            var subtitle;

            subtitle = this.getSearchDate(startTime, endTime);

            subtitle += ' ยท ' + Math.floor(duration / 60) + 'm';

            return subtitle;
        },

        /**
         * Returns the subtitle.
         *
         * @param {Date} startTime - The start time.
         * @param {Date} endTime - The end time.
         * @param {number} duration - The duration.
         * @returns {string} - The subtitle string.
         * @private
         */
        getRecordDateSubtitle: function (startTime, endTime, duration) {
            var now,
                subtitle;

            if (!app) {
                app = RuntimeContext.getCurrentApplication();
            }

            now = app.getDate();

            if (endTime >= now && startTime <= now) {

                // Program is live.
                subtitle = this._getRecordLiveDate(startTime);
            } else if (endTime > now && startTime > now) {

                // Program is in the future.
                subtitle = this._getFutureDate(startTime);
            } else {

                // Program is history.
                subtitle = this._getHistoryDate(startTime);
            }

            subtitle += ' | ' + Math.floor(duration / 60) + 'm';

            return subtitle;
        },

        /**
         * Returns the date display for the given start and end time.
         *
         * @param {Date} startTime - The start time.
         * @param {Date} endTime - The end time.
         * @param {boolean} withoutDay - Without day.
         * @returns {string} - The date format.
         * @private
         */
        getDate: function (startTime, endTime, withoutDay) {
            var now,
                subtitle;

            if (!app) {
                app = RuntimeContext.getCurrentApplication();
            }

            now = app.getDate();

            if (endTime >= now && startTime <= now) {

                // Program is live.
                subtitle = this._getLiveDate(startTime);
            } else if (endTime > now && startTime > now) {

                // Program is in the future.
                subtitle = this._getFutureDate(startTime);
            } else {

                // Program is history.
                subtitle = this._getHistoryDate(startTime, withoutDay);
            }

            return subtitle;
        },

        /**
         * Returns the future date.
         *
         * @param {Date} start - The start of the program.
         * @returns {string} - The future date string.
         * @private
         */
        _getFutureDate: function (start) {
            var date;

            if (!app) {
                app = RuntimeContext.getCurrentApplication();
            }

            date = app.getDate();

            if (date.format('Y-m-d') === start.format('Y-m-d')) {

                // This is today.
                return [
                    l10n.get('asset.today'),
                    start.format('H:i')
                ].join(' ');
            }

            date = app.getDate();
            date.setDate(date.getDate() + 1);

            if (date.format('Y-m-d') === start.format('Y-m-d')) {

                // This is yesterday.
                return [
                    l10n.get('asset.tomorrow'),
                    start.format('H:i')
                ].join(' ');
            }

            return [
                l10n.get('asset.days.' + start.getDay()),
                start.getDate(),
                l10n.get('asset.months.' + start.getMonth()),
                start.format('H:i')
            ].join(' ');
        },

        /**
         * Returns the live date.
         *
         * @param {Date} start - The start of the program.
         * @returns {string} - The live date string.
         * @private
         */
        _getLiveDate: function (start) {
            var date = l10n.get('asset.now');

            date += ' ' + start.format('H:i');

            return date;
        },

        /**
         * Returns the live record date.
         *
         * @param {Date} start - The start of the program.
         * @returns {string} - The live date string.
         * @private
         */
        _getRecordLiveDate: function (start) {
            var date = l10n.get('asset.today');

            date += ' ' + start.format('H:i');

            return date;
        },

        /**
         * Returns the history date.
         *
         * @param {Date} start - The start of the program.
         * @param {boolean} withoutDay - Without day.
         * @returns {string} - The history date string.
         * @private
         */
        _getHistoryDate: function (start, withoutDay) {
            var date,
                time;

            if (!app) {
                app = RuntimeContext.getCurrentApplication();
            }

            date = app.getDate();

            if (date.format('Y-m-d') === start.format('Y-m-d')) {

                time = Math.floor(((date - start) / 1000) / 60);

                // We are at full hours now.
                if (time > 60) {
                    time = Math.floor(time / 60) + l10n.get('asset.time.hours');
                } else {
                    time += l10n.get('asset.time.minutes');
                }

                // This is today.
                return [
                    time,
                    l10n.get('asset.passed')
                ].join(' ');
            }

            date = app.getDate();
            date.setDate(date.getDate() - 1);

            if (date.format('Y-m-d') === start.format('Y-m-d')) {

                // This is yesterday.
                return [
                    l10n.get('asset.yesterday'),
                    start.format('H:i')
                ].join(' ');
            }

            if (withoutDay) {
                return [
                    start.getDate(),
                    l10n.get('asset.months.' + start.getMonth()),
                    start.format('H:i')
                ].join(' ');
            }
            return [
                l10n.get('asset.days.' + start.getDay()),
                start.getDate(),
                l10n.get('asset.months.' + start.getMonth()),
                start.format('H:i')
            ].join(' ');
        },

        /**
         * Returns the stream date.
         *
         * @param {Date} startTime - The start time.
         * @param {Date} endTime - The end time.
         * @returns {string} - The getStreamDate string.
         * @private
         */
        getStreamDate: function (startTime, endTime) {
            var now,
                subtitle;

            if (!app) {
                app = RuntimeContext.getCurrentApplication();
            }

            now = app.getDate();

            if (endTime >= now && startTime <= now) {

                // Program is live.
                subtitle = this._getLiveDate(startTime);
            } else if (endTime > now && startTime > now) {

                // Program is in the future.
                subtitle = this._getFutureDate(startTime);
            } else {

                // Program is history.
                subtitle = this._getHistoryDate(startTime);
            }

            return subtitle;
        },

        /**
         * Returns the subtitle.
         *
         * @param {Object} startTime - The start time.
         * @param {Object} duration - The duration.
         * @returns {string} - The subtitle string.
         * @private
         */
        getAssetGuideSubtitle: function (startTime, duration) {
            var subtitle;

            subtitle = startTime.format('H:i');

            if (Utils.isUndefined(subtitle)) {
                subtitle = '-:--';
            }

            subtitle += ' | ' + Math.floor(duration / 60) + 'm';

            return subtitle;
        },

        /**
         * Checks if number is an integer.
         *
         * @param {number} n - Number.
         * @returns {boolean} - True or false.
         */
        isInt: function (n) {
            return n % 1 === 0;
        },

        /**
         * Checks time to midnight.
         *
         * @returns {number} - Hours left to midnight.
         */
        hrsToMidnight: function () {
            var now = app.getDate(),
                then = new Date(now);

            then.setDate(now.getDate() + 1);
            then.setHours(1, 59, 59, 59);

            return ((then - now) / 1000);
        },

        /**
         * Format time into human readable format.
         *
         * @param {Integer} seconds - The amount of seconds you want to convert.
         *
         * @returns {string} - Hours left to midnight.
         */
        secondsHumanReadable: function (seconds) {
            var durationHours = Math.floor(seconds / 60 / 60),
                durationMinutes = Math.floor(seconds / 60) - (durationHours * 60);

            return {
                h: durationHours,
                m: durationMinutes
            };
        },

        /**
         * Format time into human readable format.
         *
         * @param {Integer} seconds - The amount of seconds you want to convert.
         *
         * @returns {string} - Hours left to midnight.
         */
        secondsHumanReadableString: function (seconds) {
            var time = this.secondsHumanReadable(seconds),
                hours = time.h,
                minutes = time.m;

            if (hours === 0) {
                return minutes + 'm';
            }

            if (minutes === 0) {
                return hours + 'u';
            }

            return hours + 'u ' + minutes + 'm';
        },

        /**
         * Returns the stream time.
         *
         * @param {Date} startTime - The start time.
         * @returns {string} - The stream time.
         */
        getStreamTime: function (startTime) {
            return startTime.format('H:i');
        },

        /**
         * Delay the execution of a function.
         *
         * @param {Object} f - Reference to the function you want to delay.
         * @param {Integer} duration - The amount of time you with to delay. In milliseconds.
         * @param {Object} ctx - Context to apply.
         * @returns {Object} - Function closure with setTimeout.
         */
        delay: function (f, duration, ctx) {
            return function () {
                setTimeout(f.bind(ctx || this), duration);
            };
        },

        /**
         * Returns true if the broadcast is locked.
         *
         * @param {Object} broadcast - The broadcast.
         * @returns {boolean} - True if the broadcast is locked.
         */
        isBroadcastLocked: function (broadcast) {
            var parentalControlParams = SessionManager.getInstance().getUserPCParams(),
                parentalControlOn = SessionManager.getInstance().isParentalOn(),
                parentalControlLevel = parseInt(Utils.getNested(parentalControlParams, 'parentalControlLevel')),
                parentalControlGenres = Utils.getNested(parentalControlParams, 'parentalGenres'),
                i,
                isGenreProtected = function () {
                    if (parentalControlGenres.length) {
                        for (i = 0; i < parentalControlGenres.length; i++) {
                            if (broadcast.getParentalGenres().indexOf(parentalControlGenres[i]) > -1) {
                                return true;
                            }
                        }
                    }
                    return false;
                },
                isLocked = false,
                VODContentTypes = ['VOD', 'GROUP_OF_BUNDLES', 'BUNDLE'];

            if (VODContentTypes.indexOf(broadcast.getContentType()) >= 0) {
                parentalControlLevel = parseInt(Utils.getNested(parentalControlParams, 'parentalVODControlLevel'));
            }

            if (!FeatureManager.getInstance().isParentalEnabled() || !parentalControlOn || !broadcast) {
                isLocked = false;
            } else {
                isLocked = !(parentalControlLevel >= broadcast.getPCLevel()) || isGenreProtected();
            }

            return isLocked;
        },

        /**
         * Returns true if the locked title should be shown.
         *
         * @returns {boolean} - True if the locked title should be shown.
         */
        showLockedTitle: function () {
            return Utils.getNested(SessionManager.getInstance().getUserPCParams(), 'showLockedTitles');
        },

        /**
         * Returns the duration in hh mm ("1u 5m" | "1u" | "5m").
         *
         * @param {number} duration - The content's duration (seconds).
         * @returns {string} - The formatted duration text for the asset.
         * @private
         */
        getHourMinutesText: function (duration) {
            var hours,
                minutes,
                durationText = '';

            hours = Math.floor(duration / 3600);
            duration = duration - hours * 3600;
            minutes = Math.floor(duration / 60);

            if (hours) {
                durationText += hours + l10n.get('hours') + ' ';
            }

            if (minutes) {
                if (minutes < 10) {
                    durationText += '0';
                }

                durationText += minutes + l10n.get('minutes');
            }

            return durationText;
        },

        /**
         * Check if there is an asset in the params.
         *
         * @param {Object} params - The _prepareMediaSource params.
         * @param {Object} data - The userdata response data.
         * @returns {Object} - The updated _prepareMediaSource params.
         *
         * @private
         */
        checkForEmptyAsset: function (params, data) {
            var containers,
                assets,
                assetId,
                i;

            if (Utils.isUndefined(params._assetId)) {
                containers = Utils.getNested(data, 'resultObj', 'containers');

                if (!Utils.isUndefined(containers) && containers.length) {
                    assets = Utils.getNested(containers[0], 'entitlement', 'assets');

                    if (!Utils.isUndefined(assets) && assets.length) {

                        for (i = 0; i < assets.length; i++) {

                            if (assets[i].assetType === 'MASTER') {

                                if (assets[i].programType === 'CUTV') {
                                    assetId = assets[i].assetId;
                                    break;
                                }
                            }
                        }

                        if (!Utils.isEmpty(assetId)) {
                            params._assetId = assetId;
                        }
                    }
                }
            }

            return params;
        },

        /**
         * Returns the content video type for the given content type and subtype.
         *
         * @param {string} contentType - Content's type.
         * @param {string} contentSubtype - Content's subtype.
         *
         * @returns {string} - The content's video type.
         */
        getContentVideoType: function (contentType, contentSubtype) {
            switch (contentType) {
                case Constants.EPG_CONTENT_TYPE:

                    // Live / Startover.
                    if (contentSubtype === Constants.EPG_CONTENT_SUBTYPE) {
                        return Constants.LIVE_VIDEO_TYPE;
                    }

                    // Catchup.
                    if (contentSubtype === Constants.CATCHUP_CONTENT_SUBTYPE ||
                        contentSubtype === Constants.CATCHUP_EPISODE_CONTENT_SUBTYPE) {
                        return Constants.CATCHUP_VIDEO_TYPE;
                    }
                    break;

                case Constants.MOVIE_CONTENT_TYPE:

                    // VOD Movie.
                    if (contentSubtype === Constants.MOVIE_CONTENT_SUBTYPE) {
                        return Constants.VOD_MOVIE_VIDEO_TYPE;
                    }

                    // VOD Series Episode.
                    if (contentSubtype === Constants.SERIES_EPISODE_CONTENT_SUBTYPE) {
                        return Constants.VOD_EPISODE_VIDEO_TYPE;
                    }

                    break;

                case Constants.RECORDING_CONTENT_TYPE:

                    // Recordings.
                    if (contentSubtype === Constants.RECORDING_CONTENT_SUBTYPE) {
                        return Constants.RECORDING_EPISODE_VIDEO_TYPE;
                    }

                    break;
            }
        },

        /**
         * Gets the analytics type for the given video type.
         *
         * @param {string} videoType - The video type for the analytics.
         * @returns {string} - The event label type.
         */
        getAnalyticsEventLabel: function (videoType) {
            switch (videoType) {
                case Constants.LIVE_VIDEO_TYPE:
                    return Constants.ANALYTICS_EVENT_LABEL_TYPE_LIVETV;

                case Constants.RESTART_VIDEO_TYPE:
                    return Constants.ANALYTICS_EVENT_LABEL_TYPE_RESTART;

                case Constants.VOD_MOVIE_VIDEO_TYPE:
                case Constants.VOD_EPISODE_VIDEO_TYPE:
                    return Constants.ANALYTICS_EVENT_LABEL_TYPE_VOD;

                case Constants.CATCHUP_VIDEO_TYPE:
                    return Constants.ANALYTICS_EVENT_LABEL_TYPE_CATCHUP;

                case Constants.RECORDING_EPISODE_VIDEO_TYPE:
                    return Constants.ANALYTICS_EVENT_LABEL_TYPE_RECORDING;

                case Constants.PROMO_VIDEO_TYPE:
                    break;
            }
        }
    };
});