/* eslint-disable no-bitwise */
/**
 * @module modules/zoom-sk
 * @description A module that shows a zoomed in view of the canvas
 * Like commands-sk and histogram, the zoom module is another case of data
 * (a cursor location) that can be viewed and controlled from two modules.
 *
 * The zoom module shows the cursor location by where it sources data from
 * its source canvas, and allows the cursor to be moved by clicking on the zoom
 * canvas or by key bindings
 *
 * The crosshair (which is part of debug-view-sk) also shows the cursor location
 * and allows it to be moved. The cursor location is owned by zoom-sk, and
 * communicated to debug-view-sk via events.
 *
 * The zoom element also contains a textural readout of the cursor position
 * and color of the selected pixel.
 *
 * @evt move-cursor emitted when the user changes the cursor position by clicking
 *   the zoom view. The position is a coordinate in the source canvas.
 *   See debugger-page-sk for more info on move-cursor and render-cursor
 */
import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { ElementDocSk } from '../element-doc-sk/element-doc-sk';
import {
  CursorEventDetail,
  ToggleBackgroundEventDetail,
  Point,
  RenderCursorEvent,
  ToggleBackgroundEvent, MoveCursorEvent, BackgroundStyle,
} from '../events';

function clamp(c: number): number {
  return Math.round(Math.max(0, Math.min(c || 0, 255)));
}

export class ZoomSk extends ElementDocSk {
  private static template = (ele: ZoomSk) => html`
<dl>
  <dt><b>Postion</b></dt>
  <dd>(${ele._cursor[0]}, ${ele._cursor[1]})</dd>
  <dt><b>Color</b></dt>
  <dd>
    <div class=color-preview id=prevColor style="background-color: ${ele._rgb}">
    </div>${ele._rgb}
  </dd>
  <dd>${ele._hex}</dd>
</dl>
<div> <!-- this div is block while the one inside it is inline-block -->
  <div class="${ele._backdropStyle} shrink">
    <canvas class="zoom-canvas" width=228 height=228
      @click=${ele._canvasClicked}></canvas>
  </div>
</div>
<details>
  <summary><b>Keyboard shortcuts</b></summary>
  <table class=shortcuts>
    <tr><th>H</th><td>Cursor left</td></tr>
    <tr><th>L</th><td>Cursor right</td></tr>
    <tr><th>J</th><td>Cursor down</td></tr>
    <tr><th>K</th><td>Cursor up</td></tr>
    <tr><th>.</th><td>Step command forward</td></tr>
    <tr><th>,</th><td>Step command back</td></tr>
    <tr><th>w</th><td>Previous Frame</td></tr>
    <tr><th>s</th><td>Next Frame</td></tr>
    <tr><th>p</th><td>Play/Pause frame playback </td></tr>
    <tr><td colspan=2>Click the image again to turn off keyboard navigation.</td></tr>
  </table>
</details>`;

  // Our own canvas
  private _canvas: HTMLCanvasElement | null = null;

  // The other canvas we are showing a zoomed view of
  private _source: HTMLCanvasElement | null = null;

  // cursor location. origin is top left
  private _cursor: Point = [0, 0];

  // color of the last selected pixel
  private _rgb = '';

  private _hex = '';

  private _backdropStyle: BackgroundStyle = 'light-checkerboard';

  // must be an odd number of pixels
  // view is square, this is width and height
  private static ps = 12; // width of one zoomed pixel

  private static viewSize = 228

  private static size = 19; // * 12x zoom

  private static halfSize = 9;

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

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

    this._canvas = this.querySelector<HTMLCanvasElement>('canvas')!;

    this.addDocumentEventListener(RenderCursorEvent, (e) => {
      const detail = (e as CustomEvent<CursorEventDetail>).detail;
      // these three steps cannot happen in any other order, hence the repeated condition.
      if (!detail.onlyData) {
        this._cursor = detail.position;
      }
      this.update(); // to draw the canvas from the new cursor
      this._render(); // to update the textual readout of the cursor in the template
    });

    this.addDocumentEventListener(ToggleBackgroundEvent, (e) => {
      this._backdropStyle = (e as CustomEvent<ToggleBackgroundEventDetail>).detail.mode;
      this._render();
    });
  }

  set source(newsource: HTMLCanvasElement) {
    this._source = newsource;
  }

  get point(): Point {
    return this._cursor;
  }

  /** Redraw the zoomed in canvas */
  update(): void {
    const ctx = this._canvas!.getContext('2d')!;

    // Clears to transparent black. it's important that the checkerboard show through.
    ctx.clearRect(0, 0, this._canvas!.width, this._canvas!.height);

    // html canvas origin is top left.
    const sourcex = this._cursor[0] - ZoomSk.halfSize;
    const sourcey = this._cursor[1] - ZoomSk.halfSize;
    ctx.imageSmoothingEnabled = false;
    ctx.drawImage(this._source!, sourcex, sourcey, ZoomSk.size, ZoomSk.size,
      0, 0, ZoomSk.viewSize, ZoomSk.viewSize);

    // Box one selected pixel in the exact middle of the canvas.
    ctx.strokeRect(ZoomSk.halfSize * ZoomSk.ps + 0.5, ZoomSk.halfSize * ZoomSk.ps + 0.5,
      ZoomSk.ps, ZoomSk.ps);

    // store the color of the selected pixel.
    // gives a UInt8ClampedArray of RGBA
    const c = ctx.getImageData(ZoomSk.viewSize / 2, ZoomSk.viewSize / 2, 1, 1).data;
    this._rgb = `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${c[3]})`;
    this._hex = ((
      (clamp(c[0]) << 24)
      | (clamp(c[1]) << 16)
      | (clamp(c[2]) << 8)
      | ((clamp(c[3]) << 0) & 0xFFFFFFF)) >>> 0).toString(16);
  }

  // convert click in zoomed view to coordinates in source canvas
  // skia origin is top left
  private _canvasClicked(e: MouseEvent) {
    e.preventDefault();
    e.stopPropagation();
    const x = Math.floor((e.offsetX - 1) / ZoomSk.ps) - ZoomSk.halfSize;
    const y = Math.floor(e.offsetY / ZoomSk.ps) - ZoomSk.halfSize;
    const cx = Math.min(Math.max(this._cursor[0] + x, 0), this._source!.width);
    const cy = Math.min(Math.max(this._cursor[1] + y, 0), this._source!.height);
    // Don't render yet, just send the event, headquarters will tell you when to render.
    // Emit zoom-point
    this.dispatchEvent(
      new CustomEvent<CursorEventDetail>(
        MoveCursorEvent, {
          detail: { position: [cx, cy], onlyData: false },
          bubbles: true,
        },
      ),
    );
  }
}

define('zoom-sk', ZoomSk);
