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

package com.hypixel.hytale.math.vector;

import java.util.Objects;
import com.hypixel.hytale.math.Axis;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.math.util.TrigMathUtil;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class Location
{
    @Nullable
    protected String world;
    @Nonnull
    protected Vector3d position;
    @Nonnull
    protected Vector3f rotation;
    
    public Location() {
        this(null, new Vector3d(), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(@Nonnull final Vector3i position) {
        this(null, new Vector3d(position), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(@Nullable final String world, @Nonnull final Vector3i position) {
        this(world, new Vector3d(position), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(@Nonnull final Vector3d position) {
        this(null, new Vector3d(position), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(@Nullable final String world, @Nonnull final Vector3d position) {
        this(world, new Vector3d(position), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(final double x, final double y, final double z) {
        this(null, new Vector3d(x, y, z), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(@Nullable final String world, final double x, final double y, final double z) {
        this(world, new Vector3d(x, y, z), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
    }
    
    public Location(final double x, final double y, final double z, final float pitch, final float yaw, final float roll) {
        this(null, new Vector3d(x, y, z), new Vector3f(pitch, yaw, roll));
    }
    
    public Location(@Nullable final String world, final double x, final double y, final double z, final float pitch, final float yaw, final float roll) {
        this(world, new Vector3d(x, y, z), new Vector3f(pitch, yaw, roll));
    }
    
    public Location(@Nonnull final Vector3d position, @Nonnull final Vector3f rotation) {
        this(null, position, rotation);
    }
    
    public Location(@Nonnull final Transform transform) {
        this(null, transform.position, transform.rotation);
    }
    
    public Location(@Nullable final String world, @Nonnull final Transform transform) {
        this(world, transform.position, transform.rotation);
    }
    
    public Location(@Nullable final String world, @Nonnull final Vector3d position, @Nonnull final Vector3f rotation) {
        this.world = world;
        this.position = position;
        this.rotation = rotation;
    }
    
    @Nullable
    public String getWorld() {
        return this.world;
    }
    
    public void setWorld(@Nullable final String world) {
        this.world = world;
    }
    
    @Nonnull
    public Vector3d getPosition() {
        return this.position;
    }
    
    public void setPosition(@Nonnull final Vector3d position) {
        this.position = position;
    }
    
    @Nonnull
    public Vector3f getRotation() {
        return this.rotation;
    }
    
    public void setRotation(@Nonnull final Vector3f rotation) {
        this.rotation = rotation;
    }
    
    @Nonnull
    public Vector3d getDirection() {
        return Transform.getDirection(this.rotation.getPitch(), this.rotation.getYaw());
    }
    
    @Nonnull
    public Vector3i getAxisDirection() {
        return this.getAxisDirection(this.rotation.getPitch(), this.rotation.getYaw());
    }
    
    @Nonnull
    public Vector3i getAxisDirection(final float pitch, final float yaw) {
        if (Float.isNaN(pitch)) {
            throw new IllegalStateException("Pitch can't be NaN");
        }
        if (Float.isNaN(yaw)) {
            throw new IllegalStateException("Yaw can't be NaN");
        }
        final float len = TrigMathUtil.cos(pitch);
        final float x = len * -TrigMathUtil.sin(yaw);
        final float y = TrigMathUtil.sin(pitch);
        final float z = len * -TrigMathUtil.cos(yaw);
        return new Vector3i(MathUtil.fastRound(x), MathUtil.fastRound(y), MathUtil.fastRound(z));
    }
    
    @Nonnull
    public Axis getAxis() {
        final Vector3i axisDirection = this.getAxisDirection();
        if (axisDirection.getX() != 0) {
            return Axis.X;
        }
        if (axisDirection.getY() != 0) {
            return Axis.Y;
        }
        return Axis.Z;
    }
    
    @Nonnull
    public Transform toTransform() {
        return new Transform(this.position, this.rotation);
    }
    
    @Override
    public boolean equals(@Nullable final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        final Location location = (Location)o;
        return Objects.equals(this.world, location.world) && Objects.equals(this.position, location.position) && Objects.equals(this.rotation, location.rotation);
    }
    
    @Override
    public int hashCode() {
        int result = (this.world != null) ? this.world.hashCode() : 0;
        result = 31 * result + this.position.hashCode();
        result = 31 * result + this.rotation.hashCode();
        return result;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "Location{world='" + this.world + "', position=" + String.valueOf(this.position) + ", rotation=" + String.valueOf(this.rotation);
    }
}
