import { Codec } from "./Codec.js";

/**
 *
 * @param {Image|ImageBitmap|HTMLImageElement} img
 * @returns {Uint8Array}
 * @ignore
 */
function decode(img) {
    const width = img.width;
    const height = img.height;

    //
    const canvas = document.createElement('canvas');

    canvas.width = width;
    canvas.height = height;

    const context = canvas.getContext('2d');

    context.drawImage(img, 0, 0, width, height);

    const image_data = context.getImageData(0, 0, width, height);

    return image_data.data;
}

/**
 *
 * @param {HTMLImageElement} image
 * @ignore
 */
function make_decoded_data(image) {

    const rgba_data = decode(image);

    const width = image.width;
    const height = image.height;

    return {
        data: rgba_data,
        width: width,
        height: height,
        itemSize: 4,
        bitDepth: 8
    };
}

/**
 * Convert binary data to image URL that we can load.
 * Don't forget to call `URL.revokeObjectURL(url)` when done
 * @param {Uint8Array} data
 * @return {string}
 * @ignore
 */
function data_to_url(data){
    const blob = new Blob([data]);
    return URL.createObjectURL(blob);
}

/**
 * Uses the browser's native image decoder
 * @extends {Codec<{width:number, height:number, data: Uint8Array, itemSize: number, bitDepth:number}>}
 */
export class NativeImageDecoder extends Codec {
    /**
     *
     * @param {Uint8Array} data
     * @return {{data: Uint8Array, width: number, height: number, itemSize: number, bitDepth: number}}
     */
    decodeSync(data) {
        const image = new Image();

        // convert binary data to image URL that we can load
        const url = data_to_url(data);

        image.src = url;

        const result = make_decoded_data(image);

        // release resources
        URL.revokeObjectURL(url);

        return result;
    }

    async decode(data) {
        const image = new Image();

        // convert binary data to image URL that we can load
        const url = data_to_url(data);

        image.src = url;

        // give the browser a chance to decode image in async
        await image.decode();

        const result = make_decoded_data(image);

        // release resources
        URL.revokeObjectURL(url);

        return result;
    }
}
