package common.pathfinding;

import common.entity.Entity;
import common.util.ExtMath;
import common.util.IntHashMap;

public abstract class NodeProcessor
{
    protected PathCache blockaccess;
    protected IntHashMap<PathPoint> pointMap = new IntHashMap();
    protected int entitySizeX;
    protected int entitySizeY;
    protected int entitySizeZ;

    public void initProcessor(PathCache iblockaccessIn, Entity entityIn)
    {
        this.blockaccess = iblockaccessIn;
        this.pointMap.clearMap();
        this.entitySizeX = ExtMath.floorf(entityIn.width + 1.0F);
        this.entitySizeY = ExtMath.floorf(entityIn.height + 1.0F);
        this.entitySizeZ = ExtMath.floorf(entityIn.width + 1.0F);
    }

    /**
     * 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()
    {
    }

    /**
     * Returns a mapped point or creates and adds one
     */
    protected PathPoint openPoint(int x, int y, int z)
    {
        int i = PathPoint.makeHash(x, y, z);
        PathPoint pathpoint = (PathPoint)this.pointMap.lookup(i);

        if (pathpoint == null)
        {
            pathpoint = new PathPoint(x, y, z);
            this.pointMap.addKey(i, pathpoint);
        }

        return pathpoint;
    }

    /**
     * Returns given entity's position as PathPoint
     */
    public abstract PathPoint getPathPointTo(Entity entityIn);

    /**
     * Returns PathPoint for given coordinates
     */
    public abstract PathPoint getPathPointToCoords(Entity entityIn, double x, double y, double target);

    public abstract int findPathOptions(PathPoint[] pathOptions, Entity entityIn, PathPoint currentPoint, PathPoint targetPoint, float maxDistance);
}
