import { CellFilterMultiply } from "../../../src/generation/filtering/numeric/math/algebra/CellFilterMultiply.js";
import { CellFilterSimplexNoise } from "../../../src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js";
import { CellFilterLiteralFloat } from "../../../src/generation/filtering/numeric/CellFilterLiteralFloat.js";
import { CellFilterGaussianBlur } from "../../../src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js";
import { CellFilterStep } from "../../../src/generation/filtering/numeric/math/CellFilterStep.js";
import {
    CellFilterSampleLayerLinear
} from "../../../src/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js";
import { MirGridLayers } from "../grid/MirGridLayers.js";
import { CellFilterMax2 } from "../../../src/generation/filtering/numeric/math/CellFilterMax2.js";
import { CellFilterSmoothStep } from "../../../src/generation/filtering/numeric/math/CellFilterSmoothStep.js";
import { MohGridLayers } from "../../../../../generator/MohGridLayers.js";
import { CellFilterDilate } from "../../../src/generation/filtering/numeric/complex/CellFilterDilate.js";
import { CellFilterCache } from "../../../src/generation/filtering/numeric/CellFilterCache.js";
import { DEG_TO_RAD } from "../../../src/core/math/DEG_TO_RAD.js";

const fReadHeight = CellFilterSampleLayerLinear.from(MirGridLayers.Heights);

const WATER_MASK = CellFilterStep.from(fReadHeight, CellFilterLiteralFloat.from(-0.05));
const CURVATURE = CellFilterSampleLayerLinear.from(MohGridLayers.Curvature);
const SLOPE = CellFilterSampleLayerLinear.from(MohGridLayers.Slope);


export const SampleGroundMoistureFilter = CellFilterMax2.from(
    // add regional variation in relative moisture
    CellFilterMultiply.from(
        CellFilterMultiply.from(
            CellFilterSimplexNoise.fractal(2, 100, 1263),
            CellFilterMax2.from(
                // flat areas are more likely to be keep moisture
                CellFilterSmoothStep.from(
                    CellFilterLiteralFloat.from(40 * DEG_TO_RAD),
                    CellFilterLiteralFloat.from(10 * DEG_TO_RAD),
                    SLOPE
                ),
                // water accumulates in crevices
                CellFilterSmoothStep.from(
                    CellFilterLiteralFloat.from(0.0),
                    CellFilterLiteralFloat.from(0.1),
                    CURVATURE
                )
            )
        ),

        CellFilterLiteralFloat.from(0.5)
    ),

    //simulate water diffusion from lakes/rivers/sees into the nearby ground
    CellFilterGaussianBlur.from(
        CellFilterCache.from(
            CellFilterMax2.from(
                WATER_MASK,
                CellFilterMultiply.from(
                    CellFilterGaussianBlur.from(
                        CellFilterCache.from(CellFilterDilate.from(WATER_MASK)),
                        5,
                        5,
                        1
                    ),
                    /*
                     Diffuse more along surfaces with low slope (flat)
                     NOTE: we don't have to worry about directly of the slope, as water always starts at 0, so any slope will be positive in effect
                     */
                    CellFilterSmoothStep.from(
                        CellFilterLiteralFloat.from(35 * DEG_TO_RAD),
                        CellFilterLiteralFloat.from(10 * DEG_TO_RAD),
                        SLOPE
                    ),
                )
            )
        ),
        3, 3, 1
    )
);

