/**
 * @module modules/debugger-page-sk
 * @description The main module of the wasm-based SKP and MSKP debugger.
 *  Holds the loaded wasm module, pointer to the Surface in wasm, and SKP file state.
 *  Handles all the interaction and control of the application that does not cleanly fit
 *  within a submodule.
 *
 * @evt render-cursor: Emitted when the cursor changes position, or the data under it changes.
 *      There are three modules which can both change, and render representatoins of the cursor.
 *      - debugger-page-sk: Can change the cursor with keypresses, can change the data under
 *                          the cursor, uses the cursor to provide a jump-to-command feature.
 *      - debug-view-sk: Can change the cursor by clicking on the canvas, or mousing over the
 *                       canvas. Shows a visual crosshair to represent the cursor.
 *      - zoom-sk: Can change the cursor by clicking pixels on the zoom canvas. Shows data that
 *                 depends on the cursor location and data under the cursor.
 *      To solve this coordination problem, everything is sent through debugger-page-sk
 *      When the zoom or debug-view modules move the cursor, they emit move-cursor but
 *      don't render. debugger-page-sk receives this, renders itself, and re-emits render-cursor,
 *      which zoom, and debug-view consume. If the change originates from debugger-page-sk,
 *      it only emits render-cursor.
 *
 *       [               ] --- move-cursor --> [           ] <-- move-cursor --- [         ]
 *       [ debug-view-sk ]                     [ debugger- ]                     [ zoom-sk ]
 *       [               ] <- render-cursor -- [ page-sk   ] -- render-cursor -> [         ]
 */
import { define } from '../../../elements-sk/modules/define';
import { html, TemplateResult } from 'lit-html';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';
import '../../../elements-sk/modules/tabs-sk';
import '../../../elements-sk/modules/tabs-panel-sk';
import { TabsSk } from '../../../elements-sk/modules/tabs-sk/tabs-sk';
import '../../../elements-sk/modules/checkbox-sk';
import { CheckOrRadio } from '../../../elements-sk/modules/checkbox-sk/checkbox-sk';
import { ElementDocSk } from '../element-doc-sk/element-doc-sk';
import { DebugViewSk } from '../debug-view-sk/debug-view-sk';
import { CommandsSk } from '../commands-sk/commands-sk';
import { TimelineSk } from '../timeline-sk/timeline-sk';
import { PlaySk } from '../play-sk/play-sk';
import { ZoomSk } from '../zoom-sk/zoom-sk';
import '../../../elements-sk/modules/error-toast-sk';
import { AndroidLayersSk } from '../android-layers-sk/android-layers-sk';
import { ResourcesSk } from '../resources-sk/resources-sk';
import '../../../infra-sk/modules/theme-chooser-sk';
import '../../../infra-sk/modules/app-sk';

// Types for the wasm bindings
import type {
  Canvas,
  CanvasKit,
  CanvasKitInitOptions,
  Paint,
  Surface,
}
// @ts-ignore
from '../../wasm_libs/types/canvaskit'; // gazelle:ignore
import {
  Debugger,
  Matrix3x3,
  Matrix4x4,
  MatrixClipInfo,
  SkIRect,
  SkpDebugPlayer,
  SkpJsonCommandList,
} from '../debugger';

// other modules from this application
import '../android-layers-sk';
import '../commands-sk';
import '../debug-view-sk';
import '../histogram-sk';
import '../resources-sk';
import '../timeline-sk';
import '../zoom-sk';
import {
  InspectLayerEventDetail,
  CursorEventDetail,
  ToggleBackgroundEventDetail,
  InspectLayerEvent,
  JumpCommandEvent,
  JumpCommandEventDetail,
  ModeChangedManuallyEvent,
  MoveCommandPositionEvent,
  MoveCommandPositionEventDetail,
  MoveCursorEvent,
  MoveFrameEvent,
  Point,
  RenderCursorEvent,
  SelectImageEvent,
  SelectImageEventDetail,
  ToggleBackgroundEvent, ModeChangedManuallyEventDetail, MoveFrameEventDetail,
} from '../events';

