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

/**
 * Allows copying data from one sampler to another with unequal number of channels (a.itemSize !== b.itemSize)
 * @example convert RGBA to RGB or R to RGB
 * @param {Sampler2D} source
 * @param {Sampler2D} destination
 */
export function sampler2d_transfer_data(source, destination) {
    if (source.width !== destination.width || source.height !== destination.height) {
        throw new Error('Source and destination dimensions do not match');
    }

    const source_item_size = source.itemSize;
    const destination_item_size = destination.itemSize;

    const pixel_count = source.width * source.height;

    const destination_data = destination.data;
    const source_data = source.data;

    let i=0, j=0;

    if (source_item_size === destination_item_size) {
        // just copy data chunk
        destination_data.set(source_data);

    } else if (source_item_size > destination_item_size) {
        // more channels in source than in destination
        for (i = 0; i < pixel_count; i++) {
            const source_sample_offset = i * source_item_size;
            const destination_sample_offset = i * destination_item_size;

            for (j = 0; j < destination_item_size; j++) {
                destination_data[destination_sample_offset + j] = source_data[source_sample_offset + j];
            }
        }

    } else if (source_item_size === 3 && destination_item_size === 4) {

        const saturated_channel_value = saturated_value_by_constructor(destination_data.constructor);

        // RGB -> RGBA
        for (i = 0; i < pixel_count; i++) {
            const i3 = i * 3;
            const i4 = i * 4;

            destination_data[i4] = source_data[i3];
            destination_data[i4 + 1] = source_data[i3 + 1];
            destination_data[i4 + 2] = source_data[i3 + 2];

            destination_data[i4 + 3] = saturated_channel_value; // fill alpha
        }
    } else if (source_item_size === 2 && destination_item_size === 4) {
        //RA -> RGBA
        for (i = 0; i < pixel_count; i++) {
            const i2 = i * 2;
            const i4 = i * 4;

            const r = source_data[i2];

            destination_data[i4] = r;
            destination_data[i4 + 1] = r;
            destination_data[i4 + 2] = r;

            destination_data[i4 + 3] = source_data[i2 + 1]; // fill alpha
        }
    } else {
        throw new Error('Unsupported channel layout combination');
    }

    // register data change
    destination.version++;
}
