package common.block.tech;

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

public class BlockTripWireHook extends Block implements Rotatable
{
    public static final PropertyBool POWERED = PropertyBool.create("powered");
    public static final PropertyBool ATTACHED = PropertyBool.create("attached");
    public static final PropertyBool SUSPENDED = PropertyBool.create("suspended");

    public BlockTripWireHook()
    {
        super(Material.SMALL);
        this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(POWERED, Boolean.valueOf(false)).withProperty(ATTACHED, Boolean.valueOf(false)).withProperty(SUSPENDED, Boolean.valueOf(false)));
        this.setTab(CheatTab.TECHNOLOGY);
//        this.setTickRandomly(true);
    }

    /**
     * Get the actual Block state of this Block at the given position. This applies properties not visible in the
     * metadata, such as fence connections.
     */
    public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
    {
        return state.withProperty(SUSPENDED, Boolean.valueOf(!World.isSolidSurface(worldIn.getState(pos.down()))));
    }

    public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
    {
        return null;
    }

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

    public boolean isFullCube()
    {
        return false;
    }

    /**
     * Check whether this Block can be placed on the given side
     */
    public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, Facing side)
    {
        return side.getAxis().isHorizontal() && worldIn.getState(pos.offset(side.getOpposite())).getBlock().isNormalCube();
    }

    public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
    {
        for (Facing enumfacing : Facing.Plane.HORIZONTAL)
        {
            if (worldIn.getState(pos.offset(enumfacing)).getBlock().isNormalCube())
            {
                return true;
            }
        }

        return false;
    }

    /**
     * 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)
    {
        State iblockstate = this.getState().withProperty(POWERED, Boolean.valueOf(false)).withProperty(ATTACHED, Boolean.valueOf(false)).withProperty(SUSPENDED, Boolean.valueOf(false));

        if (facing.getAxis().isHorizontal())
        {
            iblockstate = iblockstate.withProperty(FACING, facing);
        }

        return iblockstate;
    }

    /**
     * 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)
    {
        this.triggerHookAt(worldIn, pos, state, false, false, -1, (State)null);
    }

    /**
     * Called when a neighboring block changes.
     */
    public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
    {
        if (neighborBlock != this)
        {
            if (this.checkForDrop(worldIn, pos, state))
            {
                Facing enumfacing = (Facing)state.getValue(FACING);

                if (!worldIn.getState(pos.offset(enumfacing.getOpposite())).getBlock().isNormalCube())
                {
                    this.dropBlockAsItem(worldIn, pos, state, 0);
                    worldIn.setBlockToAir(pos);
                }
            }
        }
    }

    public void triggerHookAt(World worldIn, BlockPos pos, State hookState, boolean removed, boolean triggered, int wireDist, State wireState)
    {
        Facing enumfacing = (Facing)hookState.getValue(FACING);
        boolean attached = ((Boolean)hookState.getValue(ATTACHED)).booleanValue();
        boolean powered = ((Boolean)hookState.getValue(POWERED)).booleanValue();
        boolean floating = !worldIn.isBlockSolid(pos.down());
        boolean nowAttached = !removed;
        boolean nowPowered = false;
        int i = 0;
        State[] aiblockstate = new State[42];

        for (int j = 1; j < 42; ++j)
        {
            BlockPos blockpos = pos.offset(enumfacing, j);
            State iblockstate = worldIn.getState(blockpos);

            if (iblockstate.getBlock() == Blocks.tripwire_hook)
            {
                if (iblockstate.getValue(FACING) == enumfacing.getOpposite())
                {
                    i = j;
                }

                break;
            }

            if (iblockstate.getBlock() != Blocks.string && j != wireDist)
            {
                aiblockstate[j] = null;
                nowAttached = false;
            }
            else
            {
                if (j == wireDist)
                {
                    iblockstate = wireState == null ? iblockstate : wireState; // (State)Objects.firstNonNull(wireState, iblockstate);
                }

                boolean flag5 = !((Boolean)iblockstate.getValue(BlockTripWire.DISARMED)).booleanValue();
                boolean flag6 = ((Boolean)iblockstate.getValue(BlockTripWire.POWERED)).booleanValue();
                boolean flag7 = ((Boolean)iblockstate.getValue(BlockTripWire.SUSPENDED)).booleanValue();
                nowAttached &= flag7 == floating;
                nowPowered |= flag5 && flag6;
                aiblockstate[j] = iblockstate;

                if (j == wireDist)
                {
                    worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos));
                    nowAttached &= flag5;
                }
            }
        }

        nowAttached = nowAttached & i > 1;
        nowPowered = nowPowered & nowAttached;
        State iblockstate1 = this.getState().withProperty(ATTACHED, Boolean.valueOf(nowAttached)).withProperty(POWERED, Boolean.valueOf(nowPowered));

        if (i > 0)
        {
            BlockPos blockpos1 = pos.offset(enumfacing, i);
            Facing enumfacing1 = enumfacing.getOpposite();
            worldIn.setState(blockpos1, iblockstate1.withProperty(FACING, enumfacing1), 3);
            this.notifyTriggered(worldIn, blockpos1, enumfacing1);
            this.playerTriggerSounds(worldIn, blockpos1, nowAttached, nowPowered, attached, powered);
        }

        this.playerTriggerSounds(worldIn, pos, nowAttached, nowPowered, attached, powered);

        if (!removed)
        {
            worldIn.setState(pos, iblockstate1.withProperty(FACING, enumfacing), 3);

            if (triggered)
            {
                this.notifyTriggered(worldIn, pos, enumfacing);
            }
        }

        if (attached != nowAttached)
        {
            for (int k = 1; k < i; ++k)
            {
                BlockPos blockpos2 = pos.offset(enumfacing, k);
                State iblockstate2 = aiblockstate[k];

                if (iblockstate2 != null && worldIn.getState(blockpos2).getBlock() != Blocks.air)
                {
                    worldIn.setState(blockpos2, iblockstate2.withProperty(ATTACHED, Boolean.valueOf(nowAttached)), 3);
                }
            }
        }
    }

    /**
     * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.)
     */
    public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random)
    {
    }

    public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand)
    {
        this.triggerHookAt(worldIn, pos, state, false, true, -1, (State)null);
    }

    private void playerTriggerSounds(World worldIn, BlockPos pos, boolean attached, boolean powered, boolean wasAttached, boolean wasPowered)
    {
        if (powered && !wasPowered)
        {
            worldIn.playSound(SoundEvent.CLICK, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D, 0.4F);
        }
        else if (!powered && wasPowered)
        {
            worldIn.playSound(SoundEvent.CLICK, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D, 0.4F);
        }
        else if (attached && !wasAttached)
        {
            worldIn.playSound(SoundEvent.CLICK, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D, 0.4F);
        }
        else if (!attached && wasAttached)
        {
            worldIn.playSound(SoundEvent.BOWHIT, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D, 0.4F);
        }
    }

    private void notifyTriggered(World worldIn, BlockPos pos, Facing face)
    {
        worldIn.notifyNeighborsOfStateChange(pos, this);
        worldIn.notifyNeighborsOfStateChange(pos.offset(face.getOpposite()), this);
    }

    private boolean checkForDrop(World worldIn, BlockPos pos, State state)
    {
        if (!this.canPlaceBlockAt(worldIn, pos))
        {
            this.dropBlockAsItem(worldIn, pos, state, 0);
            worldIn.setBlockToAir(pos);
            return false;
        }
        else
        {
            return true;
        }
    }

    
    public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
    {
        float f = 0.1875F;

        switch ((Facing)worldIn.getState(pos).getValue(FACING))
        {
            case EAST:
                this.setBlockBounds(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f);
                break;

            case WEST:
                this.setBlockBounds(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f);
                break;

            case SOUTH:
                this.setBlockBounds(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F);
                break;

            case NORTH:
                this.setBlockBounds(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F);
        }
    }

    public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state)
    {
        boolean flag = ((Boolean)state.getValue(ATTACHED)).booleanValue();
        boolean flag1 = ((Boolean)state.getValue(POWERED)).booleanValue();

        if (flag || flag1)
        {
            this.triggerHookAt(worldIn, pos, state, true, false, -1, (State)null);
        }

        if (flag1)
        {
            worldIn.notifyNeighborsOfStateChange(pos, this);
            worldIn.notifyNeighborsOfStateChange(pos.offset(((Facing)state.getValue(FACING)).getOpposite()), this);
        }

        super.onBlockRemoved(worldIn, pos, state);
    }

    public int getWeakPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side)
    {
        return ((Boolean)state.getValue(POWERED)).booleanValue() ? 15 : 0;
    }

    public int getStrongPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side)
    {
        return !((Boolean)state.getValue(POWERED)).booleanValue() ? 0 : (state.getValue(FACING) == side ? 15 : 0);
    }

    /**
     * Can this block provide power. Only wire currently seems to have this change based on its state.
     */
    public boolean canProvidePower()
    {
        return true;
    }

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

    /**
     * Convert the given metadata into a BlockState for this Block
     */
    public State getStateFromMeta(int meta)
    {
        return this.getState().withProperty(FACING, Facing.getHorizontal(meta & 3)).withProperty(POWERED, Boolean.valueOf((meta & 8) > 0)).withProperty(ATTACHED, Boolean.valueOf((meta & 4) > 0));
    }

    /**
     * Convert the BlockState into the correct metadata value
     */
    public int getMetaFromState(State state)
    {
        int i = 0;
        i = i | ((Facing)state.getValue(FACING)).getHorizontalIndex();

        if (((Boolean)state.getValue(POWERED)).booleanValue())
        {
            i |= 8;
        }

        if (((Boolean)state.getValue(ATTACHED)).booleanValue())
        {
            i |= 4;
        }

        return i;
    }

    protected Property[] getProperties()
    {
        return new Property[] {FACING, POWERED, ATTACHED, SUSPENDED};
    }
    
    public boolean isMagnetic() {
    	return true;
    }

    public Model getModel(ModelProvider provider, String name, State state) {
    	Model model;
    	if(state.getValue(ATTACHED)) {
        	if(state.getValue(SUSPENDED)) {
        		if(state.getValue(POWERED))
        			model = provider.getModel("oak_planks")
        					.add(7.75f, 2.5f, 0, 8.25f, 2.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true)
        					.d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull()
        					.u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull()
        				.add(6.2f, 4.2f, 6.7f, 9.8f, 5, 10.3f)
        					.d("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.u("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.n("tripwire_hook").uv(5, 3, 11, 4).noCull()
        					.s("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.w("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.e("tripwire_hook").uv(5, 3, 11, 4).noCull()
        				.add(7.4f, 4.2f, 9.1f, 8.6f, 5, 9.1f)
        					.n("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(7.4f, 4.2f, 7.9f, 8.6f, 5, 7.9f)
        					.s("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 4.2f, 7.9f, 7.4f, 5, 9.1f)
        					.e("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(8.6f, 4.2f, 7.9f, 8.6f, 5, 9.1f)
        					.w("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 5.2f, 10, 8.8f, 6.8f, 14).rotate(8, 6, 14, Facing.Axis.X, -22.5f, false)
        					.d().uv(7, 9, 9, 14).noCull()
        					.u().uv(7, 2, 9, 7).noCull()
        					.n().uv(7, 9, 9, 11).noCull()
        					.s().uv(7, 9, 9, 11).noCull()
        					.w().uv(2, 9, 7, 11).noCull()
        					.e().uv(9, 9, 14, 11).noCull()
        				.add(6, 1, 14, 10, 9, 16)
        					.d().uv(6, 14, 10, 16).noCull()
        					.u().uv(6, 0, 10, 2).noCull()
        					.n().uv(6, 7, 10, 15)
        					.s().uv(6, 7, 10, 15).noCull()
        					.w().uv(0, 7, 2, 15).noCull()
        					.e().uv(14, 7, 16, 15).noCull();
        		else
        			model = provider.getModel("oak_planks")
        					.add(7.75f, 3.5f, 0, 8.25f, 3.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true)
        					.d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull()
        					.u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull()
        				.add(6.2f, 4.2f, 6.7f, 9.8f, 5, 10.3f)
        					.d("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.u("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.n("tripwire_hook").uv(5, 3, 11, 4).noCull()
        					.s("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.w("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.e("tripwire_hook").uv(5, 3, 11, 4).noCull()
        				.add(7.4f, 4.2f, 9.1f, 8.6f, 5, 9.1f)
        					.n("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(7.4f, 4.2f, 7.9f, 8.6f, 5, 7.9f)
        					.s("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 4.2f, 7.9f, 7.4f, 5, 9.1f)
        					.e("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(8.6f, 4.2f, 7.9f, 8.6f, 5, 9.1f)
        					.w("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 5.2f, 10, 8.8f, 6.8f, 14).rotate(8, 6, 14, Facing.Axis.X, -22.5f, false)
        					.d().uv(7, 9, 9, 14).noCull()
        					.u().uv(7, 2, 9, 7).noCull()
        					.n().uv(7, 9, 9, 11).noCull()
        					.s().uv(7, 9, 9, 11).noCull()
        					.w().uv(2, 9, 7, 11).noCull()
        					.e().uv(9, 9, 14, 11).noCull()
        				.add(6, 1, 14, 10, 9, 16)
        					.d().uv(6, 14, 10, 16).noCull()
        					.u().uv(6, 0, 10, 2).noCull()
        					.n().uv(6, 7, 10, 15)
        					.s().uv(6, 7, 10, 15).noCull()
        					.w().uv(0, 7, 2, 15).noCull()
        					.e().uv(14, 7, 16, 15).noCull();
        	}
        	else {
        		if(state.getValue(POWERED))
        			model = provider.getModel("oak_planks")
        					.add(7.75f, 0.5f, 0, 8.25f, 0.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true)
        					.d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull()
        					.u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull()
        				.add(6.2f, 4.2f, 6.7f, 9.8f, 5, 10.3f)
        					.d("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.u("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.n("tripwire_hook").uv(5, 3, 11, 4).noCull()
        					.s("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.w("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.e("tripwire_hook").uv(5, 3, 11, 4).noCull()
        				.add(7.4f, 4.2f, 9.1f, 8.6f, 5, 9.1f)
        					.n("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(7.4f, 4.2f, 7.9f, 8.6f, 5, 7.9f)
        					.s("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 4.2f, 7.9f, 7.4f, 5, 9.1f)
        					.e("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(8.6f, 4.2f, 7.9f, 8.6f, 5, 9.1f)
        					.w("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 5.2f, 10, 8.8f, 6.8f, 14).rotate(8, 6, 14, Facing.Axis.X, -22.5f, false)
        					.d().uv(7, 9, 9, 14).noCull()
        					.u().uv(7, 2, 9, 7).noCull()
        					.n().uv(7, 9, 9, 11).noCull()
        					.s().uv(7, 9, 9, 11).noCull()
        					.w().uv(2, 9, 7, 11).noCull()
        					.e().uv(9, 9, 14, 11).noCull()
        				.add(6, 1, 14, 10, 9, 16)
        					.d().uv(6, 14, 10, 16).noCull()
        					.u().uv(6, 0, 10, 2).noCull()
        					.n().uv(6, 7, 10, 15)
        					.s().uv(6, 7, 10, 15).noCull()
        					.w().uv(0, 7, 2, 15).noCull()
        					.e().uv(14, 7, 16, 15).noCull();
        		else
        			model = provider.getModel("oak_planks")
        					.add(7.75f, 1.5f, 0, 8.25f, 1.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true)
        					.d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull()
        					.u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull()
        				.add(6.2f, 4.2f, 6.7f, 9.8f, 5, 10.3f)
        					.d("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.u("tripwire_hook").uv(5, 3, 11, 9).noCull()
        					.n("tripwire_hook").uv(5, 3, 11, 4).noCull()
        					.s("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.w("tripwire_hook").uv(5, 8, 11, 9).noCull()
        					.e("tripwire_hook").uv(5, 3, 11, 4).noCull()
        				.add(7.4f, 4.2f, 9.1f, 8.6f, 5, 9.1f)
        					.n("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(7.4f, 4.2f, 7.9f, 8.6f, 5, 7.9f)
        					.s("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 4.2f, 7.9f, 7.4f, 5, 9.1f)
        					.e("tripwire_hook").uv(7, 8, 9, 9).noCull()
        				.add(8.6f, 4.2f, 7.9f, 8.6f, 5, 9.1f)
        					.w("tripwire_hook").uv(7, 3, 9, 4).noCull()
        				.add(7.4f, 5.2f, 10, 8.8f, 6.8f, 14)
        					.d().uv(7, 9, 9, 14).noCull()
        					.u().uv(7, 2, 9, 7).noCull()
        					.n().uv(7, 9, 9, 11).noCull()
        					.s().uv(7, 9, 9, 11).noCull()
        					.w().uv(2, 9, 7, 11).noCull()
        					.e().uv(9, 9, 14, 11).noCull()
        				.add(6, 1, 14, 10, 9, 16)
        					.d().uv(6, 14, 10, 16).noCull()
        					.u().uv(6, 0, 10, 2).noCull()
        					.n().uv(6, 7, 10, 15)
        					.s().uv(6, 7, 10, 15).noCull()
        					.w().uv(0, 7, 2, 15).noCull()
        					.e().uv(14, 7, 16, 15).noCull();
        	}
    	}
    	else {
    		if(state.getValue(POWERED))
    			model = provider.getModel("oak_planks")
    					.add(6.2f, 4.2f, 6.7f, 9.8f, 5, 10.3f)
    					.d("tripwire_hook").uv(5, 3, 11, 9).noCull()
    					.u("tripwire_hook").uv(5, 3, 11, 9).noCull()
    					.n("tripwire_hook").uv(5, 3, 11, 4).noCull()
    					.s("tripwire_hook").uv(5, 8, 11, 9).noCull()
    					.w("tripwire_hook").uv(5, 8, 11, 9).noCull()
    					.e("tripwire_hook").uv(5, 3, 11, 4).noCull()
    				.add(7.4f, 4.2f, 9.1f, 8.6f, 5, 9.1f)
    					.n("tripwire_hook").uv(7, 8, 9, 9).noCull()
    				.add(7.4f, 4.2f, 7.9f, 8.6f, 5, 7.9f)
    					.s("tripwire_hook").uv(7, 3, 9, 4).noCull()
    				.add(7.4f, 4.2f, 7.9f, 7.4f, 5, 9.1f)
    					.e("tripwire_hook").uv(7, 8, 9, 9).noCull()
    				.add(8.6f, 4.2f, 7.9f, 8.6f, 5, 9.1f)
    					.w("tripwire_hook").uv(7, 3, 9, 4).noCull()
    				.add(7.4f, 5.2f, 10, 8.8f, 6.8f, 14).rotate(8, 6, 14, Facing.Axis.X, -22.5f, false)
    					.d().uv(7, 9, 9, 14).noCull()
    					.u().uv(7, 2, 9, 7).noCull()
    					.n().uv(7, 9, 9, 11).noCull()
    					.s().uv(7, 9, 9, 11).noCull()
    					.w().uv(2, 9, 7, 11).noCull()
    					.e().uv(9, 9, 14, 11).noCull()
    				.add(6, 1, 14, 10, 9, 16)
    					.d().uv(6, 14, 10, 16).noCull()
    					.u().uv(6, 0, 10, 2).noCull()
    					.n().uv(6, 7, 10, 15)
    					.s().uv(6, 7, 10, 15).noCull()
    					.w().uv(0, 7, 2, 15).noCull()
    					.e().uv(14, 7, 16, 15).noCull();
    		else
    			model = provider.getModel("oak_planks")
    					.add(6.2f, 3.8f, 7.9f, 9.8f, 4.6f, 11.5f).rotate(8, 6, 5.2f, Facing.Axis.X, -45, false)
    					.d("tripwire_hook").uv(5, 3, 11, 9).noCull()
    					.u("tripwire_hook").uv(5, 3, 11, 9).noCull()
    					.n("tripwire_hook").uv(5, 3, 11, 4).noCull()
    					.s("tripwire_hook").uv(5, 8, 11, 9).noCull()
    					.w("tripwire_hook").uv(5, 8, 11, 9).noCull()
    					.e("tripwire_hook").uv(5, 3, 11, 4).noCull()
    				.add(7.4f, 3.8f, 10.3f, 8.6f, 4.6f, 10.3f).rotate(8, 6, 5.2f, Facing.Axis.X, -45, false)
    					.n("tripwire_hook").uv(7, 8, 9, 9).noCull()
    				.add(7.4f, 3.8f, 9.1f, 8.6f, 4.6f, 9.1f).rotate(8, 6, 5.2f, Facing.Axis.X, -45, false)
    					.s("tripwire_hook").uv(7, 3, 9, 4).noCull()
    				.add(7.4f, 3.8f, 9.1f, 7.4f, 4.6f, 10.3f).rotate(8, 6, 5.2f, Facing.Axis.X, -45, false)
    					.e("tripwire_hook").uv(7, 8, 9, 9).noCull()
    				.add(8.6f, 3.8f, 9.1f, 8.6f, 4.6f, 10.3f).rotate(8, 6, 5.2f, Facing.Axis.X, -45, false)
    					.w("tripwire_hook").uv(7, 3, 9, 4).noCull()
    				.add(7.4f, 5.2f, 10, 8.8f, 6.8f, 14).rotate(8, 6, 14, Facing.Axis.X, 45, false)
    					.d().uv(7, 9, 9, 14).noCull()
    					.u().uv(7, 2, 9, 7).noCull()
    					.n().uv(7, 9, 9, 11).noCull()
    					.s().uv(7, 9, 9, 11).noCull()
    					.w().uv(2, 9, 7, 11).noCull()
    					.e().uv(9, 9, 14, 11).noCull()
    				.add(6, 1, 14, 10, 9, 16)
    					.d().uv(6, 14, 10, 16).noCull()
    					.u().uv(6, 0, 10, 2).noCull()
    					.n().uv(6, 7, 10, 15)
    					.s().uv(6, 7, 10, 15).noCull()
    					.w().uv(0, 7, 2, 15).noCull()
    					.e().uv(14, 7, 16, 15).noCull();
    	}
    	return model.rotate(ModelRotation.getNorthRot(state.getValue(FACING)));
    }
	
	protected Item getItemToRegister() {
		return new ItemBlock(this, "tripwire_hook", false);
	}
}
