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;
    });