package common.material;

public class Material
{
    public static final Material air = new MaterialTransparent();
    public static final Material grass = new Material();
    public static final Material ground = new Material();
    public static final Material wood = (new Material()).setBurning();
    public static final Material rock = (new Material()).setRequiresTool();
    public static final Material iron = (new Material()).setRequiresTool();
    public static final Material anvil = (new Material()).setRequiresTool().setImmovableMobility();
    public static final Material water = (new MaterialColdFluid()).setNoPushMobility();
    public static final Material coldFluid = (new MaterialColdFluid()).setNoPushMobility();
    public static final Material lava = (new MaterialHotFluid()).setNoPushMobility();
    public static final Material hotFluid = (new MaterialHotFluid()).setNoPushMobility();
    public static final Material leaves = (new Material()).setBurning().setTranslucent().setNoPushMobility();
    public static final Material plants = (new MaterialLogic()).setNoPushMobility();
    public static final Material vine = (new MaterialLogic()).setBurning().setNoPushMobility().setReplaceable();
    public static final Material sponge = new Material();
    public static final Material cloth = (new Material()).setBurning();
    public static final Material fire = (new MaterialTransparent()).setNoPushMobility();
    public static final Material sand = new Material();
    public static final Material circuits = (new MaterialLogic()).setNoPushMobility();
    public static final Material carpet = (new MaterialLogic()).setBurning();
    public static final Material glass = (new Material()).setTranslucent(); // .setAdventureModeExempt();
    public static final Material redstoneLight = (new Material()); // .setAdventureModeExempt();
    public static final Material tnt = (new Material()).setBurning().setTranslucent();
    public static final Material coral = (new Material()).setNoPushMobility();
    public static final Material ice = (new Material()).setTranslucent(); // .setAdventureModeExempt();
    public static final Material packedIce = (new Material()); // .setAdventureModeExempt();
    public static final Material snow = (new MaterialLogic()).setReplaceable().setTranslucent().setRequiresTool().setNoPushMobility();

    /** The material for crafted snow. */
    public static final Material craftedSnow = (new Material()).setRequiresTool();
    public static final Material cactus = (new Material()).setTranslucent().setNoPushMobility();
    public static final Material clay = new Material();
    public static final Material gourd = (new Material()).setNoPushMobility();
    public static final Material dragonEgg = (new Material()).setNoPushMobility();
    public static final Material portal = (new MaterialPortal()).setImmovableMobility();
    public static final Material cake = (new Material()).setNoPushMobility();
    public static final Material web = (new Material()
    {
        public boolean blocksMovement()
        {
            return false;
        }
    }).setRequiresTool().setNoPushMobility();

    /** Pistons' material. */
    public static final Material piston = (new Material()).setImmovableMobility();
//    public static final Material barrier = (new Material()).setRequiresTool().setImmovableMobility();

    /** Bool defining if the block can burn or not. */
    private boolean canBurn;

    /**
     * Determines whether blocks with this material can be "overwritten" by other blocks when placed - eg snow, vines
     * and tall grass.
     */
    private boolean replaceable;

    /** Indicates if the material is translucent */
    private boolean isTranslucent;

//    /** The color index used to draw the blocks of this material on maps. */
//    private final MapColor materialMapColor;

    /**
     * Determines if the material can be harvested without a tool (or with the wrong tool)
     */
    private boolean requiresNoTool = true;

    /**
     * Mobility information flag. 0 indicates that this block is normal, 1 indicates that it can't push other blocks, 2
     * indicates that it can't be pushed.
     */
    private int mobilityFlag;
//    private boolean isAdventureModeExempt;

//    public Material(MapColor color)
//    {
////        this.materialMapColor = color;
//    }

    /**
     * Returns if blocks of these materials are liquids.
     */
    public boolean isLiquid()
    {
        return false;
    }
    
    public boolean isColdLiquid()
    {
        return false;
    }
    
    public boolean isHotLiquid()
    {
        return false;
    }

    /**
     * Returns true if the block is a considered solid. This is true by default.
     */
    public boolean isSolid()
    {
        return true;
    }

    /**
     * Will prevent grass from growing on dirt underneath and kill any grass below it if it returns true
     */
    public boolean blocksLight()
    {
        return true;
    }

    /**
     * Returns if this material is considered solid or not
     */
    public boolean blocksMovement()
    {
        return true;
    }

    /**
     * Marks the material as translucent
     */
    private Material setTranslucent()
    {
        this.isTranslucent = true;
        return this;
    }

    /**
     * Makes blocks with this material require the correct tool to be harvested.
     */
    protected Material setRequiresTool()
    {
        this.requiresNoTool = false;
        return this;
    }

    /**
     * Set the canBurn bool to True and return the current object.
     */
    protected Material setBurning()
    {
        this.canBurn = true;
        return this;
    }

    /**
     * Returns if the block can burn or not.
     */
    public boolean getCanBurn()
    {
        return this.canBurn;
    }

    /**
     * Sets {@link #replaceable} to true.
     */
    public Material setReplaceable()
    {
        this.replaceable = true;
        return this;
    }

    /**
     * Returns whether the material can be replaced by other blocks when placed - eg snow, vines and tall grass.
     */
    public boolean isReplaceable()
    {
        return this.replaceable;
    }

    /**
     * Indicate if the material is opaque
     */
    public boolean isOpaque()
    {
        return this.isTranslucent ? false : this.blocksMovement();
    }

    /**
     * Returns true if the material can be harvested without a tool (or with the wrong tool)
     */
    public boolean isToolNotRequired()
    {
        return this.requiresNoTool;
    }

    /**
     * Returns the mobility information of the material, 0 = free, 1 = can't push but can move over, 2 = total
     * immobility and stop pistons.
     */
    public int getMaterialMobility()
    {
        return this.mobilityFlag;
    }

    /**
     * This type of material can't be pushed, but pistons can move over it.
     */
    protected Material setNoPushMobility()
    {
        this.mobilityFlag = 1;
        return this;
    }

    /**
     * This type of material can't be pushed, and pistons are blocked to move.
     */
    protected Material setImmovableMobility()
    {
        this.mobilityFlag = 2;
        return this;
    }

//    protected Material setAdventureModeExempt()
//    {
//        this.isAdventureModeExempt = true;
//        return this;
//    }

//    /**
//     * Retrieves the color index of the block. This is is the same color used by vanilla maps to represent this block.
//     */
//    public MapColor getMaterialMapColor()
//    {
//        return this.materialMapColor;
//    }
}
