import { assert } from "../../../../core/assert.js";


/**
 * Execute a binary operation with 2 input samplers and an output
 * @param {Sampler2D} input0
 * @param {Sampler2D} input1
 * @param {Sampler2D} result
 * @param {function( value0 : number[], value1 : number[], result : number[], index : number) : void} operation
 */
export function sampler2d_combine(input0, input1, result, operation) {
    assert.notEqual(input0, undefined, "input0 is undefined");
    assert.notEqual(input1, undefined, "input1 is undefined");
    assert.notEqual(result, undefined, "result is undefined");

    assert.isFunction(operation, "operation");

    assert.equal(input0.width, input1.width, `input0.width(=${input0.width}) is not equal to input1.width(=${input1.width})`);
    assert.equal(input0.height, input1.height, `input0.height(=${input0.height}) is not equal to input1.height(=${input1.height})`);

    assert.equal(input0.width, result.width, `input width(=${input0.width}) is not equal to result.width(=${result.width})`);
    assert.equal(input0.height, result.height, `input height(=${input0.height}) is not equal to result.height(=${result.height})`);

    const width = input0.width;
    const height = input0.height;

    const length = width * height;

    const arg0 = [];
    const arg1 = [];
    const res = [];

    const itemSize0 = input0.itemSize;
    const itemSize1 = input1.itemSize;
    const itemSizeR = result.itemSize;

    const data0 = input0.data;
    const data1 = input1.data;
    const dataR = result.data;


    let i, j;

    for (i = 0; i < length; i++) {

        // read input 0
        for (j = 0; j < itemSize0; j++) {
            arg0[j] = data0[j + i * itemSize0];
        }

        // read input 1
        for (j = 0; j < itemSize0; j++) {
            arg1[j] = data1[j + i * itemSize1];
        }

        //perform operation
        operation(arg0, arg1, res, i);

        //write result
        for (j = 0; j < itemSizeR; j++) {
            dataR[j + i * itemSizeR] = res[j];
        }

    }

    result.version++;
}
