Source: widgets/player/zappbanner.js

define('application/widgets/player/zappbanner', [
    'rofl/widgets/container',
    'rofl/widgets/label',
    'application/widgets/player/progress',
    'rofl/widgets/image',
    'application/managers/channel',
    'application/utils',
    'rofl/lib/l10n',
    'application/managers/player',
    'application/constants'
], function (
    Container,
    Label,
    Progress,
    Image,
    ChannelManager,
    AppUtils,
    L10n,
    PlayerManager,
    Constants
) {
    'use strict';

    var channelManager = ChannelManager.getInstance(),
        printTime = function (string, pad, length) {
            return (new Array(length + 1).join(pad) + string).slice(-length);
        },
        formatTime = function (secs, setHours) {
            var hours,
                minutes,
                minuteDivisor,
                secondDivisor,
                seconds,
                formatted = '';

            secs = Math.round(secs);
            hours = Math.floor(secs / (60 * 60));
            hours = !hours && setHours ? '0' : hours;

            minuteDivisor = secs % (60 * 60);
            minutes = Math.floor(minuteDivisor / 60);

            secondDivisor = minuteDivisor % 60;
            seconds = Math.ceil(secondDivisor);

            if (hours) {
                formatted = hours + ':';
            }

            return formatted +
                printTime(minutes, '0', 2) + ':' +
                printTime(seconds, '0', 2);
        },
        l10n = L10n.getInstance(),
        ZappBanner,
        CONTENT_SUBTYPE_VOD = 'VOD',
        CONTENT_SUBTYPE_EPISODE = 'EPISODE';

    ZappBanner = Container.extend({

        /**
         * Initialises the ZappBanner widget.
         */
        init: function init () {
            init.base.call(this, 'zappbanner');

            this.addClass('zappbanner');
            this._build();
        },

        /**
         * Builds the ZappBanner widget.
         *
         * @private
         */
        _build: function () {
            var displayContainer = this._displayContainer = new Container(),
                progress = this._progress = new Progress();

            displayContainer.addClass('display');

            this._buildProgramInfo();

            displayContainer.appendChildWidget(progress);
            this.appendChildWidget(displayContainer);
        },

        /**
         * Builds the program info.
         *
         * @private
         */
        _buildProgramInfo: function () {
            var logo = this._logo = new Image(null, ''),
                topText = this._topText = new Label({ text: '', classNames: ['toptext'] }),
                programTitle = this._programTitle = new Label({ text: '', classNames: ['programtitle'] }),
                subTitle = this._subTitle = new Label({ text: '', classNames: ['subtitle'] }),
                titleContainer = new Container(),
                infoContainer = new Container('info'),
                channelInfo = infoContainer.appendChildWidget(new Container('channel-info')),
                contentInfo = infoContainer.appendChildWidget(new Container('content-info'));

            infoContainer.addClass('info');
            channelInfo.addClass('channel-info');
            contentInfo.addClass('content-info');
            logo.addClass('logo');
            titleContainer.addClass('title');

            titleContainer.appendChildWidget(programTitle);
            titleContainer.appendChildWidget(subTitle);

            channelInfo.appendChildWidget(topText);
            channelInfo.appendChildWidget(logo);
            contentInfo.appendChildWidget(titleContainer);

            // Append these to the display container for alignment.
            this._displayContainer.appendChildWidget(infoContainer);
        },

        /**
         * Sets the program details.
         *
         * @param {Object} program - The program.
         */
        setProgram: function (program) {
            var contentType = program.getContentType(),
                contentSubtype = program.getContentSubtype(),
                contentVideoType = AppUtils.getContentVideoType(contentType, contentSubtype);

            PlayerManager.setProgram(program, contentVideoType);
            this._progress.setMaxPointerPosition();

            switch (contentVideoType) {
                case Constants.LIVE_VIDEO_TYPE:
                case Constants.RESTART_VIDEO_TYPE:
                    this._setLiveProgram(program);
                    break;

                case Constants.VOD_MOVIE_VIDEO_TYPE:
                case Constants.VOD_EPISODE_VIDEO_TYPE:
                    this._setVODMovie(program);
                    break;

                case Constants.RECORDING_EPISODE_VIDEO_TYPE:
                case Constants.CATCHUP_VIDEO_TYPE:
                    this._setVODProgram(program);
                    break;

                case Constants.PROMO_VIDEO_TYPE:
                    this._setPromo(program);
                    break;

                default:
                    this._setVODMovie(program);
            }
        },

        /**
         * Sets the live program.
         *
         * @param {Object} program - The program data.
         */
        _setLiveProgram: function (program) {
            var channel = program.getChannel(),
                progressBar = this._progress,
                isLocked = AppUtils.isBroadcastLocked(program);

            this.setChannelInfo(channel);
            this.setProgramTitle(isLocked ? l10n.get('asset.locked') : program.getTitle());
            this.setSubtitle((new Date(program.getStartTime() * 1000)).format('H:i') + ' | ' + AppUtils.secondsHumanReadableString(program.getDuration()));

            progressBar.setIsLive(true);
        },

        /**
         * Sets the channel info.
         *
         * @param {Object} channel - The channel's data.
         * @private
         */
        setChannelInfo: function (channel) {
            this.setLogo(channel.getImage());
            this.setTopText(channel.getNumber());
        },

        /**
         * Sets the VOD program.
         *
         * @param {Object} program - The program data.
         */
        _setVODProgram: function (program) {
            var progressBar = this._progress,
                time = new Date(program.getStartTime() * 1000),
                channel,
                channelNumber,
                date;

                date = [
                    l10n.get('asset.days.' + time.getDay()),
                    time.getDate(),
                    l10n.get('asset.monthsLong.' + time.getMonth()),
                    time.format('H:i')
                ].join(' ');

            if (program.getChannelId()) {
                channel = channelManager.getChannelById(program.getChannelId());
                channelNumber = channel.getNumber();
                this.setLogo(channel.getImage());
            }
            this.setTopText(channelNumber);
            this.setProgramTitle(program.getTitle());
            this.setSubtitle(date);

            progressBar.setIsLive(false);
        },

        /**
         * Sets the VOD program.
         *
         * @param {Object} program - The program data.
         */
        _setVODMovie: function (program) {
            var progressBar = this._progress,
                duration = AppUtils.secondsHumanReadableString(program.getDuration()),
                title,
                subtitle;

            switch (program.getContentSubtype()) {
                case CONTENT_SUBTYPE_VOD:
                    title = program.getTitle();
                    subtitle = l10n.get('player.display.vod.subtitle', {
                        year: program.getYear(),
                        duration: duration
                    });
                    break;
                case CONTENT_SUBTYPE_EPISODE:
                    title = program.getSeriesTitle();
                    subtitle = program.getTitle() || l10n.get('player.display.series.episodeFallback', {
                        episodeNumber: program.getEpisodeNumber()
                    });
                    subtitle = l10n.get('player.display.series.subtitle', {
                        season: program.getSeason(),
                        episode: subtitle,
                        duration: duration
                    });
                    break;

                    // no default
            }

            this.setLogo('');
            this.setTopText('');
            this.setProgramTitle(title);
            this.setSubtitle(subtitle);

            progressBar.setIsVodMovie(true);
        },

        /**
         * Sets the Promo video.
         *
         * @param {Object} program - The program data.
         */
        _setPromo: function (program) {
            var progressBar = this._progress;

            this.setLogo('');
            this.setTopText('');
            this.setSubtitle('');
            this.setProgramTitle(program.getTitle());

            progressBar.setIsLive(false);
        },

        /**
         * Sets the logo.
         *
         * @param {string} image - The image url.
         */
        setLogo: function (image) {

            if (!image) {
                this.addClass('no-logo');
            } else {
                this.removeClass('no-logo');
            }

            this._logo.setSrc(image);
        },

        /**
         * Sets the top text.
         *
         * @param {string} text - The top text.
         */
        setTopText: function (text) {
            this._topText.setText(text || '');
        },

        /**
         * Sets the program title.
         *
         * @param {string} text - The text to set.
         */
        setProgramTitle: function (text) {
            this._programTitle.setText(text || '');
        },

        /**
         * Sets the sub title text.
         *
         * @param {string} text - The text.
         */
        setSubtitle: function (text) {
            this._subTitle.setText(text || '');
        },

        /**
         * Sets the video progress.
         *
         * @param {Object} progress - The video progress.
         * @param {number} progress.head - The current progress in percentages.
         */
        setLiveProgress: function (progress) {
            var formatter = formatTime,
                elapsed = progress.elapsedTime,
                remaining = progress.remainingTime,
                elapsedTime = formatter(elapsed, elapsed >= 3600), // 1 hour or more.
                remainingTime = formatter(remaining, remaining >= 3600); // 1 hour or more.

            // We are at behind the head of the stream.
            if (progress.behind < 0) {

                if (progress.head > 100) {
                    progress.head = 100;
                }

                this._progress.setProgress(progress.secondHead);
                this._progress.setPauseTime({
                    position: progress.head,
                    behind: this._getMinutesBehind(progress.behind)
                });
            } else {

                // We are at the head of the stream.
                this._progress.setProgress(progress.head);
                this._progress.resetPause();
            }

            this._progress.setStartTime(elapsedTime);
            this._progress.setEndTime(remainingTime);
        },

        /**
         * Sets the VOD progress.
         *
         * @param {Object} data - The video progress.
         */
        setVODProgress: function (data) {
            var progress = this._progress,
                percentage = data.percentage,
                currentTime = data.currentTime,
                duration = data.duration,
                setHours = currentTime >= 3600, // 1 hour or more.
                formatter = formatTime;

            progress.setProgress(percentage);
            progress.setStartTime(formatter(currentTime, setHours));
            progress.setEndTime(formatter(duration));
        },

        /**
         * Returns the minutes the stream is behind head.
         *
         * @param {number} time - The time behind head. Negative value.
         * @returns {string} - The minutes and seconds behind head. mm:ss format.
         * @private
         */
        _getMinutesBehind: function (time) {
            var minutes,
                seconds;

            time = Math.abs(time); // Time is a negative value.


            minutes = Math.floor(time / 60000);
            seconds = ((time % 60000) / 1000).toFixed(0);

            return minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
        },

        /**
         * Removes the label text and pointer starts from 0.
         */
        resetPauseLabel: function () {
            this._progress.resetPause();
        },

        /**
         * Sets the trickplay settings.
         */
        setTrickplaySettings: function () {
            this._progress.setMaxPointerPosition();
        },

        /**
         * Returns the progressbar.
         *
         * @returns {Object} - The progressbar.
         */
        getProgress: function () {
            return this._progress;
        }

    });

    return ZappBanner;
});