/* 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 { html } from 'lit-html';
import { define } from '../../../elements-sk/modules/define';
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);
