/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',
  'settings'
],

function($, _, Backbone, settings) {
  'use strict';

  var Forms = {};

  // Forms model
  Forms.Model = Backbone.Model.extend({
    initialize: function(options) {
      this.surveyId = options.surveyId;
    },

    url: function() {
      if (this.get("id") !== undefined) {
        return settings.api.baseurl + '/surveys/' + this.surveyId + '/forms';
      }
      return settings.api.baseurl + '/surveys/' + this.surveyId + '/forms';
    }
  });


  // Forms collection
  Forms.Collection = Backbone.Collection.extend({
    model: Forms.Model,

    initialize: function(options) {
      this.surveyId = options.surveyId;
      this.fetch({ reset: true });
    },

    url: function() {
      return settings.api.baseurl + '/surveys/' + this.surveyId + '/forms';
    },

    parse: function(response) {
      if (response.forms.length === 0) {
        var newForm = new Forms.Model({ 'questions': [] });
        return [ newForm ];
      }

      return response.forms;
    },

    // Find the most recent form of the given type (usually "mobile" or "paper")
    getMostRecentForm: function(type) {
      var i;

      // find mobile forms by default
      if (type === undefined) {
        type = "mobile";
      }

      for (i = 0; i < this.models.length; i += 1) {
        if (this.models[i].get('type') === type) {
          return this.models[i];
        }
      }
    },

    // Helper method used by the recursive getFlattenedForm
    flattenForm: function(question, flattenedForm) {

      // Add the question to the list of questions
      // Naive -- takes more space than needed (because it includes subquestions)
      if(question.type !== 'checkbox') {
        flattenedForm.push(question);
      }

      // Check if there are sub-questions associated with any of the answers
      _.each(question.answers, function(answer){

        // Add each checkbox answer as a separate question
        if(question.type === 'checkbox') {
          flattenedForm.push({
            name: answer.name,
            text: question.text + ': ' + answer.text
          });
        }

        if (answer.questions !== undefined) {
          _.each(answer.questions, function(question) {
            // Recusively call flattenForm to process those questions.
            return this.flattenForm(question, flattenedForm);

          }, this);
        }
      }, this);

      return flattenedForm;
    },

    // Returns the most recent form as a flat list of question objects
    // Objects have name (functions as id), text (label of the question)
    getFlattenedForm: function() {
      var mostRecentForm = this.getMostRecentForm();

      var flattenedForm = [];
      var distinctQuestions = [];

      // Process the form if we have one
      if (mostRecentForm !== undefined) {
        _.each(mostRecentForm.get("questions"), function(question) {
          flattenedForm = flattenedForm.concat(this.flattenForm(question, flattenedForm));
        }, this);

        // Make sure there's only one question per ID.
        var questionNames = [];
        _.each(flattenedForm, function(question) {
          if (! _.contains(questionNames, question.name)) {
            questionNames.push(question.name);
            distinctQuestions.push(question);
          }
        });
      }

      return distinctQuestions;
    }
  });


  return Forms;

}); // End Forms module





@@ -185,16 +185,975 @@
  = %7B%7D;%0A%0A
+  // Recursive helper method used by getFlattenedForm%0A  // Modifies the flattenedForm argument.%0A  function flattenForm(question, flattenedForm) %7B%0A    // Add the question to the list of questions%0A    // Naive -- takes more space than needed (because it includes subquestions)%0A    if(question.type !== 'checkbox') %7B%0A      flattenedForm.push(question);%0A    %7D%0A%0A    // Check if there are sub-questions associated with any of the answers%0A    _.each(question.answers, function(answer)%7B%0A%0A      // Add each checkbox answer as a separate question%0A      if (question.type === 'checkbox') %7B%0A        flattenedForm.push(%7B%0A          name: answer.name,%0A          text: question.text + ': ' + answer.text%0A        %7D);%0A      %7D%0A%0A      if (answer.questions !== undefined) %7B%0A        _.each(answer.questions, function(question) %7B%0A          // Recusively call flattenForm to process those questions.%0A          flattenForm(question, flattenedForm);%0A        %7D);%0A      %7D%0A    %7D);%0A  %7D;%0A%0A%0A
   // For
@@ -1161,16 +1161,16 @@
 s model%0A
-
   Forms.
@@ -2459,1031 +2459,8 @@
 %7D,%0A%0A
-    // Helper method used by the recursive getFlattenedForm%0A    flattenForm: function(question, flattenedForm) %7B%0A%0A      // Add the question to the list of questions%0A      // Naive -- takes more space than needed (because it includes subquestions)%0A      if(question.type !== 'checkbox') %7B%0A        flattenedForm.push(question);%0A      %7D%0A%0A      // Check if there are sub-questions associated with any of the answers%0A      _.each(question.answers, function(answer)%7B%0A%0A        // Add each checkbox answer as a separate question%0A        if(question.type === 'checkbox') %7B%0A          flattenedForm.push(%7B%0A            name: answer.name,%0A            text: question.text + ': ' + answer.text%0A          %7D);%0A        %7D%0A%0A        if (answer.questions !== undefined) %7B%0A          _.each(answer.questions, function(question) %7B%0A            // Recusively call flattenForm to process those questions.%0A            return this.flattenForm(question, flattenedForm);%0A%0A          %7D, this);%0A        %7D%0A      %7D, this);%0A%0A      return flattenedForm;%0A    %7D,%0A%0A
     
@@ -2919,50 +2919,8 @@
     
-flattenedForm = flattenedForm.concat(this.
 flat
@@ -2951,17 +2951,16 @@
 nedForm)
-)
 ;%0A      

Fix a bug when handling top-level questions Top-level questions resulted in duplicated flattened-question arrays. A large number of top-level questions would grow the flattened array exponentially.