'use strict';

/**
 * The model for the diff viewer page.
 *
 * This handles all attribute storage and diff context parsing needed to
 * display and update the diff viewer.
 *
 * Model Attributes:
 *     canDownloadDiff (boolean):
 *         Whether a diff file can be downloaded, given the current revision
 *         state.
 *
 *     filenamePatterns (Array):
 *         A list of filenames or patterns used to filter the diff viewer.
 *         This is optional.
 *
 *     numDiffs (number):
 *         The total number of diffs.
 */
RB.DiffViewerPage = RB.ReviewablePage.extend({
    defaults: _.defaults({
        canDownloadDiff: false,
        filenamePatterns: null,
        numDiffs: 1
    }, RB.ReviewablePage.prototype.defaults),

    /**
     * Construct the page's instance.
     *
     * This defines child objects for managing state related to the page
     * prior to parsing the provided attributes payload and initializing
     * the instance.
     */
    constructor: function constructor() {
        this.commentsHint = new RB.DiffCommentsHint();
        this.files = new RB.DiffFileCollection();
        this.pagination = new RB.Pagination();
        this.revision = new RB.DiffRevision();

        RB.ReviewablePage.apply(this, arguments);
    },


    /**
     * Initialize the page.
     *
     * This will begin listening for events on the page and set up default
     * state.
     */
    initialize: function initialize() {
        RB.ReviewablePage.prototype.initialize.apply(this, arguments);

        this.diffReviewables = new RB.DiffReviewableCollection([], {
            reviewRequest: this.get('reviewRequest')
        });
        this.diffReviewables.watchFiles(this.files);
    },


    /**
     * Parse the data for the page.
     *
     * Args:
     *     rsp (object):
     *         The payload to parse.
     *
     * Returns:
     *     object:
     *     The returned attributes.
     */
    parse: function parse(rsp) {
        return _.extend(this._parseDiffContext(rsp), RB.ReviewablePage.prototype.parse.call(this, rsp));
    },


    /**
     * Load a new diff from the server.
     *
     * Args:
     *     options (object):
     *         The options for the diff to load.
     *
     * Option Args:
     *     filenames (string):
     *         A comma-separated string of filenames or filename patterns to
     *         load.
     *
     *     page (number):
     *         The page number to load. Defaults to the first page.
     *
     *     revision (number):
     *         The base revision. If displaying an interdiff, this will be
     *         the first revision in the range.
     *
     *     interdiffRevision (number):
     *         The optional interdiff revision, representing the ending
     *         revision in a range.
     */
    loadDiffRevision: function loadDiffRevision() {
        var _this = this;

        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

        var reviewRequestURL = this.get('reviewRequest').url();
        var queryData = [];

        if (options.revision) {
            queryData.push({
                name: 'revision',
                value: options.revision
            });
        }

        if (options.interdiffRevision) {
            queryData.push({
                name: 'interdiff-revision',
                value: options.interdiffRevision
            });
        }

        if (options.page && options.page !== 1) {
            queryData.push({
                name: 'page',
                value: options.page
            });
        }

        if (options.filenamePatterns) {
            queryData.push({
                name: 'filenames',
                value: options.filenamePatterns
            });
        }

        var url = Djblets.buildURL({
            baseURL: reviewRequestURL + 'diff-context/',
            queryData: queryData
        });

        $.ajax(url).done(function (rsp) {
            return _this.set(_this._parseDiffContext(rsp.diff_context));
        });
    },


    /**
     * Parse context for a displayed diff.
     *
     * Args:
     *     rsp (object):
     *         The payload to parse.
     *
     * Returns:
     *     object:
     *     The returned attributes.
     */
    _parseDiffContext: function _parseDiffContext(rsp) {
        if (rsp.comments_hint) {
            this.commentsHint.set(this.commentsHint.parse(rsp.comments_hint));
        }

        if (rsp.files) {
            this.files.reset(rsp.files, { parse: true });
        }

        if (rsp.pagination) {
            this.pagination.set(this.pagination.parse(rsp.pagination));
        }

        if (rsp.revision) {
            this.revision.set(this.revision.parse(rsp.revision));
        }

        return {
            canDownloadDiff: rsp.revision && rsp.revision.interdiff_revision === null,
            filenamePatterns: rsp.filename_patterns || null,
            numDiffs: rsp.num_diffs || 0
        };
    }
});

//# sourceMappingURL=diffViewerPageModel.js.map