/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@material/web/button/text-button';
import '@polymer/paper-card/paper-card';
import '@polymer/paper-checkbox/paper-checkbox';
import '@polymer/paper-dropdown-menu/paper-dropdown-menu';
import '@polymer/paper-fab/paper-fab';
import '@polymer/paper-icon-button/paper-icon-button';
import '@polymer/paper-item/paper-item';
import '@polymer/paper-listbox/paper-listbox';
import './gr-overview-image';
import './gr-zoomed-image';
import '../../../elements/shared/gr-icons/gr-icons';

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 {ValueChangedEvent} from '../../../types/events';
import {fire} from '../../../utils/event-util';
import {ImageDiffAction} from '../../../api/diff';

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 [
      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));
        }
        #automatic-blink-button {
          position: absolute;
          right: var(--spacing-xl);
          bottom: var(--spacing-xl);
          opacity: 0;
          transition: opacity 200ms ease;
          --paper-fab-background: var(--primary-button-background-color);
          --paper-fab-keyboard-focus-background: var(
            --primary-button-background-color
          );
        }
        #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 {
          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-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 paper-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);
          --paper-fab-background: var(--primary-background-color);
          --paper-fab-keyboard-focus-background: var(
            --primary-background-color
          );
        }
        #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: 0 var(--spacing-xl);
        }
        paper-item {
          cursor: pointer;
        }
        paper-item:hover {
          background-color: var(--hover-background-color);
        }
        #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 {
          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;
        }
      `,
    ];
  }

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

  private renderCheckerboardButton() {
    return html`
      <div
        class=${classMap({
          'color-picker-button': true,
          selected: this.checkerboardSelected,
        })}
      >
        <paper-icon-button
          class="color checkerboard"
          @click=${this.pickCheckerboard}
        >
        </paper-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)}
          @click=${this.selectBase}
        >
          Base
        </md-text-button>
        <paper-fab
          mini
          icon="gr-icons:swapHoriz"
          title=${this.baseSelected
            ? 'switch to Revision version'
            : 'switch to Base version'}
          @click=${this.manualBlink}
        >
        </paper-fab>
        <md-text-button
          class=${classMap(rightClasses)}
          @click=${this.selectRevision}
        >
          Revision
        </md-text-button>
      </div>
    `;

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

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

    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`
      <paper-dropdown-menu id="zoom-control" label="Zoom">
        <paper-listbox
          slot="dropdown-content"
          selected="fit"
          .attrForSelected=${'value'}
          @selected-changed=${this.zoomControlChanged}
        >
          ${this.zoomLevels.map(
            zoomLevel => html`
              <paper-item value=${zoomLevel}>
                ${zoomLevel === 'fit' ? 'Fit' : `${zoomLevel * 100}%`}
              </paper-item>
            `
          )}
        </paper-listbox>
      </paper-dropdown-menu>
    `;

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

    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`
      <paper-fab
        id="automatic-blink-button"
        class=${classMap({show: this.automaticBlinkShown})}
        title="Automatic blink"
        icon="gr-icons:${this.automaticBlink ? 'pause' : 'playArrow'}"
        @click=${this.toggleAutomaticBlink}
      >
      </paper-fab>
    `;

    // To pass CSS mixins for @apply to Polymer components, they need to appear
    // in <style> inside the template.
    /* eslint-disable lit/prefer-static-styles */
    const customStyle = html`
      <style>
        /* prettier formatter removes semi-colons after css mixins. */
        /* prettier-ignore */
        paper-item {
          --paper-item-min-height: 48;
          --paper-item: {
            min-height: 48px;
            padding: 0 var(--spacing-xl);
          };
          --paper-item-focused-before: {
            background-color: var(--selection-background-color);
          };
          --paper-item-focused: {
            background-color: var(--selection-background-color);
          };
        }
      </style>
    `;

    return html`
      ${customStyle}
      <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>

      <paper-card class="controls">
        ${versionSwitcher} ${highlightSwitcher} ${overviewImage} ${zoomControl}
        ${!this.scaledSelected ? followMouse : ''} ${backgroundPicker}
      </paper-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: ValueChangedEvent<string>) {
    const scaleString = event.detail.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>;
  }
}
