/**
 * @module meteoJS/timeline/visualisation/bsDropdown
 */
import $ from 'jquery';
import Visualisation from '../Visualisation.js';
import Text from './Text.js';

/**
 * Options for constructor.
 * 
 * @typedef {module:meteoJS/timeline/visualisation~options}
 *   module:meteoJS/timeline/visualisation/bsDropdown~options
 * @param {string|undefined} format
 *   Format string for dropdown items, used for 'getTimeText'.
 * @param {string|undefined} buttonFormat
 *   Format string for dropdown button, used for 'getTimeText'.
 * @param {string} grouping
 *   'daily', 'hourly' or a format string. Defines if items will be grouped and
 *   be title depending on groupingDivider and groupingFormat.
 * @param {boolean} groupingDivider Show dropdown divider above an item group.
 * @param {undefined|string} groupingFormat
 *   Format string for a dropdown header above an item group.
 * @param {undefined|string} classMain Class for the main node.
 * @param {undefined|string} classDropdownMenu Class for the dropdown node.
 * @param {undefined|string} classDropdownItem Class for a dropdown item.
 * @param {undefined|string} classItemActive Class for an active item.
 * @param {undefined|string} classItemNotEnabled Class for a not enabled item.
 * @param {undefined|string} classItemEnabled Class for an enabled item.
 * @param {undefined|string} classItemAllEnabled Class for an all enabled item.
 * @param {undefined|string} classDropdownHeader Class for dropdown header.
 * @param {undefined|string} classDropdownDivider Class for dropdown divider.
 * @param {undefined|string} classDropdownButton Class for the dropdown button.
 * @param {undefined|string} classButtonNotEnabled
 *   Class for the dropdown button if the selected time is not enabled.
 * @param {undefined|string} classButtonEnabled
 *   Class for the dropdown button if the selected time is enabled.
 * @param {undefined|string} classButtonAllEnabled
 *   Class for the dropdown button if the selected time is all enabled.
 */

/**
 * Show timeline in a dropdown menu. The menu will be build according to
 * bootstrap.
 * 
 * <pre><code>import bsDropdown from 'meteojs/timeline/visualisation/bsDropdown';</code></pre>
 * 
 * @extends module:meteoJS/timeline/visualisation.Visualisation
 */
export class bsDropdown extends Visualisation {
  
  /**
   * @param {module:meteoJS/timeline/visualisation/bsDropdown~options} options - Options.
   */
  constructor({
    format = 'HH:mm',
    buttonFormat = 'DD. MMMM YYYY HH:mm',
    grouping = 'daily',
    groupingDivider = true,
    groupingFormat = 'ddd, DD. MMMM YYYY',
    classMain = 'dropdown',
    classDropdownMenu = 'dropdown-menu',
    classDropdownItem = 'dropdown-item',
    classItemActive = 'active',
    classItemNotEnabled = 'disabled',
    classItemEnabled = undefined,
    classItemAllEnabled = undefined,
    classDropdownHeader = 'dropdown-header',
    classDropdownDivider = 'dropdown-divider',
    classDropdownButton = 'btn dropdown-toggle',
    classButtonNotEnabled = undefined,
    classButtonEnabled = undefined,
    classButtonAllEnabled = undefined,
    ...rest
  } = {}) {
    super(rest);
    
    this.options.format = format;
    this.options.buttonFormat = buttonFormat;
    this.options.grouping = grouping;
    this.options.groupingDivider = groupingDivider;
    this.options.groupingFormat = groupingFormat;
    this.options.classMain = classMain;
    this.options.classDropdownMenu = classDropdownMenu;
    this.options.classDropdownItem = classDropdownItem;
    this.options.classItemActive = classItemActive;
    this.options.classItemNotEnabled = classItemNotEnabled;
    this.options.classItemEnabled = classItemEnabled;
    this.options.classItemAllEnabled = classItemAllEnabled;
    this.options.classDropdownHeader = classDropdownHeader;
    this.options.classDropdownDivider = classDropdownDivider;
    this.options.classDropdownButton = classDropdownButton;
    this.options.classButtonNotEnabled = classButtonNotEnabled;
    this.options.classButtonEnabled = classButtonEnabled;
    this.options.classButtonAllEnabled = classButtonAllEnabled;
    
    /**
     * @member {module:meteoJS/timeline/visualisation/text.Text}
     * @private
     */
    this.visualisationButtonText = new Text({
      timeline: this.options.timeline,
      format: this.options.buttonFormat,
      textInvalid: this.options.textInvalid,
      outputTimezone: this.options.outputTimezone,
      getTimeText: this.options.getTimeText
    });
    /**
     * @member {external:jQuery|undefined}
     * @private
     */
    this.dropdownNode = undefined;
    
    this.setNode(this.options.node);
  }
  
