/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@material/web/button/text-button';
import '@material/web/checkbox/checkbox';
import './gr-overview-image';
import './gr-zoomed-image';
import '@material/web/labs/card/filled-card';
import '@material/web/fab/fab';
import '@material/web/icon/icon';
import '@material/web/iconbutton/icon-button';
import '@material/web/select/filled-select';
import '@material/web/select/select-option';
import {GrLibLoader} from '../../../elements/shared/gr-lib-loader/gr-lib-loader';
import {RESEMBLEJS_LIBRARY_CONFIG} from '../../../elements/shared/gr-lib-loader/resemblejs_config';
import {css, html, LitElement, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {classMap} from 'lit/directives/class-map.js';
import {StyleInfo, styleMap} from 'lit/directives/style-map.js';
import {Dimensions, fitToFrame, FrameConstrainer, Point, Rect} from './util';
import {fire} from '../../../utils/event-util';
import {ImageDiffAction} from '../../../api/diff';
import {materialStyles} from '../../../styles/gr-material-styles';

const DRAG_DEAD_ZONE_PIXELS = 5;

const DEFAULT_AUTOMATIC_BLINK_TIME_MS = 1000;

const AUTOMATIC_BLINK_BUTTON_ACTIVE_AREA_PIXELS = 350;

/**
 * This components allows the user to rapidly switch between two given images
 * rendered in the same location, to make subtle differences more noticeable.
 * Images can be magnified to compare details.
 */
@customElement('gr-image-viewer')
export class GrImageViewer extends LitElement {
  /** URL for the image to use as base. */
  @property({type: String}) baseUrl = '';

  /** URL for the image to use as revision. */
  @property({type: String}) revisionUrl = '';

  /**
   * When true, cycle automatically between base and revision image, if both
   * are available.
   */
  @property({type: Boolean}) automaticBlink = false;

  @state() protected baseSelected = false;

  @state() protected scaledSelected = true;

  @state() protected followMouse = false;

  @state() protected scale = 1;

  @state() protected checkerboardSelected = true;

  @state() protected backgroundColor = '';

  @state() protected automaticBlinkShown = false;

  @state() protected zoomedImageStyle: StyleInfo = {};

  @query('.imageArea') protected imageArea!: HTMLDivElement;

  @query('gr-zoomed-image') protected zoomedImage!: Element;

  @query('#source-image') protected sourceImage!: HTMLImageElement;

  @query('#automatic-blink-button') protected automaticBlinkButton?: Element;

  private imageSize: Dimensions = {width: 0, height: 0};

  @state()
  protected magnifierSize: Dimensions = {width: 0, height: 0};

  @state()
  protected magnifierFrame: Rect = {
    origin: {x: 0, y: 0},
    dimensions: {width: 0, height: 0},
  };

  @state()
  protected overviewFrame: Rect = {
    origin: {x: 0, y: 0},
    dimensions: {width: 0, height: 0},
  };

  protected readonly zoomLevels: Array<'fit' | number> = [
    'fit',
    1,
    1.25,
    1.5,
    1.75,
    2,
  ];

  @state() protected grabbing = false;

  @state() protected canHighlightDiffs = false;

  @state() protected diffHighlightSrc?: string;

  @state() protected showHighlight = false;

  private ownsMouseDown = false;

  private centerOnDown: Point = {x: 0, y: 0};

  private pointerOnDown: Point = {x: 0, y: 0};

  private readonly frameConstrainer = new FrameConstrainer();

  private readonly resizeObserver = new ResizeObserver(
    (entries: ResizeObserverEntry[]) => {
      for (const entry of entries) {
        if (entry.target === this.imageArea) {
          this.magnifierSize = {
            width: entry.contentRect.width,
            height: entry.contentRect.height,
          };
        }
      }
    }
  );

  // Ensure constant function references, so that render() does not bind a new
  // event listener on every call, as it would with lambdas.
  private createColorPickerCallback(color: string) {
    return {color, callback: () => this.pickColor(color)};
  }

  private readonly colorPickerCallbacks = [
    this.createColorPickerCallback('#fff'),
    this.createColorPickerCallback('#000'),
    this.createColorPickerCallback('#aaa'),
  ];

  private automaticBlinkTimer?: ReturnType<typeof setInterval>;

  // TODO(hermannloose): Make GrLibLoader a singleton.
  private static readonly libLoader = new GrLibLoader();

  static override get styles() {
    return [
      materialStyles,
      css`
        :host {
          display: grid;
          grid-template-rows: 1fr auto;
          grid-template-columns: 1fr auto;
          width: 100%;
          height: 100%;
          box-sizing: border-box;
          text-align: initial !important;
          font-size: var(--font-size-normal);
          --image-border-width: 2px;
        }
        .imageArea {
          grid-row-start: 1;
          grid-column-start: 1;
          box-sizing: border-box;
          flex-grow: 1;
          overflow: hidden;
          display: flex;
          flex-direction: column;
          align-items: center;
          margin: var(--spacing-m);
          padding: var(--image-border-width);
          max-height: 100%;
          position: relative;
        }
        #spacer {
          visibility: hidden;
        }
        gr-zoomed-image {
          border: var(--image-border-width) solid;
          margin: calc(-1 * var(--image-border-width));
          box-sizing: content-box;
          position: absolute;
          overflow: hidden;
          cursor: pointer;
        }
        gr-zoomed-image.base {
          border-color: var(--base-image-border-color, rgb(255, 205, 210));
        }
        gr-zoomed-image.revision {
          border-color: var(--revision-image-border-color, rgb(170, 242, 170));
        }
        md-icon[filled] {
          font-variation-settings: 'FILL' 1;
        }
        #automatic-blink-button {
          position: absolute;
          right: var(--spacing-xl);
          bottom: var(--spacing-xl);
          opacity: 0;
          transition: opacity 200ms ease;
          --md-sys-color-primary-container: var(
            --primary-button-background-color
          );
          --md-sys-color-on-primary-container: #ffffff;
          --md-fab-container-shape: 50px;
        }
        #automatic-blink-button.show,
        #automatic-blink-button:focus-visible {
          opacity: 1;
        }
        .checkerboard {
          --square-size: var(--checkerboard-square-size, 10px);
          --square-color: var(--checkerboard-square-color, #808080);
          background-color: var(--checkerboard-background-color, #aaaaaa);
          background-image: linear-gradient(
              45deg,
              var(--square-color) 25%,
              transparent 25%
            ),
            linear-gradient(-45deg, var(--square-color) 25%, transparent 25%),
            linear-gradient(45deg, transparent 75%, var(--square-color) 75%),
            linear-gradient(-45deg, transparent 75%, var(--square-color) 75%);
          background-size: calc(var(--square-size) * 2)
            calc(var(--square-size) * 2);
          background-position: 0 0, 0 var(--square-size),
            var(--square-size) calc(-1 * var(--square-size)),
            calc(-1 * var(--square-size)) 0;
        }
        .dimensions {
          grid-row-start: 2;
          justify-self: center;
          align-self: center;
          background: var(--primary-button-background-color);
          color: var(--primary-button-text-color);
          font-family: var(--font-family);
          font-size: var(--font-size-small);
          line-height: var(--line-height-small);
          border-radius: var(--border-radius, 4px);
          margin: var(--spacing-s);
          padding: var(--spacing-xxs) var(--spacing-s);
        }
        .controls {
          font-family: var(--header-font-family);
          box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
            0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
          grid-column-start: 2;
          flex-grow: 0;
          display: flex;
          flex-direction: column;
          align-self: flex-start;
          margin: var(--spacing-m);
          padding-bottom: var(--spacing-xl);
          --md-sys-color-surface-container-highest: var(
            --card-surface-container-highest
          );
        }
        md-text-button {
          padding: var(--spacing-m);
          font: var(--image-diff-button-font);
          text-transform: var(--image-diff-button-text-transform, uppercase);
          outline: 1px solid transparent;
          border: 1px solid var(--primary-button-background-color);
          --md-text-button-container-shape: 0;
        }
        md-text-button.unelevated {
          background-color: var(--primary-button-background-color);
          --md-sys-color-primary: var(--primary-button-text-color);
        }
        md-text-button.outlined {
          --md-sys-color-primary: var(--primary-button-background-color);
        }
        #version-switcher {
          display: flex;
          align-items: center;
          margin: var(--spacing-xl) var(--spacing-xl) var(--spacing-m);
          /* Start a stacking context to contain FAB below. */
          z-index: 0;
        }
        #version-switcher md-text-button {
          flex-grow: 1;
          margin: 0;
          /*
            The floating action button below overlaps part of the version buttons.
            This min-width ensures the button text still appears somewhat balanced.
          */
          min-width: 7rem;
        }
        #version-switcher md-fab {
          /* Round button overlaps Base and Revision buttons. */
          z-index: 1;
          margin: 0 -12px;
          /* Styled as an outlined button. */
          color: var(--primary-button-background-color);
          border: 1px solid var(--primary-button-background-color);
          border-radius: 50%;
          box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
            0 1px 5px 0 rgba(0, 0, 0, 0.12);
          --md-sys-color-primary-container: var(--primary-background-color);
          --md-sys-color-on-primary-container: var(
            --primary-button-background-color
          );
          --md-fab-container-shape: 50px;
          --md-fab-container-height: 40px;
          --md-fab-container-width: 40px;
        }
        #version-explanation {
          color: var(--deemphasized-text-color);
          text-align: center;
          margin: var(--spacing-xl) var(--spacing-xl) var(--spacing-m);
        }
        #highlight-changes {
          margin: var(--spacing-m) var(--spacing-xl);
        }
        gr-overview-image {
          min-width: 200px;
          min-height: 150px;
          margin-top: var(--spacing-m);
        }
        #zoom-control {
          margin: var(--spacing-m) var(--spacing-xl) 0;
        }
        md-filled-select::part(field) {
          cursor: pointer;
        }
        md-filled-select {
          --md-sys-color-surface-container: var(--select-surface-container);
          --md-sys-color-surface-container-highest: var(
            --select-surface-container-highest
          );
          --md-sys-color-on-surface: var(--select-on-surface);
          --md-sys-color-on-surface-variant: var(--select-on-surface-variant);
          --md-sys-color-primary: var(--select-primary);
          --md-sys-color-secondary-container: var(--select-secondary-container);
          --md-sys-color-on-secondary-container: var(
            --select-on-secondary-container
          );
        }
        #follow-mouse {
          margin: var(--spacing-m) var(--spacing-xl);
        }
        .color-picker {
          margin: var(--spacing-m) var(--spacing-xl) 0;
        }
        .color-picker .label {
          margin-bottom: var(--spacing-s);
        }
        .color-picker .options {
          display: flex;
          /* Ignore selection border for alignment, for visual balance. */
          margin-left: -3px;
        }
        .color-picker-button {
          border-width: 2px;
          border-style: solid;
          border-color: transparent;
          border-radius: 50%;
          width: 24px;
          height: 24px;
          padding: 1px;
        }
        .color-picker-button.selected {
          border-color: var(--primary-button-background-color);
        }
        .color-picker-button:focus-within:not(.selected) {
          /* Not an actual outline, as those do not follow border-radius. */
          border-color: var(--outline-color-focus);
        }
        .color-picker-button .color {
          display: flex;
          border: 1px solid var(--border-color);
          border-radius: 50%;
          width: 100%;
          height: 100%;
          box-sizing: border-box;
        }
        #source-plus-highlight-container {
          position: relative;
        }
        #source-plus-highlight-container img {
          position: absolute;
          top: 0;
          left: 0;
        }
        .highlight-changes,
        .follow-mouse {
          display: flex;
          align-items: center;
        }
      `,
    ];
  }

  private renderColorPickerButton(color: string, colorPicked: () => void) {
    const selected =
      color === this.backgroundColor && !this.checkerboardSelected;
    return html`
      <div
        class=${classMap({
          'color-picker-button': true,
          selected,
        })}
      >
        <md-icon-button
          class="color"
          touch-target="none"
          style=${styleMap({backgroundColor: color})}
          @click=${colorPicked}
        ></md-icon-button>
      </div>
    `;
  }

  private renderCheckerboardButton() {
    return html`
      <div
        class=${classMap({
          'color-picker-button': true,
          selected: this.checkerboardSelected,
        })}
      >
        <md-icon-button
          class="color checkerboard"
          touch-target="none"
          @click=${this.pickCheckerboard}
        ></md-icon-button>
      </div>
    `;
  }

  override render() {
    const src = this.baseSelected ? this.baseUrl : this.revisionUrl;

    const sourceImage = html`
      <img
        id="source-image"
        src=${src}
        class=${classMap({checkerboard: this.checkerboardSelected})}
        style=${styleMap({
          backgroundColor: this.checkerboardSelected
            ? ''
            : this.backgroundColor,
        })}
        @load=${this.updateSizes}
      />
    `;

    const sourceImageWithHighlight = html`
      <div id="source-plus-highlight-container">
        ${sourceImage}
        <img
          id="highlight-image"
          style=${styleMap({
            opacity: this.showHighlight ? '1' : '0',
            // When the highlight layer is not being shown, saving the image or
            // opening it in a new tab from the context menu, e.g. for external
            // comparison, should give back the source image, not the highlight
            // layer.
            'pointer-events': this.showHighlight ? 'auto' : 'none',
          })}
          src=${ifDefined(this.diffHighlightSrc)}
        />
      </div>
    `;

    const versionExplanation = html`
      <div id="version-explanation">
        This file is being ${this.revisionUrl ? 'added' : 'deleted'}.
      </div>
    `;

    // This uses the unelevated and outlined attributes from mwc-button with
    // manual styling, for a more seamless transition later.
    const leftClasses = {
      left: true,
      unelevated: this.baseSelected,
      outlined: !this.baseSelected,
    };
    const rightClasses = {
      right: true,
      unelevated: !this.baseSelected,
      outlined: this.baseSelected,
    };
    const versionToggle = html`
      <div id="version-switcher">
        <md-text-button
          class=${classMap(leftClasses)}
          touch-target="none"
          @click=${this.selectBase}
        >
          Base
        </md-text-button>
        <md-fab
          mini
          title=${this.baseSelected
            ? 'switch to Revision version'
            : 'switch to Base version'}
          variant="primary"
          touch-target="none"
          @click=${this.manualBlink}
        >
          <md-icon slot="icon" filled>swap_horiz</md-icon>
        </md-fab>
        <md-text-button
          class=${classMap(rightClasses)}
          touch-target="none"
          @click=${this.selectRevision}
        >
          Revision
        </md-text-button>
      </div>
    `;

    const versionSwitcher = html`
      ${this.baseUrl && this.revisionUrl ? versionToggle : versionExplanation}
    `;

    const highlightSwitcher = this.diffHighlightSrc
      ? html`
          <label class="highlight-changes">
            <md-checkbox
              id="highlight-changes"
              ?checked=${this.showHighlight}
              @change=${this.showHighlightChanged}
            >
            </md-checkbox>
            Highlight differences
          </label>
        `
      : '';

    const overviewImage = html`
      <gr-overview-image
        .frameRect=${this.overviewFrame}
        @center-updated=${this.onOverviewCenterUpdated}
      >
        <img
          src=${src}
          class=${classMap({checkerboard: this.checkerboardSelected})}
          style=${styleMap({
            backgroundColor: this.checkerboardSelected
              ? ''
              : this.backgroundColor,
          })}
        />
      </gr-overview-image>
    `;

    const zoomControl = html`
      <md-filled-select
        id="zoom-control"
        label="Zoom"
        @change=${this.zoomControlChanged}
      >
        ${this.zoomLevels.map(
          zoomLevel => html`
            <md-select-option
              ?selected=${zoomLevel === 'fit'}
              value=${zoomLevel}
            >
              <div slot="headline">
                ${zoomLevel === 'fit' ? 'Fit' : `${zoomLevel * 100}%`}
              </div>
            </md-select-option>
          `
        )}
      </md-filled-select>
    `;

    const followMouse = html`
      <label class="follow-mouse">
        <md-checkbox
          id="follow-mouse"
          ?checked=${this.followMouse}
          @change=${this.followMouseChanged}
        >
        </md-checkbox>
        Magnifier follows mouse
      </label>
    `;

    const backgroundPicker = html`
      <div class="color-picker">
        <div class="label">Background</div>
        <div class="options">
          ${this.renderCheckerboardButton()}
          ${this.colorPickerCallbacks.map(({color, callback}) =>
            this.renderColorPickerButton(color, callback)
          )}
        </div>
      </div>
    `;

    /*
     * We want the content to fill the available space until it can display
     * without being cropped, the maximum of which will be determined by
     * (max-)width and (max-)height constraints on the host element; but we
     * are also limiting the displayed content to the measured dimensions of
     * the host element without overflow, so we need something else to take up
     * the requested space unconditionally.
     */
    const spacerScale = Math.max(this.scale, 1);
    const spacerWidth = this.imageSize.width * spacerScale;
    const spacerHeight = this.imageSize.height * spacerScale;
    const spacer = html`
      <div
        id="spacer"
        style=${styleMap({
          width: `${spacerWidth}px`,
          height: `${spacerHeight}px`,
        })}
      ></div>
    `;

    const automaticBlink = html`
      <md-fab
        id="automatic-blink-button"
        class=${classMap({show: this.automaticBlinkShown})}
        title="Automatic blink"
        variant="primary"
        touch-target="none"
        @click=${this.toggleAutomaticBlink}
      >
        <md-icon slot="icon" filled
          >${this.automaticBlink ? 'pause' : 'play_arrow'}</md-icon
        >
      </md-fab>
    `;

    return html`
      <div
        class="imageArea"
        @mousemove=${this.mousemoveImageArea}
        @mouseleave=${this.mouseleaveImageArea}
      >
        <gr-zoomed-image
          class=${classMap({
            base: this.baseSelected,
            revision: !this.baseSelected,
          })}
          style=${styleMap({
            ...this.zoomedImageStyle,
            cursor: this.grabbing ? 'grabbing' : 'pointer',
          })}
          .scale=${this.scale}
          .frameRect=${this.magnifierFrame}
          @mousedown=${this.mousedownMagnifier}
          @mouseup=${this.mouseupMagnifier}
          @mousemove=${this.mousemoveMagnifier}
          @mouseleave=${this.mouseleaveMagnifier}
          @dragstart=${this.dragstartMagnifier}
        >
          ${sourceImageWithHighlight}
        </gr-zoomed-image>
        ${this.baseUrl && this.revisionUrl ? automaticBlink : ''} ${spacer}
      </div>

      <div class="dimensions">
        ${this.imageSize.width} x ${this.imageSize.height}
      </div>

      <md-filled-card class="controls">
        ${versionSwitcher} ${highlightSwitcher} ${overviewImage} ${zoomControl}
        ${!this.scaledSelected ? followMouse : ''} ${backgroundPicker}
      </md-filled-card>
    `;
  }

  override firstUpdated() {
    this.resizeObserver.observe(this.imageArea, {box: 'content-box'});
    GrImageViewer.libLoader.getLibrary(RESEMBLEJS_LIBRARY_CONFIG).then(() => {
      this.canHighlightDiffs = true;
      this.computeDiffImage();
    });
  }

  // We don't want property changes in updateSizes() to trigger infinite update
  // loops, so we perform this in update() instead of updated().
  override update(changedProperties: PropertyValues) {
    if (!this.baseUrl) this.baseSelected = false;

    if (!this.revisionUrl) this.baseSelected = true;
    this.updateSizes();
    super.update(changedProperties);
  }

  override updated(changedProperties: PropertyValues) {
    if (
      (changedProperties.has('baseUrl') && this.baseSelected) ||
      (changedProperties.has('revisionUrl') && !this.baseSelected)
    ) {
      this.frameConstrainer.requestCenter({x: 0, y: 0});
    }
    if (changedProperties.has('automaticBlink')) {
      this.updateAutomaticBlink();
    }
    if (
      this.canHighlightDiffs &&
      (changedProperties.has('baseUrl') || changedProperties.has('revisionUrl'))
    ) {
      this.computeDiffImage();
    }
  }

  private computeDiffImage() {
    if (!(this.baseUrl && this.revisionUrl)) return;
    window
      .resemble(this.baseUrl)
      .compareTo(this.revisionUrl)
      // By default Resemble.js applies some color / alpha tolerance as well as
      // min / max brightness beyond which to ignore changes. Until we have
      // controls to let the user affect these options, always highlight all
      // changed pixels.
      .ignoreNothing()
      .onComplete(result => {
        this.diffHighlightSrc = result.getImageDataUrl();
      });
  }

  fireAction(detail: ImageDiffAction) {
    fire(this, 'image-diff-action', detail);
  }

  selectBase() {
    if (!this.baseUrl) return;
    this.baseSelected = true;
    this.fireAction({type: 'version-switcher-clicked', button: 'base'});
  }

  selectRevision() {
    if (!this.revisionUrl) return;
    this.baseSelected = false;
    this.fireAction({type: 'version-switcher-clicked', button: 'revision'});
  }

  manualBlink() {
    this.toggleImage();
    this.fireAction({type: 'version-switcher-clicked', button: 'switch'});
  }

  private toggleImage() {
    if (this.baseUrl && this.revisionUrl) {
      this.baseSelected = !this.baseSelected;
    }
  }

  toggleAutomaticBlink() {
    this.automaticBlink = !this.automaticBlink;
    this.fireAction({
      type: 'automatic-blink-changed',
      value: this.automaticBlink,
    });
  }

  private updateAutomaticBlink() {
    if (this.automaticBlink) {
      this.toggleImage();
      this.setBlinkInterval();
    } else {
      this.clearBlinkInterval();
    }
  }

  private setBlinkInterval() {
    this.clearBlinkInterval();
    this.automaticBlinkTimer = setInterval(() => {
      this.toggleImage();
    }, DEFAULT_AUTOMATIC_BLINK_TIME_MS);
  }

  private clearBlinkInterval() {
    if (this.automaticBlinkTimer) {
      clearInterval(this.automaticBlinkTimer);
      this.automaticBlinkTimer = undefined;
    }
  }

  showHighlightChanged() {
    this.toggleHighlight('controls');
  }

  private toggleHighlight(source: 'controls' | 'magnifier') {
    this.showHighlight = !this.showHighlight;
    this.fireAction({
      type: 'highlight-changes-changed',
      value: this.showHighlight,
      source,
    });
  }

  zoomControlChanged(event: Event) {
    const scaleString = (event.target as HTMLSelectElement).value;
    if (!scaleString) return;
    if (scaleString === 'fit') {
      this.scaledSelected = true;
      this.fireAction({type: 'zoom-level-changed', scale: 'fit'});
    }
    const scale = Number(scaleString);
    if (Number.isFinite(scale) && scale > 0) {
      this.scaledSelected = false;
      this.scale = scale;
      this.fireAction({type: 'zoom-level-changed', scale});
    }
    this.updateSizes();
  }

  followMouseChanged() {
    this.followMouse = !this.followMouse;
    this.fireAction({type: 'follow-mouse-changed', value: this.followMouse});
  }

  pickColor(value: string) {
    this.checkerboardSelected = false;
    this.backgroundColor = value;
    this.fireAction({type: 'background-color-changed', value});
  }

  pickCheckerboard() {
    this.checkerboardSelected = true;
    this.fireAction({type: 'background-color-changed', value: 'checkerboard'});
  }

  mousemoveImageArea(event: MouseEvent) {
    if (this.automaticBlinkButton) {
      this.updateAutomaticBlinkVisibility(event);
    }
    this.mousemoveMagnifier(event);
  }

  private updateAutomaticBlinkVisibility(event: MouseEvent) {
    const rect = this.automaticBlinkButton!.getBoundingClientRect();
    const centerX = rect.left + (rect.right - rect.left) / 2;
    const centerY = rect.top + (rect.bottom - rect.top) / 2;
    const distX = Math.abs(centerX - event.clientX);
    const distY = Math.abs(centerY - event.clientY);
    this.automaticBlinkShown =
      distX < AUTOMATIC_BLINK_BUTTON_ACTIVE_AREA_PIXELS &&
      distY < AUTOMATIC_BLINK_BUTTON_ACTIVE_AREA_PIXELS;
  }

  mouseleaveImageArea() {
    this.automaticBlinkShown = false;
  }

  mousedownMagnifier(event: MouseEvent) {
    if (event.buttons === 1) {
      this.ownsMouseDown = true;
      this.centerOnDown = this.frameConstrainer.getCenter();
      this.pointerOnDown = {
        x: event.clientX,
        y: event.clientY,
      };
    }
  }

  mouseupMagnifier(event: MouseEvent) {
    if (!this.ownsMouseDown) return;
    this.grabbing = false;
    this.ownsMouseDown = false;

    if (event.shiftKey && this.diffHighlightSrc) {
      this.toggleHighlight('magnifier');
      return;
    }

    const offsetX = event.clientX - this.pointerOnDown.x;
    const offsetY = event.clientY - this.pointerOnDown.y;
    const distance = Math.max(Math.abs(offsetX), Math.abs(offsetY));
    // Consider very short drags as clicks. These tend to happen more often on
    // external mice.
    if (distance < DRAG_DEAD_ZONE_PIXELS) {
      this.toggleImage();
      this.fireAction({type: 'magnifier-clicked'});
    } else {
      this.fireAction({type: 'magnifier-dragged'});
    }
  }

  mousemoveMagnifier(event: MouseEvent) {
    if (event.buttons === 1 && this.ownsMouseDown) {
      this.handleMagnifierDrag(event);
      return;
    }
    if (this.followMouse) {
      this.handleFollowMouse(event);
      return;
    }
  }

  private handleMagnifierDrag(event: MouseEvent) {
    this.grabbing = true;
    const offsetX = event.clientX - this.pointerOnDown.x;
    const offsetY = event.clientY - this.pointerOnDown.y;
    this.frameConstrainer.requestCenter({
      x: this.centerOnDown.x - offsetX / this.scale,
      y: this.centerOnDown.y - offsetY / this.scale,
    });
    this.updateFrames();
  }

  private handleFollowMouse(event: MouseEvent) {
    const rect = this.imageArea.getBoundingClientRect();
    const offsetX = event.clientX - rect.left;
    const offsetY = event.clientY - rect.top;
    const fractionX = offsetX / rect.width;
    const fractionY = offsetY / rect.height;
    this.frameConstrainer.requestCenter({
      x: this.imageSize.width * fractionX,
      y: this.imageSize.height * fractionY,
    });
    this.updateFrames();
  }

  mouseleaveMagnifier() {
    if (!this.ownsMouseDown) return;
    this.grabbing = false;
    this.ownsMouseDown = false;
    this.fireAction({type: 'magnifier-dragged'});
  }

  dragstartMagnifier(event: DragEvent) {
    event.preventDefault();
  }

  onOverviewCenterUpdated(event: CustomEvent<Point>) {
    this.frameConstrainer.requestCenter({
      x: event.detail.x,
      y: event.detail.y,
    });
    this.updateFrames();
  }

  updateFrames() {
    this.magnifierFrame = this.frameConstrainer.getUnscaledFrame();
    this.overviewFrame = this.frameConstrainer.getScaledFrame();
  }

  updateSizes() {
    if (!this.sourceImage || !this.sourceImage.complete) return;

    this.imageSize = {
      width: this.sourceImage.naturalWidth || 0,
      height: this.sourceImage.naturalHeight || 0,
    };

    this.frameConstrainer.setBounds(this.imageSize);

    if (this.scaledSelected) {
      const fittedImage = fitToFrame(this.imageSize, this.magnifierSize);
      this.scale = Math.min(fittedImage.scale, 1);
    }

    this.frameConstrainer.setScale(this.scale);

    const scaledImageSize = {
      width: this.imageSize.width * this.scale,
      height: this.imageSize.height * this.scale,
    };

    const width = Math.min(this.magnifierSize.width, scaledImageSize.width);
    const height = Math.min(this.magnifierSize.height, scaledImageSize.height);

    this.frameConstrainer.setFrameSize({width, height});

    this.updateFrames();

    this.zoomedImageStyle = {
      ...this.zoomedImageStyle,
      width: `${width}px`,
      height: `${height}px`,
    };
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-image-viewer': GrImageViewer;
  }
  interface HTMLElementEventMap {
    'image-diff-action': CustomEvent<ImageDiffAction>;
  }
}
