import { assert } from "../../../../core/assert.js";
import { BinaryDataType } from "../../../../core/binary/type/BinaryDataType.js";
import {
    compute_binary_data_type_from_typed_array
} from "../../../../core/collection/array/typed/compute_binary_data_type_from_typed_array.js";
import { isTypedArray } from "../../../../core/collection/array/typed/isTypedArray.js";
import { max2 } from "../../../../core/math/max2.js";
import { min2 } from "../../../../core/math/min2.js";
import { sampler2d_channel_compute_max } from "./sampler2d_channel_compute_max.js";
import { sampler2d_channel_compute_min } from "./sampler2d_channel_compute_min.js";

/**
 *
 * @param {Sampler2D} sampler
 * @returns {{offset: number, scale: number}}
 */
export function sampler2d_compute_texel_value_conversion_scale_to_uint8(sampler) {
    assert.defined(sampler, 'sampler');
    assert.notNull(sampler, 'sampler');
    assert.isObject(sampler, 'sampler');
    assert.equal(sampler.isSampler2D, true, 'sampler.isSampler2D !== true');

    let dataType;

    if (isTypedArray(sampler.data)) {
        dataType = compute_binary_data_type_from_typed_array(sampler.data);
    } else {
        // plain numeric array
        dataType = BinaryDataType.Float32;
    }

    let min = 0, max = 0;

    if (dataType === BinaryDataType.Uint8) {
        min = 0;
        max = 255;
    } else {
        // unknown input type, compute min and max
        min = Infinity;
        max = -Infinity;
        for (let i = 0; i < sampler.itemSize; i++) {

            min = min2(min, sampler2d_channel_compute_min(sampler, i).value)
            max = max2(min, sampler2d_channel_compute_max(sampler, i).value)
        }
    }

    const span = max - min;

    const scale = span === 0 ? 0 : 255 / span;
    const offset = min;

    return {
        scale, offset
    };
}