// Declarations for variables defined in JS files included by main.html;
// It is assumed that canvaskit.js has been loaded and this symbol is available globally.
declare function CanvasKitInit(opts: CanvasKitInitOptions): Promise<Debugger>;
declare const SKIA_VERSION: string;

interface FileContext {
  player: SkpDebugPlayer;
  version: number;
  frameCount: number;
}

export class DebuggerPageSk extends ElementDocSk {
  private static template = (ele: DebuggerPageSk) => html`
  <app-sk>
    <header>
      <h2>Skia WASM Debugger</h2>
      <span>
        <a class="version-link"
          href="https://skia.googlesource.com/skia/+show/${ele._skiaVersion}"
          title="The skia commit at which the debugger WASM module was built">
          ${ele._skiaVersionShort}
        </a>
        &nbsp;
        <a href="/versions">Older Debugger Versions</a>
        <theme-chooser-sk></theme-chooser-sk>
      </span>
    </header>
    <main id=content>
      <div class="horizontal-flex">
        <label>SKP to open:</label>
        <input type="file" @change=${ele._fileInputChanged}
         ?disabled=${ele._debugger === null} />
        <a href="https://skia.org/dev/tools/debugger">User Guide</a>
        <p class="file-version">File version: ${ele._fileContext?.version}</p>
        <p class="file-version">Minimum version this build can open: ${ele._debugger?.MinVersion()}</p>
      </div>
      <timeline-sk></timeline-sk>
      <div class="horizontal-flex-start">
        <commands-sk></commands-sk>
        <div id=center>
          <tabs-sk id='center-tabs'>
            <button class=selected>SKP</button>
            <button>Image Resources</button>
          </tabs-sk>
          <tabs-panel-sk>
            <div>
              <debug-view-sk></debug-view-sk>
            </div>
            <div>
              <resources-sk></resources-sk>
            </div>
          </tabs-panel-sk>
        </div>
        <div id=right>
          ${DebuggerPageSk.controlsTemplate(ele)}
          <histogram-sk></histogram-sk>
          <div>Command which shaded the<br>selected pixel: ${ele._pointCommandIndex}
            <button @click=${() => {
    ele._jumpToCommand(ele._pointCommandIndex);
  }}>Jump</button>
          </div>
          <zoom-sk></zoom-sk>
          <android-layers-sk></android-layers-sk>
        </div>
      </div>
    </main>
    <footer>
      <error-toast-sk></error-toast-sk>
    </footer>
  </app-sk>
    `;

  private static controlsTemplate = (ele: DebuggerPageSk) => html`
    <div>
      <table>
        <tr>
          <td><checkbox-sk label="GPU" ?checked=${ele._gpuMode}
               title="Toggle between Skia making WebGL2 calls vs. using it's CPU backend and\
 copying the buffer into a Canvas2D element."
                       @change=${ele._gpuHandler}></checkbox-sk></td>
          <td><checkbox-sk label="Display GPU Op Bounds" ?disabled=${!ele._gpuMode}
               title="Show a visual representation of the GPU operations recorded in each\
 command's audit trail."
                       @change=${ele._opBoundsHandler}></checkbox-sk></td>
        </tr>
        <tr>
          <td><checkbox-sk label="Light/Dark"
               title="Show transparency backrounds as light or dark"
                       @change=${ele._lightDarkHandler}></checkbox-sk></td>
          <td><checkbox-sk label="Display Overdraw Viz"
               title="Shades pixels redder in proportion to how many times they were written\
 to in the current frame."
                       @change=${ele._overdrawHandler}></checkbox-sk></td>
        </tr>
      </table>
      <details ?open=${ele._showOpBounds}>
        <summary><b> GPU Op Bounds Legend</b></summary>
        <p style="width: 200px">GPU op bounds are rectangles with a 1 pixel wide stroke. This may\
 mean you can't see them unless you scale the canvas view to its original size.</p>
        <table class=shortcuts>
          <tr><td class=gpuDrawBoundColor>Bounds for the current draw.</td></tr>
          <tr><td class=gpuOpBoundColor>Individual bounds for other draws in the same op.</td></tr>
          <tr><td class=gpuTotalOpColor>Total bounds of the current op.</td></tr>
        </table>
      </details>
      <details open>
        <summary><b>Overlay Options</b></summary>
        <checkbox-sk label="Show Clip"
                     title="Show a semi-transparent teal overlay on the areas within the current\
 clip."
                     id=clip @change=${ele._clipHandler}></checkbox-sk>
        <checkbox-sk label="Show Android Device Clip Restriction"
                     title="Show a semi-transparent peach overlay on the areas within the current\
 andorid device clip restriction.
                     This is set at the beginning of each frame and recorded in the DrawAnnotation\
 Command labeled AndroidDeviceClipRestriction"
                     id=androidclip @change=${ele._androidClipHandler}></checkbox-sk>
        <checkbox-sk label="Show Origin"
                     title="Show the origin of the coordinate space defined by the current matrix."
                     id=origin @change=${ele._originHandler}></checkbox-sk>
        <div class="horizontal-flex">
          <div class="matrixClipBox">
            <h3 class="compact">Clip</h3>
            <table>
              <tr><td>${ele._info.ClipRect[0]}</td><td>${ele._info.ClipRect[1]}</td></tr>
              <tr><td>${ele._info.ClipRect[2]}</td><td>${ele._info.ClipRect[3]}</td></tr>
            </table>
          </div>
          <div class="matrixClipBox">
            <h3 class="compact">Matrix</h3>
            <table>
              ${ele._matrixTable(ele._info.ViewMatrix)}
            </table>
          </div>
        </div>
      </details>
    </div>`;

