// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.modules.entity.player;

import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import com.hypixel.hytale.protocol.Direction;
import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.protocol.MovementStates;
import java.util.Collection;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.component.ComponentType;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import javax.annotation.Nonnull;
import java.util.List;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Component;

public class PlayerInput implements Component<EntityStore>
{
    @Nonnull
    private final List<InputUpdate> inputUpdateQueue;
    private int mountId;
    
    public PlayerInput() {
        this.inputUpdateQueue = new ObjectArrayList<InputUpdate>();
    }
    
    public static ComponentType<EntityStore, PlayerInput> getComponentType() {
        return EntityModule.get().getPlayerInputComponentType();
    }
    
    public void queue(final InputUpdate inputUpdate) {
        this.inputUpdateQueue.add(inputUpdate);
    }
    
    @Nonnull
    public List<InputUpdate> getMovementUpdateQueue() {
        return this.inputUpdateQueue;
    }
    
    public int getMountId() {
        return this.mountId;
    }
    
    public void setMountId(final int mountId) {
        this.mountId = mountId;
    }
    
    @Nonnull
    @Override
    public Component<EntityStore> clone() {
        final PlayerInput playerInput = new PlayerInput();
        playerInput.inputUpdateQueue.addAll(this.inputUpdateQueue);
        return playerInput;
    }
    
    record SetMovementStates(MovementStates movementStates) implements InputUpdate {
        @Override
        public void apply(final CommandBuffer<EntityStore> commandBuffer, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
            final MovementStatesComponent movementStatesComponent = archetypeChunk.getComponent(index, MovementStatesComponent.getComponentType());
            if (movementStatesComponent == null) {
                return;
            }
            movementStatesComponent.setMovementStates(this.movementStates);
        }
    }
    
    public static class SetClientVelocity implements InputUpdate
    {
        private final Vector3d velocity;
        
        public SetClientVelocity(final com.hypixel.hytale.protocol.Vector3d velocity) {
            this.velocity = new Vector3d(velocity.x, velocity.y, velocity.z);
        }
        
        public Vector3d getVelocity() {
            return this.velocity;
        }
        
        @Override
        public void apply(final CommandBuffer<EntityStore> commandBuffer, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
            final Velocity velocityComponent = archetypeChunk.getComponent(index, Velocity.getComponentType());
            if (velocityComponent == null) {
                return;
            }
            velocityComponent.setClient(this.velocity);
        }
    }
    
    record SetRiderMovementStates(MovementStates movementStates) implements InputUpdate {
        @Override
        public void apply(final CommandBuffer<EntityStore> commandBuffer, final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
        }
    }
    
    record SetHead(Direction direction) implements InputUpdate {
        @Override
        public void apply(final CommandBuffer<EntityStore> commandBuffer, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
            final HeadRotation headRotationComponent = archetypeChunk.getComponent(index, HeadRotation.getComponentType());
            if (headRotationComponent == null) {
                return;
            }
            headRotationComponent.getRotation().assign(this.direction.pitch, this.direction.yaw, this.direction.roll);
        }
    }
    
    record SetBody(Direction direction) implements InputUpdate {
        @Override
        public void apply(final CommandBuffer<EntityStore> commandBuffer, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
            final TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType());
            if (transformComponent == null) {
                return;
            }
            transformComponent.getRotation().assign(this.direction.pitch, this.direction.yaw, this.direction.roll);
        }
    }
    
    public static class AbsoluteMovement implements InputUpdate
    {
        private double x;
        private double y;
        private double z;
        
        public AbsoluteMovement(final double x, final double y, final double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
        
        public double getX() {
            return this.x;
        }
        
        public void setX(final double x) {
            this.x = x;
        }
        
        public double getY() {
            return this.y;
        }
        
        public void setY(final double y) {
            this.y = y;
        }
        
        public double getZ() {
            return this.z;
        }
        
        public void setZ(final double z) {
            this.z = z;
        }
        
        @Override
        public void apply(@Nonnull final CommandBuffer<EntityStore> commandBuffer, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
            final Ref<EntityStore> playerRef = archetypeChunk.getReferenceTo(index);
            final Player playerComponent = archetypeChunk.getComponent(index, Player.getComponentType());
            assert playerComponent != null;
            playerComponent.moveTo(playerRef, this.x, this.y, this.z, commandBuffer);
        }
    }
    
    public static class RelativeMovement implements InputUpdate
    {
        private double x;
        private double y;
        private double z;
        
        public RelativeMovement(final double x, final double y, final double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
        
        public double getX() {
            return this.x;
        }
        
        public void setX(final double x) {
            this.x = x;
        }
        
        public double getY() {
            return this.y;
        }
        
        public void setY(final double y) {
            this.y = y;
        }
        
        public double getZ() {
            return this.z;
        }
        
        public void setZ(final double z) {
            this.z = z;
        }
        
        @Override
        public void apply(@Nonnull final CommandBuffer<EntityStore> commandBuffer, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
            final Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
            final Player playerComponent = archetypeChunk.getComponent(index, Player.getComponentType());
            assert playerComponent != null;
            final TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType());
            assert transformComponent != null;
            final Vector3d position = transformComponent.getPosition();
            playerComponent.moveTo(ref, position.x + this.x, position.y + this.y, position.z + this.z, commandBuffer);
        }
    }
    
    public static class WishMovement implements InputUpdate
    {
        private double x;
        private double y;
        private double z;
        
        public WishMovement(final double x, final double y, final double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
        
        public double getX() {
            return this.x;
        }
        
        public void setX(final double x) {
            this.x = x;
        }
        
        public double getY() {
            return this.y;
        }
        
        public void setY(final double y) {
            this.y = y;
        }
        
        public double getZ() {
            return this.z;
        }
        
        public void setZ(final double z) {
            this.z = z;
        }
        
        @Override
        public void apply(final CommandBuffer<EntityStore> commandBuffer, final ArchetypeChunk<EntityStore> archetypeChunk, final int index) {
        }
    }
    
    public interface InputUpdate
    {
        void apply(final CommandBuffer<EntityStore> p0, final ArchetypeChunk<EntityStore> p1, final int p2);
    }
}
