package projectzombie.task;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import projectzombie.util.ClassBdf;
import bdf.types.BdfArray;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import projectzombie.entity.Entity;
import projectzombie.init.Tasks;

public abstract class Task implements ClassBdf
{
	protected Entity parent;
	
	public abstract void update();
	public abstract boolean isDone();
	
	public Task(Entity parent) {
		this.parent = parent;
	}
	
	public Task(Entity parent, BdfObject bdf)
	{
		this(parent);
		
		BdfClassLoad(bdf);
	}
	
	public int getID() {
		for(int i=0;i<Tasks.TASKS.size();i++) {
			Class<? extends Task> tc = Tasks.TASKS.get(i);
			if(tc == this.getClass()) {
				return i;
			}
		}
		return -1;
	}
	
	public static Task loadTask(Entity parent, BdfObject bdf)
	{
		try
		{
			// Load the entity id
			BdfNamedList nl = bdf.getNamedList();
			int id = nl.get("id").getInteger();
			
			// Send back null if the id is out of range
			if(id < 0 || id >= Tasks.TASKS.size()) {
				System.out.println("Invalid task ID found: " + id);
				return null;
			}
			
			// Get the class and the constructor
			Class<? extends Task> tcl = Tasks.TASKS.get(id);
			Constructor<? extends Task> tcon = tcl.getConstructor(Entity.class, BdfObject.class);
			
			// Send back the new entity
			return tcon.newInstance(parent, bdf);
		}
		
		catch(
				NoSuchMethodException |
				SecurityException |
				InstantiationException |
				IllegalAccessException |
				IllegalArgumentException |
				InvocationTargetException e)
		{
			e.printStackTrace();
			
			// Send null if there was an issue
			return null;
		}
	}
	
	@Override
	public void BdfClassLoad(BdfObject bdf) {
		
	}
	
	@Override
	public void BdfClassSave(BdfObject bdf) {
		BdfNamedList nl = bdf.getNamedList();
		nl.set("id", bdf.newObject().setInteger(getID()));
	}
	
	public static Task[] loadTasks(Entity parent, BdfObject bdf)
	{
		BdfArray array = bdf.getArray();
		Task[] tasks = new Task[array.size()];
		
		for(int i=0;i<array.size();i++) {
			tasks[i] = loadTask(parent, array.get(i));
		}
		
		return tasks;
	}
	
	public static BdfObject saveTasks(BdfObject bdf, Task[] tasks)
	{
		BdfArray array = bdf.getArray();
		bdf.setArray(array);
		
		for(int i=0;i<tasks.length;i++) {
			BdfObject task_bdf = bdf.newObject();
			tasks[i].BdfClassSave(task_bdf);
			array.add(task_bdf);
		}
		
		return bdf;
	}
}
