APFS = "030" # WBMap:APFS
global version = APFS

include("WBInclusions")

mutable struct Foo
   links::Array{String}
   count::Int32
end
global NONEXISTENT = Foo(["NONEXISTENT"],0)

global allFiles = Dict{String, Foo}()

global excludeds = ["XXXTree.html", "XXXRTree.html", 
            "XXXXTree.html", "IndexOfSubjects.html", "Images.html"]   # "NYNYT.html"] 
global lim = 0
global totLinks = 0
global totExtLinks = 0
global totFiles = 1
global bottomLevel = []
global atLevels = [[1,1],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],
            [0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],
            [0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]]
global totItems = 1
global ignoreds = [
    "JUNK.html",
    "JUNK2.html",
    "JUNK6.html",
    "JUNK7.html",
    "JUNK10.html"
]

try
    global errId = 1
    a = readdir()
    global errId = 2
    for itm in a
        if findfirst(".html", itm) == nothing || itm in ignoreds   #     || itm == "JSource.html"
            continue
        end
        global totFiles += 1
        global errId = 3
        sres = RRead(itm, "clean")       
        x = findall(r" href=\"[a-zA-Z0-9\-_]+!?\.html", sres)

        global totLinks += length(x)
        global totExtLinks += length(findall(r" href=\"https?://", sres))

        if itm in excludeds
            continue
        end

        y = []
        for z in x
            w = sres[z]
            w = w[8:length(w)]
            if w in y || w == itm
                 continue
            end
            push!(y, w)
        end
        allFiles[itm] = Foo(sort(y), 0)
    end
catch ex
    s = string(ex)  
    if length(s) > 200
        s = s[1:200] * "..."
    end
    println("\n      Failure[" * string(errId) * "]: ", typeof(ex), ".\n", s);
    exit(16)
end
println("allFiles: " , length(allFiles))
SEEDFILE = length(ARGS) > 0 ? ARGS[1] : "index"

allKeys = sort(collect(keys(allFiles)))
if !(SEEDFILE * ".html" in allKeys)
    println("\n Root file does not exist: \"" * SEEDFILE * "\".")
    exit(16)
end

allFiles[SEEDFILE * ".html"].count = 1

global iterations = 0
while iterations < 20
    local allFiles_NEW = Dict{String, Foo}()
    for Key in allKeys
        allFiles_NEW[Key] = Foo(copy(allFiles[Key].links),allFiles[Key].count )
    end
    global iterations += 1
    if iterations > 18
        println("Overflow!")
        exit(16)
    end
    local thisLevel = []
    local nextLevel = []
    local addedInNextLevel = []        
    for Key in allKeys
        if allFiles[Key].count == 1
            push!(thisLevel, Key)
            push!(nextLevel, Key)
            for itm in allFiles[Key].links
                if itm in excludeds
                    continue
                end
                if get!(allFiles,itm,NONEXISTENT) == NONEXISTENT
                    println("Key error: \"" * Key * "\" > \"" * itm * "\"")
                    exit(16)
                end

                if allFiles_NEW[itm].count == 0
                    allFiles_NEW[itm].count = 1
                    push!(addedInNextLevel, itm)
                    push!(nextLevel, itm)
                    atLevels[iterations + 1][1] += 1
                    global totItems += 1
                    atLevels[iterations + 1][2] = totItems
                    
                end
            end
        end 
    end
    if length(thisLevel) == length(nextLevel)
        break
    end
    global bottomLevel = addedInNextLevel
    global allFiles = allFiles_NEW
end

println("\n  WBMap v" * version * "\n  totFiles: " * string(totFiles) * "           iterations: " * string(iterations) *  
                ".\n  totLinks: " * string(totLinks) * ":" * string(totExtLinks) *
                "    Root: \"" * SEEDFILE * "\"\n")

global THEREST = ""
global disconnecteds = 0
for Key in allKeys
    itm = allFiles[Key]
    if itm.count == 0 && !(Key in ["WWWTree.html","WWWRTree.html","WWWXTree.html"])
        global THEREST *= "\n " * Key
        global disconnecteds += 1
    end
end

global atLevels2 = []
for i in 1 : 100
    if atLevels[i] == [0,0]
        break
    end
    x = [i, atLevels[i][1], atLevels[i][2]]
    push!(atLevels2, x) 
end
tt = atLevels2[length(atLevels2)][3]
ttt = []
for i in 1 : length(atLevels2)
    alti = atLevels2[i]
    #altk = string((alti[3]/tt) * 100 + 0.005) * "0000"
    altj = replace(string((alti[3]/tt) * 100 + 0.005) * "0000", r"\.([0-9]{2})[0-9]+" => s".\1%")
    push!(ttt, [alti[1], alti[2], alti[3], altj])
end
shit = ttt[length(ttt)][3]
ttt = replace(string(ttt), "\"" => "")
ttt = ttt[5:length(ttt) - 1]
ttt = replace(ttt, r"Any\[([0-9]+)," => s"[\1:")
ttt = replace(ttt, r"\[([0-9]+)\: ([0-9]+), ([0-9]+)," => s"\1: [\2, \3.")
ttt = replace(ttt, ".00" => "")
ttt = replace(ttt, r", (5|9|13|17|21|25|29):" => s",\n    \1:")
ttt = replace(ttt, r"(\d+\.?\d*%)" => SubstitutionString(HI_YELLOW * "\\1" * HI_END))
println(" ", iterations, "  " , ttt, "  ", atLevels2[length(atLevels2)][2] + 
            length(excludeds) + disconnecteds, " " , shit, "\n " , THEREST * "\n\n", bottomLevel)