  /**
   * @inheritdoc
   */
  setOutputTimezone(outputTimezone) {
    super.setOutputTimezone(outputTimezone);
    this.visualisationButtonText.setOutputTimezone(outputTimezone);
    return this;
  }
  
  /**
   * @inheritdoc
   */
  onChangeTime() {
    if (this.dropdownNode === undefined)
      return;
    
    var time = this.options.timeline.getSelectedTime();
    this.options.node.children('li').children('button')
      .removeClass(this.options.classButtonActive)
      .removeClass(this.options.classButtonNotEnabled)
      .removeClass(this.options.classButtonEnabled)
      .removeClass(this.options.classButtonAllEnabled);
    if (this.options.timeline.isTimeAllEnabled(time))
      this.options.node.children('button')
        .addClass(this.options.classButtonAllEnabled);
    else if (this.options.timeline.isTimeEnabled(time))
      this.options.node.children('button')
        .addClass(this.options.classButtonEnabled);
    else
      this.options.node.children('button')
        .addClass(this.options.classButtonNotEnabled);
    var that = this;
    this.dropdownNode
      .children('li')
      .children('button.'+this.options.classDropdownItem)
      .each(function () {
        var t = new Date(+$(this).data('time'));
        $(this)
          .removeClass(that.options.classItemActive)
          .removeClass(that.options.classItemNotEnabled)
          .removeClass(that.options.classItemEnabled)
          .removeClass(that.options.classItemAllEnabled);
        if (time.valueOf() == t.valueOf())
          $(this).addClass(that.options.classItemActive);
        else if (that.options.timeline.isTimeAllEnabled(t))
          $(this).addClass(that.options.classItemAllEnabled);
        else if (that.options.timeline.isTimeEnabled(t))
          $(this).addClass(that.options.classItemEnabled);
        else
          $(this).addClass(that.options.classItemNotEnabled);
      });
  }
  
  /**
   * @inheritdoc
   */
  onChangeTimes() {
    if (this.dropdownNode === undefined)
      this.dropdownNode = $('<div>');
    this.dropdownNode.empty();
    
    var groupingFormat =
            (this.options.grouping == 'daily') ? 'YYYY-MM-DD' :
              (this.options.grouping == 'hourly') ? 'YYYY-MM-DD HH' :
                this.options.grouping;
    var lastGroupTimeStr = undefined;
    this.getTimelineTimes().forEach(function (time) {
      if (lastGroupTimeStr === undefined ||
                    lastGroupTimeStr != this.timeToText(time, groupingFormat)) {
        if (lastGroupTimeStr !== undefined && // No divider at the beginning
                        this.options.groupingDivider)
          this.dropdownNode
            .append($('<div>')
              .addClass(this.options.classDropdownDivider));
        if (this.options.groupingFormat !== undefined)
          this.dropdownNode
            .append($('<h6>')
              .addClass(this.options.classDropdownHeader)
              .text(this.timeToText(time, this.options.groupingFormat)));
        lastGroupTimeStr = this.timeToText(time, groupingFormat);
      }
      var btn = $('<button>')
        .addClass(this.options.classDropdownItem)
        .attr('type', 'button')
        .text(this.timeToText(time, this.options.format))
        .data('time', time.valueOf());
      var that = this;
      btn.click(function () {
        that.options.timeline.setSelectedTime(new Date(+$(this).data('time')));
        that.trigger('input');
      });
      this.dropdownNode.append($('<li>').append(btn));
    }, this);
  }
  
  /**
   * @inheritdoc
   */
  emptyNode() {
    if (this.visualisationButtonText !== undefined)
      this.visualisationButtonText.setNode(undefined);
    this.dropdownNode = undefined;
    this.options.node.empty();
  }
  
  /**
   * @inheritdoc
   */
  onInitNode() {
    var id = 'dropdownMenuButton';
    var i=0;
    while (document.getElementById(id) != null) {
      id = 'dropdownMenuButton'+(++i);
    }
    
    var button = $('<button>')
      .addClass(this.options.classDropdownButton)
      .attr('type', 'button')
      .attr('id', id)
      .attr('data-bs-toggle', 'dropdown')
      .attr('aria-haspopup', true)
      .attr('aria-expanded', false);
    this.visualisationButtonText.setNode(button);
    this.dropdownNode = $('<ul>')
      .addClass(this.options.classDropdownMenu)
      .attr('aria-labelledby', id);
    this.options.node
      .addClass(this.options.classMain)
      .append(button)
      .append(this.dropdownNode);
  }
  
}
export default bsDropdown;