package com.elytradev.concrete;

import java.util.ArrayList;
import java.util.Collection;
import com.google.common.base.Supplier;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.INBTSerializable;

public class NBTHelper {

	/**
	 * Convert the given Collection of INBTSerializable objects into an
	 * NBTTagList.
	 */
	public <T extends INBTSerializable<U>,
			U extends NBTBase> NBTTagList serialize(Collection<T> in) {
		NBTTagList out = new NBTTagList();
		for (T t : in) {
			out.appendTag(t.serializeNBT());
		}
		return out;
	}
	
	/**
	 * Convert the given NBTTagList into an ArrayList of INBTSerializable
	 * objects, using freshly-created objects from the passed constructor.
	 * <p>
	 * Example: {@code NBTHelper.deserialize(MyObject::new, myNBTList)}
	 */
	public <T extends INBTSerializable<U>,
			U extends NBTBase> ArrayList<T> deserialize(Supplier<T> constructor, NBTTagList in) {
		return deserialize(constructor, in, ArrayList::new);
	}
	
	/**
	 * Convert the given NBTTagList into a Collection of INBTSerializable
	 * objects, using freshly-created objects from the passed constructor, and
	 * a freshly-created collection from the passed collection constructor. 
	 * <p>
	 * Example: {@code NBTHelper.deserialize(MyObject::new, myNBTList, ArrayList::new)}
	 */
	public <T extends INBTSerializable<U>,
			U extends NBTBase,
			C extends Collection<T>> C deserialize(Supplier<T> constructor, NBTTagList in, Supplier<C> collectionConstructor) {
		return deserializeInto(constructor, in, collectionConstructor.get());
	}
	
	/**
	 * Add INBTSerializable objects from the given NBTTagList into a
	 * pre-existing Collection of the correct type, using freshly-created
	 * objects from the passed constructor.
	 * <p>
	 * This method does not clear the passed collection, that's up to you if you
	 * want to do it. 
	 * <p>
	 * Example: {@code NBTHelper.deserialize(MyObject::new, myNBTList, myList)}
	 */
	public <T extends INBTSerializable<U>,
			U extends NBTBase,
			C extends Collection<T>> C deserializeInto(Supplier<T> constructor, NBTTagList in, C collection) {
		for (int i = 0; i < in.tagCount(); i++) {
			T t = constructor.get();
			t.deserializeNBT((U)in.get(i));
			collection.add(t);
		}
		return collection;
	}
	
}

@@ -127,133 +127,409 @@
 er;%0A
-import net.minecraft.nbt.NBTBase;%0Aimport net.minecraft.nbt.NBTTagList;%0Aimport net.minecraftforge.common.util.INBTSerializable
+%0Aimport net.minecraft.inventory.IInventory;%0Aimport net.minecraft.item.ItemStack;%0Aimport net.minecraft.nbt.NBTBase;%0Aimport net.minecraft.nbt.NBTTagCompound;%0Aimport net.minecraft.nbt.NBTTagList;%0Aimport net.minecraftforge.common.util.INBTSerializable;%0Aimport net.minecraftforge.items.IItemHandler;%0Aimport net.minecraftforge.items.IItemHandlerModifiable;%0Aimport net.minecraftforge.items.wrapper.InvWrapper
 ;%0A%0Ap
@@ -2569,10 +2569,979 @@
 n;%0A%09%7D%0A%09%0A
+%09%0A%09%0A%09%0A%09public NBTTagList serializeInventory(IInventory in) %7B%0A%09%09return serializeInventory(new InvWrapper(in));%0A%09%7D%0A%09%0A%09public void deserializeInventory(IInventory out, NBTTagList in) %7B%0A%09%09deserializeInventory(new InvWrapper(out), in);%0A%09%7D%0A%09%0A%09public NBTTagList serializeInventory(IItemHandler in) %7B%0A%09%09NBTTagList out = new NBTTagList();%0A%09%09for (int i = 0; i %3C in.getSlots(); i++) %7B%0A%09%09%09ItemStack is = in.getStackInSlot(i);%0A%09%09%09if (is == null %7C%7C is.isEmpty()) continue;%0A%09%09%09NBTTagCompound stackTag = is.serializeNBT();%0A%09%09%09stackTag.setInteger(%22Slot%22, i);%0A%09%09%09out.appendTag(stackTag);%0A%09%09%7D%0A%09%09return out;%0A%09%7D%0A%09%0A%09public void deserializeInventory(IItemHandlerModifiable out, NBTTagList in) %7B%0A%09%09for (int i = 0; i %3C out.getSlots(); i++) %7B%0A%09%09%09out.setStackInSlot(i, ItemStack.EMPTY);%0A%09%09%7D%0A%09%09for (int i = 0; i %3C in.tagCount(); i++) %7B%0A%09%09%09NBTTagCompound stackTag = in.getCompoundTagAt(i);%0A%09%09%09ItemStack is = new ItemStack(stackTag);%0A%09%09%09out.setStackInSlot(stackTag.getInteger(%22Slot%22), is);%0A%09%09%7D%0A%09%7D%0A%09%0A
 %7D%0A

Add {de,}serializeInventory to NBTHelper