// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.procedurallib.logic.cell;

import com.hypixel.hytale.procedurallib.logic.point.PointConsumer;
import com.hypixel.hytale.procedurallib.logic.ResultBuffer;
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.DensityPointEvaluator;
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.JitterPointEvaluator;
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.NormalPointEvaluator;
import com.hypixel.hytale.procedurallib.condition.IDoubleCondition;
import com.hypixel.hytale.procedurallib.condition.IIntCondition;
import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.PointEvaluator;

public class BorderDistanceFunction implements CellDistanceFunction
{
    protected final CellDistanceFunction distanceFunction;
    @Nonnull
    protected final PointEvaluator cellEvaluator;
    @Nonnull
    protected final PointEvaluator borderEvaluator;
    @Nonnull
    protected final IIntCondition density;
    
    public BorderDistanceFunction(final CellDistanceFunction distanceFunction, @Nonnull final PointEvaluator borderEvaluator, final IDoubleCondition density) {
        this.distanceFunction = distanceFunction;
        this.borderEvaluator = borderEvaluator;
        this.cellEvaluator = new JitterPointEvaluator(NormalPointEvaluator.EUCLIDEAN, borderEvaluator.getJitter());
        this.density = DensityPointEvaluator.getDensityCondition(density);
    }
    
    @Override
    public double scale(final double value) {
        return this.distanceFunction.scale(value);
    }
    
    @Override
    public double invScale(final double value) {
        return this.distanceFunction.invScale(value);
    }
    
    @Override
    public int getCellX(final double x, final double y) {
        return this.distanceFunction.getCellX(x, y);
    }
    
    @Override
    public int getCellY(final double x, final double y) {
        return this.distanceFunction.getCellY(x, y);
    }
    
    @Override
    public void nearest2D(final int seed, final double x, final double y, final int cellX, final int cellY, @Nonnull final ResultBuffer.ResultBuffer2d buffer, final PointEvaluator pointEvaluator) {
        this.transition2D(seed, x, y, cellX, cellY, buffer, pointEvaluator);
    }
    
    @Override
    public void transition2D(final int seed, final double x, final double y, int cellX, int cellY, @Nonnull final ResultBuffer.ResultBuffer2d buffer, final PointEvaluator pointEvaluator) {
        this.distanceFunction.nearest2D(seed, x, y, cellX, cellY, buffer, this.cellEvaluator);
        if (!this.density.eval(buffer.hash)) {
            buffer.distance = 0.0;
            return;
        }
        cellX = buffer.ix;
        cellY = buffer.iy;
        buffer.ix2 = cellX;
        buffer.iy2 = cellY;
        buffer.x2 = buffer.x;
        buffer.y2 = buffer.y;
        buffer.distance = Double.POSITIVE_INFINITY;
        buffer.distance2 = Double.POSITIVE_INFINITY;
        final int dx = (this.borderEvaluator.getJitter().getMaxX() > 0.5) ? 2 : 1;
        for (int dy = (this.borderEvaluator.getJitter().getMaxY() > 0.5) ? 2 : 1, cy = cellY - dy; cy <= cellY + dy; ++cy) {
            for (int cx = cellX - dx; cx <= cellX + dx; ++cx) {
                this.distanceFunction.evalPoint2(seed, x, y, cx, cy, buffer, this.borderEvaluator);
            }
        }
    }
    
    @Override
    public void nearest3D(final int seed, final double x, final double y, final double z, final int cellX, final int cellY, final int cellZ, final ResultBuffer.ResultBuffer3d buffer, final PointEvaluator pointEvaluator) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void transition3D(final int seed, final double x, final double y, final double z, final int cellX, final int cellY, final int cellZ, final ResultBuffer.ResultBuffer3d buffer, final PointEvaluator pointEvaluator) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void evalPoint(final int seed, final double x, final double y, final int cellX, final int cellY, final ResultBuffer.ResultBuffer2d buffer, final PointEvaluator pointEvaluator) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void evalPoint2(final int seed, final double x, final double y, final int cellX, final int cellY, final ResultBuffer.ResultBuffer2d buffer, final PointEvaluator pointEvaluator) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void evalPoint(final int seed, final double x, final double y, final double z, final int cellX, final int cellY, final int cellZ, final ResultBuffer.ResultBuffer3d buffer, final PointEvaluator pointEvaluator) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void evalPoint2(final int seed, final double x, final double y, final double z, final int cellX, final int cellY, final int cellZ, final ResultBuffer.ResultBuffer3d buffer, final PointEvaluator pointEvaluator) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public <T> void collect(final int originalSeed, final int seed, final int minX, final int minY, final int maxX, final int maxY, final ResultBuffer.Bounds2d bounds, final T ctx, final PointConsumer<T> collector, final PointEvaluator pointEvaluator) {
        this.distanceFunction.collect(originalSeed, seed, minX, minY, maxX, maxY, bounds, ctx, collector, pointEvaluator);
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "BorderDistanceFunction{distanceFunction=" + String.valueOf(this.distanceFunction) + ", cellEvaluator=" + String.valueOf(this.cellEvaluator) + ", borderEvaluator=" + String.valueOf(this.borderEvaluator) + ", density=" + String.valueOf(this.density);
    }
}
