# Source: src/js/views/maps/LayerDetailView.js

    'use strict';

    define(
      [
        'jquery',
        'underscore',
        'backbone',
        'models/maps/assets/MapAsset',
        'text!templates/maps/layer-detail.html',
      ],
      function (
        $,
        _,
        Backbone,
        MapAsset,
        Template
      ) {

        /**
        * @class LayerDetailView
        * @classdesc A LayerDetailView creates a section to be inserted into a
        * LayerDetailsView. It renders a label and a toggle to collapse and expand the
        * section's contents. The contents of the Detail section can be rendered by any other
        * view, but the view should be one that shows details about a MapAsset or allows
        * editing elements of the MapAsset.
        * @classcategory Views/Maps
        * @name LayerDetailView
        * @extends Backbone.View
        * @screenshot views/maps/LayerDetailView.png
        * @since 2.18.0
        * @constructs
        */
        var LayerDetailView = Backbone.View.extend(
          /** @lends LayerDetailView.prototype */{

            /**
            * The type of View this is
            * @type {string}
            */
            type: 'LayerDetailView',

            /**
            * The HTML classes to use for this view's element
            * @type {string}
            */
            className: 'layer-detail',

            /**
            * The model that this view uses
            * @type {MapAsset}
            */
            model: undefined,

            /**
             * The primary HTML template for this view
             * @type {Underscore.template}
             */
            template: _.template(Template),

            /**
             * CSS classes for HTML elements within this view.
             * @property {string} toggle The element in the template that acts as a toggle to
             * expand or collapse this Layer Detail section.
             * @property {string} open The class to add to the view when the contents are
             * visible (i.e. the section is expanded)
             * @property {string} noHeader The class to add to the view when there is no
             * title/label and the view is not collapsible.
             * @property {string} label The element that holds the view's label text
             * @property {string} contentContainer The container into which the contentView's
             * rendered content will be placed
             */
            classes: {
              open: 'layer-detail--open',
              noHeader: 'layer-detail--no-header',
              label: 'layer-detail__label',
              toggle: 'layer-detail__toggle',
              contentContainer: 'layer-detail__content'
            },

            /**
             * Indicates whether this section is collapsed or expanded
             * @type {Boolean}
             */
            isOpen: true,

            /**
             * The name to display for the Layer Detail section
             * @type {string}
             */
            label: null,

            /**
             * The sub-view that will show details about, or allow editing of, the given Layer
             * model. The contentView will be passed the Layer model.
             * @type {Backbone.View}
             */
            contentView: null,

            /**
            * Creates an object that gives the events this view will listen to and the
            * associated function to call. Each entry in the object has the format 'event
            * selector': 'function'.
            * @returns {Object}
            */
            events: function () {
              var events = {};
              // Collapse or expand this Detail section when the toggle button is clicked. Get
              // the class of the toggle button from the classes property set in this view.
              events['click .' + this.classes.toggle] = 'toggle'
              return events
            },

            /**
            * Executed when a new LayerDetailView is created
            * @param {Object} [options] - A literal object with options to pass to the view
            */
            initialize: function (options) {

              try {
                // Get all the options and apply them to this view
                if (typeof options == 'object') {
                  for (const [key, value] of Object.entries(options)) {
                    this[key] = value;
                  }
                }
              } catch (e) {
                console.log('A LayerDetailView failed to initialize. Error message: ' + e);
              }

            },

            /**
            * Renders this view
            * @return {LayerDetailView} Returns the rendered view element
            */
            render: function () {

              try {

                // Save a reference to this view
                var view = this;

                // Ensure the view's main element has the given class name
                this.el.classList.add(this.className);

                // Display the section's contents depending on the view's initial setting
                if (this.isOpen) {
                  this.el.classList.add(this.classes.open);
                }

                // Insert the template into the view
                this.$el.html(this.template({
                  label: this.label,
                  collapsible: this.collapsible,
                  showTitle: this.showTitle
                }));

                // Render the content for this Layer Detail section
                if (this.contentView) {
                  var contentContainer = this.el.querySelector(
                    '.' + this.classes.contentContainer
                  )
                  this.renderedContentView = new this.contentView({
                    model: this.model
                  })
                  contentContainer.append(this.renderedContentView.el)
                  this.renderedContentView.render()
                }

                if (!this.collapsible && !this.showTitle) {
                  this.el.classList.add(this.classes.noHeader);
                }

                return this

              }
              catch (error) {
                console.log(
                  'There was an error rendering a LayerDetailView' +
                  '. Error details: ' + error
                );
              }
            },

            /**
             * Show or hide this section's contents by adding or removing the open class.
             */
            toggle : function(){
              try {
                this.el.classList.toggle(this.classes.open)
                if (this.isOpen) {
                  this.isOpen = false
                } else {
                  this.isOpen = true
                }
              }
              catch (error) {
                console.log(
                  'There was an error toggling a LayerDetailView' +
                  '. Error details: ' + error
                );
              }
            },

            /**
             * Perform clean-up functions when this view is about to be removed from the page
             * or navigated away from.
             */
            onClose: function () {
              try {
                if (
                  this.renderedContentView &&
                  typeof this.renderedContentView.onClose === 'function'
                ) {
                  this.renderedContentView.onClose()
                }
              }
              catch (error) {
                console.log(
                  'There was an error performing clean up functions in a LayerDetailView' +
                  '. Error details: ' + error
                );
              }
            }

          }
        );

        return LayerDetailView;

      }
    );