package electrosphere.server.terrain.manager;

import java.util.LinkedList;
import java.util.List;

import org.joml.Vector3i;

import electrosphere.server.terrain.models.TerrainModification;

/**
 * Is a single chunk of terrain on the server
 */
public class ServerTerrainChunk {

    //all chunks are 16x16x16
    public static final int CHUNK_DIMENSION = 16;
    //The size of the data passed into marching cubes/transvoxel to generate a fully connected and seamless chunk
    public static final int CHUNK_DATA_GENERATOR_SIZE = CHUNK_DIMENSION + 1;

    int worldX, worldY, worldZ;
    List<TerrainModification> modifications = new LinkedList<TerrainModification>();
    float[][][] weights;
    int[][][] values;

    public ServerTerrainChunk(int worldX, int worldY, int worldZ, float[][][] weights, int[][][] values) {
        this.worldX = worldX;
        this.worldY = worldY;
        this.worldZ = worldZ;
        this.weights = weights;
        this.values = values;
    }

    public int getWorldX() {
        return worldX;
    }

    public int getWorldY() {
        return worldY;
    }

    public int getWorldZ() {
        return worldZ;
    }

    /**
     * Gets the world position of this terrain chunk as a joml Vector
     * @return The vector
     */
    public Vector3i getWorldPosition(){
        return new Vector3i(worldX,worldY,worldZ);
    }

    public List<TerrainModification> getModifications() {
        return modifications;
    }

    public float[][][] getWeights() {
        return weights;
    }

    public int[][][] getValues() {
        return values;
    }

    public void addModification(TerrainModification modification){
        modifications.add(modification);
        values[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getValue();
        weights[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getWeight();
    }

    /**
     * Gets the weight of a voxel at a poisiton
     * @param localPosition The local position
     * @return The weight of the specified voxel
     */
    public float getWeight(Vector3i localPosition){
        return getWeight(localPosition.x,localPosition.y,localPosition.z);
    }

    /**
     * Gets the weight of a voxel at a poisiton
     * @param x The x coordinate
     * @param y The y coordinate
     * @param z The z coordinate
     * @return The weight of the specified voxel
     */
    public float getWeight(int x, int y, int z){
        return weights[x][y][z];
    }

    /**
     * Gets the type of a voxel at a position
     * @param localPosition The local position
     * @return The type of the specified voxel
     */
    public int getType(Vector3i localPosition){
        return getType(localPosition.x,localPosition.y,localPosition.z);
    }

    /**
     * Gets the type of a voxel at a position
     * @param x The x coordinate
     * @param y The y coordinate
     * @param z The z coordinate
     * @return The type of the specified voxel
     */
    public int getType(int x, int y, int z){
        return values[x][y][z];
    }
    
    
}
