# Source: src/js/views/filters/ToggleFilterView.js

    /*global define */
    define(['jquery', 'underscore', 'backbone',
            'models/filters/ToggleFilter',
            'views/filters/FilterView',
            'text!templates/filters/toggleFilter.html',
            'text!templates/filters/booleanFilter.html'],
      function($, _, Backbone, ToggleFilter, FilterView, Template, BooleanTemplate) {
      'use strict';

      /**
      * @class ToggleFilterView
      * @classdesc Render a view of a single ToggleFilter model
      * @classcategory Views/Filters
      * @extends FilterView
      */
      var ToggleFilterView = FilterView.extend(
        /** @lends ToggleFilterView.prototype */{

        /**
        *  A ToggleFilter model to be rendered in this view
        * @type {ToggleFilter} */
        model: null,

        /**
         * @inheritdoc
         */
        modelClass: ToggleFilter,

        className: "filter toggle",

        template: _.template(Template),
        booleanTemplate: _.template(BooleanTemplate),

        /**
         * @inheritdoc
         */
        events: function () {
          try {
            var events = FilterView.prototype.events.call(this);
            events["change input.toggle-checkbox"] = "updateModel";
            return events
          }
          catch (error) {
            console.log('There was an error creating the events object for a ToggleFilterView' +
              ' Error details: ' + error);
          }
        },

        /**
        * @inheritdoc
        */
        render: function () {

          try {
            var templateVars = this.model.toJSON();
            templateVars.id = this.model.cid;

            if( !this.model.get("falseLabel") ){
              //If the value is the same as the trueValue, the checkbox should be checked
              templateVars.checked = (this.model.get("values")[0] == this.model.get("trueValue"))? true : false;

              //Use the BooleanFilter template for toggles with only a true value
              this.$el.addClass("boolean");
              this.template = this.booleanTemplate
            }

            // Renders the template and inserts the FilterEditorView if the mode is uiBuilder
            FilterView.prototype.render.call(this, templateVars);

            this.listenTo(this.model, "change:values", this.updateToggle);
          }
          catch (error) {
            console.log( 'There was an error rendering a ToggleFilterView.' +
              ' Error details: ' + error );
          }

        },

        /**
        * Actions to perform after the render() function has completed and this view's
        * element is added to the webpage.
        */
        postRender: function(){
          this.setToggleWidth();
        },

        updateToggle: function(){

          //If the model is set to true
          if( this.model.get("values").length && this.model.get("values")[0] == this.model.get("trueValue") ){
            this.$("input").prop("checked", true);
          }
          else if( this.model.get("values").length && this.model.get("values")[0] == this.model.get("falseValue") ){
            this.$("input").prop("checked", false);
          }
          else if( !this.model.get("values").length ){
            this.$("input").prop("checked", false);
          }

          this.setToggleWidth();

        },

        /**
        * Gets the width of the toggle labels and sets the various CSS attributes
        * necessary for the switch to fully display each label
        */
        setToggleWidth: function(){

          //If there is no toggle element, exit now
          if( !this.$(".can-toggle-switch").length ){
            return;
          }

          //Get the padding and widths of the switch elements
          var switchPadding    = 24,
              onSwitchWidth = this.$(".true-label").width(),
              offSwitchWidth  = this.$(".false-label").width(),
              totalSwitchWidth = onSwitchWidth + offSwitchWidth + (switchPadding * 2) + 2,
              isChecked = this.$("input[type='checkbox']").prop("checked");

          //Set the width on the whole view
          this.$el.width(totalSwitchWidth + "px");

          //Get the toggle switch element
          var toggleSwitch = this.$(".can-toggle-switch");

          //Add an identifier to the toggle switch element
          toggleSwitch.attr("id", "toggle-" + this.model.cid);

          //Change the width of the toggle switch
          toggleSwitch.css("flex", "0 0 " + totalSwitchWidth + "px");

          //Create CSS for the :before and :after pseudo elements, which is best done
          // by adding a style tag directly to the DOM
          if( isChecked ){
            var newCSS = "#" + "toggle-" + this.model.cid + ":before{ " +
                           "transform: translate3d(" + (onSwitchWidth + switchPadding) + "px, 0, 0);" +
                           "width: " + (offSwitchWidth + switchPadding) + "px ;" +
                         "}" +
                         "#" + "toggle-" + this.model.cid + ":after{ " +
                          "width: " + (onSwitchWidth + switchPadding) + "px;" +
                          "transform: translate3d(0px, 0, 0);" +
                        "}";
          }
          else{
            var newCSS = "#" + "toggle-" + this.model.cid + ":before{ " +
                           "width: " + (offSwitchWidth + switchPadding) + "px ;" +
                           "left: 0px ;" +
                         "}" +
                         "#" + "toggle-" + this.model.cid + ":after{ " +
                          "width: " + (onSwitchWidth + switchPadding) + "px;" +
                          "transform: translate3d(" + (offSwitchWidth + switchPadding) + "px, 0, 0);" +
                        "}";
          }

          //Get or create a style tag
          var styleTag = toggleSwitch.children("style");
          if( !styleTag.length ){
            styleTag = $(document.createElement("style"));
            toggleSwitch.append(styleTag);
          }

          //Add the CSS to the style tag
          styleTag.html(newCSS);
        },

        /**
        * Updates the value set on the ToggleFilter Model associated with this view.
        * The filter value is grabbed from the checkbox element in this view.
        *
        */
        updateModel: function(){

          //Check if the checkbox is checked
          var isChecked = this.$("input").prop("checked");

          //If the toggle is checked, then set the true toggle value on the model
          if( isChecked ){
            if( this.model.get("values")[0] !== this.model.get("trueValue") ){
              this.model.set("values", [ this.model.get("trueValue") ]);
            }
          }
          //If the toggle is not checked and there is no false value specified,
          // then remove the value from the model completely
          else if(!this.model.get("falseValue")){
            if( this.model.get("values").length > 0 ){
              this.model.set("values", []);
            }
          }
          //If the toggle is not checked and there is a false value specified,
          // then set the false toggle value on the model
          else{
            if( this.model.get("values")[0] !== this.model.get("falseValue") ){
              this.model.set("values", [ this.model.get("falseValue") ]);
            }
          }

        }

      });
      return ToggleFilterView;
    });