# Source: themes/ess-dive/views/metadata/EML211View.js

    define(['underscore', 'jquery', 'backbone',
            'views/metadata/BaseEML211View',
            'views/metadata/EMLGeoCoverageView',
            'views/metadata/EMLPartyView',
            'views/metadata/EMLMethodsView',
            'views/metadata/EMLTempCoverageView',
            'models/metadata/eml211/EML211',
            'models/metadata/eml211/EMLGeoCoverage',
            'models/metadata/eml211/EMLKeywordSet',
            'models/metadata/eml211/EMLParty',
            'models/metadata/eml211/EMLProject',
            'models/metadata/eml211/EMLText',
            'models/metadata/eml211/EMLTaxonCoverage',
            'models/metadata/eml211/EMLTemporalCoverage',
            'models/metadata/eml211/EMLMethods',
            'text!templates/metadata/eml.html',
            'text!templates/metadata/EMLPartyCopyMenu.html',
            'text!templates/metadata/metadataOverview.html',
            'text!templates/metadata/dates.html',
            'text!templates/metadata/locationsSection.html',
            'text!templates/metadata/taxonomicCoverage.html',
            'text!templates/metadata/taxonomicClassificationTable.html',
            'text!templates/metadata/taxonomicClassificationRow.html',
            'themes/ess-dive/views/metadata/EMLFundingOrganizationsSubView',
            'themes/ess-dive/views/metadata/EMLProjectSubView',
            'themes/ess-dive/views/metadata/EMLDOEContractsSubView',
            'themes/ess-dive/views/metadata/EMLVocabularySubView',
            'themes/ess-dive/views/metadata/EMLReferencePaperSubView'],
        function (_, $, Backbone, BaseEML211View, EMLGeoCoverageView, EMLPartyView, EMLMethodsView, EMLTempCoverageView,
                  EML, EMLGeoCoverage, EMLKeywordSet, EMLParty, EMLProject, EMLText, EMLTaxonCoverage,
                  EMLTemporalCoverage, EMLMethods, Template, EMLPartyCopyMenuTemplate, OverviewTemplate,
                  DatesTemplate, LocationsTemplate,
                  TaxonomicCoverageTemplate, TaxonomicClassificationTable, TaxonomicClassificationRow, EMLFundingOrganizationsSubView,
                 EMLProjectSubView, EMLDOEContractsSubView, EMLVocabularySubView, EMLReferencePaperSubView) {

            var PARTY_TYPE_MAP = {
    	    			"contact" : "contact",
    	    			"creator" : "creator",
    	    			"contributor" : "associatedParty"
                    };

            var PARTY_LABELS_MAP = {
    	    			"contact" : "Contact",
                        "creator" : "Creators",
    	    			"contributor" : "Contributors"

    	    	}
            var PARTY_HELP_MAP = {
                        "contact" : "Person who should be listed as the contact for the data package " +
                        "for the purposes of the DOI or for users seeking further information for the " +
                        "data. <br/><em>Only one contact is allowed per data package. If none are entered, " +
                        "you will be set as the contact for this document.</em>",
                        "creator" : "The main researchers involved in producing the data. " +
                        "These include authors, owners, originators and principal investigators " +
                        "who should be listed in the citation. <br/><em>One or more creators is required. " +
                        "If none are entered, you will be set as the creator of this document. List creators " +
                        "in the order they need to appear in the citation. More entries will appear as you enter information.</em>",
    	    			"contributor" : "Additional contributors involved in producing the data. These " +
                        "could include people who assisted in creating the data package but wouldn't be " +
                        "considered authors for publication. <br/><em>Enter as many contributors as needed.</em>"

                    };

            var ORGANIZATIONS = [];

            var EMLView = BaseEML211View.extend({

                renderFunding: function(){
                    // Override funding section
                },

                get_organization_list: function() {
                    if (ORGANIZATIONS.length==0) {
                        // Synchronous call
                        ORGANIZATIONS = JSON.parse($.ajax({type: "GET", url: MetacatUI.root + "/js/themes/ess-dive/data/organizations.json", async: false}).responseText);
                    }

                    return ORGANIZATIONS;
                },
                /***
                 * Updates the placeholders for all data sections
                 *
                 */
                updateInputPlaceHolders: function(){
                    // Grab all data-sections
                    var sectionElements = $(document).find("section[data-section]");
                    if (typeof sectionElements != "undefined") {

                        // Iterate over all data sections
                        _.each(sectionElements, function(sectionEl){
                            var sectionName = $(sectionEl).attr("data-section");

                            // Get all text areas and input fields
                            var inputElements = $(sectionEl).find("textarea,input");

                            // Get the helper text from teh app model configuration
                            var helperText = MetacatUI.appModel.get("formHelpText") &&
                                MetacatUI.appModel.get("formHelpText").datasetEdit[sectionName];
                            if (typeof inputElements != "undefined") {

                                _.each(inputElements, function (element) {

                                    // the input name is either in data-category
                                    // or data-attribute
                                    var name = $(element).attr("data-category");
                                    if (typeof name == "undefined") {
                                        name = $(element).attr("data-attribute");
                                    }

                                    if (typeof name != "undefined" && typeof helperText != "undefined" )
                                        // update the place holder
                                        $(element).attr("placeholder", helperText[name]);
                                });

                            }

                        });

                    }
                },
                /**
                 * Extend to update all placeholder helper text
                 */
                renderAllSections: function(){
                    BaseEML211View.prototype.renderAllSections.apply(this)

                    // Add the helper text
                    this.updateInputPlaceHolders();
                },

                /**
                 * Extend the initialization function to add the Funding Organization Sub View
                 * @param options
                 * @returns {*}
                 */
                renderOverview: function(){
                    BaseEML211View.prototype.renderOverview.apply(this);
                    var overviewEl = this.$container.find(".overview");

                    // Remove the funding container. ESS-DIVE will manage
                    // funding contract numbers with alternative identifers
                    var funding  = overviewEl.find(".funding-container");
                    $( funding ).parent().remove();

                    // Remove the keyword container. ESS-DIVE will manage
                    // keywords as variables and categories
                    var keyword  = overviewEl.find(".keyword-container");
                    $( keyword ).parent().remove();

                    // Replace empty keyword container with the subview
                    $(overviewEl.find(".keyword-categorical-container")).replaceWith(
                        new EMLVocabularySubView({parentModel:this.model,
                            type:"categorical"}).render().el);

                    // Replace empty keyword variable container with the subview
                    $(overviewEl.find(".keyword-variable-container")).replaceWith(
                        new EMLVocabularySubView({parentModel:this.model,
                            type:"variable"}).render().el);

                    // Add the ESS-DIVE subviews the the overview section
                    $(overviewEl).append(new EMLProjectSubView({parentModel:this.model}).render().el);
                    $(overviewEl).append(new EMLFundingOrganizationsSubView({parentModel:this.model}).render().el);
                    $(overviewEl).append(new EMLDOEContractsSubView({parentModel:this.model}).render().el);
                    $(overviewEl).append(new EMLReferencePaperSubView({parentModel:this.model}).render().el);

                },

                /***
                 * Render an EML Party on the edit form
                 *
                 * @param {EMLView} view - EMLView isntance
                 * @param type - the type of party could be an assosiatedParty role of a party type
                 * @param parties - the parties to render edit sections for
                 */
                renderParty: function (view, type, parties){

                        view.$(".section.people").append("<i>All information entered in this section will be made public once the data " +
                                    "package is published.</i>",
                                    "<h4>" + PARTY_LABELS_MAP[type] + "<i class='required-icon hidden' data-category='"+type+"'></i></h4>",
                                    '<p class="subtle">'+ PARTY_HELP_MAP[type]+'</p>',
                                    '<div class="party-section" data-attribute="'+type+'"></div>');
                        _.each(parties, view.renderPerson, view);

                        // Publishers and contact need at least one .
                        if(type != "contact" ||  parties.length == 0)
                            view.renderPerson(null, type);
                },

                /**
                 * Overrides the handlePersonTyping function
                 *
                 * This function reacts to the user typing a new person in the person section (an EMLPartyView)
                 */
                handlePersonTyping: function(e){
                    var container = $(e.target).parents(".eml-party"),
                        emlParty  = container.length? container.data("model") : null,
                        partyType = container.length && emlParty? emlParty.get("role") || emlParty.get("type") : null;

                    if(this.$("[data-attribute='" + partyType + "'] .eml-party.new").length > 1) return;

                    //Render a new person if more than one are allowed
                    if( partyType != "contact" )
                        this.renderPerson(null, partyType);
                },

                /**
                 * Entirely override base class to control the number of persons rendered on copy
                 * @param emlParty
                 * @param partyType
                 */
                renderPerson: function(emlParty, partyType){

                    //If no model is given, create a new model
                    if(!emlParty){
                        var emlParty = new EMLParty({
                            parentModel: this.model
                        });

                        //Mark this model as new
                        var isNew = true;

                        //Find the party type or role based on the type given
                        if(_.contains(emlParty.get("roleOptions"), partyType))
                            emlParty.set("role", partyType);
                        else if(_.contains(emlParty.get("typeOptions"), partyType))
                            emlParty.set("type", partyType);

                    }
                    else{
                        var isNew = false;

                        //Get the party type, if it was not sent as a parameter
                        if(!partyType || typeof partyType != "string")
                            var partyType = emlParty.get("role") || emlParty.get("type");
                    }

                    //Find the container section for this party type
                    var container = this.$(".section.people").find('[data-attribute="' + partyType + '"]');

                    //See if this view already exists
                    if( !isNew && container.length && emlParty ){
                        var partyView;

                        _.each(container.find(".eml-party"), function(singlePartyEl){

                            //If this EMLPartyView element is for the current model, then get the View
                            if( $(singlePartyEl).data("model") == emlParty )
                                partyView = $(singlePartyEl).data("view");
                        });

                        //If a partyView was found, just rerender it and exit
                        if(partyView){
                            partyView.render();
                            return;
                        }
                    }

                    //If there still is no partyView found, create a new one
                    var partyView = new EMLPartyView({
                        model: emlParty,
                        edit: this.edit,
                        isNew: isNew,
                    });

                    //If this person type is not on the page yet, add it
                    if(!container.length){
                        this.addNewPersonType(emlParty.get("type") || emlParty.get("role"));
                        container = this.$(".section.people").find('[data-attribute="' + partyType + '"]');
                    }

                    // Find can return more than one new row
                    var newParties = container.find(".new");
                    if(!isNew && newParties.length)
                        container.find(".new")[0].before(partyView.render().el);
                    else {
                        container.append(partyView.render().el);
                    }

                    // Add autocomplete to the organization input fields
                    var view = this;
                    var organization_input_fields = view.$el.find('input[name="Organization"]');
                    $.map(organization_input_fields, function(input_field) {
                        $(input_field).autocomplete({
                            source: view.get_organization_list()
                        });
                    });

                    //Initialize the tooltips
                    this.$("input.tooltip-this").tooltip({
                        placement: "top",
                        title: function () {
                            return $(this).attr("placeholder")
                        },
                        delay: 1000
                    });

                    //if( partyType != "contact" )
                    //  container.append("<a class='edit-add-people-link' >Add +</a>");

                },
                /**
                 * Overrides the renderPeople view of the form
                 */
                renderPeople: function () {
                    this.$(".section.people").empty().append("<h2>People</h2>");

                    // Instance variable expected by other functions
                    this.partyTypeMap = PARTY_LABELS_MAP;

                    //Iterate through party map and get associated parties
                    for (var key in this.partyTypeMap) {

                        if (this.partyTypeMap.hasOwnProperty(key))
                        {

                            var parties = null;
                            // If this is an associatedParty we need to get the role
                            if ("associatedParty" == PARTY_TYPE_MAP[key]) {
                                parties = _.filter(this.model.get("associatedParty"), function(party){ return party.get("role") == key })
                            }
                            else
                            {
                                parties = this.model.get(key);
                            }

                            // Always the party form section
                            this.renderParty(this, key, parties);

                        }
                    }

                    //Listen to the EML model for new EMLParty models that are added behind the scenes
                    // (mainly from EMLParty.createFromUser()
                    var view = this;
                    this.listenTo(this.model, "change:creator change:contributor", function (emlModel, changedModels) {

                        if (changedModels && changedModels.length)
                            this.renderPerson(changedModels[0], changedModels[0].get("type"));
                    });

                },
                /*
                 * Override Switch section
                 */
                switchSection: function(e){
                    if(!e) return;

                    e.preventDefault();

                    var clickedEl = $(e.target),
                        section = clickedEl.attr("data-section") ||
                                  clickedEl.children("[data-section]").attr("data-section") ||
                                  clickedEl.parents("[data-section]").attr("data-section");

                    if(this.visibleSection == "all")
                        this.scrollToSection(section);
                    else{
                        this.$(".section." + this.activeSection).hide()
                        this.$(".section." + section).show();
                        this.highlightTOC(section);
                        this.activeSection = section;
                        this.visibleSection = section;

                        $(document).scrollTop(this.$(".section." + section).offset().top - $("#Navbar").height());
                        //$("body").scrollTop(this.$(".section." + section).offset().top - $("#Navbar").height());
                    }
                 },
                 /*
                 * Override remove person, add validation trigger
                 */
                removePerson: function(e){
                  BaseEML211View.prototype.removePerson.apply(this,[e]);

                  //trigger validation check for first part entry
                  this.$(".section.people").find('[data-attribute="creator"]').find(".eml-party").first().data("view").showValidation();
                }

            });

            return EMLView;
        });