package projectzombie.worker;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ProcessBuilder.Redirect;
import java.nio.ByteBuffer;

import bdf.data.BdfDatabase;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import projectzombie.display.DisplayLighting;

public class Worker extends Thread
{
	ProcessBuilder pb;
	Process process;
	
	InputStream in;
	OutputStream out;
	
	boolean running = true;
	
	public Worker() throws IOException
	{
		pb = new ProcessBuilder("java", "-jar", "worker.jar");
		pb.redirectError(Redirect.INHERIT);
		pb.redirectOutput(Redirect.PIPE);
		pb.redirectInput(Redirect.PIPE);
		
		process = pb.start();
		
		in = process.getInputStream();
		out = process.getOutputStream();
	}
	
	
	
	public void processLighting(float[] lights, int width, int height, int x, int y)
	{
		BdfObject bdf = new BdfObject();
		BdfNamedList nl = bdf.getNamedList();
		nl.set("task", BdfObject.withString("light"));
		nl.set("light", BdfObject.withFloatArray(lights));
		nl.set("w", BdfObject.withInteger(width));
		nl.set("h", BdfObject.withInteger(height));
		nl.set("x", BdfObject.withInteger(x));
		nl.set("y", BdfObject.withInteger(y));
		
		sendData(bdf);
	}
	
	public void updateTime()
	{
		BdfObject bdf = new BdfObject();
		BdfNamedList nl = bdf.getNamedList();
		nl.set("task", BdfObject.withString("time"));
		nl.set("millis", BdfObject.withLong(System.currentTimeMillis()));
		
		sendData(bdf);
	}
	
	private void sendData(BdfObject bdf)
	{
		byte[] data = bdf.serialize().getBytes();
		
		ByteBuffer size_buff = ByteBuffer.allocate(4);
		size_buff.putInt(0, data.length);
		
		try
		{
			out.write(size_buff.array());
			out.write(data);
			out.write('\n');
			out.flush();
		}
		
		catch(IOException e)
		{
			
		}
	}
	
	@Override
	public void run() {
		super.run();
		
		try
		{
			while(true)
			{
				ByteBuffer size_buff = ByteBuffer.allocate(4);
				byte[] data;
				
				in.read(size_buff.array());
				data = new byte[size_buff.getInt(0)];
				in.read(data);
				in.read(new byte[1]);
				
				BdfObject bdf = new BdfObject(new BdfDatabase(data));
				BdfNamedList nl = bdf.getNamedList();
				
				switch(nl.get("task").getString())
				{
				case "light":
					DisplayLighting.updateLighting(bdf);
					break;
				default:
					Thread.sleep(10);
				}
				
				if(!running) {
					return;
				}
			}
		}
		
		catch(IOException | InterruptedException e)
		{
			
		}
	}
	
	public void kill() {
		process.destroy();
		running = false;
	}
}
