package com.infinityraider.agricraft.api.v1.plant;

import com.infinityraider.agricraft.api.v1.client.IAgriGrowableGuiRenderer;
import com.infinityraider.agricraft.api.v1.crop.IAgriGrowthStage;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;

/**
 * Common interface between all "things" that can grow on crop sticks
 */
public interface IAgriGrowable {
    /**
     * Determines the initial Growth Stage of a plant or weed when first planted
     *
     * @return the IAgriGrowthStage for the initial growth stage
     */
    @Nonnull
    IAgriGrowthStage getInitialGrowthStage();

    /**
     * Gets all the possible growth stages that a plant or weed can have.
     *
     * For AgriCraft specifically, the conventional number of growth stages is 8.
     *
     * @return a set containing all the possible growth stages of the plant.
     */
    @Nonnull
    Collection<IAgriGrowthStage> getGrowthStages();

    /**
     * @return the final growth stage for this plant
     */
    default IAgriGrowthStage getFinalStage() {
        return this.getGrowthStages().stream().filter(IAgriGrowthStage::isFinal).findAny()
                // This should not ever be reached
                .orElseThrow(() -> new IllegalStateException("Plant without final growth stage"));
    }

    /**
     * Fetches the height of the plant at the given growth stage in 1/16ths of a block.
     * Note that it is possible to return heights taller than 16
     *
     * For instance, returning 8 corresponds to a plant half a block high,
     * while returning 16 corresponds to a full block high,
     * and returning 32 corresponds to a plant which is two blocks high.     *
     *
     * @param stage the growth stage
     * @return height of the plant in 1/16ths of a block
     */
    double getPlantHeight(IAgriGrowthStage stage);

    /**
     * Method to render plants or weeds on crop sticks,
     * only called when a plant or weed of this growth stage is about to be rendered.
     *
     * Given the large amount of combinations of plants, weeds and growth stages,
     * AgriCraft internally caches quads for each combination of plant and growth stage,
     * only baking the quads when they are required and then caching them to preserve memory.
     * If multiple growth stages have identical quads, it is advised to cache the quads on the implementing side as well.
     *
     * Note that it is possible to use the IAgriPlantQuadGenerator to generate quads according to AgriCraft's
     * default crop patterns.
     *
     * @param stage the current growth stage of the plant
     * @param face the face to get quads for
     * @return a list of quads for rendering the plant
     */
    @Nonnull
    @OnlyIn(Dist.CLIENT)
    List<BakedQuad> bakeQuads(@Nullable Direction face, IAgriGrowthStage stage);

    /**
     * Method which fetches all required texture to render a plant or weed for a certain growth stage,
     * used to stitch these textures to the texture atlas.
     *
     * @param stage the growth stage
     * @return a list of ResourceLocations pointing to the required textures, can be empty
     */
    @Nonnull
    List<ResourceLocation> getTexturesFor(IAgriGrowthStage stage);

    /**
     * @return gui renderer
     */
    @Nonnull
    @OnlyIn(Dist.CLIENT)
    default IAgriGrowableGuiRenderer getGuiRenderer() {
        return IAgriGrowableGuiRenderer.DEFAULT;
    }

    /**
     * Sub-interface for plants with seeds
     */
    interface WithSeed extends IAgriGrowable {
        /**
         * @return The resource location for the texture of the seed
         */
        @Nonnull
        ResourceLocation getSeedTexture();

        /**
         * @return The resource location for the model of the seed
         */
        @Nonnull
        ResourceLocation getSeedModel();

        /**
         * @return gui renderer
         */
        @Nonnull
        @Override
        default IAgriGrowableGuiRenderer.WithSeed getGuiRenderer() {
            return IAgriGrowableGuiRenderer.WithSeed.DEFAULT;
        }
    }
}

@@ -4188,16 +4188,45 @@
 verride%0A
+        @OnlyIn(Dist.CLIENT)%0A
         

Fix server crash (#1397)