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

package com.hypixel.hytale.protocol.packets.player;

import java.util.Objects;
import com.hypixel.hytale.protocol.io.ValidationResult;
import com.hypixel.hytale.protocol.io.PacketIO;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nonnull;
import com.hypixel.hytale.protocol.Vector3d;
import com.hypixel.hytale.protocol.TeleportAck;
import com.hypixel.hytale.protocol.Direction;
import com.hypixel.hytale.protocol.Position;
import com.hypixel.hytale.protocol.HalfFloatPosition;
import javax.annotation.Nullable;
import com.hypixel.hytale.protocol.MovementStates;
import com.hypixel.hytale.protocol.Packet;

public class ClientMovement implements Packet
{
    public static final int PACKET_ID = 108;
    public static final boolean IS_COMPRESSED = false;
    public static final int NULLABLE_BIT_FIELD_SIZE = 2;
    public static final int FIXED_BLOCK_SIZE = 153;
    public static final int VARIABLE_FIELD_COUNT = 0;
    public static final int VARIABLE_BLOCK_START = 153;
    public static final int MAX_SIZE = 153;
    @Nullable
    public MovementStates movementStates;
    @Nullable
    public HalfFloatPosition relativePosition;
    @Nullable
    public Position absolutePosition;
    @Nullable
    public Direction bodyOrientation;
    @Nullable
    public Direction lookOrientation;
    @Nullable
    public TeleportAck teleportAck;
    @Nullable
    public Position wishMovement;
    @Nullable
    public Vector3d velocity;
    public int mountedTo;
    @Nullable
    public MovementStates riderMovementStates;
    
    @Override
    public int getId() {
        return 108;
    }
    
    public ClientMovement() {
    }
    
    public ClientMovement(@Nullable final MovementStates movementStates, @Nullable final HalfFloatPosition relativePosition, @Nullable final Position absolutePosition, @Nullable final Direction bodyOrientation, @Nullable final Direction lookOrientation, @Nullable final TeleportAck teleportAck, @Nullable final Position wishMovement, @Nullable final Vector3d velocity, final int mountedTo, @Nullable final MovementStates riderMovementStates) {
        this.movementStates = movementStates;
        this.relativePosition = relativePosition;
        this.absolutePosition = absolutePosition;
        this.bodyOrientation = bodyOrientation;
        this.lookOrientation = lookOrientation;
        this.teleportAck = teleportAck;
        this.wishMovement = wishMovement;
        this.velocity = velocity;
        this.mountedTo = mountedTo;
        this.riderMovementStates = riderMovementStates;
    }
    
    public ClientMovement(@Nonnull final ClientMovement other) {
        this.movementStates = other.movementStates;
        this.relativePosition = other.relativePosition;
        this.absolutePosition = other.absolutePosition;
        this.bodyOrientation = other.bodyOrientation;
        this.lookOrientation = other.lookOrientation;
        this.teleportAck = other.teleportAck;
        this.wishMovement = other.wishMovement;
        this.velocity = other.velocity;
        this.mountedTo = other.mountedTo;
        this.riderMovementStates = other.riderMovementStates;
    }
    
    @Nonnull
    public static ClientMovement deserialize(@Nonnull final ByteBuf buf, final int offset) {
        final ClientMovement obj = new ClientMovement();
        final byte[] nullBits = PacketIO.readBytes(buf, offset, 2);
        if ((nullBits[0] & 0x1) != 0x0) {
            obj.movementStates = MovementStates.deserialize(buf, offset + 2);
        }
        if ((nullBits[0] & 0x2) != 0x0) {
            obj.relativePosition = HalfFloatPosition.deserialize(buf, offset + 24);
        }
        if ((nullBits[0] & 0x4) != 0x0) {
            obj.absolutePosition = Position.deserialize(buf, offset + 30);
        }
        if ((nullBits[0] & 0x8) != 0x0) {
            obj.bodyOrientation = Direction.deserialize(buf, offset + 54);
        }
        if ((nullBits[0] & 0x10) != 0x0) {
            obj.lookOrientation = Direction.deserialize(buf, offset + 66);
        }
        if ((nullBits[0] & 0x20) != 0x0) {
            obj.teleportAck = TeleportAck.deserialize(buf, offset + 78);
        }
        if ((nullBits[0] & 0x40) != 0x0) {
            obj.wishMovement = Position.deserialize(buf, offset + 79);
        }
        if ((nullBits[0] & 0x80) != 0x0) {
            obj.velocity = Vector3d.deserialize(buf, offset + 103);
        }
        obj.mountedTo = buf.getIntLE(offset + 127);
        if ((nullBits[1] & 0x1) != 0x0) {
            obj.riderMovementStates = MovementStates.deserialize(buf, offset + 131);
        }
        return obj;
    }
    
    public static int computeBytesConsumed(@Nonnull final ByteBuf buf, final int offset) {
        return 153;
    }
    
