/**
 * @license
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '@polymer/paper-button/paper-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 {GrLibLoader} from '../../shared/gr-lib-loader/gr-lib-loader';
import {RESEMBLEJS_LIBRARY_CONFIG} from '../../shared/gr-lib-loader/resemblejs_config';

import {
  css,
  customElement,
  html,
  LitElement,
  property,
  PropertyValues,
  query,
  state,
} from 'lit-element';
import {classMap} from 'lit-html/directives/class-map';
import {StyleInfo, styleMap} from 'lit-html/directives/style-map';

import {
  createEvent,
  Dimensions,
  fitToFrame,
  FrameConstrainer,
  Point,
  Rect,
} from './util';

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 styles = 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);
    }
    paper-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);
    }
    paper-button[unelevated] {
      color: var(--primary-button-text-color);
      background-color: var(--primary-button-background-color);
    }
    paper-button[outlined] {
      color: 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 paper-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>
    `;
  }

  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',
          })}"
          src="${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 versionToggle = html`
      <div id="version-switcher">
        <paper-button
          class="left"
          ?unelevated=${this.baseSelected}
          ?outlined=${!this.baseSelected}
          @click="${this.selectBase}"
        >
          Base
        </paper-button>
        <paper-fab mini icon="gr-icons:swapHoriz" @click="${this.manualBlink}">
        </paper-fab>
        <paper-button
          class="right"
          ?unelevated=${!this.baseSelected}
          ?outlined=${this.baseSelected}
          @click="${this.selectRevision}"
        >
          Revision
        </paper-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"
          attr-for-selected="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.
    const customStyle = html`
      <style>
        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>
    `;
  }

  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().
  update(changedProperties: PropertyValues) {
    if (!this.baseUrl) this.baseSelected = false;
    if (!this.revisionUrl) this.baseSelected = true;
    this.updateSizes();
    super.update(changedProperties);
  }

  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();
      });
  }

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

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

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

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

  toggleAutomaticBlink() {
    this.automaticBlink = !this.automaticBlink;
    this.dispatchEvent(
      createEvent({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.dispatchEvent(
      createEvent({
        type: 'highlight-changes-changed',
        value: this.showHighlight,
        source,
      })
    );
  }

  zoomControlChanged(event: CustomEvent) {
    const value = event.detail.value;
    if (!value) return;
    if (value === 'fit') {
      this.scaledSelected = true;
      this.dispatchEvent(
        createEvent({type: 'zoom-level-changed', scale: 'fit'})
      );
    }
    if (value > 0) {
      this.scaledSelected = false;
      this.scale = value;
      this.dispatchEvent(
        createEvent({type: 'zoom-level-changed', scale: value})
      );
    }
    this.updateSizes();
  }

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

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

  pickCheckerboard() {
    this.checkerboardSelected = true;
    this.dispatchEvent(
      createEvent({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.dispatchEvent(createEvent({type: 'magnifier-clicked'}));
    } else {
      this.dispatchEvent(createEvent({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.dispatchEvent(createEvent({type: 'magnifier-dragged'}));
  }

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

  onOverviewCenterUpdated(event: CustomEvent) {
    this.frameConstrainer.requestCenter({
      x: event.detail.x as number,
      y: event.detail.y as number,
    });
    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;
  }
}
