define(["jquery",
        "underscore",
        "backbone",
        "models/project/ProjectModel",
        "models/Search",
        "models/Stats",
        "text!templates/alert.html",
        "text!templates/project/project.html",
        "views/project/ProjectHeaderView",
        "views/project/ProjectDataView",
        "views/project/ProjectSectionView",
        "views/project/ProjectMembersView",
        "views/StatsView",
        "views/project/ProjectLogosView"
    ],
    function($, _, Backbone, Project, SearchModel, StatsModel, AlertTemplate, ProjectTemplate, ProjectHeaderView,
        ProjectDataView, ProjectSectionView, ProjectMembersView, StatsView, ProjectLogosView) {
        "use_strict";
        /* The ProjectView is a generic view to render
         * projects, it will hold project sections
         */
        var ProjectView = Backbone.View.extend({

            /* The Project Element*/
            el: "#Content",

            type: "Project",

            //@type {string} - the section in this ProjectView that is currently active/being viewed
            activeSection: "",

            //@type {string} - The seriesId of the project document
            projectId: "",

            //@type {string} - The unique short name of the project
            projectName: "",

            subviews: new Array(), // Could be a literal object {} */

            // @type {Project} - A Project Model is associated with this view and gets created during render()
            model: null,

            /* Renders the compiled template into HTML */
            template: _.template(ProjectTemplate),
            //A template to display a notification message
            alertTemplate: _.template(AlertTemplate),

            events: {
              "click #metrics-link" : "renderMetricsView"
            },

            initialize: function(options) {
                // Set the current ProjectView properties
                this.projectId = options.projectId ? options.projectId : undefined;
                this.projectName = options.projectName ? options.projectName : undefined;
                this.activeSection = options.activeSection ? options.activeSection : undefined;
            },

            /*
             * Renders the ProjectView
             *
             * @return {ProjectView} Returns itself for easy function stacking in the app
             */
            render: function() {

                $("body").addClass("ProjectView");

                // Create a new Project model
                this.model = new Project({
                    id: this.projectId
                });

                // When the model has been synced, render the results
                this.stopListening();
                this.listenTo(this.model, "sync", this.renderProject);

                //If the project isn't found, display a 404 message
                this.listenToOnce(this.model, "notFound", this.showNotFound);

                //Fetch the model
                this.model.fetch();

                return this;
            },

            renderProject: function() {

                // Insert the overall project template
                this.$el.html(this.template(this.model.toJSON()));

                //Render the header view
                this.headerView = new ProjectHeaderView({
                    model: this.model
                });
                this.headerView.render();
                this.subviews.push(this.headerView);

                // Cache this model for later use
                MetacatUI.projects = MetacatUI.projects || {};
                MetacatUI.projects[this.model.get("id")] = this.model.clone();

                //Render the content sections
                _.each(this.model.get("sections"), function(section){
                  this.addSection(section);
                }, this);

                // Render the Data section
                if(!this.model.get("hideData")) {
                    this.sectionDataView = new ProjectDataView({
                        model: this.model,
                        id: "data"
                    });
                    this.subviews.push(this.sectionDataView);

                    this.$("#project-sections").append(this.sectionDataView.el);

                    //Render the section view and add it to the page
                    this.sectionDataView.render();

                    this.addSectionLink( this.sectionDataView, "Data" );
                }

                //Render the metrics section
                //Create a navigation link
                this.$("#project-section-tabs").append(
                  $(document.createElement("li"))
                    .append( $(document.createElement("a"))
                               .text("Metrics")
                               .attr("id", "metrics-link")
                               .attr("href", "#metrics" )
                               .attr("data-toggle", "tab")));

                this.$("#project-sections").append( $(document.createElement("div"))
                                                    .attr("id", "metrics")
                                                     .addClass("tab-pane") );

                // Render the members section
                if (!this.model.get("hideMembers")) {
                    this.sectionMembersView = new ProjectMembersView({
                        model: this.model,
                        id: "members"
                    });
                    this.subviews.push(this.sectionMembersView);

                    this.$("#project-sections").append(this.sectionMembersView.el);

                    //Render the section view and add it to the page
                    this.sectionMembersView.render();

                    this.addSectionLink( this.sectionMembersView, "Members" );
                }

                //After all the sections are rendered, mark the first one as active
                this.$("#project-sections").children().first().addClass("active");
                this.$("#project-section-tabs").children().first().addClass("active");

                //Space out the tabs evenly
                var widthEach = 100/this.$("#project-section-tabs").children().length;
                this.$("#project-section-tabs").children().css("width", widthEach + "%");

                //Render the logos at the bottom of the project page
                var ackLogos = this.model.get("acknowledgmentsLogos") || [];
                this.logosView = new ProjectLogosView();
                this.logosView.logos = ackLogos;
                this.subviews.push(this.logosView);
                this.logosView.render();
                this.$(".project-view").append(this.logosView.el);

                var view = this;

                //When each tab is clicked and shown
                this.$('a[data-toggle="tab"]').on('shown', function(e) {
                  var sectionView = $(e.target).data("view");

                  if( typeof sectionView !== "undefined"){
                    sectionView.postRender();
                  }

                  //Get the href of the clicked link
                  var linkTarget = $(e.target).attr("href");
                  linkTarget = linkTarget.substring(1);

                  //Set this view's active section name to the link href
                  view.activeSection = linkTarget;

                  //Get the new pathname using the active section
                  if( !MetacatUI.root.length || MetacatUI.root == "/" ){
                    var newPathName = window.location.pathname.substring(0, window.location.pathname.indexOf(view.projectName)) +
                                        view.projectName + "/" + view.activeSection;
                  }
                  else{
                    var newPathName = window.location.pathname.substring( window.location.pathname.indexOf(MetacatUI.root) + MetacatUI.root.length );
                    newPathName = newPathName.substring(0, newPathName.indexOf(view.projectName)) +
                                        view.projectName + "/" + view.activeSection;
                  }

                  //Update the window location
                  MetacatUI.uiRouter.navigate( newPathName, { trigger: false } );
                });

                //Switch to the active section tab
                if( this.activeSection ){
                  this.$('#project-section-tabs a[href="#' + this.activeSection + '"]').tab("show");

                  if( this.activeSection == "metrics" ){
                    this.renderMetricsView();
                  }
                }
                else{
                  this.$(".project-section-view").first().data("view").postRender();
                }

                //Scroll to an inner-page link if there is one specified
                if( window.location.hash && this.$(window.location.hash).length ){
                  MetacatUI.appView.scrollTo(this.$(window.location.hash));
                }

            },

            /*
            * Creates a ProjectSectionView to display the content in the given project
            * section. Also creates a navigation link to the section.
            *
            * @param {ProjectSectionModel} sectionModel - The section to render in this view
            */
            addSection: function(sectionModel){

              //Create a new ProjectSectionView
              var sectionView = new ProjectSectionView({
                model: sectionModel
              });

              //Render the section
              sectionView.render();

              //Add the section view to this project view
              this.$("#project-sections").append(sectionView.el);

              this.addSectionLink(sectionView, sectionModel.get("label"));

            },

            /*
            * Add a link to a section of this project page
            */
            addSectionLink: function(sectionView, label){

              //Create a navigation link
              this.$("#project-section-tabs").append(
                $(document.createElement("li"))
                  .append( $(document.createElement("a"))
                             .text(label)
                             .attr("href", "#" + sectionView.$el.attr("id") )
                             .attr("data-toggle", "tab")
                             .data("view", sectionView)));

            },

            /*
            * Render the metrics section
            */
            renderMetricsView: function() {

              if( this.model.get("hideMetrics") ) {
                return;
              }

              //If this subview is already rendered, exit
              if( this.sectionMetricsView ){
                return;
              }

              //If the search results haven't been fetched yet, wait. We need the
              // facet counts for the metrics view.
              if( !this.model.get("searchResults").length ){
                this.listenToOnce( this.model.get("searchResults"), "sync", this.renderMetricsView );
                return;
              }

              //Get all the facet counts from the search results collection
              var facetCounts = this.model.get("allSearchResults").facetCounts,
                  //Get the id facet counts
                  idFacets = facetCounts? facetCounts.id : [],
                  //Get the documents facet counts
                  documentsFacets = facetCounts? facetCounts.documents : [],
                  //Start an array to hold all the ids
                  allIDs = [];

              //If there are resource map facet counts, get all the ids
              if( idFacets && idFacets.length ){

                //Merge the id and documents arrays
                var allFacets = idFacets.concat(documentsFacets);

                //Get all the ids, which should be every other element in the
                // facets array
                for( var i=0; i < allFacets.length; i+=2 ){
                  allIDs.push( allFacets[i] );
                }

                //Create a search model that filters by all the data object Ids
                var statsSearchModel = new SearchModel({
                  idOnly: allIDs,
                  formatType: [],
                  exclude: []
                });

                //Create a StatsModel
                var statsModel = new StatsModel({
                  query: statsSearchModel.getQuery(),
                  searchModel: statsSearchModel,
                  supportDownloads: false
                });

              }

              // add a stats view
              this.sectionMetricsView = new StatsView({
                  title: "Statistics and Figures",
                  description: "A summary of all datasets from " + this.model.get("label"),
                  el: "#metrics",
                  model: statsModel
              });

              this.sectionMetricsView.render();

              this.subviews.push(this.sectionMetricsView);

            },

            /*
            * If the given project doesn't exist, display a Not Found message.
            */
            showNotFound: function(){

              var notFoundMessage = "The project \"" + (this.projectName || this.projectId) +
                                    "\" doesn't exist.",
                  notification = this.alertTemplate({
                    classes: "alert-error",
                    msg: notFoundMessage,
                    includeEmail: true
                  });

              this.$el.html(notification);

            },

            /*
             * This function is called when the app navigates away from this view.
             * Any clean-up or housekeeping happens at this time.
             */
            onClose: function() {
                //Remove each subview from the DOM and remove listeners
                _.invoke(this.subviews, "remove");

                this.subviews = new Array();

                delete this.sectionMetricsView;

                $("body").removeClass("ProjectView");
            }
        });

        return ProjectView;
    });