package common.pathfinding;

import common.block.Block;
import common.entity.Entity;
import common.util.BlockPos;
import common.util.ExtMath;
import common.util.Facing;

public class SwimNodeProcessor extends NodeProcessor
{
    public void initProcessor(PathCache iblockaccessIn, Entity entityIn)
    {
        super.initProcessor(iblockaccessIn, entityIn);
    }

    /**
     * This method is called when all nodes have been processed and PathEntity is created.
     *  {@link game.pathfinding.WalkNodeProcessor WalkNodeProcessor} uses this to change its field {@link
     * game.pathfinding.WalkNodeProcessor#avoidsWater avoidsWater}
     */
    public void postProcess()
    {
        super.postProcess();
    }

    /**
     * Returns given entity's position as PathPoint
     */
    public PathPoint getPathPointTo(Entity entityIn)
    {
        return this.openPoint(ExtMath.floord(entityIn.getEntityBoundingBox().minX), ExtMath.floord(entityIn.getEntityBoundingBox().minY + 0.5D), ExtMath.floord(entityIn.getEntityBoundingBox().minZ));
    }

    /**
     * Returns PathPoint for given coordinates
     */
    public PathPoint getPathPointToCoords(Entity entityIn, double x, double y, double target)
    {
        return this.openPoint(ExtMath.floord(x - (double)(entityIn.width / 2.0F)), ExtMath.floord(y + 0.5D), ExtMath.floord(target - (double)(entityIn.width / 2.0F)));
    }

    public int findPathOptions(PathPoint[] pathOptions, Entity entityIn, PathPoint currentPoint, PathPoint targetPoint, float maxDistance)
    {
        int i = 0;

        for (Facing enumfacing : Facing.values())
        {
            PathPoint pathpoint = this.getSafePoint(entityIn, currentPoint.xCoord + enumfacing.getFrontOffsetX(), currentPoint.yCoord + enumfacing.getFrontOffsetY(), currentPoint.zCoord + enumfacing.getFrontOffsetZ());

            if (pathpoint != null && !pathpoint.visited && pathpoint.distanceTo(targetPoint) < maxDistance)
            {
                pathOptions[i++] = pathpoint;
            }
        }

        return i;
    }

    /**
     * Returns a point that the entity can safely move to
     */
    private PathPoint getSafePoint(Entity entityIn, int x, int y, int z)
    {
        int i = this.findNonLiquid(entityIn, x, y, z);
        return i == -1 ? this.openPoint(x, y, z) : null;
    }

    private int findNonLiquid(Entity entityIn, int x, int y, int z)
    {
        BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();

        for (int i = x; i < x + this.entitySizeX; ++i)
        {
            for (int j = y; j < y + this.entitySizeY; ++j)
            {
                for (int k = z; k < z + this.entitySizeZ; ++k)
                {
                    Block block = this.blockaccess.getState(blockpos$mutableblockpos.set(i, j, k)).getBlock();

                    if (!block.getMaterial().isColdLiquid())
                    {
                        return 0;
                    }
                }
            }
        }

        return -1;
    }
}