  // defined by version.js which is included by main.html and generated in Makefile.
  private _skiaVersion: string = SKIA_VERSION;

  private _skiaVersionShort: string = SKIA_VERSION.substring(0, 7);

  // null as long as no file loaded.
  private _fileContext: FileContext | null = null;

  // null until the DebuggerInit promise resolves.
  private _debugger: Debugger | null = null;

  // null until either file loaded or cpu/gpu switch toggled
  private _surface: Surface | null = null;

  // submodules are null until first template render
  private _androidLayersSk: AndroidLayersSk | null = null;

  private _debugViewSk: DebugViewSk | null = null;

  private _commandsSk: CommandsSk | null = null;

  private _resourcesSk: ResourcesSk | null = null;

  private _timelineSk: TimelineSk | null = null;

  private _zoom: ZoomSk | null = null

  // application state
  private _targetItem: number = 0; // current command playback index in filtered list

  // When turned on, always draw to the end of a frame
  private _drawToEnd: boolean = false;

  // the index of the last command to alter the pixel under the crosshair
  private _pointCommandIndex = 0;

  // The matrix and clip retrieved from the last draw
  private _info: MatrixClipInfo = {
    ClipRect: [0, 0, 0, 0],
    ViewMatrix: [
      [1, 0, 0],
      [0, 1, 0],
      [0, 0, 1],
    ],
  };

  // things toggled by the upper right checkboxes.
  private _gpuMode = true; // true means use gpu

  private _showOpBounds = false;

  private _darkBackgrounds = false; // true means dark

  private _showOverdrawViz = false;

  private _showClip = false;

  private _showAndroidClip = false;

  private _showOrigin = false;

  constructor() {
    super(DebuggerPageSk.template);

    CanvasKitInit({
      locateFile: (file: string) => `/dist/${file}`,
    }).then((loadedWasmModule) => {
      // Save a reference to the module somewhere we can use it later.
      this._debugger = loadedWasmModule;
      // File input element should now be enabled, so we need to render.
      this._render();
      // It is now possible to load SKP files.
      this._checkUrlParams();
    });
  }

