package net.minecraft.data.models.model;

import java.util.function.Function;
import com.google.gson.JsonElement;
import java.util.function.Supplier;
import net.minecraft.resources.ResourceLocation;
import java.util.function.BiConsumer;
import net.minecraft.world.level.block.Block;
import java.util.function.Consumer;

public class TexturedModel {
    public static final Provider CUBE;
    public static final Provider CUBE_MIRRORED;
    public static final Provider COLUMN;
    public static final Provider COLUMN_HORIZONTAL;
    public static final Provider CUBE_TOP_BOTTOM;
    public static final Provider CUBE_TOP;
    public static final Provider ORIENTABLE_ONLY_TOP;
    public static final Provider ORIENTABLE;
    public static final Provider CARPET;
    public static final Provider GLAZED_TERRACOTTA;
    public static final Provider CORAL_FAN;
    public static final Provider PARTICLE_ONLY;
    public static final Provider ANVIL;
    public static final Provider LEAVES;
    public static final Provider LANTERN;
    public static final Provider HANGING_LANTERN;
    public static final Provider SEAGRASS;
    public static final Provider COLUMN_ALT;
    public static final Provider COLUMN_HORIZONTAL_ALT;
    public static final Provider TOP_BOTTOM_WITH_WALL;
    public static final Provider COLUMN_WITH_WALL;
    private final TextureMapping mapping;
    private final ModelTemplate template;
    
    private TexturedModel(final TextureMapping iy, final ModelTemplate iw) {
        this.mapping = iy;
        this.template = iw;
    }
    
    public ModelTemplate getTemplate() {
        return this.template;
    }
    
    public TextureMapping getMapping() {
        return this.mapping;
    }
    
    public TexturedModel updateTextures(final Consumer<TextureMapping> consumer) {
        consumer.accept(this.mapping);
        return this;
    }
    
    public ResourceLocation create(final Block bvr, final BiConsumer<ResourceLocation, Supplier<JsonElement>> biConsumer) {
        return this.template.create(bvr, this.mapping, biConsumer);
    }
    
    public ResourceLocation createWithSuffix(final Block bvr, final String string, final BiConsumer<ResourceLocation, Supplier<JsonElement>> biConsumer) {
        return this.template.createWithSuffix(bvr, string, this.mapping, biConsumer);
    }
    
    private static Provider createDefault(final Function<Block, TextureMapping> function, final ModelTemplate iw) {
        return bvr -> new TexturedModel(function.apply(bvr), iw);
    }
    
    public static TexturedModel createAllSame(final ResourceLocation uh) {
        return new TexturedModel(TextureMapping.cube(uh), ModelTemplates.CUBE_ALL);
    }
    
    static {
        CUBE = createDefault(TextureMapping::cube, ModelTemplates.CUBE_ALL);
        CUBE_MIRRORED = createDefault(TextureMapping::cube, ModelTemplates.CUBE_MIRRORED_ALL);
        COLUMN = createDefault(TextureMapping::column, ModelTemplates.CUBE_COLUMN);
        COLUMN_HORIZONTAL = createDefault(TextureMapping::column, ModelTemplates.CUBE_COLUMN_HORIZONTAL);
        CUBE_TOP_BOTTOM = createDefault(TextureMapping::cubeBottomTop, ModelTemplates.CUBE_BOTTOM_TOP);
        CUBE_TOP = createDefault(TextureMapping::cubeTop, ModelTemplates.CUBE_TOP);
        ORIENTABLE_ONLY_TOP = createDefault(TextureMapping::orientableCubeOnlyTop, ModelTemplates.CUBE_ORIENTABLE);
        ORIENTABLE = createDefault(TextureMapping::orientableCube, ModelTemplates.CUBE_ORIENTABLE_TOP_BOTTOM);
        CARPET = createDefault(TextureMapping::wool, ModelTemplates.CARPET);
        GLAZED_TERRACOTTA = createDefault(TextureMapping::pattern, ModelTemplates.GLAZED_TERRACOTTA);
        CORAL_FAN = createDefault(TextureMapping::fan, ModelTemplates.CORAL_FAN);
        PARTICLE_ONLY = createDefault(TextureMapping::particle, ModelTemplates.PARTICLE_ONLY);
        ANVIL = createDefault(TextureMapping::top, ModelTemplates.ANVIL);
        LEAVES = createDefault(TextureMapping::cube, ModelTemplates.LEAVES);
        LANTERN = createDefault(TextureMapping::lantern, ModelTemplates.LANTERN);
        HANGING_LANTERN = createDefault(TextureMapping::lantern, ModelTemplates.HANGING_LANTERN);
        SEAGRASS = createDefault(TextureMapping::defaultTexture, ModelTemplates.SEAGRASS);
        COLUMN_ALT = createDefault(TextureMapping::logColumn, ModelTemplates.CUBE_COLUMN);
        COLUMN_HORIZONTAL_ALT = createDefault(TextureMapping::logColumn, ModelTemplates.CUBE_COLUMN_HORIZONTAL);
        TOP_BOTTOM_WITH_WALL = createDefault(TextureMapping::cubeBottomTopWithWall, ModelTemplates.CUBE_BOTTOM_TOP);
        COLUMN_WITH_WALL = createDefault(TextureMapping::columnWithWall, ModelTemplates.CUBE_COLUMN);
    }
    
    @FunctionalInterface
    public interface Provider {
        TexturedModel get(final Block bvr);
        
        default ResourceLocation create(final Block bvr, final BiConsumer<ResourceLocation, Supplier<JsonElement>> biConsumer) {
            return this.get(bvr).create(bvr, biConsumer);
        }
        
        default ResourceLocation createWithSuffix(final Block bvr, final String string, final BiConsumer<ResourceLocation, Supplier<JsonElement>> biConsumer) {
            return this.get(bvr).createWithSuffix(bvr, string, biConsumer);
        }
        
        default Provider updateTexture(final Consumer<TextureMapping> consumer) {
            return bvr -> this.get(bvr).updateTextures(consumer);
        }
    }
}
