<?php

use Doom\Texture\TextureXParser;

function le16s(int $value): string
{
    return pack('v', $value & 0xFFFF);
}

test('parses TEXTUREX definitions and patch references', function (): void {
    $headerSize = 4 + (2 * 4);
    $offset0 = $headerSize;
    $offset1 = $offset0 + 32;

    $texture0 = pack('a8VvvVv', 'BRICK1', 0, 64, 128, 0, 1)
        . le16s(8)
        . le16s(-4)
        . pack('v', 3)
        . pack('v', 0)
        . pack('v', 0);

    $texture1 = pack('a8VvvVv', 'METAL2', 1, 32, 32, 0, 2)
        . le16s(0)
        . le16s(0)
        . pack('v', 7)
        . pack('v', 0)
        . pack('v', 0)
        . le16s(12)
        . le16s(4)
        . pack('v', 8)
        . pack('v', 0)
        . pack('v', 0);

    $data = pack('V', 2)
        . pack('V', $offset0)
        . pack('V', $offset1)
        . $texture0
        . $texture1;

    $textureX = TextureXParser::parseBytes($data);

    expect($textureX->numTextures)->toBe(2);
    expect($textureX->offsets)->toBe([$offset0, $offset1]);
    expect($textureX->textures)->toHaveCount(2);

    $first = $textureX->textures[0];
    expect($first->name)->toBe('BRICK1');
    expect($first->masked)->toBeFalse();
    expect($first->width)->toBe(64);
    expect($first->height)->toBe(128);
    expect($first->patches)->toHaveCount(1);
    expect($first->patches[0]->originX)->toBe(8);
    expect($first->patches[0]->originY)->toBe(-4);
    expect($first->patches[0]->patch)->toBe(3);

    $second = $textureX->firstTextureByName('metal2');
    expect($second)->not->toBeNull();
    expect($second->masked)->toBeTrue();
    expect($second->patches)->toHaveCount(2);
    expect($second->patches[1]->originX)->toBe(12);
    expect($second->patches[1]->originY)->toBe(4);
    expect($second->patches[1]->patch)->toBe(8);
});

test('throws on invalid texture offset', function (): void {
    $data = pack('V', 1) . pack('V', 999);

    expect(fn () => TextureXParser::parseBytes($data))->toThrow(RuntimeException::class);
});
