Source: views/population/populationView.js

/*global require, define, console, $ */
/*jslint nomen: true, debug: true */

/**
 * @module populationView
 * @extends module:defaultView
 */


define([
    "framework",
    "views/defaultView",
    "text!templates/populationTpl.hbs",
    "models/populationModel",
    "underscore",
    "utils",
    "views/population/populationAvgChartView",
    "views/population/populationYearChartView"

], function ($, defaultView, tpl, Model, _, utils, avgChartView, yearChartView) {
    "use strict";
    /**
     * @name module:populationView
     * @description Population informer
     * @class Backbone.View
     *
     * @requires module:defaultView
     * @requires module:populationModel
     * @requires text!templates/populationTpl {String} Population hbs template
     * @requires underscore
     * @requires module:utils
     * @requires module:populationAvgChartView
     * @requires module:populationYearChartView
     *
     * @see module:defaultView
     * @see module:utils
     * @see module:populationModel
     * @see module:populationYearChartView
     * @see module:populationYearChartView
     *
     * @constructor
     * @returns {Function} Backbone.View constructor
     */

    var MENU_CLASS = ".enw__menu";

    return defaultView.extend({
        /**
         * @name module:populationView#template
         * @description Raw handlebars template
         * @type {String}
         */
        template: tpl,

        /**
         * @name module:populationView#name
         * @description Template id
         * @type {String}
         */
        name: "populationTpl",

        /**
         * @name module:populationView#title
         * @description Default widget title
         * @type {String}
         */
        title: "populationTitle",

        /**
         * @name module:populationView#ModelConstructor
         * @see module:defaultView#ModelConstructor
         * @see module:populationModel
         * @description Population model class
         */
        ModelConstructor: Model,

        /**
         * @name module:populationView#mode
         * @description Current widget mode
         * @type {object}
         */
        mode: {
            year: "avg"
        },

        /**
         * @name module:populationView#renderData
         * @description Chart update & widget menu render
         * @function
         */
        renderData: function () {
            var collection = this.model.get("collection"),
                relatedView = this.getRelatedView();

            /* istanbul ignore else */
            if (this.renderMenu) {
                // Getting unique years from model
                this.renderMenu(
                    ["avg"].concat(_.uniq(_.pluck(collection, 'year'))),
                    MENU_CLASS
                );

                // There's no need to render another one;
                this.renderMenu = undefined;
            }

            //this.switchModeDelayed();
            this.showMsg();

            // Foolproof
            /* istanbul ignore else */
            if (relatedView) {
                relatedView.render(collection || this.model.get("population"));
                this.switchRelatedView(relatedView.$el);
            }
            return this.model.attributes;
        },
        /**
         * @name module:populationView#afterRender
         * @description Menu event bindings
         * @see module:defaultView#afterRender
         * @function
         */
        afterRender: function () {
            var MENU_LINK_SELECTOR = ".enw__menu__link";

            this.$el.on(
                "click",
                MENU_LINK_SELECTOR,
                $.proxy(this.onMenuClick, this)
            );
        },
        /**
         * @name module:populationView#getRelatedView
         * @description Gets related view by widget mode
         * @function
         */
        getRelatedView: function () {
            var mode = this.mode,
                SELECTOR,
                hash,
                // View constructor
                View;

            if (mode.year === "avg") {
                hash = "avgChart";
                SELECTOR = ".avgChart";
                View = avgChartView;
            } else {
                hash = "yearChart";
                SELECTOR = ".yearChart";
                View = yearChartView;
            }

            // Delayed chart initialization
            return this.initRelatedView(hash, View, SELECTOR);

        },
        /**
         * @name module:populationView#onMenuClick
         * @description Primary and secondary menu click handler.
         * Switches widget mode by click
         * @function
         */
        onMenuClick: function (e) {
            var $target = $(e.target),
                mode = $target.data("href");

            // "Throttling": suspends handler while previous data request is being proceed
            /* istanbul ignore else */
            if (this.status === 2) {
                // Part of switchMode logic
                // this.selectMenuItem($target);

                this.switchMode(mode);
            }
            return mode;
        },
        /**
         * @name module:populationView#switchMode
         * @description Updates model state by selected mode
         * @function
         * @param [year] {String|Number} Year in xxxx format
         */
        switchMode: function (year) {
            var mode = this.setMode(year),
                model = this.model,
                url = model.host + "/" + model.path;

            /* istanbul ignore else */
            if (mode) {

                // Menu class switch
                this.selectMenuItem(mode.year, this.$el.find(MENU_CLASS));

                // NB: As far as we have no pre-initialized related views
                // DOM state may be switched in renderData callback only
                // So we just form the request and wait. DDP as is.

                /* istanbul ignore else */
                if (mode.year !== "avg") {
                    url += "/" + mode.year;
                }
                this.fetch(url);
            }
            return mode;
        }
    });
});