package me.km.blocks;

import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.state.StateContainer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

public class BlockLantern extends DirectionalBlock {
    protected static final VoxelShape HANGING_AABB = Block.makeCuboidShape(3.0, 2.0, 3.0, 13.0, 16.0, 13.0);
    protected static final VoxelShape STANDING_AABB = Block.makeCuboidShape(3.0, 0.0, 3.0, 13.0, 12.0, 13.0);

    protected static final VoxelShape TORCH_NORTH_AABB = Block.makeCuboidShape(3.0, 0.0, 6.0, 13.0, 16.0, 16.0);
    protected static final VoxelShape TORCH_SOUTH_AABB = Block.makeCuboidShape(3.0, 0.0, 0.0, 13.0, 16.0, 10.0);
    protected static final VoxelShape TORCH_WEST_AABB = Block.makeCuboidShape(6.0, 0.0, 3.0, 16.0, 16.0, 13.0);
    protected static final VoxelShape TORCH_EAST_AABB = Block.makeCuboidShape(0, 0.0, 3.0, 10.0, 16.0, 13.0);

    protected String name;

    public BlockLantern(String name) {
        super(Properties.create(Material.MISCELLANEOUS).doesNotBlockMovement().hardnessAndResistance(0.0f).lightValue(14).sound(SoundType.METAL));
        this.setRegistryName(name);
        this.setDefaultState(this.stateContainer.getBaseState().with(FACING, Direction.UP));
    }

    @Override
    public VoxelShape getShape(BlockState state, IBlockReader w, BlockPos pos, ISelectionContext context) {
        switch(state.get(FACING)) {
            case UP:
                return STANDING_AABB;
            case DOWN:
                return HANGING_AABB;
            case EAST:
                return TORCH_EAST_AABB;
            case WEST:
                return TORCH_WEST_AABB;
            case SOUTH:
                return TORCH_SOUTH_AABB;
            case NORTH:
                return TORCH_NORTH_AABB;
        }
        return TORCH_NORTH_AABB;
    }

    @OnlyIn(Dist.CLIENT)
    @Override
    public void animateTick(BlockState state, World w, BlockPos pos, Random rand) {
        Direction face = state.get(FACING);
        double x = pos.getX() + 0.5;
        double y = pos.getY() + 0.7;
        double z = pos.getZ() + 0.5;
        switch(face) {
            case EAST:
            case NORTH:
            case WEST:
            case SOUTH:
                Direction oface = face.getOpposite();
                x += 0.1875 * oface.getXOffset();
                z += 0.1875 * oface.getZOffset();
                break;
            case DOWN:
                break;
            case UP:
                y -= 0.125d;
                break;
        }
        w.addParticle(ParticleTypes.SMOKE, x, y, z, 0.0, 0.0, 0.0);
        w.addParticle(ParticleTypes.FLAME, x, y, z, 0.0, 0.0, 0.0);
    }

    @Override
    public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) {
        return false;
    }

    @Override
    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(FACING);
    }

    @Override
    public boolean isValidPosition(BlockState state, IWorldReader w, BlockPos pos) {
        Direction direction = state.get(FACING);
        if(direction == Direction.UP) {
            return hasEnoughSolidSide(w, pos.down(), Direction.UP);
        }
        BlockPos blockpos = pos.offset(direction.getOpposite());
        BlockState blockstate = w.getBlockState(blockpos);
        return Block.hasSolidSide(blockstate, w, blockpos, direction);
    }

    @Override
    public BlockState getStateForPlacement(BlockItemUseContext context) {
        return this.getDefaultState().with(FACING, context.getFace());
    }

    @Override
    public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld w, BlockPos currentPos, BlockPos facingPos) {
        return state.get(FACING).getOpposite() == facing && !state.isValidPosition(w, currentPos) ? Blocks.AIR.getDefaultState() : state;
    }
}