  connectedCallback(): void {
    super.connectedCallback();
    this._render();
    this._androidLayersSk = this.querySelector<AndroidLayersSk>('android-layers-sk')!;
    this._debugViewSk = this.querySelector<DebugViewSk>('debug-view-sk')!;
    this._commandsSk = this.querySelector<CommandsSk>('commands-sk')!;
    this._resourcesSk = this.querySelector<ResourcesSk>('resources-sk')!;
    this._timelineSk = this.querySelector<TimelineSk>('timeline-sk')!;
    this._zoom = this.querySelector<ZoomSk>('zoom-sk')!;

    this._zoom.source = this._debugViewSk.canvas;

    this._commandsSk.addEventListener(MoveCommandPositionEvent, (e) => {
      const detail = (e as CustomEvent<MoveCommandPositionEventDetail>).detail;
      this._targetItem = detail.position;
      this._updateDebuggerView();
      if (detail.paused) {
        this._updateJumpButton(this._zoom!.point);
      }
    });

    this._timelineSk.playsk.addEventListener(
      ModeChangedManuallyEvent, (e) => {
        const mode = (e as CustomEvent<ModeChangedManuallyEventDetail>).detail.mode;
        if (mode === 'pause') {
          this._setCommands();
        }
      },
    );

    // this is the timeline, which owns the frame position, telling this element to update
    this._timelineSk.addEventListener(MoveFrameEvent, (e) => {
      const frame = (e as CustomEvent<MoveFrameEventDetail>).detail.frame;
      this._moveFrameTo(frame);
    });

    // this is the command list telling us to show the resource viewer and select an image
    this._commandsSk.addEventListener(SelectImageEvent, (e) => {
      this.querySelector<TabsSk>('tabs-sk')!.select(1);
      const id = (e as CustomEvent<SelectImageEventDetail>).detail.id;
      this._resourcesSk!.selectItem(id, true);
    });

    this._androidLayersSk.addEventListener(InspectLayerEvent, (e) => {
      const detail = (e as CustomEvent<InspectLayerEventDetail>).detail;
      this._inspectLayer(detail.id, detail.frame);
      this.querySelector<TabsSk>('tabs-sk')!.select(0);
    });

    this.addDocumentEventListener('keydown', this._keyDownHandler.bind(this),
      true /* useCapture */);

    this.addDocumentEventListener(MoveCursorEvent, (e) => {
      const detail = (e as CustomEvent<CursorEventDetail>).detail;
      // Update this module's cursor-dependent element(s)
      this._updateJumpButton(detail.position);
      // re-emit event as render-cursor
      this.dispatchEvent(
        new CustomEvent<CursorEventDetail>(
          RenderCursorEvent, {
            detail: detail,
            bubbles: true,
          },
        ),
      );
    });
  }

  private _checkUrlParams(): void {
    const params = new URLSearchParams(window.location.search);
    if (params.has('url')) {
      const skpurl = params.get('url')!;
      fetch(skpurl).then((response) => response.arrayBuffer()).then((ab) => {
        if (ab) {
          this._openSkpFile(ab);
        } else {
          errorMessage(`No data received from ${skpurl}`);
        }
      });
    }
  }

  // Searches for the command which left the given pixel in it's current color,
  // Updates the Jump button with the result.
  // Consider disabling this feature alltogether for CPU backed debugging, too slow.
  private _updateJumpButton(p: Point): void {
    if (!this._debugViewSk!.crosshairActive) {
      return; // Too slow to do this on every mouse move.
    }
    this._pointCommandIndex = this._fileContext!.player.findCommandByPixel(
      this._surface!, p[0], p[1], this._targetItem,
    );
    this._render();
  }

  // Template helper rendering a number[][] in a table
  private _matrixTable(m: Matrix3x3 | Matrix4x4): TemplateResult[] {
    return (m as number[][]).map((row: number[]) => html`<tr>${row.map((i: number) => html`<td>${i}</td>`)}</tr>`);
  }

  // Called when the filename in the file input element changs
  private _fileInputChanged(e: Event): void {
    // Did the change event result in the file-input element specifing a file?
    // (user might have cancelled the dialog)
    const element = e.target as HTMLInputElement;
    if (element.files?.length === 0) {
      return;
    }
    const file = element.files![0];
    // Create a reader and a callback for when the file finishes being read.
    const reader = new FileReader();
    reader.onload = (e: ProgressEvent<FileReader>) => {
      if (e.target) {
        this._openSkpFile(e.target.result as ArrayBuffer);
      }
    };
    reader.readAsArrayBuffer(file);
  }

