package common.item.block;

import common.block.Block;
import common.color.TextColor;
import common.entity.Entity;
import common.entity.npc.EntityNPC;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.item.CheatTab;
import common.item.Item;
import common.item.ItemStack;
import common.model.Model;
import common.model.ModelProvider;
import common.model.Transforms;
import common.tags.TagObject;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.util.Facing;
import common.world.State;
import common.world.World;

public class ItemBlock extends Item
{
    protected final Block block;
    protected final String flatTexture;

    public ItemBlock(Block block, String flatTexture)
    {
        this.block = block;
        this.flatTexture = flatTexture;
    }

    public ItemBlock(Block block, String flatTexture, boolean item)
    {
        this(block, (item ? "items" : "blocks") + "/" + flatTexture);
    }

    public ItemBlock(Block block)
    {
        this(block, null);
    }

    public ItemBlock setDisplay(String unlocalizedName)
    {
        super.setDisplay(unlocalizedName);
        return this;
    }

    public ItemBlock setColor(TextColor color)
    {
        super.setColor(color);
        return this;
    }

    /**
     * Called when a Block is right-clicked with this Item
     */
    public boolean onItemUse(ItemStack stack, EntityNPC playerIn, World worldIn, BlockPos pos, Facing side, float hitX, float hitY, float hitZ)
    {
        State iblockstate = worldIn.getState(pos);
        Block block = iblockstate.getBlock();

        if (!block.isReplaceable(worldIn, pos))
        {
            pos = pos.offset(side);
        }

        if (stack.size == 0)
        {
            return false;
        }
        else if (!playerIn.canPlayerEdit(pos, side, stack))
        {
            return false;
        }
        else if (worldIn.canBlockBePlaced(this.block, pos, false, side, (Entity)null, stack))
        {
            State iblockstate1 = this.block.onBlockPlaced(worldIn, pos, side, hitX, hitY, hitZ, playerIn);

            if (worldIn.setState(pos, iblockstate1, 3))
            {
                iblockstate1 = worldIn.getState(pos);

                if (iblockstate1.getBlock() == this.block)
                {
                    setTileEntityNBT(worldIn, playerIn, pos, stack);
                    this.block.onBlockPlacedBy(worldIn, pos, iblockstate1, playerIn, stack);
                }

                worldIn.playSound(this.block.sound.getPlaceSound(), (double)((float)pos.getX() + 0.5F), (double)((float)pos.getY() + 0.5F), (double)((float)pos.getZ() + 0.5F), 1.0F);
                --stack.size;
            }

            return true;
        }
        else
        {
            return false;
        }
    }

    public static boolean setTileEntityNBT(World worldIn, EntityNPC pos, BlockPos stack, ItemStack p_179224_3_)
    {
//        Server server = Server.getServer();
//
//        if (server == null)
//        {
//            return false;
//        }
//        else
//        {
        if (p_179224_3_.hasTagCompound() && p_179224_3_.getTagCompound().hasObject("BlockEntityTag"))
        {
            TileEntity tileentity = worldIn.getTileEntity(stack);

            if (tileentity != null)
            {
                if (!worldIn.client /* && tileentity.hasSpecialNBT() */ && !pos.connection.isAdmin())
                {
                    return false;
                }

                TagObject nbttagcompound = new TagObject();
                TagObject nbttagcompound1 = nbttagcompound.copy();
                tileentity.writeTags(nbttagcompound);
                TagObject nbttagcompound2 = p_179224_3_.getTagCompound().getObject("BlockEntityTag");
                nbttagcompound.merge(nbttagcompound2);
                nbttagcompound.setInt("x", stack.getX());
                nbttagcompound.setInt("y", stack.getY());
                nbttagcompound.setInt("z", stack.getZ());

                if (!nbttagcompound.equals(nbttagcompound1))
                {
                    tileentity.readTags(nbttagcompound);
                    tileentity.markDirty();
                    return true;
                }
            }
        }

        return false;
//        }
    }

    public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, Facing side, EntityNPC player, ItemStack stack)
    {
        Block block = worldIn.getState(pos).getBlock();

        if (block == Blocks.snow_layer)
        {
            side = Facing.UP;
        }
        else if (!block.isReplaceable(worldIn, pos))
        {
            pos = pos.offset(side);
        }

        return worldIn.canBlockBePlaced(this.block, pos, false, side, (Entity)null, stack);
    }

    /**
     * Returns the unlocalized name of this item. This version accepts an ItemStack so different stacks can have
     * different names based on their damage or NBT.
     */
    public String getDisplay(ItemStack stack)
    {
        return this.block.getDisplay();
    }

//    /**
//     * Returns the unlocalized name of this item.
//     */
//    public String getUnlocalizedName()
//    {
//        return this.block.getUnlocalizedName();
//    }

    /**
     * gets the tab this item is displayed on
     */
    public CheatTab getTab()
    {
        return this.block.getTab();
    }

    public Block getBlock()
    {
        return this.block;
    }
    
//    public Set<String> getValidTags() {
//    	return Sets.newHashSet("BlockEntityTag");
//    }
//    
//    protected boolean validateNbt(NBTTagCompound tag) {
//    	if(tag.hasKey("BlockEntityTag")) {
//    		if(!tag.hasTag("BlockEntityTag")) {
//        		return false;
//        	}
//    	}
//    	return true;
//    }
    
    public boolean isMagnetic() {
    	return this.block.isMagnetic();
    }

    public Transforms getTransform() {
    	return this.flatTexture != null ? super.getTransform() : this.block.getTransform();
    }

    public Model getModel(ModelProvider provider, String name) {
    	return this.flatTexture != null ? provider.getModel(this.getTransform(), !this.flatTexture.isEmpty() ? this.flatTexture : 
    			this.block.getModel(provider, 
    			BlockRegistry.getNameFromBlock(this.block).toString(), this.block.getState()).getPrimary() /* "blocks/" + name */) : 
    			provider.getModel(this.block.getModel(provider, 
    			BlockRegistry.getNameFromBlock(this.block).toString(), this.block.getState()), this.getTransform());
    }
}
