package projectzombie.world.chunk;

import gl_engine.MathHelpers;
import gl_engine.vec.Vec2i;
import gl_engine.vec.Vec3d;
import mainloop.task.IMainloopTask;
import projectzombie.Main;
import projectzombie.display.DisplayLighting;
import projectzombie.util.math.map.Map2DElement;
import projectzombie.worker.WorkerTasks;
import projectzombie.world.layer.Layer;

public class ChunkEventHandler implements IMainloopTask
{
	public static final ChunkEventHandler CHUNK_EVENT_HANDLER = new ChunkEventHandler();
	public static boolean loaded = false;

	@Override
	public boolean MainLoopDelay(long millis) {
		return millis > 100;
	}

	@Override
	public boolean MainLoopRepeat() {
		return true;
	}

	@Override
	public void MainLoopUpdate()
	{
		// Get the layer
		Vec3d ppos = Main.player.getPos();
		Layer layer = Main.world.getLayer();
		
		int loaded_count = 0;
		
		// Loop over all the chunks in this layer
		for(Map2DElement<Chunk> ce : layer.chunks)
		{
			// Convert the player pos to x and y
			int px = (int)ppos.x / 16;
			int py = (int)ppos.z / 16;
			
			if(
				// Is this chunk beyond the simulation distance
				px > ce.pos.x + Chunk.SIMULATION_DISTANCE + 1 || 
				px < ce.pos.x - Chunk.SIMULATION_DISTANCE - 1 || 
				py > ce.pos.y + Chunk.SIMULATION_DISTANCE + 1 || 
				py < ce.pos.y - Chunk.SIMULATION_DISTANCE - 1
			) {
				// Unload the chunk
				layer.unloadChunk(ce.pos);
				ce.o.free();
			}
			
			else {
				loaded_count += 1;
			}
		}
		
		if(loaded_count >= 4 * Chunk.SIMULATION_DISTANCE * (Chunk.SIMULATION_DISTANCE + 1) + 1) {
			loaded = true;
		}
		
		layer.loadChunks();
		
		// Loop over the simulation distance
		for(int x=-Chunk.SIMULATION_DISTANCE;x<=Chunk.SIMULATION_DISTANCE;x++) {
			for(int y=-Chunk.SIMULATION_DISTANCE;y<=Chunk.SIMULATION_DISTANCE;y++)
			{
				// Get the chunk based on the player position
				int cx = MathHelpers.floor(ppos.x / 16) + x;
				int cy = MathHelpers.floor(ppos.z / 16) + y;
				Vec2i c_pos = new Vec2i(cx, cy);
				
				// Is this chunk not loaded
				if(!layer.chunkLoaded(c_pos) && !WorkerTasks.hasChunk(c_pos))
				{
					// Load the chunk
					layer.loadChunk(c_pos);
				}
			}
		}
		
		DisplayLighting.update();
	}

}
