/**
 * @module modules/histogram-sk
 *
 * @description A visual representation of the command name counts totalled by
 * commands-sk when a frame is loaded, and a controller for the set of included
 * command names in the filter (also in commands-sk).
 *
 * It's not an indepentent model-view-controller, just a view-controller for a
 * model in commands-sk. The main reason it's a seperate module is that it's
 * visually self-contained in different element elsewhere on the page, and as
 * far as I know commandsSk cannot export two different elements.
 *
 * Due to the functionality depending on the integration with commands-sk,
 * this module is tested in debugger-page-sk_test.ts.
 *
 * @evt toggle-command-inclusion: Emitted when a row is clicked, indicating it's
 * inclusion in the command filter should be toggled.
 */
import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { ElementDocSk } from '../element-doc-sk/element-doc-sk';

import {
  HistogramUpdateEventDetail, HistogramEntry,
  HistogramUpdateEvent,
  ToggleCommandInclusionEvent,
  ToggleCommandInclusionEventDetail,
} from '../events';

export class HistogramSk extends ElementDocSk {
  private static template = (ele: HistogramSk) => html`
<details title="A table of the number of occurrences of each command." open>
  <summary><b>Histogram</b></summary>
  <table>
    <tr>
      <td title="Occurrences of command in current frame (or single frame skp file).">frame</td>
      <td title="Occurrences of command within the current range filter.">range</td>
      <td>name</td>
    </tr>
    ${ele._hist.map((item: HistogramEntry) => HistogramSk.rowTemplate(ele, item))}
    <tr><td class=countCol>${ele._total()}</td><td><b>Total</b></td></tr>
  </table>
</details>`;

  private static rowTemplate = (ele: HistogramSk, item: HistogramEntry) => html`
<tr @click=${() => { ele._toggle(item.name); }} id="hist-row-${item.name.toLowerCase()}"
    class="${ele._incl.has(item.name.toLowerCase()) ? '' : 'pinkBackground'}">
  <td class=countCol>${item.countInFrame}</td>
  <td class=countCol>${item.countInRange}</td>
  <td>${item.name}</td>
</tr>`;

  // counts of command occurrences
  private _hist: HistogramEntry[] = [];

  // commands which the filter includes
  private _incl = new Set<string>();

  private _total(): number {
    let total = 0;
    for (const item of this._hist) {
      total += item.countInRange;
    }
    return total;
  }

  constructor() {
    super(HistogramSk.template);
  }

  connectedCallback(): void {
    super.connectedCallback();
    this._render();

    this.addDocumentEventListener(HistogramUpdateEvent, (e) => {
      const detail = (e as CustomEvent<HistogramUpdateEventDetail>).detail;
      // event may update one or both items
      if (detail.hist) {
        this._hist = detail.hist;
      }
      if (detail.included) {
        this._incl = detail.included;
      }
      this._render();
    });
  }

  // Toggle the given item in or out of the included set in commands-sk
  private _toggle(name: string) {
    const lowerName = name.toLowerCase();
    // short cut to change our own appearance
    if (this._incl.has(lowerName)) {
      this._incl.delete(lowerName);
    } else {
      this._incl.add(lowerName);
    }
    this._render();

    // but make sure to tell the module that actually owns this model
    this.dispatchEvent(
      new CustomEvent<ToggleCommandInclusionEventDetail>(
        ToggleCommandInclusionEvent, {
          detail: { name: lowerName },
          bubbles: true,
        },
      ),
    );
  }
}

define('histogram-sk', HistogramSk);
