// luma.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors

import {Device, Framebuffer} from '@luma.gl/core';
import {picking} from '@luma.gl/shadertools';
import {ShaderInputs} from '../../shader-inputs';
import {NumberArray3} from '@math.gl/types';

/**
 * Helper class for using the legacy picking module
 */
export class LegacyPickingManager {
  device: Device;
  framebuffer: Framebuffer | null = null;
  shaderInputs: ShaderInputs<{picking: typeof picking.props}>;

  constructor(device: Device, shaderInputs: ShaderInputs) {
    this.device = device;
    this.shaderInputs = shaderInputs as ShaderInputs<{picking: typeof picking.props}>;
  }

  destroy() {
    this.framebuffer?.destroy();
  }

  getFramebuffer() {
    if (!this.framebuffer) {
      this.framebuffer = this.device.createFramebuffer({
        colorAttachments: ['rgba8unorm'],
        depthStencilAttachment: 'depth24plus'
      });
    }
    return this.framebuffer;
  }

  /** Clear highlighted / picked object */
  clearPickState() {
    this.shaderInputs.setProps({picking: {highlightedObjectColor: null}});
  }

  /** Prepare for rendering picking colors */
  beginRenderPass() {
    const framebuffer = this.getFramebuffer();
    framebuffer.resize(this.device.getCanvasContext().getDevicePixelSize());

    this.shaderInputs.setProps({picking: {isActive: true}});

    const pickingPass = this.device.beginRenderPass({
      framebuffer,
      clearColor: [0, 0, 0, 0],
      clearDepth: 1
    });

    return pickingPass;
  }

  updatePickState(mousePosition: [number, number]) {
    const framebuffer = this.getFramebuffer();

    // use the center pixel location in device pixel range
    const [pickX, pickY] = this.getPickPosition(mousePosition);

    // Read back
    const color255 = this.device.readPixelsToArrayWebGL(framebuffer, {
      sourceX: pickX,
      sourceY: pickY,
      sourceWidth: 1,
      sourceHeight: 1
    });
    // console.log(color255);

    // Check if we have
    let highlightedObjectColor: NumberArray3 | null = [...color255].map(
      x => x / 255
    ) as NumberArray3;
    const isHighlightActive =
      highlightedObjectColor[0] + highlightedObjectColor[1] + highlightedObjectColor[2] > 0;

    if (!isHighlightActive) {
      highlightedObjectColor = null;
    }

    this.shaderInputs.setProps({
      picking: {isActive: false, highlightedObjectColor}
    });
  }

  /**
   * Get pick position in device pixel range
   * use the center pixel location in device pixel range
   */
  getPickPosition(mousePosition: [number, number]): [number, number] {
    const devicePixels = this.device.getCanvasContext().cssToDevicePixels(mousePosition);
    const pickX = devicePixels.x + Math.floor(devicePixels.width / 2);
    const pickY = devicePixels.y + Math.floor(devicePixels.height / 2);
    return [pickX, pickY];
  }
}
