/** @internal NOTE: Internal APIs. Subject to change. Use of these APIs in production applications is not supported. */ /** */

import { Camera, DeepImmutable, ISize } from '../loader/babylonjs-import';

/**
 * Options for {@link IconSizeCalculator}.
 */
export interface IconSizeOptions {
    resolution?: number;
    atFov?: number;
}

/**
 * Calculates icon size. Used by {@link IconHandler} to calculate the size
 * a icon shall be rendered with.
 */
export class IconSizeCalculator {
    private readonly _atFovK: number;

    public readonly options: DeepImmutable<Required<IconSizeOptions>>;

    public constructor(o?: IconSizeOptions) {
        this.options = {
            resolution: o?.resolution ?? 1000,
            atFov: o?.atFov ?? 0.8
        };
        this._atFovK = Math.tan(this.options.atFov / 2);
    }

    /**
     * Get icon size
     * @param iconLength side of the icon
     * @param camera camera the icon will be rendered with
     * @param renderTargetSize size of the render target that the icon will be rendered to.
     * @returns Size of icon to use when rendering.
     */
    public get(iconLength: number, camera: Camera, renderTargetSize: ISize): number {
        if (camera.mode === Camera.ORTHOGRAPHIC_CAMERA) {
            const orthoSize = camera.twinfinity.getOrthoFrustumSizeToRef({ x: 0, y: 0 });
            const size = {
                width: this.calcOrthoCamera(iconLength, renderTargetSize.width, orthoSize.x),
                height: this.calcOrthoCamera(iconLength, renderTargetSize.height, orthoSize.y)
            };
            const magicNumber = 70;
            return Math.round(Math.min(size.width, size.height)) / magicNumber;
        } else {
            const size = {
                width: this.calcPerspectiveCamera(iconLength, renderTargetSize.width, camera.fov),
                height: this.calcPerspectiveCamera(iconLength, renderTargetSize.height, camera.fov)
            };
            const magicNumber = 16;
            return Math.round(Math.min(size.width, size.height)) * magicNumber;
        }
    }

    private calcOrthoCamera(iconLength: number, renderTargetLen: number, orthoLen: number): number {
        return (renderTargetLen * iconLength) / orthoLen;
    }

    private calcPerspectiveCamera(iconLength: number, renderTargetLen: number, fov: number): number {
        return ((renderTargetLen / this.options.resolution) * iconLength * this._atFovK) / Math.tan(fov / 2);
    }
}
