using Printf

function bipartition(arr::Array{T}, x1::Int, x2::Int, v::T) :: Int where {T}
    # @printf("Bipartition %s (%d,%d) with value  %s\n", arr, x1, x2, v)
    t1 = x1
    t2 = x2

    if length(arr) <= 0 || v < arr[t1]
        return t1
    end

    if v > arr[t2]
        # @printf("It's bigger than last elem, appending to the end of vector")
        return t2 + 1
    end

    t::Int = t1
    # @printf("Starting bipartition loop\n")
    while t1 < t2 - 1
        # @printf("(%d, %d) - %s\n", t1, t2, v)
        t = div(t1 + t2, 2)
        c = arr[t]
        # @printf("Round %d with val %s\n", t, c)
        if c <= v
            t1 = t
        else
            t2 = t
        end
    end

    # @printf("T1: %d, T2: %d\n", t1, t2)

    if t1 == t2
        return t1
    else
        return t2
    end

end

struct BTree{T}
    # NOTE: assumption that children size is always +1 than size of children
    level :: Int # how many max elements can Btree have in one node, should be even for simplifying merge / split
    values:: Vector{T} # only root can have smaller number of elements that level / 2
    children::Vector{Union{Nothing, BTree{T}}}
end

function add_sorted(arr::Vector{T}, v::T) :: Int where {T}
    idx :: Int = bipartition(arr, 1, length(arr), v)
    # println("Array " * string(arr) * " to add elem " * string(v))
    # println("Index for adding: " * string(idx))
    sizehint!(arr, max(length(v)+1, idx))
    # arr[idx] = v
    insert!(arr, idx, v)
    return idx
end

function find_node(node:: BTree{T}, value::T) :: Tuple{Bool,BTree{T}} where {T}
    x :: T
    q :: BTree{T} = node
    while true
        x = bipartition(q.values, 1, len(q.values), value)
        c = q.children[x]
        if c == Nothing
            return (q.values[x] == value, x)
        else
           q = c 
        end
    end
end

function BTree_add(node::BTree{T}, value::T) :: BTree{T} where {T}
    print("Result: ", string(find_node(node, value)))
    return node
end

println("Provide number line by line until double enters: ")

s::String = ""
# v::Vector{Int} = []
q :: BTree{Int} = BTree{Int}(4, [], [])
while true
    global s = readline(keep=false)

    if length(s) == 0
        break
    end

    n = parse(Int, s)

    # add_sorted(v, n)
    BTree_add(q, 1)
    println("Vector: " * string(v))
end

# v :: Vector{Int} = [ 1, 2, 4, 5 ]
# println("V: " * string(v))
# idx = bipartition(v, 1, length(v), 3)
# println("Index: " * string(idx))