  // Finds the version number from the binary SKP or MSKP file format
  // This is done in JS because to avoid any chance of SkpFilePlayer crashing on old
  // versions and not reporting back with a version number.
  // Overall it was just a lot simpler to do it here.
  private _skpFileVersion(fileContents: ArrayBuffer): number {
    const utf8decoder = new TextDecoder();
    // only check up to 2000 bytes
    // MSKP files have a variable sized header before the internal SKP with the version
    // number we're looking for.
    const head = new Uint8Array(fileContents).subarray(0, 2000);
    function isMagicWord(element: number, index: number, array: Uint8Array) {
      return utf8decoder.decode(array.subarray(index, index + 8)) === 'skiapict';
    }
    // Note that we want to locate the offset in a Uint8Array, not in a string that
    // might interpret binary stuff before "skiapict" as multi-byte code points.
    const magicOffset = head.findIndex(isMagicWord);
    // The unint32 after the first occurance of "skiapict" is the SKP version
    return new Uint32Array(head.subarray(magicOffset + 8, magicOffset + 12))[0];
  }

  // Open an SKP or MSKP file. fileContents is expected to be an arraybuffer
  // with the file's contents
  private _openSkpFile(fileContents: ArrayBuffer): void {
    if (!this._debugger) { return; }
    const version = this._skpFileVersion(fileContents);
    const minVersion = this._debugger.MinVersion();
    if (version < minVersion) {
      errorMessage(`File version (${version}) is older than this skia build's minimum\
 supported version (${minVersion}). Debugger may crash if the file contains unreadable sections.`);
    }
    // Create the instance of SkpDebugPlayer and load the file.
    // This function is provided by helper.js in the JS bundled with the wasm module.
    const playerResult = this._debugger.SkpFilePlayer(fileContents);
    if (playerResult.error) {
      errorMessage(`SKP deserialization error: ${playerResult.error}`);
      return;
    }
    const p = playerResult.player;
    this._fileContext = {
      player: p,
      version: version,
      frameCount: p.getFrameCount(),
    };
    this._replaceSurface();
    if (!this._surface) {
      errorMessage('Could not create Surface, try GPU/CPU toggle.');
      return;
    }
    p.setGpuOpBounds(this._showOpBounds);
    p.setOverdrawVis(this._showOverdrawViz);
    p.setAndroidClipViz(this._showAndroidClip);
    p.setOriginVisible(this._showOrigin);
    this._showClip = false;
    p.setClipVizColor(0);

    console.log(`Loaded SKP file with ${this._fileContext.frameCount} frames`);
    this._resourcesSk!.reset();
    // Determine if we loaded a single-frame or multi-frame SKP.
    if (this._fileContext.frameCount > 1) {
      this._timelineSk!.count = this._fileContext.frameCount;
      this._timelineSk!.hidden = false;
      // shared images deserialproc only used with mskps
      this._resourcesSk!.update(p);
    } else {
      this._timelineSk!.hidden = true;
    }

    // Pull the command list for the first frame.
    // triggers render
    this._setCommands();
    this._androidLayersSk!.update(this._commandsSk!.layerInfo,
      this._fileContext!.player.getLayerSummariesJs(), 0);
  }

  // Create a new drawing surface. this should be called when
  // * GPU/CPU mode changes
  // * Bounds of the skp change (skp loaded)
  // * (not yet supported) Color mode changes
  private _replaceSurface(): void {
    if (!this._debugger) { return; }

    let width = 400;
    let height = 400;
    if (this._fileContext) {
      // From the loaded SKP, player knows how large its picture is. Resize our canvas
      // to match.
      const bounds = this._fileContext.player.getBounds();
      width = bounds.fRight - bounds.fLeft;
      height = bounds.fBottom - bounds.fTop;
      // Still ok to proceed if no skp, the toggle still should work before a file
      // is picked.
    }
    this._replaceSurfaceKnownBounds(width, height);
  }

