package fr.koka99cab.spiderman.client.render;

import fr.koka99cab.spiderman.entity.GrapplingHookEntity;
import java.util.List;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.ThrownItemRenderer;
import net.minecraft.client.renderer.entity.state.EntityRenderState.LeashState;
import net.minecraft.client.renderer.entity.state.ThrownItemRenderState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;

public class GrapplingHookRenderer extends ThrownItemRenderer<GrapplingHookEntity> {
	private static final Vec3 HOOK_LEASH_OFFSET = new Vec3(0.0D, 0.04D, 0.0D);

	public GrapplingHookRenderer(EntityRendererProvider.Context context) {
		super(context, 0.9F, false);
		this.shadowRadius = 0.08F;
	}

	@Override
	public void extractRenderState(GrapplingHookEntity hook, ThrownItemRenderState state, float partialTick) {
		super.extractRenderState(hook, state, partialTick);
		Entity owner = hook.getOwner();
		if (owner == null) {
			state.leashStates = null;
			return;
		}

		Vec3 hookPosition = hook.getPosition(partialTick);
		Vec3 leashStart = hookPosition.add(HOOK_LEASH_OFFSET);
		Vec3 leashEnd = owner.getRopeHoldPosition(partialTick);
		LeashState leashState = new LeashState();

		leashState.offset = HOOK_LEASH_OFFSET;
		leashState.start = leashStart;
		leashState.end = leashEnd;
		leashState.slack = false;
		fillLight(hook.level(), leashState, leashStart, leashEnd);
		state.leashStates = List.of(leashState);
	}

	@Override
	protected boolean affectedByCulling(GrapplingHookEntity hook) {
		return false;
	}

	private static void fillLight(Level level, LeashState leashState, Vec3 leashStart, Vec3 leashEnd) {
		BlockPos start = BlockPos.containing(leashStart);
		BlockPos end = BlockPos.containing(leashEnd);

		leashState.startBlockLight = level.getBrightness(LightLayer.BLOCK, start);
		leashState.endBlockLight = level.getBrightness(LightLayer.BLOCK, end);
		leashState.startSkyLight = level.getBrightness(LightLayer.SKY, start);
		leashState.endSkyLight = level.getBrightness(LightLayer.SKY, end);
	}
}
