/*
 * Derived from Epic Fight (https://github.com/Epic-Fight/epicfight)
 * by the Epic Fight Team, licensed under GPLv3.
 * Modifications © 2026 TiedUp! Remake Contributors, distributed under GPLv3.
 */

package com.tiedup.remake.rig.anim.types;

import java.util.Optional;

import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import com.tiedup.remake.rig.anim.AnimationClip;
import com.tiedup.remake.rig.anim.AnimationManager.AnimationAccessor;
import com.tiedup.remake.rig.anim.Pose;
import com.tiedup.remake.rig.anim.property.AnimationProperty;
import com.tiedup.remake.rig.asset.AssetAccessor;
import com.tiedup.remake.rig.anim.client.Layer.Priority;
import com.tiedup.remake.rig.anim.client.property.JointMaskEntry;
import com.tiedup.remake.rig.TiedUpRigRegistry;
import com.tiedup.remake.rig.patch.LivingEntityPatch;

@OnlyIn(Dist.CLIENT)
public class LayerOffAnimation extends DynamicAnimation implements AnimationAccessor<LayerOffAnimation> {
	private AssetAccessor<? extends DynamicAnimation> lastAnimation;
	private Pose lastPose;
	private final Priority layerPriority;
	
	public LayerOffAnimation(Priority layerPriority) {
		this.layerPriority = layerPriority;
		this.animationClip = new AnimationClip();
	}
	
	public void setLastPose(Pose pose) {
		this.lastPose = pose;
	}
	
	@Override
	public void end(LivingEntityPatch<?> entitypatch, AssetAccessor<? extends DynamicAnimation> nextAnimation, boolean isEnd) {
		if (entitypatch.isLogicalClient() && isEnd) {
			entitypatch.getClientAnimator().baseLayer.disableLayer(this.layerPriority);
		}
	}
	
	@Override
	public Pose getPoseByTime(LivingEntityPatch<?> entitypatch, float time, float partialTicks) {
		Pose lowerLayerPose = entitypatch.getClientAnimator().getComposedLayerPoseBelow(this.layerPriority, Minecraft.getInstance().getFrameTime());
		Pose interpolatedPose = Pose.interpolatePose(this.lastPose, lowerLayerPose, time / this.getTotalTime());
		interpolatedPose.disableJoint((joint) -> !this.lastPose.hasTransform(joint.getKey()));
		
		return interpolatedPose;
	}
	
	@Override
	public Optional<JointMaskEntry> getJointMaskEntry(LivingEntityPatch<?> entitypatch, boolean useCurrentMotion) {
		return this.lastAnimation.get().getJointMaskEntry(entitypatch, useCurrentMotion);
	}
	
	@Override
	public <V> Optional<V> getProperty(AnimationProperty<V> propertyType) {
		return this.lastAnimation.get().getProperty(propertyType);
	}
	
	public void setLastAnimation(AssetAccessor<? extends DynamicAnimation> animation) {
		this.lastAnimation = animation;
	}
	
	@Override
	public boolean doesHeadRotFollowEntityHead() {
		return this.lastAnimation.get().doesHeadRotFollowEntityHead();
	}
	
	@Override
	public AssetAccessor<? extends StaticAnimation> getRealAnimation() {
		return TiedUpRigRegistry.EMPTY_ANIMATION;
	}

	@Override
	public AnimationClip getAnimationClip() {
		return this.animationClip;
	}
	
	@Override
	public boolean hasTransformFor(String joint) {
		return this.lastPose.hasTransform(joint);
	}
	
	@Override
	public boolean isLinkAnimation() {
		return true;
	}
	
	@Override
	public LayerOffAnimation get() {
		return this;
	}

	@Override
	public ResourceLocation registryName() {
		return null;
	}

	@Override
	public boolean isPresent() {
		return true;
	}

	@Override
	public int id() {
		return -1;
	}
	
	@Override
	public AnimationAccessor<? extends LayerOffAnimation> getAccessor() {
		return this;
	}
	
	@Override
	public boolean inRegistry() {
		return false;
	}
}
