package projectzombie.util;

import java.util.ArrayList;

import bdf.types.BdfArray;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import projectzombie.init.Items;
import projectzombie.items.Item;
import projectzombie.items.modifier.ItemModifier;

public class ItemStack implements ClassBdf
{
	public ItemModifier[] modifiers;
	public Item item;
	public int count;
	
	public ItemStack(Item item, int count, ItemModifier ... modifiers) {
		this.item = item;
		this.count = count;
		this.modifiers = modifiers;
	}
	
	public ItemStack copy() {
		return new ItemStack(item, count, copyModifiers());
	}
	
	public ItemModifier[] copyModifiers()
	{
		ItemModifier[] modifiers = new ItemModifier[this.modifiers.length];
		
		for(int i=0;i<modifiers.length;i++) {
			modifiers[i] = this.modifiers[i].copy();
		}
		
		return modifiers;
	}
	
	public void addModifier(ItemModifier modifier)
	{
		ItemModifier[] modifiers = new ItemModifier[this.modifiers.length + 1];
		
		for(int i=0;i<this.modifiers.length;i++) {
			modifiers[i] = this.modifiers[i];
		}
		
		modifiers[modifiers.length - 1] = modifier;
		
		this.modifiers = modifiers;
	}
	
	public boolean isEmpty() {
		if(count < 1) return true;
		if(item == null) return true;
		if(item == Items.EMPTY) return true;
		return item.isEmpty(this);
	}
	
	public boolean hasModifier(Class<? extends ItemModifier> modifier) {
		return getModifier(modifier) != null;
	}
	
	public ItemModifier getModifier(Class<? extends ItemModifier> modifier)
	{
		for(int i=0;i<modifiers.length;i++) {
			if(modifiers[i].getClass() == modifier) {
				return modifiers[i];
			}
		}
		
		return null;
	}
	
	public boolean stackEquals(ItemStack other)
	{
		if(other.item != item)
			return false;
		
		for(int i=0;i<other.modifiers.length;i++)
		{
			ItemModifier modifier = getModifier(other.modifiers[i].getClass());
			
			if(modifier == null || !modifier.isEqual(other.modifiers[i])) {
				return false;
			}
		}
		
		for(int i=0;i<modifiers.length;i++)
		{
			ItemModifier modifier = other.getModifier(modifiers[i].getClass());
			
			if(modifier == null || !modifier.isEqual(modifiers[i])) {
				return false;
			}
		}
		
		return true;
	}
	
	public boolean stackAbstractEquals(ItemStack other)
	{
		if(other.item != item)
			return false;
		
		for(int i=0;i<other.modifiers.length;i++)
		{
			ItemModifier modifier = getModifier(other.modifiers[i].getClass());
			
			if(modifier == null || !modifier.isEqual(other.modifiers[i])) {
				return false;
			}
		}
		
		return true;
	}

	@Override
	public void BdfClassLoad(BdfObject bdf)
	{
		BdfNamedList nl = bdf.getNamedList();
		count = nl.get("count").getInteger();
		item = Items.items.get(nl.get("item").getInteger());
		
		BdfArray modifiers_bdf = nl.get("modifiers").getArray();
		ArrayList<ItemModifier> modifiers = new ArrayList<ItemModifier>();
		
		for(int i=0;i<modifiers_bdf.size();i++) {
			ItemModifier modifier = ItemModifier.loadModifier(modifiers_bdf.get(i));
			if(modifier != null) modifiers.add(modifier);
		}
		
		this.modifiers = new ItemModifier[modifiers.size()];
		
		for(int i=0;i<modifiers.size();i++) {
			this.modifiers[i] = modifiers.get(i);
		}
	}

	@Override
	public void BdfClassSave(BdfObject bdf)
	{
		BdfNamedList nl = bdf.getNamedList();
		nl.set("count", bdf.newObject().setInteger(count));
		nl.set("item", bdf.newObject().setInteger(item.id));
		
		BdfArray modifiers = bdf.newArray();
		nl.set("modifiers", bdf.newObject().setArray(modifiers));
		
		for(int i=0;i<this.modifiers.length;i++)
		{
			BdfObject modifier = bdf.newObject();
			
			int id = this.modifiers[i].getID();
			
			if(id == -1) {
				continue;
			}
			
			this.modifiers[i].BdfClassSave(modifier);
			
			BdfNamedList modifier_nl = modifier.getNamedList();
			modifier_nl.set("id", bdf.newObject().setInteger(id));
			
			modifiers.add(modifier);
		}
	}
	
	public ItemStack(BdfObject bdf) {
		BdfClassLoad(bdf);
	}
	
	public static ItemStack getEmpty() {
		return new ItemStack(Items.EMPTY, 0);
	}
}
