package projectzombie.inventory;

import projectzombie.util.ClassBdf;
import projectzombie.util.ItemStack;
import bdf.types.BdfArray;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import gl_engine.vec.Vec2d;
import gl_engine.vec.Vec3d;
import projectzombie.entity.EntityItem;
import projectzombie.items.Item;
import projectzombie.items.modifier.ItemModifier;
import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer;

public class Inventory implements IInventory, ClassBdf
{
	protected ItemStack[] items;
	
	public Inventory(int size)
	{
		items = new ItemStack[size];
		
		for(int i=0;i<size;i++) {
			items[i] = ItemStack.getEmpty();
		}
	}

	@Override
	public ItemStack getItem(int slot) {
		return items[slot];
	}

	@Override
	public int getSlotCount() {
		return items.length;
	}

	@Override
	public void setItem(ItemStack stack, int slot) {
		items[slot] = stack;
	}

	@Override
	public ItemStack removeItem(int slot) {
		ItemStack stack = items[slot];
		items[slot] = ItemStack.getEmpty();
		return stack;
	}
	
	public int getItemCount(ItemStack item)
	{
		int count = 0;
		
		for(ItemStack check : items) {
			if(check.stackAbstractEquals(item) && !check.isEmpty()) {
				count += check.count;
			}
		}
		
		return count;
	}
	
	public void addItem(ItemStack stack)
	{
		if(stack.isEmpty()) {
			return;
		}
		
		for(ItemStack check : items)
		{
			if(stack.stackEquals(check) && !check.isEmpty())
			{
				if(check.count + stack.count > check.item.max) {
					stack.count = (check.count + stack.count) - check.item.max;
					check.count = check.item.max;
				}
				
				else {
					check.count += stack.count;
					stack.count = 0;
					return;
				}
			}
		}
		
		for(ItemStack check : items)
		{
			if(check.isEmpty())
			{
				ItemModifier[] modifiers = new ItemModifier[stack.modifiers.length];
				
				for(int i=0;i<modifiers.length;i++) {
					modifiers[i] = stack.modifiers[i].copy();
				}
				
				check.item = stack.item;
				check.count = stack.count;
				check.modifiers = modifiers;
				stack.count = 0;
				return;
			}
		}
	}
	
	public void dropInventory(Layer layer, Chunk chunk, Vec3d pos, Vec3d velocity)
	{
		for(int i=0;i<items.length;i++)
		{
			if(!items[i].isEmpty())
			{
				chunk.spawnEntity(new EntityItem(pos, velocity, items[i]));
				
				items[i] = ItemStack.getEmpty();
			}
		}
	}
	
	public void removeItem(ItemStack stack)
	{
		for(ItemStack check : items) {
			if(check.stackAbstractEquals(stack) && !stack.isEmpty())
			{
				if(check.count < stack.count) {
					stack.count -= check.count;
					check.count = 0;
				}
				
				else {
					check.count -= stack.count;
					stack.count = 0;
					return;
				}
			}
		}
	}

	@Override
	public void BdfClassLoad(BdfObject bdf)
	{
		BdfNamedList nl = bdf.getNamedList();
		items = new ItemStack[nl.get("size").getInteger()];
		
		BdfArray array = nl.get("items").getArray();
		
		for(int i=0;i<items.length;i++) {
			items[i] = new ItemStack(array.get(i));
		}
	}

	@Override
	public void BdfClassSave(BdfObject bdf)
	{
		BdfNamedList nl = bdf.getNamedList();
		
		nl.set("size", bdf.newObject().setInteger(items.length));
		BdfArray array = nl.get("items").getArray();
		
		for(ItemStack stack : items) {
			BdfObject stack_bdf = bdf.newObject();
			stack.BdfClassSave(stack_bdf);
			array.add(stack_bdf);
		}
	}
	
	public Inventory(BdfObject bdf) {
		BdfClassLoad(bdf);
	}
	
}
