# Source: models/filters/ChoiceFilter.js

    /* global define */
    define(['jquery', 'underscore', 'backbone', 'models/filters/Filter'],
        function($, _, Backbone, Filter) {

      /**
      * @class ChoiceFilter
      * @classdesc A Filter whose search term is one or more choices from a defined list
      * @name ChoiceFilter
      * @constructs ChoiceFilter
      * @extends Filter
      */
    	var ChoiceFilter = Filter.extend(
        /** @lends ChoiceFilter.prototype */{

        /**
        * @inheritdoc
        * @type {string}
        */
        type: "ChoiceFilter",

        /**
        * The Backbone Model attributes set on this ChoiceFilter
        * @type {object}
        * @extends Filter#defaultts
        * @property {boolean} chooseMultiple - If true, this ChoiceFilter can have multiple choices set as the search term
        * @property {string[]} choices - The list of search terms that can possibly be set on this Filter
        * @property {string} nodeName - The XML node name to use when serializing this model into XML
        */
        defaults: function(){
          return _.extend(Filter.prototype.defaults(), {
            chooseMultiple: true,
            //@type {object} - A literal JS object with a "label" and "value" attribute
            choices: [],
            nodeName: "choiceFilter"
          });
        },

        /**
        * Parses the choiceFilter XML node into JSON
        *
        * @param {Element} xml - The XML Element that contains all the ChoiceFilter elements
        * @return {JSON} - The JSON object literal to be set on the model
        */
        parse: function(xml){

          var modelJSON = Filter.prototype.parse.call(this, xml);

          //Parse the chooseMultiple boolean field
          modelJSON.chooseMultiple = (this.parseTextNode(xml, "chooseMultiple") === "true")? true : false;

          //Start an array for the choices
          modelJSON.choices = [];

          //Iterate over each choice and parse it
          var self = this;
          $(xml).find("choice").each(function(i, choiceNode){

            //Parse the label and value nodes into a literal object
            var choiceObject = {
              label: self.parseTextNode(choiceNode, "label"),
              value: self.parseTextNode(choiceNode, "value")
            }

            //Check that there is a label and value (value can be boolean false or 0, so just check for null or undefined)
            if(choiceObject.label && choiceObject.value !== null && typeof choiceObject.value !== "undefined"){
              modelJSON.choices.push(choiceObject);
            }

          });

          return modelJSON;
        },

        /**
         * Updates the XML DOM with the new values from the model
         *  @inheritdoc
         *  @return {XMLElement} An updated choiceFilter XML element from a portal document
        */
        updateDOM:function(options){

          try{

            var objectDOM = Filter.prototype.updateDOM.call(this);

            if(typeof options != "object"){
              var options = {};
            }

            if( !options.forCollection ){
              // Serialize <choice> elements
              var choices = this.get("choices");

              if(choices){
                //Remove all the choice elements
                $(objectDOM).children("choice").remove();

                //Make a new choice element for each choice in the model
                _.each(choices, function(choice){
                  // Make new <choice> node
                  choiceSerialized = objectDOM.ownerDocument.createElement("choice");
                  // Make choice subnodes <label> and <value>
                  _.map(choice, function(value, nodeName){

                    if(value || value === false){
                      var nodeSerialized = objectDOM.ownerDocument.createElement(nodeName);
                      $(nodeSerialized).text(value);
                      $(choiceSerialized).append(nodeSerialized);
                    }

                  });
                // append subnodes
                $(objectDOM).append(choiceSerialized);

                });

              }

              //Get the chooseMultiple value from the model
              var chooseMultiple = this.get("chooseMultiple");
              //Remove the chooseMultiple element
              $(objectDOM).children("chooseMultiple").remove();
              //If the model value is a boolean, create a chooseMultiple element and add it to the DOM
              if(chooseMultiple === true || chooseMultiple === false){
                chooseMultipleSerialized = objectDOM.ownerDocument.createElement("chooseMultiple");
                $(chooseMultipleSerialized).text(chooseMultiple);
                $(objectDOM).append(chooseMultipleSerialized);
              };
            }
            else{
              //Remove the filterOptions
              $(objectDOM).find("filterOptions").remove();

              //Change the root element into a <filter> element
              var newFilterEl = objectDOM.ownerDocument.createElement("filter");
              $(newFilterEl).html( $(objectDOM).children() );

              //Return this node
              return newFilterEl;
            }

            return objectDOM;
          }
          //If there's an error, return the original DOM or an empty string
          catch(e){
            return this.get("objectDOM") || "";
          }

        }

      });

      return ChoiceFilter;
    });