<?php

use Doom\Image\Renderer;
use Doom\Picture\Picture;
use Intervention\Image\Encoders\PngEncoder;

/**
 * @return array<int, array{0:int,1:int,2:int}>
 */
function imageTestPalette(): array
{
    $palette = array_fill(0, 256, [0, 0, 0]);
    $palette[1] = [255, 0, 0];
    $palette[2] = [0, 255, 0];

    return $palette;
}

function testPatchPicture(): Picture
{
    return new Picture(
        width: 2,
        height: 2,
        left: 0,
        top: 0,
        posts: [
            0 => [
                ['y' => 0, 'topdelta' => 0, 'pixels' => [1]],
            ],
            1 => [
                ['y' => 1, 'topdelta' => 1, 'pixels' => [2]],
            ],
        ],
    );
}

test('can blit a Picture into a texture and encode png', function (): void {
    $texture = (new Renderer(imageTestPalette()))->createTexture(4, 3);
    $texture->blit(testPatchPicture(), 1, 1);

    $png = (string) $texture->image()->encode(new PngEncoder());
    expect(substr($png, 0, 8))->toBe("\x89PNG\r\n\x1A\n");

    $image = imagecreatefromstring($png);
    expect($image)->not->toBeFalse();

    $pixel = imagecolorsforindex($image, imagecolorat($image, 1, 1));
    expect([$pixel['red'], $pixel['green'], $pixel['blue'], $pixel['alpha']])->toBe([255, 0, 0, 0]);

    $transparent = imagecolorsforindex($image, imagecolorat($image, 0, 0));
    expect($transparent['alpha'])->toBe(127);

    imagedestroy($image);
});

test('can blit a png file into a texture and write it', function (): void {
    $sourcePath = tempnam(sys_get_temp_dir(), 'doom-src-');
    $outPath = tempnam(sys_get_temp_dir(), 'doom-out-');
    if ($sourcePath === false || $outPath === false) {
        throw new RuntimeException('Failed to allocate temp files.');
    }

    $sourcePng = $sourcePath . '.png';
    $targetPng = $outPath . '.png';
    @unlink($sourcePath);
    @unlink($outPath);

    try {
        $sourceTexture = (new Renderer(imageTestPalette()))->createTexture(2, 2);
        $sourceTexture->blit(testPatchPicture());
        $sourceTexture->image()->encode(new PngEncoder())->save($sourcePng);

        $targetTexture = (new Renderer())->createTexture(6, 4);
        $targetTexture->blit($sourcePng, 2, 1);
        $targetTexture->image()->encode(new PngEncoder())->save($targetPng);

        expect(is_file($targetPng))->toBeTrue();

        $image = imagecreatefrompng($targetPng);
        expect($image)->not->toBeFalse();

        $pixel = imagecolorsforindex($image, imagecolorat($image, 2, 1));
        expect([$pixel['red'], $pixel['green'], $pixel['blue']])->toBe([255, 0, 0]);

        imagedestroy($image);
    } finally {
        @unlink($sourcePng);
        @unlink($targetPng);
    }
});