  // replace surface, using the given size
  private _replaceSurfaceKnownBounds(width: number, height: number): void {
    if (!this._debugger) { return; }
    const canvas = this._debugViewSk!.resize(width, height);
    // free the wasm memory of the previous surface
    if (this._surface) { this._surface.dispose(); }
    if (this._gpuMode) {
      let glAttrs = {
        // for the zoom to be able to access the pixels. Incurs performance penalty
        'preserveDrawingBuffer': 1,
      };
      this._surface = this._debugger.MakeWebGLCanvasSurface(canvas,
        this._debugger.ColorSpace.SRGB, glAttrs);
    } else {
      this._surface = this._debugger.MakeSWCanvasSurface(canvas);
    }
    this._zoom!.source = canvas;
  }

  // Moves the player to a frame and updates dependent elements
  // Note that if you want to move the frame for the whole app, just as if a user did it,
  // this is not the function you're looking for, instead set this._timelineSk.item
  private _moveFrameTo(n: number): void {
    // bounds may change too, requiring a new surface and gl context, but this is costly and
    // only rarely necessary
    const oldBounds = this._fileContext!.player.getBounds();
    const newBounds = this._fileContext!.player.getBoundsForFrame(n);
    if (!this._boundsEqual(oldBounds, newBounds)) {
      const width = newBounds.fRight - newBounds.fLeft;
      const height = newBounds.fBottom - newBounds.fTop;
      this._replaceSurfaceKnownBounds(width, height);
    } else if (this._surface) {
      // When not changing size, it only needs to be cleared.
      this._surface.getCanvas().clear(this._debugger!.TRANSPARENT);
    }

    this._fileContext!.player.changeFrame(n);
    // If the frame moved and the state is paused, also update the command list
    const mode = this._timelineSk!.querySelector<PlaySk>('play-sk')!.mode;
    if (mode === 'pause') {
      this._setCommands();
      this._androidLayersSk!.update(this._commandsSk!.layerInfo,
        this._fileContext!.player.getLayerSummariesJs(), n);
    } else {
      this._updateDebuggerView();
    }
    this._timelineSk!.playsk.movedTo(n);
  }

  private _boundsEqual(a: SkIRect, b: SkIRect): boolean {
    return (a.fLeft === b.fLeft
         && a.fTop === b.fTop
         && a.fRight === b.fRight
         && a.fBottom === b.fBottom);
  }

  // Fetch the list of commands for the frame or layer the debugger is currently showing
  // from wasm.
  private _setCommands(): void {
    // Cache only holds the regular frame's commands, not layers.
    // const json = (self.inspectedLayer === -1 ? this._memoizedJsonCommandList()
    //               : this._player.jsonCommandList(this._surface));
    const json = this._fileContext!.player.jsonCommandList(this._surface!);
    const parsed = JSON.parse(json) as SkpJsonCommandList;
    // this will eventually cause a move-command-position event
    this._commandsSk!.processCommands(parsed);
  }

  private _jumpToCommand(i: number): void {
    // listened to by commands-sk
    this.dispatchEvent(
      new CustomEvent<JumpCommandEventDetail>(
        JumpCommandEvent, {
          detail: { unfilteredIndex: i },
          bubbles: true,
        },
      ),
    );
  }

  // Asks the wasm module to draw to the provided surface.
  // Up to the command index indidated by this._targetItem
  _updateDebuggerView(): void {
    if (!this._fileContext) {
      return; // Return early if no file. commands-sk tests load data to that
      // modules but not a whole file.
    }
    if (this._drawToEnd) {
      this._fileContext!.player!.draw(this._surface!);
    } else {
      this._fileContext!.player!.drawTo(this._surface!, this._targetItem);
    }
    if (!this._gpuMode) {
      this._surface!.flush();
    }
    this.dispatchEvent(
      new CustomEvent<CursorEventDetail>(
        RenderCursorEvent, {
          detail: { position: [0, 0], onlyData: true },
          bubbles: true,
        },
      ),
    );

    const clipmatjson = this._fileContext.player.lastCommandInfo();
    this._info = JSON.parse(clipmatjson) as MatrixClipInfo;
    this._render();
  }

  // controls change handlers

  private _gpuHandler(e: Event): void {
    this._gpuMode = (e.target as CheckOrRadio).checked;
    this._replaceSurface();
    if (!this._surface) {
      errorMessage('Could not create Surface.');
      return;
    }
    this._setCommands();
  }

