package electrosphere.client.scene;

import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;

/**
 * Client's data on the world
 */
public class ClientWorldData {

    
    
    /*
    
                       world max
    +---------------------+
    |                     |
    |                     |
    |                     |
    |                     |
    |                     |
    +---------------------+
 world min
    
    
    basically we're saying what the maximum and minimum x and z something can occupy are
    
    FOR THE TIME BEING DOES NOT ACCOUNT FOR Y
    */
    Vector3f worldMinPoint;
    Vector3f worldMaxPoint;
    
    int dynamicInterpolationRatio;
    
    float randomDampener;
    
    
    int worldDiscreteSize;
    

    public ClientWorldData(
        Vector3f worldMinPoint,
        Vector3f worldMaxPoint,
        int dynamicInterpolationRatio,
        float randomDampener,
        int worldDiscreteSize
    ) {
        this.worldMinPoint = worldMinPoint;
        this.worldMaxPoint = worldMaxPoint;
        this.dynamicInterpolationRatio = dynamicInterpolationRatio;
        this.randomDampener = randomDampener;
        this.worldDiscreteSize = worldDiscreteSize;
    }
    
    
    
    
    public Vector3f getWorldBoundMin(){
        return worldMinPoint;
    }
    
    public Vector3f getWorldBoundMax(){
        return worldMaxPoint;
    }

    public int getDynamicInterpolationRatio() {
        return dynamicInterpolationRatio;
    }

    public float getRandomDampener() {
        return randomDampener;
    }

    public int getWorldDiscreteSize() {
        return worldDiscreteSize;
    }
    
    
    public int convertRealToChunkSpace(double real){
        return (int)Math.floor(real / dynamicInterpolationRatio);
    }

    public float convertChunkToRealSpace(int chunk){
        return chunk * dynamicInterpolationRatio;
    }

    public int convertRealToWorld(double real){
        return convertRealToChunkSpace(real);
    }

    public double convertWorldToReal(int world){
        return convertChunkToRealSpace(world);
    }

    /**
     * Converts a real space position to its world space equivalent
     * @param position The real space position
     * @return The world space position (ie the chunk containing the real space position)
     */
    public Vector3i convertRealToWorldSpace(Vector3d position){
        return new Vector3i(
            convertRealToChunkSpace(position.x),
            convertRealToChunkSpace(position.y),
            convertRealToChunkSpace(position.z)
        );
    }

    /**
     * Converts a world space vector to a real space vector
     * @param position The world space vector
     * @return The real space vector
     */
    public Vector3d convertWorldToRealSpace(Vector3i position){
        return new Vector3d(
            convertWorldToReal(position.x),
            convertWorldToReal(position.y),
            convertWorldToReal(position.z)
        );
    }

    public Vector3i convertRealToVoxelSpace(Vector3d position){
        return new Vector3i(
            (int)Math.floor(position.x - convertChunkToRealSpace(convertRealToChunkSpace(position.x))),
            (int)Math.floor(position.y - convertChunkToRealSpace(convertRealToChunkSpace(position.y))),
            (int)Math.floor(position.z - convertChunkToRealSpace(convertRealToChunkSpace(position.z)))
        );
    }

}
