// Copyright (C) 2024 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.

/**
 * Canvases have limits on their maximum size (which is determined by the
 * system). Usually, this limit is fairly large, but can be as small as
 * 4096x4096px on some machines.
 *
 * If we need a super large canvas, we need to use a different approach.
 *
 * Unless the user has a huge monitor, most of the time any sufficiently large
 * canvas will overflow it's container, so we assume this container is set to
 * scroll so that the user can actually see all of the canvas. We can take
 * advantage of the fact that users may only see a small portion of the canvas
 * at a time. So, if we position a small floating canvas element over the
 * viewport of the scrolling container, we can approximate a huge canvas using a
 * much smaller one.
 *
 * Given a target element and it's scrolling container, VirtualCanvas turns an
 * empty HTML element into a "virtual" canvas with virtually unlimited size
 * using the "floating" canvas technique described above.
 */

import {DisposableStack} from './disposable_stack';
import {type Bounds2D, Rect2D, type Size2D} from './geom';

export type LayoutShiftListener = (
  canvas: HTMLCanvasElement,
  rect: Rect2D,
) => void;

export type CanvasResizeListener = (
  canvas: HTMLCanvasElement,
  width: number,
  height: number,
) => void;

export interface VirtualCanvasOpts {
  // How much buffer to add around the visible window in the scrollable axes.
  // The larger this number, the more we can scroll before triggering a move and
  // update which reduces thrashing when scrolling quickly, but the more canvas
  // will need to be drawn each render cycle.
  readonly overdrawPx: number;

  // This figure controls how close we can get to the edge of the drawn canvas
  // before moving it and triggering a redraw. If 0, we can get all the way to
  // the edge of the canvas before moving it. Larger values will result in more
  // frequent redraws but less chance of seeing blank bits of canvas when
  // scrolling quickly.
  readonly tolerancePx?: number;

  // Which axes should we overdraw? Typically we only want to overdraw in the
  // axes we expect to scroll in. So if we only expect the container to be
  // vertically scrolled, choose 'y'.
  readonly overdrawAxes?: 'none' | 'x' | 'y' | 'both';
}

export class VirtualCanvas implements Disposable {
  private readonly _trash = new DisposableStack();
  private readonly _canvasElement: HTMLCanvasElement;
  private readonly _targetElement: HTMLElement;

  // Describes the offset of the canvas w.r.t. the "target" container
  private _canvasRect: Rect2D;
  private _viewportRect: Rect2D;
  private _viewportLimits: Rect2D;
  private _layoutShiftListener?: LayoutShiftListener;
  private _canvasResizeListener?: CanvasResizeListener;
  private _dpr?: number;

