package common.block;

import java.util.List;

import common.entity.Entity;
import common.entity.item.EntityItem;
import common.entity.npc.EntityNPC;
import common.init.Blocks;
import common.init.FluidRegistry;
import common.init.Items;
import common.item.Item;
import common.item.ItemArmor;
import common.item.ItemBanner;
import common.item.ItemStack;
import common.material.Material;
import common.model.Model;
import common.model.ModelProvider;
import common.properties.IProperty;
import common.properties.PropertyInteger;
import common.rng.Random;
import common.tileentity.TileEntityBanner;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.util.ExtMath;
import common.util.Facing;
import common.world.State;
import common.world.World;

public class BlockCauldron extends Block
{
	private static final Model cauldron_empty = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude()
			.add(0, 3, 0, 2, 16, 16)
				.d("cauldron_inner").uv(0, 0, 2, 16)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13).noCull()
			.add(2, 3, 2, 14, 4, 14)
				.d("cauldron_inner").uv(2, 2, 14, 14)
				.u("cauldron_inner").uv(2, 2, 14, 14)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13)
			.add(14, 3, 0, 16, 16, 16)
				.d("cauldron_inner").uv(14, 0, 16, 16)
				.u("cauldron_top").uv(14, 0, 16, 16)
				.n().uv(16, 0, 14, 13)
				.s().uv(14, 0, 16, 13)
				.w().uv(0, 0, 16, 13).noCull()
				.e().uv(0, 0, 16, 13)
			.add(2, 3, 0, 14, 16, 2)
				.d("cauldron_inner").uv(2, 0, 14, 2)
				.u("cauldron_top").uv(2, 0, 14, 2)
				.n().uv(2, 0, 14, 13)
				.s().uv(2, 0, 14, 13).noCull()
				.w().uv(0, 0, 2, 13)
				.e().uv(0, 0, 2, 13)
			.add(2, 3, 14, 14, 16, 16)
				.d("cauldron_inner").uv(2, 14, 14, 16)
				.u("cauldron_top").uv(2, 14, 14, 16)
				.n().uv(2, 0, 14, 13).noCull()
				.s().uv(2, 0, 14, 13)
				.w().uv(14, 0, 16, 13)
				.e().uv(14, 0, 16, 13)
			.add(0, 0, 0, 4, 3, 2)
				.d("cauldron_bottom").uv(0, 0, 4, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(4, 13, 0, 16)
				.s().uv(0, 13, 4, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(0, 0, 2, 2, 3, 4)
				.d("cauldron_bottom").uv(0, 2, 2, 4)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 13, 0, 16)
				.s().uv(0, 13, 2, 16)
				.w().uv(2, 13, 4, 16)
				.e().uv(2, 13, 4, 16)
			.add(12, 0, 0, 16, 3, 2)
				.d("cauldron_bottom").uv(12, 0, 16, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(16, 13, 12, 16)
				.s().uv(12, 13, 16, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(14, 0, 2, 16, 3, 4)
				.d("cauldron_bottom").uv(14, 2, 16, 4).noCull()
				.u("cauldron_top").uv(0, 0, 2, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(4, 13, 2, 16).noCull()
				.e().uv(4, 13, 2, 16).noCull()
			.add(0, 0, 14, 4, 3, 16)
				.d("cauldron_bottom").uv(14, 0, 16, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(4, 13, 0, 16).noCull()
				.s().uv(0, 13, 4, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(0, 0, 12, 2, 3, 14)
				.d("cauldron_bottom").uv(12, 0, 14, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(2, 13, 0, 16).noCull()
				.s().uv(0, 13, 2, 16).noCull()
				.w().uv(12, 13, 14, 16).noCull()
				.e().uv(12, 13, 14, 16).noCull()
			.add(12, 0, 14, 16, 3, 16)
				.d("cauldron_bottom").uv(14, 12, 16, 16).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 12, 16).noCull()
				.s().uv(12, 13, 16, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(14, 0, 12, 16, 3, 14)
				.d("cauldron_bottom").uv(14, 12, 16, 14).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(14, 13, 12, 16).noCull()
				.e().uv(14, 13, 12, 16).noCull()
	;
	private static final Model cauldron_level1 = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude()
			.add(0, 3, 0, 2, 16, 16)
				.d("cauldron_inner").uv(0, 0, 2, 16)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13).noCull()
			.add(2, 3, 2, 14, 4, 14)
				.d("cauldron_inner").uv(2, 2, 14, 14)
				.u("cauldron_inner").uv(2, 2, 14, 14)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13)
			.add(14, 3, 0, 16, 16, 16)
				.d("cauldron_inner").uv(14, 0, 16, 16)
				.u("cauldron_top").uv(14, 0, 16, 16)
				.n().uv(16, 0, 14, 13)
				.s().uv(14, 0, 16, 13)
				.w().uv(0, 0, 16, 13).noCull()
				.e().uv(0, 0, 16, 13)
			.add(2, 3, 0, 14, 16, 2)
				.d("cauldron_inner").uv(2, 0, 14, 2)
				.u("cauldron_top").uv(2, 0, 14, 2)
				.n().uv(2, 0, 14, 13)
				.s().uv(2, 0, 14, 13).noCull()
				.w().uv(0, 0, 2, 13)
				.e().uv(0, 0, 2, 13)
			.add(2, 3, 14, 14, 16, 16)
				.d("cauldron_inner").uv(2, 14, 14, 16)
				.u("cauldron_top").uv(2, 14, 14, 16)
				.n().uv(2, 0, 14, 13).noCull()
				.s().uv(2, 0, 14, 13)
				.w().uv(14, 0, 16, 13)
				.e().uv(14, 0, 16, 13)
			.add(0, 0, 0, 4, 3, 2)
				.d("cauldron_bottom").uv(0, 0, 4, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(4, 13, 0, 16)
				.s().uv(0, 13, 4, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(0, 0, 2, 2, 3, 4)
				.d("cauldron_bottom").uv(0, 2, 2, 4)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 13, 0, 16)
				.s().uv(0, 13, 2, 16)
				.w().uv(2, 13, 4, 16)
				.e().uv(2, 13, 4, 16)
			.add(12, 0, 0, 16, 3, 2)
				.d("cauldron_bottom").uv(12, 0, 16, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(16, 13, 12, 16)
				.s().uv(12, 13, 16, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(14, 0, 2, 16, 3, 4)
				.d("cauldron_bottom").uv(14, 2, 16, 4).noCull()
				.u("cauldron_top").uv(0, 0, 2, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(4, 13, 2, 16).noCull()
				.e().uv(4, 13, 2, 16).noCull()
			.add(0, 0, 14, 4, 3, 16)
				.d("cauldron_bottom").uv(14, 0, 16, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(4, 13, 0, 16).noCull()
				.s().uv(0, 13, 4, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(0, 0, 12, 2, 3, 14)
				.d("cauldron_bottom").uv(12, 0, 14, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(2, 13, 0, 16).noCull()
				.s().uv(0, 13, 2, 16).noCull()
				.w().uv(12, 13, 14, 16).noCull()
				.e().uv(12, 13, 14, 16).noCull()
			.add(12, 0, 14, 16, 3, 16)
				.d("cauldron_bottom").uv(14, 12, 16, 16).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 12, 16).noCull()
				.s().uv(12, 13, 16, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(14, 0, 12, 16, 3, 14)
				.d("cauldron_bottom").uv(14, 12, 16, 14).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(14, 13, 12, 16).noCull()
				.e().uv(14, 13, 12, 16).noCull()
			.add(2, 9, 2, 14, 9, 14)
				.u("water_still").uv(2, 2, 14, 14).noCull()
	;
	private static final Model cauldron_level2 = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude()
			.add(0, 3, 0, 2, 16, 16)
				.d("cauldron_inner").uv(0, 0, 2, 16)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13).noCull()
			.add(2, 3, 2, 14, 4, 14)
				.d("cauldron_inner").uv(2, 2, 14, 14)
				.u("cauldron_inner").uv(2, 2, 14, 14)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13)
			.add(14, 3, 0, 16, 16, 16)
				.d("cauldron_inner").uv(14, 0, 16, 16)
				.u("cauldron_top").uv(14, 0, 16, 16)
				.n().uv(16, 0, 14, 13)
				.s().uv(14, 0, 16, 13)
				.w().uv(0, 0, 16, 13).noCull()
				.e().uv(0, 0, 16, 13)
			.add(2, 3, 0, 14, 16, 2)
				.d("cauldron_inner").uv(2, 0, 14, 2)
				.u("cauldron_top").uv(2, 0, 14, 2)
				.n().uv(2, 0, 14, 13)
				.s().uv(2, 0, 14, 13).noCull()
				.w().uv(0, 0, 2, 13)
				.e().uv(0, 0, 2, 13)
			.add(2, 3, 14, 14, 16, 16)
				.d("cauldron_inner").uv(2, 14, 14, 16)
				.u("cauldron_top").uv(2, 14, 14, 16)
				.n().uv(2, 0, 14, 13).noCull()
				.s().uv(2, 0, 14, 13)
				.w().uv(14, 0, 16, 13)
				.e().uv(14, 0, 16, 13)
			.add(0, 0, 0, 4, 3, 2)
				.d("cauldron_bottom").uv(0, 0, 4, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(4, 13, 0, 16)
				.s().uv(0, 13, 4, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(0, 0, 2, 2, 3, 4)
				.d("cauldron_bottom").uv(0, 2, 2, 4)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 13, 0, 16)
				.s().uv(0, 13, 2, 16)
				.w().uv(2, 13, 4, 16)
				.e().uv(2, 13, 4, 16)
			.add(12, 0, 0, 16, 3, 2)
				.d("cauldron_bottom").uv(12, 0, 16, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(16, 13, 12, 16)
				.s().uv(12, 13, 16, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(14, 0, 2, 16, 3, 4)
				.d("cauldron_bottom").uv(14, 2, 16, 4).noCull()
				.u("cauldron_top").uv(0, 0, 2, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(4, 13, 2, 16).noCull()
				.e().uv(4, 13, 2, 16).noCull()
			.add(0, 0, 14, 4, 3, 16)
				.d("cauldron_bottom").uv(14, 0, 16, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(4, 13, 0, 16).noCull()
				.s().uv(0, 13, 4, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(0, 0, 12, 2, 3, 14)
				.d("cauldron_bottom").uv(12, 0, 14, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(2, 13, 0, 16).noCull()
				.s().uv(0, 13, 2, 16).noCull()
				.w().uv(12, 13, 14, 16).noCull()
				.e().uv(12, 13, 14, 16).noCull()
			.add(12, 0, 14, 16, 3, 16)
				.d("cauldron_bottom").uv(14, 12, 16, 16).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 12, 16).noCull()
				.s().uv(12, 13, 16, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(14, 0, 12, 16, 3, 14)
				.d("cauldron_bottom").uv(14, 12, 16, 14).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(14, 13, 12, 16).noCull()
				.e().uv(14, 13, 12, 16).noCull()
			.add(2, 12, 2, 14, 12, 14)
				.u("water_still").uv(2, 2, 14, 14).noCull()
	;
	private static final Model cauldron_level3 = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude()
			.add(0, 3, 0, 2, 16, 16)
				.d("cauldron_inner").uv(0, 0, 2, 16)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13).noCull()
			.add(2, 3, 2, 14, 4, 14)
				.d("cauldron_inner").uv(2, 2, 14, 14)
				.u("cauldron_inner").uv(2, 2, 14, 14)
				.n().uv(2, 0, 0, 13)
				.s().uv(0, 0, 2, 13)
				.w().uv(0, 0, 16, 13)
				.e().uv(0, 0, 16, 13)
			.add(14, 3, 0, 16, 16, 16)
				.d("cauldron_inner").uv(14, 0, 16, 16)
				.u("cauldron_top").uv(14, 0, 16, 16)
				.n().uv(16, 0, 14, 13)
				.s().uv(14, 0, 16, 13)
				.w().uv(0, 0, 16, 13).noCull()
				.e().uv(0, 0, 16, 13)
			.add(2, 3, 0, 14, 16, 2)
				.d("cauldron_inner").uv(2, 0, 14, 2)
				.u("cauldron_top").uv(2, 0, 14, 2)
				.n().uv(2, 0, 14, 13)
				.s().uv(2, 0, 14, 13).noCull()
				.w().uv(0, 0, 2, 13)
				.e().uv(0, 0, 2, 13)
			.add(2, 3, 14, 14, 16, 16)
				.d("cauldron_inner").uv(2, 14, 14, 16)
				.u("cauldron_top").uv(2, 14, 14, 16)
				.n().uv(2, 0, 14, 13).noCull()
				.s().uv(2, 0, 14, 13)
				.w().uv(14, 0, 16, 13)
				.e().uv(14, 0, 16, 13)
			.add(0, 0, 0, 4, 3, 2)
				.d("cauldron_bottom").uv(0, 0, 4, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(4, 13, 0, 16)
				.s().uv(0, 13, 4, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(0, 0, 2, 2, 3, 4)
				.d("cauldron_bottom").uv(0, 2, 2, 4)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(2, 13, 0, 16)
				.s().uv(0, 13, 2, 16)
				.w().uv(2, 13, 4, 16)
				.e().uv(2, 13, 4, 16)
			.add(12, 0, 0, 16, 3, 2)
				.d("cauldron_bottom").uv(12, 0, 16, 2)
				.u("cauldron_top").uv(0, 0, 2, 16)
				.n().uv(16, 13, 12, 16)
				.s().uv(12, 13, 16, 16)
				.w().uv(0, 13, 2, 16)
				.e().uv(0, 13, 2, 16)
			.add(14, 0, 2, 16, 3, 4)
				.d("cauldron_bottom").uv(14, 2, 16, 4).noCull()
				.u("cauldron_top").uv(0, 0, 2, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(4, 13, 2, 16).noCull()
				.e().uv(4, 13, 2, 16).noCull()
			.add(0, 0, 14, 4, 3, 16)
				.d("cauldron_bottom").uv(14, 0, 16, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(4, 13, 0, 16).noCull()
				.s().uv(0, 13, 4, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(0, 0, 12, 2, 3, 14)
				.d("cauldron_bottom").uv(12, 0, 14, 4).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(2, 13, 0, 16).noCull()
				.s().uv(0, 13, 2, 16).noCull()
				.w().uv(12, 13, 14, 16).noCull()
				.e().uv(12, 13, 14, 16).noCull()
			.add(12, 0, 14, 16, 3, 16)
				.d("cauldron_bottom").uv(14, 12, 16, 16).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 12, 16).noCull()
				.s().uv(12, 13, 16, 16).noCull()
				.w().uv(14, 13, 16, 16).noCull()
				.e().uv(14, 13, 16, 16).noCull()
			.add(14, 0, 12, 16, 3, 14)
				.d("cauldron_bottom").uv(14, 12, 16, 14).noCull()
				.u("cauldron_top").uv(14, 0, 16, 16).noCull()
				.n().uv(16, 13, 14, 16).noCull()
				.s().uv(14, 13, 16, 16).noCull()
				.w().uv(14, 13, 12, 16).noCull()
				.e().uv(14, 13, 12, 16).noCull()
			.add(2, 15, 2, 14, 15, 14)
				.u("water_still").uv(2, 2, 14, 14).noCull()
	;
	private static final Model[] cauldron_levels = 
			new Model[] {cauldron_empty, cauldron_level1, cauldron_level2, cauldron_level3};
	
    public static final PropertyInteger LEVEL = PropertyInteger.create("level", 0, 3);

    public BlockCauldron()
    {
        super(Material.iron);
        this.setDefaultState(this.getBaseState().withProperty(LEVEL, Integer.valueOf(0)));
    }

    /**
     * Add all collision boxes of this Block to the list that intersect with the given mask.
     */
    public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
    {
        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.3125F, 1.0F);
        super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
        float f = 0.125F;
        this.setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
        super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
        super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
        this.setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
        super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
        this.setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
        super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
        this.setBlockBoundsForItemRender();
    }

    /**
     * Sets the block's bounds for rendering it as an item
     */
    public void setBlockBoundsForItemRender()
    {
        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    }

    /**
     * Used to determine ambient occlusion and culling when rebuilding chunks for render
     */
    public boolean isOpaqueCube()
    {
        return false;
    }

    public boolean isFullCube()
    {
        return false;
    }

    /**
     * Called When an Entity Collided with the Block
     */
    public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn)
    {
        int i = ((Integer)state.getValue(LEVEL)).intValue();
        float f = (float)pos.getY() + (6.0F + (float)(3 * i)) / 16.0F;

        if (!worldIn.client && entityIn.isBurning() && i > 0 && entityIn.getEntityBoundingBox().minY <= (double)f)
        {
            entityIn.extinguish();
            this.setWaterLevel(worldIn, pos, state, i - 1);
        }
    }

    public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
    {
        if (worldIn.client)
        {
            return true;
        }
        else
        {
            ItemStack itemstack = playerIn.inventory.getCurrentItem();

            if (itemstack == null)
            {
                return true;
            }
            else
            {
                int i = ((Integer)state.getValue(LEVEL)).intValue();
                Item item = itemstack.getItem();

                if (item == Items.water_bucket && FluidRegistry.getStaticBlock(itemstack.getMetadata()) == Blocks.water)
                {
                    if (i < 3)
                    {
//                        if (!playerIn.creative)
//                        {
                        playerIn.inventory.setInventorySlotContents(playerIn.inventory.currentItem, new ItemStack(Items.bucket));
//                        }

//                        playerIn.triggerAchievement(StatRegistry.cauldronFilledStat);
                        this.setWaterLevel(worldIn, pos, state, 3);
                    }

                    return true;
                }
                else if (item == Items.glass_bottle)
                {
                    if (i > 0)
                    {
//                        if (!playerIn.creative)
//                        {
                        ItemStack itemstack2 = new ItemStack(Items.potion, 1, 0);

                        if (!playerIn.inventory.addItemStackToInventory(itemstack2))
                        {
                            worldIn.spawnEntityInWorld(new EntityItem(worldIn, (double)pos.getX() + 0.5D, (double)pos.getY() + 1.5D, (double)pos.getZ() + 0.5D, itemstack2));
                        }
                        else
                        {
                            playerIn.connection.sendContainerToPlayer(playerIn.inventoryContainer);
                        }

//                        playerIn.triggerAchievement(StatRegistry.cauldronUsedStat);
                        --itemstack.stackSize;

                        if (itemstack.stackSize <= 0)
                        {
                            playerIn.inventory.setInventorySlotContents(playerIn.inventory.currentItem, (ItemStack)null);
                        }
//                        }

                        this.setWaterLevel(worldIn, pos, state, i - 1);
                    }

                    return true;
                }
                else
                {
                    if (i > 0 && item instanceof ItemArmor)
                    {
                        ItemArmor itemarmor = (ItemArmor)item;

                        if (itemarmor.getArmorMaterial().canBeDyed() && itemarmor.hasColor(itemstack))
                        {
                            itemarmor.removeColor(itemstack);
                            this.setWaterLevel(worldIn, pos, state, i - 1);
//                            playerIn.triggerAchievement(StatRegistry.armorCleanedStat);
                            return true;
                        }
                    }

                    if (i > 0 && item instanceof ItemBanner && TileEntityBanner.getPatterns(itemstack) > 0)
                    {
                        ItemStack itemstack1 = itemstack.copy();
                        itemstack1.stackSize = 1;
                        TileEntityBanner.removeBannerData(itemstack1);

                        if (itemstack.stackSize <= 1) // && !playerIn.creative)
                        {
                            playerIn.inventory.setInventorySlotContents(playerIn.inventory.currentItem, itemstack1);
                        }
                        else
                        {
                            if (!playerIn.inventory.addItemStackToInventory(itemstack1))
                            {
                                worldIn.spawnEntityInWorld(new EntityItem(worldIn, (double)pos.getX() + 0.5D, (double)pos.getY() + 1.5D, (double)pos.getZ() + 0.5D, itemstack1));
                            }
                            else
                            {
                                playerIn.connection.sendContainerToPlayer(playerIn.inventoryContainer);
                            }

//                            playerIn.triggerAchievement(StatRegistry.bannerCleanedStat);

//                            if (!playerIn.creative)
//                            {
                            --itemstack.stackSize;
//                            }
                        }

//                        if (!playerIn.creative)
//                        {
                        this.setWaterLevel(worldIn, pos, state, i - 1);
//                        }

                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }
    }

    public void setWaterLevel(World worldIn, BlockPos pos, State state, int level)
    {
        worldIn.setState(pos, state.withProperty(LEVEL, Integer.valueOf(ExtMath.clampi(level, 0, 3))), 2);
        worldIn.updateComparatorOutputLevel(pos, this);
    }

    /**
     * Called similar to random ticks, but only when it is raining.
     */
    public void fillWithRain(World worldIn, BlockPos pos)
    {
        if (worldIn.rand.chance(20)) // == 1
        {
            State iblockstate = worldIn.getState(pos);

            if (((Integer)iblockstate.getValue(LEVEL)).intValue() < 3)
            {
                worldIn.setState(pos, iblockstate.cycleProperty(LEVEL), 2);
            }
        }
    }

    /**
     * Get the Item that this Block should drop when harvested.
     */
    public Item getItemDropped(State state, Random rand, int fortune)
    {
        return Items.cauldron;
    }

    public Item getItem(World worldIn, BlockPos pos)
    {
        return Items.cauldron;
    }

    public boolean hasComparatorInputOverride()
    {
        return true;
    }

    public int getComparatorInputOverride(World worldIn, BlockPos pos)
    {
        return ((Integer)worldIn.getState(pos).getValue(LEVEL)).intValue();
    }

    /**
     * Convert the given metadata into a BlockState for this Block
     */
    public State getStateFromMeta(int meta)
    {
        return this.getState().withProperty(LEVEL, Integer.valueOf(meta > 3 ? 0 : meta));
    }

    /**
     * Convert the BlockState into the correct metadata value
     */
    public int getMetaFromState(State state)
    {
        return ((Integer)state.getValue(LEVEL)).intValue();
    }

    protected IProperty[] getProperties()
    {
        return new IProperty[] {LEVEL};
    }
    
    public boolean isMagnetic() {
    	return true;
    }

    public Model getModel(ModelProvider provider, String name, State state) {
    	return cauldron_levels[state.getValue(LEVEL)];
    }
}
