/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.datagen.provider;

import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.properties.WoodType;
import net.minecraftforge.client.model.generators.BlockModelProvider;
import net.minecraftforge.common.data.ExistingFileHelper;
import top.r3944realms.eroticdungeongame.EroticDungeon;
import top.r3944realms.eroticdungeongame.util.ColorContent;
import top.r3944realms.eroticdungeongame.util.WoodTypeHelper;

public class EDGBlockModelProvider extends BlockModelProvider {

    public EDGBlockModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
        super(output, EroticDungeon.MOD_ID, existingFileHelper);
    }

    @Override
    protected void registerModels() {
        generateCuffBedModels();
        generateRackModels();
        generateCruxModels();
        generateXCrossModels();
        generatePetrineCrossModels();
        generateSpanishDonkeyModels();
        generatePilloryModels();
        generateWallRackModels();
        generateCuffPoleModels();
        generateProneBenchModels();
        generateHangingPostModels();
        generateDungeonCraftingTableModels();
    }

    protected void generateDungeonCraftingTableModels() {
        ResourceLocation bottom = EroticDungeon.rl("block/dungeon_crafting_table_bottom");
        ResourceLocation top = EroticDungeon.rl("block/dungeon_crafting_table_top");
        ResourceLocation side = EroticDungeon.rl("block/dungeon_crafting_table_side");
        ResourceLocation front = EroticDungeon.rl("block/dungeon_crafting_table_front");
        getBuilder("block/dungeon_crafting_table")
                .parent(getExistingFile(mcLoc("block/cube")))
                .texture("down",bottom)
                .texture("east",side)
                .texture("north",front)
                .texture("south",side)
                .texture("west",front)
                .texture("up",top)
                .texture("particle",bottom);
    }

    /*Spanish Donkey*/
    //============= BEGIN
    protected void generateSpanishDonkeyModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createSpanishDonkeyModel(woodType);
        }
    }

    private void createSpanishDonkeyModel(WoodType woodType) {
        ResourceLocation texture = WoodTypeHelper.getWoodPlankRL(woodType);
        getBuilder("block/spanish_donkey/" + woodType.name())
                .parent(getExistingFile(EroticDungeon.rl("block/spanish_donkey")))
                .texture("wood", texture)
                .ao(false);
    }
    //============= END

    /*Cuff Bed*/
    //============= BEGIN
    protected void generateCuffBedModels() {
        for (String color : ColorContent.COLORS) {
            createCuffBedHeadModel(color);
            createCuffBedFootModel(color);
        }
    }

    private void createCuffBedHeadModel(String color) {
        ResourceLocation rl = EroticDungeon.rl("block/bed/" + color);
        getBuilder("block/cuff_bed/" + color + "_head")
                .parent(getExistingFile(EroticDungeon.rl("block/base_cuff_bed_head")))
                .texture("bed", rl)
                .ao(false);
    }

    private void createCuffBedFootModel(String color) {
        ResourceLocation rl = EroticDungeon.rl("block/bed/" + color);
        getBuilder("block/cuff_bed/" + color + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_cuff_bed_foot")))
                .texture("bed", rl)
                .ao(false);

    }
    //============= END

    /*Rack*/
    //============= BEGIN
    protected void generateRackModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createRackHeadModel(woodType);
            createRackMiddleModel(woodType);
            createRackFootModel(woodType);
        }
    }

    private void createRackHeadModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/rack/" + woodString + "_head")
                .parent(getExistingFile(EroticDungeon.rl("block/base_rack_head")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createRackMiddleModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/rack/" + woodString + "_middle")
                .parent(getExistingFile(EroticDungeon.rl("block/base_rack_middle")))
                .texture("wood", rl)
                .ao(false);

    }

    private void createRackFootModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/rack/" + woodString + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_rack_foot")))
                .texture("wood", rl)
                .ao(false);
    }
    //============= END

    /*X Cross*/
    //============= BEGIN
    protected void generateXCrossModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createXCrossHeadModel(woodType);
            createXCrossFootModel(woodType);
        }
    }

    private void createXCrossHeadModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/x_cross/" + woodString + "_head")
                .parent(getExistingFile(EroticDungeon.rl("block/base_x_cross_head")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createXCrossFootModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/x_cross/" + woodString + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_x_cross_foot")))
                .texture("wood", rl)
                .ao(false);

    }
    //============= END

    /*Petrine Cross*/
    //============= BEGIN
    protected void generatePetrineCrossModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createPetrineCrossHeadModel(woodType);
            createPetrineCrossFootLeftModel(woodType);
            createPetrineCrossFootRightModel(woodType);
            createPetrineCrossFootMiddleModel(woodType);
        }
    }

    private void createPetrineCrossFootLeftModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/petrine_cross/" + woodString + "_foot_left")
                .parent(getExistingFile(EroticDungeon.rl("block/base_petrine_cross_foot_left")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createPetrineCrossFootRightModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/petrine_cross/" + woodString + "_foot_right")
                .parent(getExistingFile(EroticDungeon.rl("block/base_petrine_cross_foot_right")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createPetrineCrossFootMiddleModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/petrine_cross/" + woodString + "_foot_middle")
                .parent(getExistingFile(EroticDungeon.rl("block/base_petrine_cross_foot_middle")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createPetrineCrossHeadModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/petrine_cross/" + woodString + "_head")
                .parent(getExistingFile(EroticDungeon.rl("block/base_petrine_cross_head")))
                .texture("wood", rl)
                .ao(false);
    }
    //============= END

    /*Crux*/
    //============= BEGIN
    protected void generateCruxModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createCruxFootModel(woodType);
            createCruxHeadRightModel(woodType);
            createCruxHeadLeftModel(woodType);
            createCruxHeadMiddleModel(woodType);
        }
    }

    private void createCruxHeadLeftModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/crux/" + woodString + "_head_left")
                .parent(getExistingFile(EroticDungeon.rl("block/base_crux_head_left")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createCruxHeadRightModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/crux/" + woodString + "_head_right")
                .parent(getExistingFile(EroticDungeon.rl("block/base_crux_head_right")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createCruxHeadMiddleModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/crux/" + woodString + "_head_middle")
                .parent(getExistingFile(EroticDungeon.rl("block/base_crux_head_middle")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createCruxFootModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/crux/" + woodString + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_crux_foot")))
                .texture("wood", rl)
                .ao(false);
    }
    //============= END


    /*Pillory*/
    //============= BEGIN
    protected void generatePilloryModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createPilloryClosedHeadModel(woodType);
            createPilloryOpenedHeadModel(woodType);
            createPilloryFootModel(woodType);
        }
    }

    protected void createPilloryOpenedHeadModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/pillory/" + woodString + "_head_opened")
                .parent(getExistingFile(EroticDungeon.rl("block/base_pillory_head_opened")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createPilloryClosedHeadModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/pillory/" + woodString + "_head_closed")
                .parent(getExistingFile(EroticDungeon.rl("block/base_pillory_head_closed")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createPilloryFootModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodPlankRL(wood);
        getBuilder("block/pillory/" + woodString + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_pillory_foot")))
                .texture("wood", rl)
                .ao(false);

    }
    //============= END

    /*Wall Rack*/
    //============= BEGIN
    private void generateWallRackModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createWallRackLeftModel(woodType);
            createWallRackMiddleModel(woodType);
            createWallRackRightModel(woodType);
        }
    }

    private void createWallRackLeftModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodPlankRL = WoodTypeHelper.getWoodPlankRL(wood);
        ResourceLocation woodLogRL = WoodTypeHelper.getWoodLogRL(wood);
        getBuilder("block/wall_rack/" + woodString + "_left")
                .parent(getExistingFile(EroticDungeon.rl("block/base_wall_rack_left")))
                .texture("plank", woodPlankRL)
                .texture("wood", woodLogRL)
                .ao(false);
    }

    private void createWallRackRightModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodPlankRL = WoodTypeHelper.getWoodPlankRL(wood);
        ResourceLocation woodLogRL = WoodTypeHelper.getWoodLogRL(wood);
        getBuilder("block/wall_rack/" + woodString + "_right")
                .parent(getExistingFile(EroticDungeon.rl("block/base_wall_rack_right")))
                .texture("plank", woodPlankRL)
                .texture("wood", woodLogRL)
                .ao(false);
    }

    private void createWallRackMiddleModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodPlankRL = WoodTypeHelper.getWoodPlankRL(wood);
        ResourceLocation woodLogRL = WoodTypeHelper.getWoodLogRL(wood);
        getBuilder("block/wall_rack/" + woodString + "_middle")
                .parent(getExistingFile(EroticDungeon.rl("block/base_wall_rack_middle")))
                .texture("plank", woodPlankRL)
                .texture("wood", woodLogRL)
                .ao(false);
    }

    //============= END

    /*Cuff Pole*/
    //============= BEGIN
    protected void generateCuffPoleModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createCuffPoleHeadModel(woodType);
            createCuffPoleFootModel(woodType);
        }
    }

    private void createCuffPoleHeadModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodLogRL(wood);
        getBuilder("block/cuff_pole/" + woodString + "_head")
                .parent(getExistingFile(EroticDungeon.rl("block/base_cuff_pole_head")))
                .texture("wood", rl)
                .ao(false);
    }

    private void createCuffPoleFootModel(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation rl = WoodTypeHelper.getWoodLogRL(wood);
        getBuilder("block/cuff_pole/" + woodString + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_cuff_pole_foot")))
                .texture("wood", rl)
                .ao(false);

    }
    //============= END

    /*Prone Bench*/
    //============= BEGIN
    protected void generateProneBenchModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            for (String content : ColorContent.COLORS) {
                createProneBenchModel(content, woodType);
            }
        }
    }

    private void createProneBenchModel(String color, WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodRl = WoodTypeHelper.getStrippedWoodRL(wood);
        ResourceLocation woolRl = EroticDungeon.mrl("block/" + color + "_wool");
        getBuilder("block/prone_bench/" + color + "_" + woodString )
                .parent(getExistingFile(EroticDungeon.rl("block/base_prone_bench")))
                .texture("wood", woodRl)
                .texture("wool", woolRl)
                .ao(false);
    }
    //============= END

    /*Prone Bench*/
    //============= BEGIN
    protected void generateHangingPostModels() {
        for (WoodType woodType : WoodTypeHelper.SUPPORTED_WOOD_TYPES) {
            createHangingPostModelFoot(woodType);
            createHangingPostModelMiddle(woodType);
            createHangingPostModelHead(woodType);
        }
    }

    private void createHangingPostModelHead(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodRl = WoodTypeHelper.getStrippedWoodRL(wood);

        getBuilder("block/hanging_post/"  + woodString + "_head")
                .parent(getExistingFile(EroticDungeon.rl("block/base_hanging_post_head")))
                .texture("wood", woodRl)
                .ao(false);
    }
    private void createHangingPostModelMiddle(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodRl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/hanging_post/" + woodString + "_middle" )
                .parent(getExistingFile(EroticDungeon.rl("block/base_hanging_post_middle")))
                .texture("wood", woodRl)
                .ao(false);
    }
    private void createHangingPostModelFoot(WoodType wood) {
        String woodString = WoodTypeHelper.getWoodSimpleName(wood);
        ResourceLocation woodRl = WoodTypeHelper.getStrippedWoodRL(wood);
        getBuilder("block/hanging_post/" + woodString  + "_foot")
                .parent(getExistingFile(EroticDungeon.rl("block/base_hanging_post_foot")))
                .texture("wood", woodRl)
                .ao(false);
    }
    //============= END

}