  /**
   * @param targetElement The element to turn into a virtual canvas. The
   * dimensions of this element are used to size the canvas, so ensure this
   * element is sized appropriately.
   * @param containerElement The scrolling container to be used for determining
   * the size and position of the canvas. The targetElement should be a child of
   * this element.
   * @param opts Setup options for the VirtualCanvas.
   */
  constructor(
    targetElement: HTMLElement,
    containerElement: Element,
    opts?: Partial<VirtualCanvasOpts>,
  ) {
    const {
      overdrawPx = 200,
      tolerancePx = 100,
      overdrawAxes: scrollAxes = 'none',
    } = opts ?? {};

    const viewportOversize = overdrawPx - tolerancePx;

    // Returns the rect of the container's viewport W.R.T the target element.
    function getViewportRect() {
      const containerRect = new Rect2D(
        containerElement.getBoundingClientRect(),
      );
      const targetElementRect = targetElement.getBoundingClientRect();

      // Calculate the intersection of the container's viewport and the target
      const intersection = containerRect.intersect(targetElementRect);

      return intersection.reframe(targetElementRect);
    }

    const getCanvasRect = (viewport: Rect2D) => {
      if (this._viewportLimits.contains(viewport)) {
        return this._canvasRect;
      } else {
        const canvasRect = viewport.expand({
          height: scrollAxes === 'both' || scrollAxes === 'y' ? overdrawPx : 0,
          width: scrollAxes === 'both' || scrollAxes === 'x' ? overdrawPx : 0,
        });

        this._viewportLimits = viewport.expand({
          height:
            scrollAxes === 'both' || scrollAxes === 'y' ? viewportOversize : 0,
          width:
            scrollAxes === 'both' || scrollAxes === 'x' ? viewportOversize : 0,
        });

        return canvasRect;
      }
    };

    const updateCanvas = () => {
      let repaintRequired = false;

      const viewport = getViewportRect();
      this._viewportRect = viewport;
      const canvasRect = getCanvasRect(viewport);
      const canvasRectPrev = this._canvasRect;
      this._canvasRect = canvasRect;

      if (
        canvasRectPrev.width !== canvasRect.width ||
        canvasRectPrev.height !== canvasRect.height ||
        devicePixelRatio !== this._dpr
      ) {
        this._dpr = devicePixelRatio;

        // Canvas needs to change size, update its size
        canvas.style.width = `${canvasRect.width}px`;
        canvas.style.height = `${canvasRect.height}px`;
        this._canvasResizeListener?.(
          canvas,
          canvasRect.width,
          canvasRect.height,
        );
        repaintRequired = true;
      }

      if (
        canvasRectPrev.left !== canvasRect.left ||
        canvasRectPrev.top !== canvasRect.top
      ) {
        // Canvas needs to move, update the transform
        canvas.style.transform = `translate(${canvasRect.left}px, ${canvasRect.top}px)`;
        repaintRequired = true;
      }

      repaintRequired && this._layoutShiftListener?.(canvas, canvasRect);
    };

    containerElement.addEventListener('scroll', updateCanvas, {
      passive: true,
    });
    this._trash.defer(() =>
      containerElement.removeEventListener('scroll', updateCanvas),
    );

    // Resize observer callbacks are called once immediately after registration
    const resizeObserver = new ResizeObserver((_cb) => {
      updateCanvas();
    });

    resizeObserver.observe(containerElement);
    resizeObserver.observe(targetElement);
    this._trash.defer(() => {
      resizeObserver.disconnect();
    });

    // Ensures the canvas doesn't change the size of the target element
    targetElement.style.overflow = 'hidden';

    const canvas = document.createElement('canvas');
    canvas.style.position = 'absolute';
    targetElement.appendChild(canvas);
    this._trash.defer(() => {
      targetElement.removeChild(canvas);
    });

    this._canvasElement = canvas;
    this._targetElement = targetElement;
    const emptyRect = new Rect2D({
      left: 0,
      top: 0,
      bottom: 0,
      right: 0,
    });
    this._canvasRect = emptyRect;
    this._viewportRect = emptyRect;
    this._viewportLimits = emptyRect;
  }

  /**
   * Set the callback that gets called when the canvas element is moved or
   * resized, thus, invalidating the contents, and should be re-painted.
   *
   * @param cb The new callback.
   */
  setLayoutShiftListener(cb: LayoutShiftListener) {
    this._layoutShiftListener = cb;
  }

  /**
   * Set the callback that gets called when the canvas element is resized. This
   * might be a good opportunity to update the size of the canvas' draw buffer.
   *
   * @param cb The new callback.
   */
  setCanvasResizeListener(cb: CanvasResizeListener) {
    this._canvasResizeListener = cb;
  }

  /**
   * The floating canvas element.
   */
  get canvasElement(): HTMLCanvasElement {
    return this._canvasElement;
  }

  /**
   * The target element, i.e. the one passed to our constructor.
   */
  get targetElement(): HTMLElement {
    return this._targetElement;
  }

  /**
   * The size of the target element, aka the size of the virtual canvas.
   */
  get size(): Size2D {
    return {
      width: this._targetElement.clientWidth,
      height: this._targetElement.clientHeight,
    };
  }

  /**
   * Returns the rect of the floating canvas with respect to the target element.
   * This will need to be subtracted from any drawing operations to get the
   * right alignment within the virtual canvas.
   */
  get canvasRect(): Rect2D {
    return this._canvasRect;
  }

  /**
   * Returns the cached rect of the visible viewport with respect to the target
   * element. Unlike canvasRect, this does not include overdraw area.
   */
  get viewportRect(): Rect2D {
    return this._viewportRect;
  }

  /**
   * Stop listening to DOM events.
   */
  [Symbol.dispose]() {
    this._trash.dispose();
  }

  /**
   * Return true if a rect overlaps the floating canvas.
   * @param rect The rect to test.
   * @returns true if rect overlaps, false otherwise.
   */
  overlapsCanvas(rect: Bounds2D): boolean {
    const c = this._canvasRect;
    const y = rect.top < c.bottom && rect.bottom > c.top;
    const x = rect.left < c.right && rect.right > c.left;
    return x && y;
  }
}
