Source: widgets/detail/header.js

define('application/widgets/detail/header', [
    'rofl/widgets/container',
    'rofl/widgets/label',
    'rofl/widgets/image',
    'rofl/widgets/horizontallist',
    'application/widgets/detail/iconbutton',
    'application/widgets/detail/progress',
    'rofl/widgets/verticallist',
    'rofl/lib/utils',
    'application/utils',
    'antie/runtimecontext',
    'application/widgets/detail/buttons/play',
    'application/widgets/detail/buttons/record',
    'application/widgets/detail/buttons/close',
    'application/widgets/detail/buttons/restart',
    'application/widgets/detail/buttons/delete',
    'application/managers/recording',
    'application/managers/feature',
    'application/models/production/series',
    'rofl/lib/l10n',
    'application/models/production/recordings/record',
    'application/events/recorddeletedevent'
], function (
    Container,
    Label,
    Image,
    HorizontalList,
    IconButton,
    Progress,
    VerticalList,
    Utils,
    AppUtils,
    RuntimeContext,
    PlayButton,
    RecordButton,
    CloseButton,
    RestartButton,
    DeleteButton,
    RecordingManager,
    FeatureManager,
    Series,
    L10N,
    Record,
    RecordDeletedEvent
) {
    'use strict';

    var VIDEO_RATINGS = {
            G: 'icon-kijkwijzer-geweld-v2', // Geweld
            A: 'icon-kijkwijzer-eng-v2', // Fear
            S: 'icon-kijkwijzer-sex-v2', // Sex
            D: 'icon-kijkwijzer-pesten-v2', // Discrimination
            H: 'icon-kijkwijzer-drugs-v2', // Drugs or Alcohol use
            T: 'icon-kijkwijzer-taal-v2', // Violent language,
            'PC-6': 'icon-kijkwijzer-6-v2',
            'PC-12': 'icon-kijkwijzer-12-v2',
            'PC-16': 'icon-kijkwijzer-16-v2',
            'PC-99': 'icon-kijkwijzer-al-v2'
        },
        application = RuntimeContext.getCurrentApplication(),
        recordingManager = RecordingManager.getInstance(),
        layoutObject = application.getLayout(),
        layout = layoutObject.detailsHeader,
        featureManager = FeatureManager.getInstance(),
        l10n = L10N.getInstance(),
        TYPES = {
            LIVE: 'LIVE',
            VOD: 'VOD',
            RESTART: 'RESTART',
            PROGRAM: 'PROGRAM',
            RECORDING: 'RECORDING'
        };

    return Container.extend({

        /**
         * Initialises the input widget.
         */
        init: function init () {
            init.base.call(this);

            this.addClass('details-page-header');
            this._build();
        },

        /**
         * Builds the widget.
         */
        _build: function () {
            this._buildBackImage();
            this._buildGradient();
            this._buildRowsList();
            this._buildFirstRow();
            this._buildChannelLogo();
            this._buildSubtitle();
            this._buildSecondRow();
            this._buildTitle();
            this._buildDuration();
            this._buildDescription();
            this._buildVideoRatings();
            this._buildButtonsList();
            this._buildProgressBar();
            this._buildContentMessage();
        },

        /**
         * Builds the back image.
         *
         * @private
         */
        _buildBackImage: function () {
            var backimg = this._backimg = new Image();

            backimg.addClass('back-image');

            this.appendChildWidget(backimg);
        },

        /**
         * Builds the gradient.
         *
         * @private
         */
        _buildGradient: function () {
            var gradient = this._gradient = new Container();

            gradient.addClass('gradient');

            this.appendChildWidget(gradient);
        },

        /**
         * Builds the list for rows.
         */
        _buildRowsList: function () {
            var rowsList = this._rowslist = new VerticalList();

            rowsList.addClass('rowslist');
            this.appendChildWidget(rowsList);
        },

        /**
         * Builds the container for logo and subtitle.
         */
        _buildFirstRow: function () {
            var firstrow = this._firstrow = new Container();

            firstrow.addClass('first-row');

            this._rowslist.appendChildWidget(firstrow);
        },

        /**
         * Builds the logo.
         */
        _buildChannelLogo: function () {
            var logo = this._logo = new Image('');

            logo.addClass('channel-logo');

            this._firstrow.appendChildWidget(logo);
        },

        /**
         * Builds the subtitle.
         *
         * @private
         */
        _buildSubtitle: function () {
            var subtitle = this._subtitle = new Label({ classNames: ['subtitle'] });

            this._firstrow.appendChildWidget(subtitle);
        },

        /**
         * Builds the container for title and duration.
         */
        _buildSecondRow: function () {
            var secondrow = this._secondrow = new Container();

            secondrow.addClass('second-row');

            this._rowslist.appendChildWidget(secondrow);
        },

        /**
         * Builds the title.
         */
        _buildTitle: function () {
            var title = this._title = new Label({ text: '', classNames: ['detail-header-title', 'title'] });

            title.setWidth(layout.titleWidget);
            title.setMaximumLines(2);
            title.setTruncationMode(Label.TRUNCATION_MODE_RIGHT_ELLIPSIS);
            this._secondrow.appendChildWidget(title);
        },

        /**
         * Builds the duratio.
         */
        _buildDuration: function () {
            var duration = this._duration = new Label({ classNames: ['duration'] });

            this._secondrow.appendChildWidget(duration);
        },

        /**
         * Builds the description.
         */
        _buildDescription: function () {
            var description = this._description = new Label({ text: '', classNames: ['detail-header-description', 'description'] });

            description.setWidth(layout.titleWidget);
            description.setMaximumLines(5);
            description.setTruncationMode(Label.TRUNCATION_MODE_RIGHT_ELLIPSIS);

            this._rowslist.appendChildWidget(description);
        },

        /**
         * Builds the icons list.
         */
        _buildVideoRatings: function () {
            var videoRatings = this._videoRatings = new Container();

            videoRatings.addClass('video-ratings');

            this._rowslist.appendChildWidget(videoRatings);
        },

        /**
         * Builds the buttons list.
         */
        _buildButtonsList: function () {
            var list = this._buttonList = new HorizontalList('');

            list.addClass('buttons-list');
            list.focus();

            this._rowslist.appendChildWidget(list);
        },

        /**
         * Builds the progressbar.
         */
        _buildProgressBar: function () {
            var progressBar = this._progressBar = new Progress();

            progressBar.setIsLive(true);

            this.appendChildWidget(progressBar);
        },

        /**
         * Builds the container for forbidden playback message.
         */
        _buildContentMessage: function () {
            var headerMessages = this._headerMessages = new Container();

            headerMessages.addClass('header-messages');
            this.appendChildWidget(headerMessages);
        },

        /**
         * Builds the replay state.
         *
         * @param {Object} data - The data item.
         * @private
         */
        _buildReplayState: function (data) {

            if (data instanceof Series) {
                return;
            }

            if (!featureManager.isReplayEnabled() && data.isReplayItem()) {
                this._headerMessages.appendChildWidget(this._createReplayMessage());
            } else if (data.isReplayItem() && !data.canCatchup() && !data.isRecording()) {
                this._headerMessages.appendChildWidget(this._createUnablePlayIcon());
                this._headerMessages.appendChildWidget(this._createForbiddenReplayMessage());
            }
        },

        /**
         * Sets data props to elements.
         *
         * @param {Object} data - Data.
         */
        setData: function (data) {
            var startTime = new Date(data.getStartTime() * 1000),
                endTime = new Date(data.getEndTime() * 1000),
                percentage = this._getPercentage(startTime, endTime),
                headerLayout = layout.image;

            if (Utils.isFunction(data.getImageUrl)) {
                this.setBackground(
                    data.getImageUrl(Math.round(headerLayout.width) + 'x' + Math.round(headerLayout.height)));
            } else {
                this.setBackground(data.getImage('manual', headerLayout));
            }

            if (Utils.isFunction(data.getChannelLogo)) {
                this.setLogo(data.getChannelLogo());
            } else {
                this.setLogo(this._getLogo(data));
            }

            this.setTitle(data.getTitle());
            this.setDuration(data.getDuration());
            this.setSubtitle(startTime, endTime);

            this.setDescription(data);

            // Set the age rating and content ratings.
            this.setVideoRatings([data.getAgeRating()]);
            this.setVideoRatings(data.getVideoRatings());

            if (0 > percentage < 100) {
                if (this._progressBar.isRendered()) {
                    this._progressBar.hide();
                }
            } else {
                this.setProgressBar(startTime, endTime);
            }
        },

        /**
         * Sets the series data.
         *
         * @param {Object} data - The data.
         * @private
         */
        setSeriesData: function (data) {
            var startTime = new Date(data.getStartTime() * 1000),
                endTime = new Date(data.getEndTime() * 1000),
                headerLayout = layout.image,
                item = data;

            this.setBackground(data.getImageUrl(Math.round(headerLayout.width) + 'x' + Math.round(headerLayout.height)));
            this.setLogo(data.getChannelLogo());

            this.setTitle(data.getTitle());
            this.setDuration(item.getDuration());
            this.setVideoRatings([item.getAgeRating()]);
            this.setVideoRatings(item.getVideoRatings());
            this.setDescription(item);
            this.setSubtitle(startTime, endTime);

            this._progressBar.hide({skipAnim: true});
        },

        /**
         * Returns the subtitle.
         *
         * @param {Object} data - The item.
         * @returns {string} - The subtitle string.
         * @private
         */
        _getSubtitle: function (data) {
            var duration = data.getDuration(),
                subtitle;

            subtitle = new Date(data.getStartTime() * 1000).format('H:i')
                + ' | ' + Math.floor(duration / 60) + 'm';

            return subtitle;
        },

        /**
         * Returns the logo.
         *
         * @param {Object} data - The item.
         * @returns {string} - The logo url.
         * @private
         */
        _getLogo: function (data) {
            return data.getChannel().getImage('128');
        },

        /**
         * Sets the background image.
         *
         * @param {string} url - Url.
         */
        setBackground: function (url) {
            this._backimg.setSrc(url);
        },

        /**
         * Sets the logo.
         *
         * @param {string} url - The url.
         */
        setLogo: function (url) {
            this._logo.setSrc(url);
        },

        /**
         * Sets the title.
         *
         * @param {string} title - The title.
         */
        setTitle: function (title) {
            this._title.setText(title);
        },

        /**
         * Sets the duration.
         *
         * @param {number} duration - The duration.
         */
        setDuration: function (duration) {
            this._duration.setText(Math.floor(duration / 60) + 'm');
        },

        /**
         * Sets the description.
         *
         * @param {Object} data - The data.
         */
        setDescription: function (data) {
            var genre = data.getProgramType(),
                description = '';

            if (genre) {
                description = genre + ' - ';
            }

            description += data.getDescription();

            this._description.setText(description);
        },

        /**
         * Sets the subtitle.
         *
         * @param {Date} startTime - The startTime.
         * @param {Date} endTime - The endTime.
         */
        setSubtitle: function (startTime, endTime) {
            this._subtitle.setText(AppUtils.getStreamDate(startTime, endTime));
        },

        /**
         * Sets the video ratings.
         *
         * @param {Array} ratings - The video ratings.
         */
        setVideoRatings: function (ratings) {
            var list = this._videoRatings;

            Utils.each(ratings, function (rating) {
                list.appendChildWidget(this._createVideoRating(rating));
            }, this);
        },

        /**
         * Creates a video rating label.
         *
         * @param {string} rating - The rating.
         * @returns {Object} - The video rating label.
         * @private
         */
        _createVideoRating: function (rating) {
            var videoRating = new Label({ text: '', classNames: [VIDEO_RATINGS[rating]] });

            return videoRating;
        },

        /**
         * Returns the progressBar percentage.
         *
         * @param {Date} startTime - The startTime.
         * @param {Date} endTime - The end time.
         * @returns {number} - The percentage.
         * @private
         */
        _getPercentage: function (startTime, endTime) {
            var now = application.getDate(),
                percentage,
                allTime,
                passedTime;

            allTime = endTime - startTime;
            passedTime = now - startTime;
            percentage = Math.round((passedTime * 100) / allTime);

            return percentage;
        },

        /**
         * Sets the progress.
         *
         * @param {Date} startTime - The startTime.
         * @param {Date} endTime - The end time.
         */
        setProgressBar: function (startTime, endTime) {
            var percentage = this._getPercentage(startTime, endTime);

            this._progressBar.setProgress(percentage);
        },

        /**
         * Sets the data item.
         *
         * @param {Object} item - The item.
         * @param {Object} seriesItem - The series item.
         */
        setDataItem: function setDataItem (item, seriesItem) {
            setDataItem.base.call(this, item);
            this._buttonList.removeChildWidgets();
            this._addButtons(seriesItem || item);
            this._buildReplayState(item);
        },

        /**
         * Adds the buttons.
         *
         * @param {Object} item - The item.
         * @private
         */
        _addButtons: function (item) {
            var isRecording,
                isFutureBroadcast,
                isFutureRecordable,
                isScheduledRecording,
                assets;

            if (!(item instanceof Series || !item.hasChannelRights())) {

                isFutureBroadcast = !item.isLive() && item.getStartTime() >= application.getDate() / 1000;
                isFutureRecordable = isFutureBroadcast && item.canRecord();
                isScheduledRecording = isFutureBroadcast && item.getContentType() === 'RECORDING';

                if (item.isLive()) {

                    if (item instanceof Record || item.getContentType() === 'RECORDING') {

                        this._addPlayButton();

                        if (item.getStartTime() <= application.getDate() / 1000) {
                            this._addDeleteButton();
                        } else {
                            this._addRecordButton();
                        }
                    } else {
                        this._addPlayButton();
                        this._addRestartButton();

                        if (item.canRecord()) {
                            this._addRecordButton();
                        }
                    }
                } else if (item.canPlay() && featureManager.isReplayEnabled() && item.isPlayable() && item.getAssetId() !== undefined) {
                    this._addPlayButton();

                    if ((item instanceof Record || item.getContentType() === 'RECORDING')
                        && item.getStartTime() <= application.getDate() / 1000) {
                        this._addDeleteButton();
                    }

                } else {

                    isRecording = (item instanceof Record || item.getContentType() === 'RECORDING')
                          && item.getStartTime() <= application.getDate() / 1000;

                    if (isRecording) {
                        this._addDeleteButton();
                    }

                    if (isRecording) {
                        assets = item.getAssets();

                        if (assets[0] && assets[0].status && assets[0].status === 'RecordSuccess') {

                            // recording item that cannot be played - show message
                            this._headerMessages.appendChildWidget(this._createUnablePlayIcon('more-to-right'));
                            this._headerMessages.appendChildWidget(this._createForbiddenPlaybackMessage());
                        } else {
                            this._headerMessages.appendChildWidget(this._createUnablePlayIcon('more-to-right'));
                            this._headerMessages.appendChildWidget(this._createRecordingFailedMessage());
                        }
                    }
                }

                // Add record button for future assets
                if (isFutureRecordable || isScheduledRecording) {
                    this._addRecordButton();
                }
            }
        },

        /**
         * Adds a play button.
         *
         * @private
         */
        _addPlayButton: function () {
            this._playButton = new PlayButton();
            this._playButton.setDataItem(this.getDataItem());

            this._buttonList.appendChildWidget(this._playButton);
        },

        /**
         * Adds a record button.
         *
         * @private
         */
        _addRecordButton: function () {
            var dataItem = this.getDataItem(),
                hasRecording;

            if (!application.getUser().canRecord()) {
                return;
            }

            if (dataItem instanceof Series) {
                hasRecording = recordingManager.hasRecording(
                    null, dataItem.getId());
            } else {
                hasRecording = recordingManager.hasRecording(
                    dataItem.getId(), dataItem.getSeriesId());
            }

            this._recordButton = new RecordButton();
            this._recordButton.setDataItem(this.getDataItem());

            if (hasRecording.episode || hasRecording.series) {
                if (dataItem.isFutureItem() && dataItem.getContentType() === TYPES.RECORDING) {
                    this._recordButton.cancelRecording();
                } else {
                    this._recordButton.recording();
                }

            }
            this._buttonList.appendChildWidget(this._recordButton);
        },

        /**
         * Adds a close button.
         *
         * @private
         */
        _addCloseButton: function () {
            this._closeButton = new CloseButton();
            this._closeButton.setDataItem(this.getDataItem());

            this._buttonList.appendChildWidget(this._closeButton);
        },

        /**
         * Adds a restart button.
         *
         * @private
         */
        _addRestartButton: function () {
            this._restartButton = new RestartButton();
            this._restartButton.setDataItem(this.getDataItem());

            this._buttonList.appendChildWidget(this._restartButton);
        },

        /**
         * Adds a delete button.
         *
         * @private
         */
        _addDeleteButton: function () {
            var button = this._deleteButton = new DeleteButton();

            button.setDataItem(this.getDataItem());

            this._buttonList.appendChildWidget(button);
        },

        /**
         * Creates the replay icon.
         *
         * @param {Object} [className] - Class name.
         * @private
         * @returns {string} The label.
         */
        _createUnablePlayIcon: function (className) {
            var icon = new Label({ text: '', classNames: ['replay-disabled-icon', 'icon-unable-play', 'icon'] });

            if (className) {
                icon.addClass(className);
            }

            return icon;
        },

        /**
         * Creates the replay message.
         *
         * @private
         * @returns {string} The label.
         */
        _createReplayMessage: function () {
            var label = new Label({ text: l10n.get('details.replay_disabled'), classNames: ['replay-disabled'] });

            return label;
        },

        /**
         * Creates the forbidden replay message.
         *
         * @private
         * @returns {string} The label.
         */
        _createForbiddenReplayMessage: function () {
            var label = new Label({ text: l10n.get('details.replay_forbidden'), classNames: ['replay-forbidden'] });

            return label;
        },

        /**
         * Creates the recording failed message.
         *
         * @private
         * @returns {string} The label.
         */
        _createRecordingFailedMessage: function () {
            var label = new Label({ text: l10n.get('details.recording_failed'), classNames: ['recording-failed'] });

            return label;
        },

        /**
         * Creates the forbidden replay message.
         *
         * @param {string} className  - The classname.
         * @private
         *
         * @returns {string} The label.
         */
        _createForbiddenPlaybackMessage: function (className) {
            var label = new Label({ text: l10n.get('details.playback_forbidden'), classNames: ['playback-forbidden'] });

            if (className) {
                label.addClass(className);
            }

            return label;
        },

        /**
         * Dispose the widget.
         */
        dispose: function dispose () {
            dispose.base.call(this);
        },

        /**
         * Updates the recording status.
         *
         * @private
         */
        updateRecordingStatus: function () {
            var dataItem = this.getDataItem(),
                hasRecording = recordingManager.hasRecording(
                    dataItem.getId(), dataItem.getSeriesId());

            if (this._recordButton) {
                if (hasRecording.episode || hasRecording.series) {
                    if (dataItem.isFutureItem() && dataItem.getContentType() === TYPES.RECORDING) {
                        this._recordButton.cancelRecording();
                    } else {
                        this._recordButton.recording();
                    }
                } else {
                    this._recordButton.record();
                }
            }

            if ((dataItem instanceof Record || dataItem.getContentType() === 'RECORDING')
                && !hasRecording.episode) {
                this.dispose();
                this.bubbleEvent(new RecordDeletedEvent(dataItem));
            }
        },

        /**
         * Focuses the widget.
         *
         * @returns {boolean} - True if focus is set.
         */
        focus: function () {
            if (this._buttonList.getChildWidgetCount()) {
                return this._buttonList.focus();
            }
        },

        /**
         * Clears the widget.
         */
        clear: function () {
            this._backimg.setSrc('');
            this._title.setText('');
            this._subtitle.setText('');
            this._buttonList.removeChildWidgets();
            this._headerMessages.removeChildWidgets();
            this._videoRatings.removeChildWidgets();
            this.removeClass('shortheader');
        },

        /**
         * Returns the button list count.
         *
         * @returns {number} - Number of widgets contained in button list.
         */
        getButtonListLength: function () {
            return this._buttonList.getChildWidgetCount();
        }
    });
});