// See lipsum.dev

import React, { useEffect, useRef, useState } from "react";

const L = 8;

function baseFunc(u, v) {
    return (x, y) =>
        Math.cos(((2 * x + 1) * u * Math.PI) / 16) *
        Math.cos(((2 * y + 1) * v * Math.PI) / 16);
}

function drawBaseFunc(canvas, factor, u, v) {
    const ctx = canvas.getContext("2d");
    const func = baseFunc(u, v);
    const size = factor * L;
    const imgData = ctx.createImageData(size, size);
    for (var i = 0; i < size; i++) {
        for (var j = 0; j < size; j++) {
            var pixelIndex = (i + j * size) * 4;
            var pixelColor =
                128 +
                Math.round(128 * func(Math.floor(i / factor), Math.floor(j / factor)));
            imgData.data[pixelIndex + 0] = pixelColor;
            imgData.data[pixelIndex + 1] = pixelColor;
            imgData.data[pixelIndex + 2] = pixelColor;
            imgData.data[pixelIndex + 3] = 255;
        }
    }
    ctx.putImageData(imgData, 0, 0);
}

function BaseImage(props) {
    const canvasRef = useRef(null);
    const size = L * props.factor;
    useEffect(() => {
        const canvas = canvasRef.current;
        drawBaseFunc(canvas, props.factor, props.u, props.v);
    });
    return (
        <div>
            <canvas ref={canvasRef} width={size} height={size}></canvas>
        </div>
    );
}

function CosinusTransform(props) {
    const [u, setU] = useState(2);
    const [v, setV] = useState(5);
    return (
        <div>
            <BaseImage factor={props.factor} u={u} v={v} />
            <div>
                <label for="u">u = {u} </label>
                <input
                    id="u"
                    type="range"
                    min={0}
                    max={7}
                    value={u}
                    onChange={(e) => setU(e.target.value)}
                />
            </div>
            <div>
                <label for="v">v = {v} </label>
                <input
                    id="v"
                    type="range"
                    min={0}
                    max={7}
                    value={v}
                    onChange={(e) => setV(e.target.value)}
                />
            </div>
        </div>
    );
}

export { CosinusTransform }