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.IBdfDatabase;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import bdf.types.BdfReader;
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.redirectOutput(Redirect.PIPE);
		pb.redirectInput(Redirect.PIPE);
		pb.redirectError(Redirect.INHERIT);
		
		process = pb.start();
		
		in = process.getInputStream();
		out = process.getOutputStream();
	}
	
	
	
	public void processLighting(float[] lights, int width, int height, int x, int y)
	{
		BdfReader reader = new BdfReader();
		BdfObject bdf = reader.getObject();
		BdfNamedList nl = bdf.getNamedList();
		nl.set("task", bdf.newObject().setString("light"));
		nl.set("light", bdf.newObject().setFloatArray(lights));
		nl.set("w", bdf.newObject().setInteger(width));
		nl.set("h", bdf.newObject().setInteger(height));
		nl.set("x", bdf.newObject().setInteger(x));
		nl.set("y", bdf.newObject().setInteger(y));
		
		sendData(reader);
	}
	
	public void updateTime()
	{
		BdfReader reader = new BdfReader();
		BdfObject bdf = reader.getObject();
		BdfNamedList nl = bdf.getNamedList();
		nl.set("task", bdf.newObject().setString("time"));
		nl.set("millis", bdf.newObject().setLong(System.currentTimeMillis()));
		
		sendData(reader);
	}
	
	private void sendData(BdfReader reader)
	{
		IBdfDatabase data = reader.serialize();
		
		ByteBuffer size_buff = ByteBuffer.allocate(4);
		size_buff.putInt(0, data.size());
		
		try
		{
			out.write(size_buff.array());
			data.writeToStream(out);
			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]);
				
				BdfReader reader = new BdfReader(data);
				BdfObject bdf = reader.getObject();
				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;
	}
}
