package net.halbear.Terrain4J.EngineCore.Main.Scene;

import org.joml.Matrix4f;
import org.joml.Vector3f;

public class Camera {
    private final Vector3f Direction;
    private final Vector3f Position;
    private final Vector3f Right;
    private final Vector3f Rotation;
    private final Vector3f Up;
    private final Matrix4f ViewMatrix;

    public Camera(){
        Direction = new Vector3f();
        Position = new Vector3f();
        Right = new Vector3f();
        Rotation = new Vector3f();
        Up = new Vector3f();
        ViewMatrix = new Matrix4f();
    }
    public void SetRotation(float x, float y, float z){Rotation.set(x,y,z); Recalculate();}

    public void AddRotation(float x, float y, float z){Rotation.add(x,y,z); Recalculate();}
    public void AddRotX(float x){Rotation.x += x; Recalculate();}
    public void AddRotY(float y){Rotation.y += y; Recalculate();}
    public void AddRotZ(float z){Rotation.z += z; Recalculate();}

    public Vector3f GetRotation(){return Rotation;}

    public void SetPosition(float x, float y, float z){Position.set(x,y,z); Recalculate();}

    public void AddPosition(float x, float y, float z){Position.add(x,y,z);Recalculate(); }
    public void AddPosX(float x){Position.x += x;Recalculate();}
    public void AddPosY(float y){Position.y += y;Recalculate();}
    public void AddPosZ(float z){Position.z += z;Recalculate();}
    public Vector3f GetPosition(){return Position;}

    public Matrix4f GetViewMatrix(){
        return ViewMatrix;
    }

    public void MoveForward(float Distance){
        ViewMatrix.positiveZ(Direction).negate().mul(Distance);
        Position.add(Direction);
        Recalculate();
    }
    public void MoveBackward(float Distance){
        ViewMatrix.positiveZ(Direction).negate().mul(Distance);
        Position.sub(Direction);
        Recalculate();
    }
    public void MoveUp(float Distance){
        ViewMatrix.positiveY(Up).negate().mul(Distance);
        Position.sub(Up);
        Recalculate();
    }
    public void MoveDown(float Distance){
        ViewMatrix.positiveY(Up).negate().mul(Distance);
        Position.add(Up);
        Recalculate();
    }
    public void MoveLeft(float Distance){
        ViewMatrix.positiveX(Right).negate().mul(Distance);
        Position.add(Right);
        Recalculate();
    }
    public void MoveRight(float Distance){
        ViewMatrix.positiveX(Right).negate().mul(Distance);
        Position.sub(Right);
        Recalculate();
    }
    public void Recalculate(){
        ViewMatrix.identity()
                .rotateX(Rotation.x)
                .rotateY(Rotation.y)
                //.rotateZ(Rotation.z)
                .translate(-Position.x, -Position.y, -Position.z);
    }
}
