/**
 * @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.
 */

export interface Point {
  x: number;
  y: number;
}

export interface Dimensions {
  width: number;
  height: number;
}

export interface Rect {
  origin: Point;
  dimensions: Dimensions;
}

export interface FittedContent {
  top: number;
  left: number;
  width: number;
  height: number;
  scale: number;
}

function clamp(value: number, min: number, max: number) {
  return Math.max(min, Math.min(value, max));
}

/**
 * Fits content of the given dimensions into the given frame, maintaining the
 * aspect ratio of the content and applying letterboxing / pillarboxing as
 * needed.
 */
export function fitToFrame(
  content: Dimensions,
  frame: Dimensions
): FittedContent {
  const contentAspectRatio = content.width / content.height;
  const frameAspectRatio = frame.width / frame.height;
  // If the content is wider than the frame, it will be letterboxed, otherwise
  // it will be pillarboxed. When letterboxed, content and frame width will
  // match exactly, when pillarboxed, content and frame height will match
  // exactly.
  const isLetterboxed = contentAspectRatio > frameAspectRatio;
  let width: number;
  let height: number;
  if (isLetterboxed) {
    width = Math.min(frame.width, content.width);
    height = content.height * (width / content.width);
  } else {
    height = Math.min(frame.height, content.height);
    width = content.width * (height / content.height);
  }
  const top = (frame.height - height) / 2;
  const left = (frame.width - width) / 2;
  const scale = width / content.width;
  return {top, left, width, height, scale};
}

function ensureInBounds(part: Rect, bounds: Dimensions): Rect {
  const x =
    part.dimensions.width <= bounds.width
      ? clamp(part.origin.x, 0, bounds.width - part.dimensions.width)
      : (bounds.width - part.dimensions.width) / 2;
  const y =
    part.dimensions.height <= bounds.height
      ? clamp(part.origin.y, 0, bounds.height - part.dimensions.height)
      : (bounds.height - part.dimensions.height) / 2;
  return {origin: {x, y}, dimensions: part.dimensions};
}

/**
 * Maintains a given frame inside given bounds, adjusting requested positions
 * for the frame as needed. This supports the non-destructive application of a
 * scaling factor, so that e.g. the magnification of an image can be changed
 * easily while keeping the frame centered over the same spot. Changing bounds
 * or frame size also keeps the frame position when possible.
 */
export class FrameConstrainer {
  private center: Point = {x: 0, y: 0};

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

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

  private scale = 1;

  private unscaledFrame: Rect = {
    origin: {x: 0, y: 0},
    dimensions: {width: 0, height: 0},
  };

  private scaledFrame: Rect = {
    origin: {x: 0, y: 0},
    dimensions: {width: 0, height: 0},
  };

  getCenter(): Point {
    return {...this.center};
  }

  /**
   * Returns the frame at its original size, positioned within the given bounds
   * at the given scale; its origin will be in scaled bounds coordinates.
   *
   * Ex: for given bounds 100x50 and frame size 30x20, centered over (50, 25),
   * all at 1x scale, when setting scale to 2, this will return a frame of size
   * 30x20, centered over (100, 50), within bounds 200x100.
   *
   * Useful for positioning a viewport of fixed size over a magnified image.
   */
  getUnscaledFrame(): Rect {
    return {
      origin: {...this.unscaledFrame.origin},
      dimensions: {...this.unscaledFrame.dimensions},
    };
  }

  /**
   * Returns the scaled down frame–a scale of 2 will result in frame dimensions
   * being halved—position within the given bounds at 1x scale; its origin will
   * be in unscaled bounds coordinates.
   *
   * Ex: for given bounds 100x50 and frame size 30x20, centered over (50, 25),
   * all at 1x scale, when setting scale to 2, this will return a frame of size
   * 15x10, centered over (50, 25), within bounds 100x50.
   *
   * Useful for highlighting the magnified portion of an image as determined by
   * getUnscaledFrame() in an overview image of fixed size.
   */
  getScaledFrame(): Rect {
    return {
      origin: {...this.scaledFrame.origin},
      dimensions: {...this.scaledFrame.dimensions},
    };
  }

  /**
   * Requests the frame to be centered over the given point, in unscaled bounds
   * coordinates. This will keep the frame within the given bounds, also when
   * requesting a center point fully outside the given bounds.
   */
  requestCenter(center: Point) {
    this.center = {...center};

    this.ensureFrameInBounds();
  }

  /**
   * Sets the frame size, while keeping the frame within the given bounds, and
   * maintaining the current center if possible.
   */
  setFrameSize(frameSize: Dimensions) {
    if (frameSize.width <= 0 || frameSize.height <= 0) return;
    this.frameSize = {...frameSize};

    this.ensureFrameInBounds();
  }

  /**
   * Sets the bounds, while keeping the frame within them, and maintaining the
   * current center if possible.
   */
  setBounds(bounds: Dimensions) {
    if (bounds.width <= 0 || bounds.height <= 0) return;
    this.bounds = {...bounds};

    this.ensureFrameInBounds();
  }

  /**
   * Sets the applied scale, while keeping the frame within the given bounds,
   * and maintaining the current center if possible (both relevant moving from
   * a larger scale to a smaller scale).
   */
  setScale(scale: number) {
    if (!scale || scale <= 0) return;
    this.scale = scale;

    this.ensureFrameInBounds();
  }

  private ensureFrameInBounds() {
    const scaledCenter = {
      x: this.center.x * this.scale,
      y: this.center.y * this.scale,
    };
    const scaledBounds = {
      width: this.bounds.width * this.scale,
      height: this.bounds.height * this.scale,
    };
    const scaledFrameSize = {
      width: this.frameSize.width / this.scale,
      height: this.frameSize.height / this.scale,
    };

    const requestedUnscaledFrame = {
      origin: {
        x: scaledCenter.x - this.frameSize.width / 2,
        y: scaledCenter.y - this.frameSize.height / 2,
      },
      dimensions: this.frameSize,
    };
    const requestedScaledFrame = {
      origin: {
        x: this.center.x - scaledFrameSize.width / 2,
        y: this.center.y - scaledFrameSize.height / 2,
      },
      dimensions: scaledFrameSize,
    };

    this.unscaledFrame = ensureInBounds(requestedUnscaledFrame, scaledBounds);
    this.scaledFrame = ensureInBounds(requestedScaledFrame, this.bounds);

    this.center = {
      x: this.scaledFrame.origin.x + this.scaledFrame.dimensions.width / 2,
      y: this.scaledFrame.origin.y + this.scaledFrame.dimensions.height / 2,
    };
  }
}