    @Override
    public void serialize(@Nonnull final ByteBuf buf) {
        final byte[] nullBits = new byte[2];
        if (this.movementStates != null) {
            final byte[] array = nullBits;
            final int n = 0;
            array[n] |= 0x1;
        }
        if (this.relativePosition != null) {
            final byte[] array2 = nullBits;
            final int n2 = 0;
            array2[n2] |= 0x2;
        }
        if (this.absolutePosition != null) {
            final byte[] array3 = nullBits;
            final int n3 = 0;
            array3[n3] |= 0x4;
        }
        if (this.bodyOrientation != null) {
            final byte[] array4 = nullBits;
            final int n4 = 0;
            array4[n4] |= 0x8;
        }
        if (this.lookOrientation != null) {
            final byte[] array5 = nullBits;
            final int n5 = 0;
            array5[n5] |= 0x10;
        }
        if (this.teleportAck != null) {
            final byte[] array6 = nullBits;
            final int n6 = 0;
            array6[n6] |= 0x20;
        }
        if (this.wishMovement != null) {
            final byte[] array7 = nullBits;
            final int n7 = 0;
            array7[n7] |= 0x40;
        }
        if (this.velocity != null) {
            final byte[] array8 = nullBits;
            final int n8 = 0;
            array8[n8] |= (byte)128;
        }
        if (this.riderMovementStates != null) {
            final byte[] array9 = nullBits;
            final int n9 = 1;
            array9[n9] |= 0x1;
        }
        buf.writeBytes(nullBits);
        if (this.movementStates != null) {
            this.movementStates.serialize(buf);
        }
        else {
            buf.writeZero(22);
        }
        if (this.relativePosition != null) {
            this.relativePosition.serialize(buf);
        }
        else {
            buf.writeZero(6);
        }
        if (this.absolutePosition != null) {
            this.absolutePosition.serialize(buf);
        }
        else {
            buf.writeZero(24);
        }
        if (this.bodyOrientation != null) {
            this.bodyOrientation.serialize(buf);
        }
        else {
            buf.writeZero(12);
        }
        if (this.lookOrientation != null) {
            this.lookOrientation.serialize(buf);
        }
        else {
            buf.writeZero(12);
        }
        if (this.teleportAck != null) {
            this.teleportAck.serialize(buf);
        }
        else {
            buf.writeZero(1);
        }
        if (this.wishMovement != null) {
            this.wishMovement.serialize(buf);
        }
        else {
            buf.writeZero(24);
        }
        if (this.velocity != null) {
            this.velocity.serialize(buf);
        }
        else {
            buf.writeZero(24);
        }
        buf.writeIntLE(this.mountedTo);
        if (this.riderMovementStates != null) {
            this.riderMovementStates.serialize(buf);
        }
        else {
            buf.writeZero(22);
        }
    }
    
    @Override
    public int computeSize() {
        return 153;
    }
    
    public static ValidationResult validateStructure(@Nonnull final ByteBuf buffer, final int offset) {
        if (buffer.readableBytes() - offset < 153) {
            return ValidationResult.error("Buffer too small: expected at least 153 bytes");
        }
        return ValidationResult.OK;
    }
    
    public ClientMovement clone() {
        final ClientMovement copy = new ClientMovement();
        copy.movementStates = ((this.movementStates != null) ? this.movementStates.clone() : null);
        copy.relativePosition = ((this.relativePosition != null) ? this.relativePosition.clone() : null);
        copy.absolutePosition = ((this.absolutePosition != null) ? this.absolutePosition.clone() : null);
        copy.bodyOrientation = ((this.bodyOrientation != null) ? this.bodyOrientation.clone() : null);
        copy.lookOrientation = ((this.lookOrientation != null) ? this.lookOrientation.clone() : null);
        copy.teleportAck = ((this.teleportAck != null) ? this.teleportAck.clone() : null);
        copy.wishMovement = ((this.wishMovement != null) ? this.wishMovement.clone() : null);
        copy.velocity = ((this.velocity != null) ? this.velocity.clone() : null);
        copy.mountedTo = this.mountedTo;
        copy.riderMovementStates = ((this.riderMovementStates != null) ? this.riderMovementStates.clone() : null);
        return copy;
    }
    
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof final ClientMovement other) {
            return Objects.equals(this.movementStates, other.movementStates) && Objects.equals(this.relativePosition, other.relativePosition) && Objects.equals(this.absolutePosition, other.absolutePosition) && Objects.equals(this.bodyOrientation, other.bodyOrientation) && Objects.equals(this.lookOrientation, other.lookOrientation) && Objects.equals(this.teleportAck, other.teleportAck) && Objects.equals(this.wishMovement, other.wishMovement) && Objects.equals(this.velocity, other.velocity) && this.mountedTo == other.mountedTo && Objects.equals(this.riderMovementStates, other.riderMovementStates);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(this.movementStates, this.relativePosition, this.absolutePosition, this.bodyOrientation, this.lookOrientation, this.teleportAck, this.wishMovement, this.velocity, this.mountedTo, this.riderMovementStates);
    }
}
