package p.studio.workspaces.assets.metadata;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public record AssetStudioSceneLayerBinding(
        boolean enabled,
        int index,
        String layerName,
        int width,
        int height,
        String tilemap,
        String tilesetAssetRoot,
        float parallaxFactorX,
        float parallaxFactorY,
        int defaultPaletteId,
        List<AssetStudioSceneTile> tiles) {
    public AssetStudioSceneLayerBinding {
        layerName = Objects.requireNonNull(layerName, "layerName").trim();
        tilemap = Objects.requireNonNull(tilemap, "tilemap").trim();
        tilesetAssetRoot = Objects.requireNonNull(tilesetAssetRoot, "tilesetAssetRoot").trim();
        tiles = List.copyOf(Objects.requireNonNull(tiles, "tiles"));
        if (index <= 0) {
            throw new IllegalArgumentException("index must be positive");
        }
        if (layerName.isBlank()) {
            throw new IllegalArgumentException("layerName must not be blank");
        }
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("layer dimensions must be positive");
        }
        if (tilemap.isBlank()) {
            throw new IllegalArgumentException("tilemap must not be blank");
        }
        if (!Float.isFinite(parallaxFactorX) || parallaxFactorX < 0.0f) {
            throw new IllegalArgumentException("parallaxFactorX must be finite and non-negative");
        }
        if (!Float.isFinite(parallaxFactorY) || parallaxFactorY < 0.0f) {
            throw new IllegalArgumentException("parallaxFactorY must be finite and non-negative");
        }
        if (defaultPaletteId < 0) {
            throw new IllegalArgumentException("defaultPaletteId must be non-negative");
        }
        if (tiles.size() != width * height) {
            throw new IllegalArgumentException("tiles must match width * height");
        }
    }

    public AssetStudioSceneLayerBinding(
            boolean enabled,
            int index,
            String layerName,
            int width,
            int height,
            String tilemap,
            String tilesetAssetRoot,
            float parallaxFactorX,
            float parallaxFactorY,
            int defaultPaletteId) {
        this(
                enabled,
                index,
                layerName,
                width,
                height,
                tilemap,
                tilesetAssetRoot,
                parallaxFactorX,
                parallaxFactorY,
                defaultPaletteId,
                blankTiles(width, height, defaultPaletteId));
    }

    private static List<AssetStudioSceneTile> blankTiles(int width, int height, int defaultPaletteId) {
        final List<AssetStudioSceneTile> tiles = new ArrayList<>(width * height);
        for (int index = 0; index < width * height; index += 1) {
            tiles.add(AssetStudioSceneTile.inactive(defaultPaletteId));
        }
        return List.copyOf(tiles);
    }
}