  private _lightDarkHandler(e: Event): void {
    this._darkBackgrounds = (e.target as CheckOrRadio).checked;
    // should be received by anything in the application that shows a checkerboard
    // background for transparency
    this.dispatchEvent(
      new CustomEvent<ToggleBackgroundEventDetail>(
        ToggleBackgroundEvent, {
          detail: { mode: this._darkBackgrounds ? 'dark-checkerboard' : 'light-checkerboard' },
          bubbles: true,
        },
      ),
    );
  }

  private _opBoundsHandler(e: Event): void {
    this._showOpBounds = (e.target as CheckOrRadio).checked;
    this._fileContext!.player.setGpuOpBounds(this._showOpBounds);
    this._updateDebuggerView();
  }

  private _overdrawHandler(e: Event): void {
    this._showOverdrawViz = (e.target as CheckOrRadio).checked;
    this._fileContext!.player.setOverdrawVis(this._showOverdrawViz);
    this._updateDebuggerView();
  }

  private _clipHandler(e: Event): void {
    this._showClip = (e.target as CheckOrRadio).checked;
    if (this._showClip) { // ON: 30% transparent dark teal
      this._fileContext!.player.setClipVizColor(0x500e978d);
    } else { // OFF: transparent black
      this._fileContext!.player.setClipVizColor(0);
    }
    this._updateDebuggerView();
  }

  private _androidClipHandler(e: Event): void {
    this._showAndroidClip = (e.target as CheckOrRadio).checked;
    this._fileContext!.player.setAndroidClipViz(this._showAndroidClip);
    this._updateDebuggerView();
  }

  private _originHandler(e: Event): void {
    this._showOrigin = (e.target as CheckOrRadio).checked;
    this._fileContext!.player.setOriginVisible(this._showOrigin);
    this._updateDebuggerView();
  }

  private _updateCursor(x: number, y: number): void {
    this._updateJumpButton([x, y]);
    this.dispatchEvent(
      new CustomEvent<CursorEventDetail>(
        RenderCursorEvent, {
          detail: { position: [x, y], onlyData: false },
          bubbles: true,
        },
      ),
    );
  }

  private _keyDownHandler(e: KeyboardEvent): void {
    if (this.querySelector<HTMLInputElement>('#text-filter') === document.activeElement) {
      return; // don't interfere with the filter textbox.
    }
    const [x, y] = this._zoom!.point;
    // If adding a case here, document it in the user-visible keyboard shortcuts area.
    switch (e.keyCode) {
      case 74: // J
        this._updateCursor(x, y + 1);
        break;
      case 75: // K
        this._updateCursor(x, y - 1);
        break;
      case 72: // H
        this._updateCursor(x - 1, y);
        break;
      case 76: // L
        this._updateCursor(x + 1, y);
        break;
      case 190: // Period, step command forward
        this._commandsSk!.keyMove(1);
        break;
      case 188: // Comma, step command back
        this._commandsSk!.keyMove(-1);
        break;
      case 87: // w
        this._timelineSk!.playsk.prev();
        break;
      case 83: // s
        this._timelineSk!.playsk.next();
        break;
      case 80: // p
        this._timelineSk!.playsk.togglePlay();
        break;
      default:
        return;
    }
    e.stopPropagation();
  }

  private _inspectLayer(layerId: number, frame: number): void {
    // This method is called any time one of the Inspector/Exit buttons is pressed.
    // if the the button was on the layer already being inspected, it says "exit"
    // and -1 is passed to layerId.
    // It is also called from the jump action in the image resorce viewer.
    // TODO(nifong): Either disable the timeline or make it have some kind of layer-aware
    // mode that would jump between updates. At the moment if you move the frame while viewing
    // a layer, you'll bork the app.
    this._timelineSk!.item = frame;
    this._fileContext!.player.setInspectedLayer(layerId);
    this._replaceSurface();
    this._setCommands();
    this._commandsSk!.end();
  }
}

define('debugger-page-sk', DebuggerPageSk);
