#--------------------------------------------------------------------------------------------------
# Functions on [0, 1] tests
#--------------------------------------------------------------------------------------------------
using Test
using Hensel

#--------------------------------------------------------------------------------------------------

@test Hensel.pIndex(0.5     , 2) == 1
@test Hensel.pIndex(0.4999  , 2) == 0
@test Hensel.pIndex(0.499999, 3) == 1
@test Hensel.pIndex(0.699999, 3) == 2

@test Hensel.hVector(0.5, 2, 3)   == [1, 0, 0]
@test Hensel.hVector(0.999, 2, 3) == [1, 1, 1]
@test Hensel.hVector(0.499, 2, 3) == [0, 1, 1]
@test Hensel.hVector(0.3, 2, 3)   == [0, 1, 0]


@test Hensel.iValue([1, 1, 0], 2) == 3
@test Hensel.iValue([1, 0, 1], 2) == 5
@test Hensel.iValue([1, 1, 1], 2) == 7

@test Hensel.hVector(0, 2, 3) == [0, 0, 0]
@test Hensel.hVector(1, 2, 3) == [1, 0, 0]
@test Hensel.hVector(3, 2, 3) == [1, 1, 0]
@test Hensel.hVector(5, 2, 3) == [1, 0, 1]
@test Hensel.hVector(7, 2, 3) == [1, 1, 1]

@test Hensel.hVector(0.0, 2, 3) == [0, 0, 0]
@test Hensel.hVector(0.9, 2, 3) == [1, 1, 1] 
@test Hensel.hVector(1.0, 2, 3) == [1, 1, 1]
@test Hensel.hVector(0.0, 7, 3) == [0, 0, 0]
@test Hensel.hVector(0.005, 7, 3) == [0, 0, 1]
@test Hensel.hVector(0.995, 7, 3) == [6, 6, 5]
@test Hensel.hVector(1.0, 7, 3) == [6, 6, 6]


@test ((x) -> Hensel.hVector(x, 2, 5)).(0:9) == [
    [0, 0, 0, 0, 0],
    [1, 0, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [1, 1, 0, 0, 0],
    [0, 0, 1, 0, 0],
    [1, 0, 1, 0, 0],
    [0, 1, 1, 0, 0],
    [1, 1, 1, 0, 0],
    [0, 0, 0, 1, 0],
    [1, 0, 0, 1, 0]
]
@test ((x) -> Hensel.hVector(x, 3, 5)).(0:9) == [
    [0, 0, 0, 0, 0],
    [1, 0, 0, 0, 0],
    [2, 0, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [1, 1, 0, 0, 0],
    [2, 1, 0, 0, 0],
    [0, 2, 0, 0, 0],
    [1, 2, 0, 0, 0],
    [2, 2, 0, 0, 0],
    [0, 0, 1, 0, 0] 
]
@test ((x) -> Hensel.hVector(x, 7, 5)).(0:9) == [
    [0, 0, 0, 0, 0],
    [1, 0, 0, 0, 0],
    [2, 0, 0, 0, 0],
    [3, 0, 0, 0, 0],
    [4, 0, 0, 0, 0],
    [5, 0, 0, 0, 0],
    [6, 0, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [1, 1, 0, 0, 0],
    [2, 1, 0, 0, 0]
]

@test ((x) -> Hensel.hVector(x, 2, 5)).([n/10.0 for n in 0:10]) == [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 1, 1],
    [0, 0, 1, 1, 0],
    [0, 1, 0, 0, 1],
    [0, 1, 1, 0, 0],
    [1, 0, 0, 0, 0],
    [1, 0, 0, 1, 1],
    [1, 0, 1, 1, 0],
    [1, 1, 0, 0, 1],
    [1, 1, 1, 0, 0],
    [1, 1, 1, 1, 1]
]
@test ((x) -> Hensel.hVector(x, 3, 5)).([n/10.0 for n in 0:10]) == [
    [0, 0, 0, 0, 0],
    [0, 0, 2, 2, 0],
    [0, 1, 2, 1, 0],
    [0, 2, 2, 0, 0],
    [1, 0, 1, 2, 1],
    [1, 1, 1, 1, 1],
    [1, 2, 1, 0, 1],
    [2, 0, 0, 2, 2],
    [2, 1, 0, 1, 2],
    [2, 2, 0, 0, 2],
    [2, 2, 2, 2, 2]
]
@test ((x) -> Hensel.hVector(x, 7, 5)).([n/10.0 for n in 0:10]) == [
    [0, 0, 0, 0, 0],
    [0, 4, 6, 2, 0],
    [1, 2, 5, 4, 1],
    [2, 0, 4, 6, 2],
    [2, 5, 4, 1, 2],
    [3, 3, 3, 3, 3],
    [4, 1, 2, 5, 4],
    [4, 6, 2, 0, 4],
    [5, 4, 1, 2, 5],
    [6, 2, 0, 4, 6],
    [6, 6, 6, 6, 6]
]

@test ((x) -> Hensel.rValue(Hensel.hVector(x, 2, 5), 2)).(0:9) == [
    0.015625,
    0.515625,
    0.265625,
    0.765625,
    0.140625,
    0.640625,
    0.390625,
    0.890625,
    0.078125,
    0.578125
]
@test ((x) -> Hensel.rValue(Hensel.hVector(x, 3, 5), 5)).(0:9) == [
    0.00016,
    0.20015999999999998,
    0.40015999999999996,
    0.04016,
    0.24016,
    0.44016,
    0.08016,
    0.28016,
    0.48016,
    0.00816,
]
@test ((x) -> Hensel.rValue(Hensel.hVector(x, 7, 5), 7)).(0:9) == [
    2.9749509133099306e-5,
    0.14288689236627597,
    0.2857440352234188,
    0.4286011780805617,
    0.5714583209377045,
    0.7143154637948473,
    0.8571726066519902,
    0.02043791277443922,
    0.16329505563158206,
    0.30615219848872494
]

# -----------------------------------------------------------------

function hTest(x, p, sz)
    @test Hensel.hVector(Hensel.rValue(Hensel.hVector(x, p, sz), p), p, sz) == Hensel.hVector(x, p, sz)
end

hTest(0.5, 2, 3)
hTest(0.5, 3, 4)
hTest(0.009, 3, 14)
hTest(0.333, 3, 14)
hTest(0.999, 3, 14)

dist(x, p, sz) = abs(Hensel.rValue(Hensel.hVector(x, p, sz), p) - x)

function dTest(x, p, sz)
    dist(x, p, sz) <= 1/p^(sz)
end

dTest(0.5, 2, 3)
dTest(0.5, 3, 4)
dTest(0.009, 3, 14)
dTest(0.333, 3, 14)
dTest(0.999, 3, 14)


#--------------------------------------------------------------------------------------------------
