'use strict';

/**
 * Abstract base for review UIs.
 *
 * This provides all the basics for creating a review UI. It does the
 * work of loading in comments, creating views, and displaying comment dialogs,
 */
RB.AbstractReviewableView = Backbone.View.extend({
    /**
     * The AbstractCommentBlockView subclass.
     *
     * This is the type that will be instantiated for rendering comment blocks.
     */
    commentBlockView: null,

    /**
     * The list type (as a string) for passing to CommentDlg.
     */
    commentsListName: null,

    /**
     * Initialize AbstractReviewableView.
     *
     * Args:
     *     options (object, optional):
     *         Options for the view.
     */
    initialize: function initialize() {
        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

        console.assert(this.commentBlockView, 'commentBlockView must be defined by the subclass');
        console.assert(this.commentsListName, 'commentsListName must be defined by the subclass');

        this.commentDlg = null;
        this._activeCommentBlock = null;
        this.renderedInline = options.renderedInline || false;
    },


    /**
     * Render the reviewable to the page.
     *
     * This will call the subclass's renderContent(), and then handle
     * rendering each comment block on the reviewable.
     *
     * Returns:
     *     RB.AbstractReviewableView:
     *     This object, for chaining.
     */
    render: function render() {
        this.renderContent();

        this.model.commentBlocks.each(this._addCommentBlockView, this);
        this.model.commentBlocks.on('add', this._addCommentBlockView, this);

        return this;
    },


    /**
     * Render the content of the reviewable.
     *
     * This should be overridden by subclasses.
     */
    renderContent: function renderContent() {},


    /**
     * Create a new comment in a comment block and opens it for editing.
     *
     * Args:
     *     options (object):
     *         Options for the comment block creation.
     */
    createAndEditCommentBlock: function createAndEditCommentBlock(options) {
        var _this = this;

        if (this.commentDlg !== null && this.commentDlg.model.get('dirty') && !confirm(gettext('You are currently editing another comment. Would you like to discard it and create a new one?'))) {
            return;
        }

        var defaultCommentBlockFields = _.result(this.model, 'defaultCommentBlockFields');

        if (defaultCommentBlockFields.length === 0 && this.model.reviewableIDField) {
            console.log('Deprecation notice: Reviewable subclass is missing ' + 'defaultCommentBlockFields. Rename reviewableIDField ' + 'to defaultCommentBlockFields, and make it a list.');
            defaultCommentBlockFields = [this.model.reviewableIDField];
        }

        /* As soon as we add the comment block, show the dialog. */
        this.once('commentBlockViewAdded', function (commentBlockView) {
            return _this.showCommentDlg(commentBlockView);
        });

        _.extend(options, _.pick(this.model.attributes, defaultCommentBlockFields));
        this.model.createCommentBlock(options);
    },


    /**
     * Show the comment details dialog for a comment block.
     *
     * Args:
     *     commentBlockView (RB.AbstractCommentBlockView):
     *         The comment block to show the dialog for.
     */
    showCommentDlg: function showCommentDlg(commentBlockView) {
        var _this2 = this;

        var commentBlock = commentBlockView.model;

        commentBlock.ensureDraftComment();

        if (this._activeCommentBlock === commentBlock) {
            return;
        }

        this.stopListening(this.commentDlg, 'closed');
        this.commentDlg = RB.CommentDialogView.create({
            comment: commentBlock.get('draftComment'),
            publishedComments: commentBlock.get('serializedComments'),
            publishedCommentsType: this.commentsListName,
            position: function position(dlg) {
                return commentBlockView.positionCommentDlg(dlg);
            }
        });
        this._activeCommentBlock = commentBlock;

        this.listenTo(this.commentDlg, 'closed', function () {
            _this2.commentDlg = null;
            _this2._activeCommentBlock = null;
        });
    },


    /**
     * Add a CommentBlockView for the given CommentBlock.
     *
     * This will create a view for the block, render it, listen for clicks
     * in order to show the comment dialog, and then emit
     * 'commentBlockViewAdded'.
     *
     * Args:
     *     commentBlock (RB.AbstractCommentBlock):
     *         The comment block to add a view for.
     */
    _addCommentBlockView: function _addCommentBlockView(commentBlock) {
        var _this3 = this;

        var commentBlockView = new this.commentBlockView({
            model: commentBlock
        });

        commentBlockView.on('clicked', function () {
            return _this3.showCommentDlg(commentBlockView);
        });
        commentBlockView.render();
        this.trigger('commentBlockViewAdded', commentBlockView);
    }
});

//# sourceMappingURL=abstractReviewableView.js.map