package common.inventory;

import java.util.List;

import common.attributes.AttributeMap;
import common.attributes.UsageSlot;
import common.collect.Lists;
import common.entity.npc.EntityNPC;
import common.init.CraftingRegistry;
import common.item.ItemStack;
import common.item.tool.ItemArmor;

public class ContainerPlayer extends Container
{
	private final InventoryCrafting craftMatrix = new InventoryCrafting(this, 2, 2);
	private final IInventory craftResult = new InventoryCraftResult();
    private final boolean isLocalWorld;
    private final EntityNPC thePlayer;
    private final AttributeMap attributes;
    private final List<ItemStack> lastStacks = Lists.<ItemStack>newArrayList();

    public ContainerPlayer(final InventoryPlayer playerInventory, boolean localWorld, EntityNPC player)
    {
        this.isLocalWorld = localWorld;
        this.thePlayer = player;
        this.attributes = player.getAttributeMap();
        this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 144, 36));

        for (int i = 0; i < 2; ++i)
        {
            for (int j = 0; j < 2; ++j)
            {
                this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 2, 88 + j * 18, 26 + i * 18));
            }
        }

        for (int k = 0; k < 4; ++k)
        {
            final int k_f = k;
            this.addSlotToContainer(new Slot(playerInventory, playerInventory.getSizeInventory() - 1 - k, 8, 8 + k * 18)
            {
                public int getSlotStackLimit()
                {
                    return 1;
                }
                public boolean isItemValid(ItemStack stack)
                {
                    return stack != null && stack.getItem() instanceof ItemArmor && ((ItemArmor)stack.getItem()).armorType.getArmorSlot() == k_f; // : (stack.getItem() != Items.pumpkin && stack.getItem() != Items.skull ? false : k_f == 0));
                }
//                public String getSlotTexture()
//                {
//                    return ItemArmor.EMPTY_SLOT_NAMES[k_f];
//                }
            });
        }

        for (int l = 0; l < 3; ++l)
        {
            for (int j1 = 0; j1 < 9; ++j1)
            {
                this.addSlotToContainer(new Slot(playerInventory, j1 + (l + 1) * 9, 8 + j1 * 18, 84 + l * 18));
            }
        }

        for (int i1 = 0; i1 < 9; ++i1)
        {
            this.addSlotToContainer(new Slot(playerInventory, i1, 8 + i1 * 18, 142));
        }

        this.onCraftMatrixChanged(this.craftMatrix);
    }
    
    protected Slot addSlotToContainer(Slot slotIn)
    {
        slotIn = super.addSlotToContainer(slotIn);
    	if(slotIn.slotNumber >= 9)
    		this.lastStacks.add((ItemStack)null);
        return slotIn;
    }
    
    public void detectAttributeChanges()
    {
        for (int i = 0; i < this.inventorySlots.size(); ++i)
        {
        	Slot slot = this.inventorySlots.get(i);
        	if(slot.slotNumber >= 9) {
	            ItemStack current = slot.getStack();
	            ItemStack last = (ItemStack)this.lastStacks.get(i - 9);
	
	            if (!ItemStack.areItemStacksEqual(last, current))
	            {
	            	if (last != null)
	                {
	                    this.attributes.remove(last.getAttributeModifiers(UsageSlot.INVENTORY), slot.getIndex());
	                }
	
	                if (current != null)
	                {
	                    this.attributes.add(current.getAttributeModifiers(UsageSlot.INVENTORY), slot.getIndex(), current.size);
	                }
	            	
	                last = current == null ? null : current.copy();
	                this.lastStacks.set(i - 9, last);
	            }
        	}
        }
    }

    /**
     * Callback for when the crafting matrix is changed.
     */
    public void onCraftMatrixChanged(IInventory inventoryIn)
    {
        this.craftResult.setInventorySlotContents(0, CraftingRegistry.getBasic(this.craftMatrix, this.thePlayer.worldObj));
    }

    /**
     * Called when the container is closed.
     */
    public void onContainerClosed(EntityNPC playerIn)
    {
        super.onContainerClosed(playerIn);

        for (int i = 0; i < 4; ++i)
        {
            ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i);

            if (itemstack != null)
            {
                playerIn.dropPlayerItemWithRandomChoice(itemstack, false);
            }
        }

        this.craftResult.setInventorySlotContents(0, (ItemStack)null);
    }

    public boolean canInteractWith(EntityNPC playerIn)
    {
        return true;
    }

    /**
     * Take a stack from the specified inventory slot.
     */
    public ItemStack transferStackInSlot(EntityNPC playerIn, int index)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(index);

        if (slot != null && slot.getHasStack())
        {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (index == 0)
            {
                if (!this.mergeItemStack(itemstack1, 9, 45, true))
                {
                    return null;
                }

                slot.onSlotChange(itemstack1, itemstack);
            }
            else if (index >= 1 && index < 5)
            {
                if (!this.mergeItemStack(itemstack1, 9, 45, false))
                {
                    return null;
                }
            }
            else if (index >= 5 && index < 9)
            {
                if (!this.mergeItemStack(itemstack1, 9, 45, false))
                {
                    return null;
                }
            }
            else if (itemstack.getItem() instanceof ItemArmor && !((Slot)this.inventorySlots.get(5 + ((ItemArmor)itemstack.getItem()).armorType.getArmorSlot())).getHasStack())
            {
                int i = 5 + ((ItemArmor)itemstack.getItem()).armorType.getArmorSlot();

                if (!this.mergeItemStack(itemstack1, i, i + 1, false))
                {
                    return null;
                }
            }
            else if (index >= 9 && index < 36)
            {
                if (!this.mergeItemStack(itemstack1, 36, 45, false))
                {
                    return null;
                }
            }
            else if (index >= 36 && index < 45)
            {
                if (!this.mergeItemStack(itemstack1, 9, 36, false))
                {
                    return null;
                }
            }
            else if (!this.mergeItemStack(itemstack1, 9, 45, false))
            {
                return null;
            }

            if (itemstack1.size == 0)
            {
                slot.putStack((ItemStack)null);
            }
            else
            {
                slot.onSlotChanged();
            }

            if (itemstack1.size == itemstack.size)
            {
                return null;
            }

            slot.onPickupFromSlot(playerIn, itemstack1);
        }

        return itemstack;
    }

    /**
     * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in
     * is null for the initial slot that was double-clicked.
     */
    public boolean canMergeSlot(ItemStack stack, Slot slotIn)
    {
        return slotIn.inventory != this.craftResult && super.canMergeSlot(stack, slotIn);
    }
}
