import { listen } from "rkgk/framework.js";

function* chunksInRectangle(left, top, right, bottom, chunkSize) {
    let leftChunk = Math.floor(left / chunkSize);
    let topChunk = Math.floor(top / chunkSize);
    let rightChunk = Math.ceil(right / chunkSize);
    let bottomChunk = Math.ceil(bottom / chunkSize);
    for (let chunkY = topChunk; chunkY < bottomChunk; ++chunkY) {
        for (let chunkX = leftChunk; chunkX < rightChunk; ++chunkX) {
            yield [chunkX, chunkY];
        }
    }
}

export function renderToChunksInArea(wall, renderArea, renderToPixmap) {
    for (let [chunkX, chunkY] of chunksInRectangle(
        renderArea.left,
        renderArea.top,
        renderArea.right,
        renderArea.bottom,
        wall.chunkSize,
    )) {
        let chunk = wall.getOrCreateChunk(chunkX, chunkY);
        let translationX = -chunkX * wall.chunkSize;
        let translationY = -chunkY * wall.chunkSize;
        let result = renderToPixmap(chunk.pixmap, translationX, translationY);
        chunk.markModified();
        if (result.status != "ok") return result;
    }

    return { status: "ok" };
}

export function dotterRenderArea(wall, dotter) {
    let halfPaintArea = wall.paintArea / 2;
    return {
        left: dotter.toX - halfPaintArea,
        top: dotter.toY - halfPaintArea,
        right: dotter.toX + halfPaintArea,
        bottom: dotter.toY + halfPaintArea,
    };
}

export function selfController(interactionQueue, wall, event) {
    let renderArea = null;
    return {
        async runScribble(renderToPixmap) {
            interactionQueue.push({ kind: "scribble" });
            if (renderArea != null) {
                return renderToChunksInArea(wall, renderArea, renderToPixmap);
            } else {
                console.debug("render area is empty, nothing will be rendered");
            }
            return { status: "ok" };
        },

        async runDotter() {
            let dotter = await event.continueAsDotter();
            interactionQueue.push({
                kind: "dotter",
                from: { x: dotter.fromX, y: dotter.fromY },
                to: { x: dotter.toX, y: dotter.toY },
                num: dotter.num,
            });
            renderArea = dotterRenderArea(wall, dotter);
            return dotter;
        },
    };
}