package com.yolp900.itsjustacharm.common.tileEntities;
import com.yolp900.itsjustacharm.api.IJCConstants;
import com.yolp900.itsjustacharm.api.ItsJustaCharmAPI;
import com.yolp900.itsjustacharm.api.affinities.IAffinity;
import com.yolp900.itsjustacharm.api.affinities.IAffinityHolderTile;
import com.yolp900.itsjustacharm.common.crafting.CraftingHandlerConstructionTable;
import com.yolp900.itsjustacharm.reference.LibTileEntities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemBucket;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class TileEntityConstructionTable extends ModTileEntityIInventory implements IAffinityHolderTile {
private ItemStack[] slots = new ItemStack[18];
private IAffinity[] storedAffinities = new IAffinity[4];
@Override
public int getSizeInventory() {
return slots.length;
}
@Nullable
@Override
public ItemStack getStackInSlot(int index) {
return slots[index];
}
@Nullable
@Override
public ItemStack decrStackSize(int index, int amount) {
ItemStack stack = getStackInSlot(index);
if (stack != null) {
if (index == 0) {
ItemStack[] gridInputs = getGridInputs();
ItemStack[] secInputs = getSecInputs();
CraftingHandlerConstructionTable.RecipeType recipeType = CraftingHandlerConstructionTable.getCurrentRecipeType(gridInputs, secInputs, worldObj);
if (recipeType == CraftingHandlerConstructionTable.RecipeType.Vanilla) {
decrVanillaGrid(amount / stack.stackSize);
} else if (recipeType == CraftingHandlerConstructionTable.RecipeType.CTShaped || recipeType == CraftingHandlerConstructionTable.RecipeType.CTShapeless) {
decrAllGrid(amount / stack.stackSize);
}
}
if (stack.stackSize <= amount) {
setInventorySlotContents(index, null);
} else {
stack = stack.splitStack(amount);
if (stack.stackSize == 0) {
setInventorySlotContents(index, null);
}
}
checkRecipes();
}
return stack;
}
private void decrVanillaGrid(int amount) {
for (int i = 1; i < 10; i++) {
if (slots[i] != null) {
if (slots[i].stackSize == amount) {
if (slots[i].getItem() instanceof ItemBucket) {
slots[i] = new ItemStack(Items.BUCKET);
} else {
slots[i] = null;
}
} else if (slots[i].stackSize > amount) {
slots[i].stackSize -= amount;
}
}
}
}
private void decrAllGrid(int amount) {
for (int i = 1; i <= 17; i++) {
if (slots[i] != null) {
if (slots[i].stackSize == amount) {
if (slots[i].getItem() instanceof ItemBucket) {
slots[i] = new ItemStack(Items.BUCKET);
} else {
slots[i] = null;
}
} else if (slots[i].stackSize > amount) {
slots[i].stackSize -= amount;
}
}
}
}
@Nullable
@Override
public ItemStack removeStackFromSlot(int index) {
if (this.slots[index] != null) {
ItemStack itemstack = this.slots[index];
this.slots[index] = null;
checkRecipes();
return itemstack;
} else {
checkRecipes();
return null;
}
}
@Override
public void setInventorySlotContents(int index, @Nullable ItemStack stack) {
slots[index] = stack;
checkRecipes();
if (stack != null && stack.stackSize > getInventoryStackLimit()) {
stack.stackSize = getInventoryStackLimit();
}
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
slots = new ItemStack[18];
NBTTagList customSlotsTag = tag.getTagList(IJCConstants.NBT.INVENTORY, 10);
for (int i = 0; i < customSlotsTag.tagCount(); i++) {
NBTTagCompound t = customSlotsTag.getCompoundTagAt(i);
int index = t.getByte(IJCConstants.NBT.INDEX);
if (index >= 0 && index < slots.length) {
slots[index] = ItemStack.loadItemStackFromNBT(t);
}
}
for (int i = 0; i < storedAffinities.length; i++) {
String affinityName = tag.getString(IJCConstants.NBT.STORED_AFFINITY(i));
IAffinity affinity = ItsJustaCharmAPI.Affinities.getAffinityFromName(affinityName);
if (affinity != null) {
storeAffinity(affinity, i);
}
}
}
@Override
@Nonnull
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
NBTTagList customSlotsTag = new NBTTagList();
for (int i = 0; i < slots.length; i++) {
ItemStack stack = slots[i];
if (stack != null) {
NBTTagCompound t = new NBTTagCompound();
stack.writeToNBT(t);
t.setByte(IJCConstants.NBT.INDEX, (byte)i);
customSlotsTag.appendTag(t);
}
}
tag.setTag(IJCConstants.NBT.INVENTORY, customSlotsTag);
for (int i = 0; i < storedAffinities.length; i++) {
if (storedAffinities[i] != null) {
tag.setString(IJCConstants.NBT.STORED_AFFINITY(i), storedAffinities[i].getName());
}
}
return tag;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public boolean isItemValidForSlot(int slot, @Nonnull ItemStack stack) {
return true;
}
@Override
public void clear() {
for (int i = 0; i < this.slots.length; ++i) {
this.slots[i] = null;
}
}
@Override
@Nonnull
public String getName() {
return LibTileEntities.ConstructionTable.getName();
}
@Override
public boolean hasCustomName() {
return false;
}
@Override
@Nonnull
public ITextComponent getDisplayName() {
return new TextComponentString(getName());
}
public ItemStack[] getGridInputs() {
return new ItemStack[] { slots[1], slots[2], slots[3], slots[4], slots[5], slots[6], slots[7], slots[8], slots[9] };
}
public ItemStack[] getSecInputs() {
return new ItemStack[] { slots[10], slots[11], slots[12], slots[13], slots[14], slots[15], slots[16], slots[17] };
}
private void checkRecipes() {
ItemStack[] gridInputs = getGridInputs();
ItemStack[] secInputs = getSecInputs();
CraftingHandlerConstructionTable.RecipeType recipeType = CraftingHandlerConstructionTable.getCurrentRecipeType(gridInputs, secInputs, worldObj);
ItemStack output = null;
if (recipeType != CraftingHandlerConstructionTable.RecipeType.None) {
if (recipeType == CraftingHandlerConstructionTable.RecipeType.Vanilla && CraftingHandlerConstructionTable.getVanillaRecipeOutput(gridInputs, worldObj) != null) {
output = CraftingHandlerConstructionTable.getVanillaRecipeOutput(gridInputs, worldObj);
} else if (recipeType == CraftingHandlerConstructionTable.RecipeType.CTShapeless && CraftingHandlerConstructionTable.getConstructionTableShapelessRecipeOutput(gridInputs, secInputs) != null) {
output = CraftingHandlerConstructionTable.getConstructionTableShapelessRecipeOutput(gridInputs, secInputs);
} else if (recipeType == CraftingHandlerConstructionTable.RecipeType.CTShaped && CraftingHandlerConstructionTable.getConstructionTableShapedRecipeOutput(gridInputs, secInputs) != null) {
output = CraftingHandlerConstructionTable.getConstructionTableShapedRecipeOutput(gridInputs, secInputs);
}
}
this.slots[0] = ItemStack.copyItemStack(output);
}
public int getMaxStackSizeShiftClickOutput() {
ItemStack[] gridInputs = getGridInputs();
ItemStack[] secInputs = getSecInputs();
CraftingHandlerConstructionTable.RecipeType recipeType = CraftingHandlerConstructionTable.getCurrentRecipeType(gridInputs, secInputs, worldObj);
ItemStack output = slots[0];
int stackSize = 0;
if (output != null) {
int factor = output.stackSize;
int max = 64;
for (int i = 0; i < 9; i++) {
if (gridInputs[i] != null) {
if (max > gridInputs[i].stackSize) max = gridInputs[i].stackSize;
}
}
if (recipeType == CraftingHandlerConstructionTable.RecipeType.CTShaped || recipeType == CraftingHandlerConstructionTable.RecipeType.CTShapeless) {
for (int i = 0; i < 8; i++) {
if (secInputs[i] != null) {
if (max > secInputs[i].stackSize) max = secInputs[i].stackSize;
}
}
}
stackSize = factor * max;
}
return stackSize;
}
private void storeAffinity(@Nonnull IAffinity affinity, int index) {
storedAffinities[index] = affinity;
}
private void removeAffinity(int index) {
storedAffinities[index] = null;
}
@Override
public boolean storeAffinity(@Nonnull IAffinity affinity, EntityPlayer player, World world) {
IAffinity[] storedAffinities = getStoredAffinities(player, world);
for (IAffinity storedAffinity : storedAffinities) {
if (storedAffinity != null && storedAffinity == affinity) {
return false;
}
}
for (int i = 0; i < storedAffinities.length; i++) {
if (storedAffinities[i] == null) {
storeAffinity(affinity, i);
return true;
}
}
return false;
}
@Override
public boolean removeAffinity(EntityPlayer player, World world) {
for (int i = 0; i < getStoredAffinities(player, world).length; i++) {
if (getStoredAffinities(player, world)[i] != null) {
removeAffinity(i);
for (int j = i; j < (getStoredAffinities(player, world).length-(i+1)); j++) {
IAffinity a = getStoredAffinities(player, world)[j];
IAffinity b = getStoredAffinities(player, world)[j+1];
if (a == null) {
if (b == null) continue;
storeAffinity(b, j);
}
}
return true;
}
}
return false;
}
@Override
public IAffinity[] getStoredAffinities(EntityPlayer player, World world) {
return storedAffinities;
}
}