package common.block.foliage;

import common.block.Block;
import common.block.Rotatable;
import common.block.Material;
import common.entity.types.EntityLiving;
import common.init.Blocks;
import common.init.Items;
import common.item.Item;
import common.item.ItemStack;
import common.model.BlockLayer;
import common.model.Model;
import common.model.ModelProvider;
import common.model.ModelRotation;
import common.properties.Property;
import common.properties.PropertyInteger;
import common.rng.Random;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.util.Facing;
import common.vars.Vars;
import common.world.IWorldAccess;
import common.world.State;
import common.world.World;
import common.world.AWorldServer;

public class BlockCocoa extends Block implements Rotatable, IGrowable
{
    public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 2);

    public BlockCocoa()
    {
        super(Material.PLANT);
        this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(AGE, Integer.valueOf(0)));
        this.setTickRandomly();
    }

    public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand)
    {
        if (!this.canBlockStay(worldIn, pos, state))
        {
            this.dropBlock(worldIn, pos, state);
        }
        else if (Vars.cocoaGrowth > 0 && worldIn.rand.chance(Vars.cocoaGrowth))
        {
            int i = ((Integer)state.getValue(AGE)).intValue();

            if (i < 2)
            {
                worldIn.setState(pos, state.withProperty(AGE, Integer.valueOf(i + 1)), 2);
            }
        }
    }

    public boolean canBlockStay(World worldIn, BlockPos pos, State state)
    {
        pos = pos.offset((Facing)state.getValue(FACING));
        State iblockstate = worldIn.getState(pos);
        return iblockstate.getBlock() == Blocks.jungle_log; // && iblockstate.getValue(BlockPlanks.VARIANT) == BlockPlanks.EnumType.JUNGLE;
    }

    public boolean isFullCube()
    {
        return false;
    }

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

    public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
    {
        this.setBlockBoundsBasedOnState(worldIn, pos);
        return super.getCollisionBoundingBox(worldIn, pos, state);
    }

    public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos)
    {
        this.setBlockBoundsBasedOnState(worldIn, pos);
        return super.getSelectedBoundingBox(worldIn, pos);
    }

    
    public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
    {
        State iblockstate = worldIn.getState(pos);
        Facing enumfacing = (Facing)iblockstate.getValue(FACING);
        int i = ((Integer)iblockstate.getValue(AGE)).intValue();
        int j = 4 + i * 2;
        int k = 5 + i * 2;
        float f = (float)j / 2.0F;

        switch (enumfacing)
        {
            case SOUTH:
                this.setBlockBounds((8.0F - f) / 16.0F, (12.0F - (float)k) / 16.0F, (15.0F - (float)j) / 16.0F, (8.0F + f) / 16.0F, 0.75F, 0.9375F);
                break;

            case NORTH:
                this.setBlockBounds((8.0F - f) / 16.0F, (12.0F - (float)k) / 16.0F, 0.0625F, (8.0F + f) / 16.0F, 0.75F, (1.0F + (float)j) / 16.0F);
                break;

            case WEST:
                this.setBlockBounds(0.0625F, (12.0F - (float)k) / 16.0F, (8.0F - f) / 16.0F, (1.0F + (float)j) / 16.0F, 0.75F, (8.0F + f) / 16.0F);
                break;

            case EAST:
                this.setBlockBounds((15.0F - (float)j) / 16.0F, (12.0F - (float)k) / 16.0F, (8.0F - f) / 16.0F, 0.9375F, 0.75F, (8.0F + f) / 16.0F);
        }
    }

    /**
     * Called by ItemBlocks after a block is set in the world, to allow post-place logic
     */
    public void onBlockPlacedBy(World worldIn, BlockPos pos, State state, EntityLiving placer, ItemStack stack)
    {
        Facing enumfacing = Facing.fromAngle((double)placer.rotYaw);
        worldIn.setState(pos, state.withProperty(FACING, enumfacing), 2);
    }

    /**
     * Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
     * IBlockstate
     */
    public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, EntityLiving placer)
    {
        if (!facing.getAxis().isHorizontal())
        {
            facing = Facing.NORTH;
        }

        return this.getState().withProperty(FACING, facing.getOpposite()).withProperty(AGE, Integer.valueOf(0));
    }

    /**
     * Called when a neighboring block changes.
     */
    public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
    {
        if (!this.canBlockStay(worldIn, pos, state))
        {
            this.dropBlock(worldIn, pos, state);
        }
    }

    private void dropBlock(World worldIn, BlockPos pos, State state)
    {
        worldIn.setState(pos, Blocks.air.getState(), 3);
        this.dropBlockAsItem(worldIn, pos, state, 0);
    }

    /**
     * Spawns this Block's drops into the World as EntityItems.
     */
    public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune)
    {
        int i = ((Integer)state.getValue(AGE)).intValue();
        int j = 1;

        if (i >= 2)
        {
            j = 3;
        }

        for (int k = 0; k < j; ++k)
        {
            spawnAsEntity(worldIn, pos, new ItemStack(Items.cocoa));
        }
    }

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

    /**
     * Whether this IGrowable can grow
     */
    public boolean canGrow(World worldIn, BlockPos pos, State state, boolean isClient)
    {
        return ((Integer)state.getValue(AGE)).intValue() < 2;
    }

    public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, State state)
    {
        return true;
    }

    public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state)
    {
        worldIn.setState(pos, state.withProperty(AGE, Integer.valueOf(((Integer)state.getValue(AGE)).intValue() + 1)), 2);
    }

    public BlockLayer getBlockLayer()
    {
        return BlockLayer.CUTOUT;
    }

    /**
     * Convert the given metadata into a BlockState for this Block
     */
    public State getStateFromMeta(int meta)
    {
        return this.getState().withProperty(FACING, Facing.getHorizontal(meta)).withProperty(AGE, Integer.valueOf((meta & 12) == 12 ? 0 : ((meta & 12) >> 2)));
    }

    /**
     * Convert the BlockState into the correct metadata value
     */
    public int getMetaFromState(State state)
    {
        int i = 0;
        i = i | ((Facing)state.getValue(FACING)).getHorizontalIndex();
        i = i | ((Integer)state.getValue(AGE)).intValue() << 2;
        return i;
    }

    protected Property[] getProperties()
    {
        return new Property[] {FACING, AGE};
    }

    public Model getModel(ModelProvider provider, String name, State state) {
    	Model model;
    	switch(state.getValue(AGE)) {
    	case 0:
    		model = provider.getModel("cocoa_0")
    				.add(6, 7, 11, 10, 12, 15)
    				.d().uv(0, 0, 4, 4).noCull()
    				.u().uv(0, 0, 4, 4).noCull()
    				.n().uv(11, 4, 15, 9).noCull()
    				.s().uv(11, 4, 15, 9).noCull()
    				.w().uv(11, 4, 15, 9).noCull()
    				.e().uv(11, 4, 15, 9).noCull()
    			.add(8, 12, 12, 8, 16, 16)
    				.w().uv(12, 0, 16, 4).noCull()
    				.e().uv(16, 0, 12, 4).noCull();
    		break;
    	case 1:
    		model = provider.getModel("cocoa_1")
    				.add(5, 5, 9, 11, 12, 15)
    				.d().uv(0, 0, 6, 6).noCull()
    				.u().uv(0, 0, 6, 6).noCull()
    				.n().uv(9, 4, 15, 11).noCull()
    				.s().uv(9, 4, 15, 11).noCull()
    				.w().uv(9, 4, 15, 11).noCull()
    				.e().uv(9, 4, 15, 11).noCull()
    			.add(8, 12, 12, 8, 16, 16)
    				.w().uv(12, 0, 16, 4).noCull()
    				.e().uv(16, 0, 12, 4).noCull();
    		break;
    	case 2:
    	default:
    		model = provider.getModel("cocoa_2")
    				.add(4, 3, 7, 12, 12, 15)
    				.d().uv(0, 0, 7, 7).noCull()
    				.u().uv(0, 0, 7, 7).noCull()
    				.n().uv(7, 4, 15, 13).noCull()
    				.s().uv(7, 4, 15, 13).noCull()
    				.w().uv(7, 4, 15, 13).noCull()
    				.e().uv(7, 4, 15, 13).noCull()
    			.add(8, 12, 12, 8, 16, 16)
    				.w().uv(12, 0, 16, 4).noCull()
    				.e().uv(16, 0, 12, 4).noCull();
    		break;
    	}
    	return model.rotate(ModelRotation.getNorthRot(state.getValue(FACING).getOpposite()));
    }
	
	protected Item getItemToRegister() {
		return null;
	}
}
