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

package com.hypixel.hytale.protocol;

import java.util.Objects;
import com.hypixel.hytale.protocol.io.ValidationResult;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class MountedUpdate
{
    public static final int NULLABLE_BIT_FIELD_SIZE = 1;
    public static final int FIXED_BLOCK_SIZE = 48;
    public static final int VARIABLE_FIELD_COUNT = 0;
    public static final int VARIABLE_BLOCK_START = 48;
    public static final int MAX_SIZE = 48;
    public int mountedToEntity;
    @Nullable
    public Vector3f attachmentOffset;
    @Nonnull
    public MountController controller;
    @Nullable
    public BlockMount block;
    
    public MountedUpdate() {
        this.controller = MountController.Minecart;
    }
    
    public MountedUpdate(final int mountedToEntity, @Nullable final Vector3f attachmentOffset, @Nonnull final MountController controller, @Nullable final BlockMount block) {
        this.controller = MountController.Minecart;
        this.mountedToEntity = mountedToEntity;
        this.attachmentOffset = attachmentOffset;
        this.controller = controller;
        this.block = block;
    }
    
    public MountedUpdate(@Nonnull final MountedUpdate other) {
        this.controller = MountController.Minecart;
        this.mountedToEntity = other.mountedToEntity;
        this.attachmentOffset = other.attachmentOffset;
        this.controller = other.controller;
        this.block = other.block;
    }
    
    @Nonnull
    public static MountedUpdate deserialize(@Nonnull final ByteBuf buf, final int offset) {
        final MountedUpdate obj = new MountedUpdate();
        final byte nullBits = buf.getByte(offset);
        obj.mountedToEntity = buf.getIntLE(offset + 1);
        if ((nullBits & 0x1) != 0x0) {
            obj.attachmentOffset = Vector3f.deserialize(buf, offset + 5);
        }
        obj.controller = MountController.fromValue(buf.getByte(offset + 17));
        if ((nullBits & 0x2) != 0x0) {
            obj.block = BlockMount.deserialize(buf, offset + 18);
        }
        return obj;
    }
    
    public static int computeBytesConsumed(@Nonnull final ByteBuf buf, final int offset) {
        return 48;
    }
    
    public void serialize(@Nonnull final ByteBuf buf) {
        byte nullBits = 0;
        if (this.attachmentOffset != null) {
            nullBits |= 0x1;
        }
        if (this.block != null) {
            nullBits |= 0x2;
        }
        buf.writeByte(nullBits);
        buf.writeIntLE(this.mountedToEntity);
        if (this.attachmentOffset != null) {
            this.attachmentOffset.serialize(buf);
        }
        else {
            buf.writeZero(12);
        }
        buf.writeByte(this.controller.getValue());
        if (this.block != null) {
            this.block.serialize(buf);
        }
        else {
            buf.writeZero(30);
        }
    }
    
    public int computeSize() {
        return 48;
    }
    
    public static ValidationResult validateStructure(@Nonnull final ByteBuf buffer, final int offset) {
        if (buffer.readableBytes() - offset < 48) {
            return ValidationResult.error("Buffer too small: expected at least 48 bytes");
        }
        return ValidationResult.OK;
    }
    
    public MountedUpdate clone() {
        final MountedUpdate copy = new MountedUpdate();
        copy.mountedToEntity = this.mountedToEntity;
        copy.attachmentOffset = ((this.attachmentOffset != null) ? this.attachmentOffset.clone() : null);
        copy.controller = this.controller;
        copy.block = ((this.block != null) ? this.block.clone() : null);
        return copy;
    }
    
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof final MountedUpdate other) {
            return this.mountedToEntity == other.mountedToEntity && Objects.equals(this.attachmentOffset, other.attachmentOffset) && Objects.equals(this.controller, other.controller) && Objects.equals(this.block, other.block);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(this.mountedToEntity, this.attachmentOffset, this.controller, this.block);
    }
}
