/**
 * @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 {
  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 = '';

  @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 automaticBlink = false;

  @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;

  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>;

  static styles = css`
    :host {
      display: flex;
      width: 100%;
      height: 100%;
      box-sizing: border-box;
      text-align: initial !important;
      font-size: var(--font-size-normal);
      --image-border-width: 2px;
    }
    .imageArea {
      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;
    }
    .controls {
      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);
    }
    #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: 10;
      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);
    }
    gr-overview-image {
      min-width: 200px;
      min-height: 150px;
    }
    #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;
    }
  `;

  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 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 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}"
        >
          ${sourceImage}
        </gr-zoomed-image>
        ${this.baseUrl && this.revisionUrl ? automaticBlink : ''} ${spacer}
      </div>

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

  firstUpdated() {
    this.resizeObserver.observe(this.imageArea, {box: 'content-box'});
  }

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

  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;
    if (this.automaticBlink) {
      this.toggleImage();
      this.setBlinkInterval();
    } else {
      if (this.automaticBlinkTimer) {
        clearInterval(this.automaticBlinkTimer);
        this.automaticBlinkTimer = undefined;
      }
    }
    this.dispatchEvent(
      createEvent({type: 'automatic-blink-changed', value: this.automaticBlink})
    );
  }

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

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