module AhornPersonalAdditivesMaker

using ..Ahorn, Maple

displayName = "Presets"
group = "Presets"

drawingLayers = Ahorn.Layer[]

toolsLayer = nothing
targetLayer = nothing

selectionPreviews = Set{Ahorn.SelectedObject}()

relevantRoom = Ahorn.loadedState.room
editDisabled = false

function cleanup()
    global relevantRoom = Ahorn.loadedState.room
    global editDisabled = false
    global targetLayer = nothing
    global toolsLayer = nothing
    global drawingLayers = Ahorn.Layer[]
end

function toolSelected(subTools::Ahorn.ListContainer, layers::Ahorn.ListContainer, materials::Ahorn.ListContainer)
    global relevantRoom = Ahorn.loadedState.room

    wantedLayer = get(Ahorn.persistence, "placements_layer", "entities")
    Ahorn.updateLayerList!(["entities", "triggers"], row -> row[1] == wantedLayer)

    Ahorn.redrawingFuncs["tools"] = drawSelections
    Ahorn.redrawLayer!(toolsLayer)

    updateMaterials!()
end

function layerSelected(list::Ahorn.ListContainer, materials::Ahorn.ListContainer, selected::String)
    global targetLayer = Ahorn.getLayerByName(drawingLayers, selected)
    Ahorn.persistence["placements_layer"] = selected

    updateMaterials!()
end

function materialSelected(list::Ahorn.ListContainer, selected::String)
    # how the fuck
    if !isdefined(AhornPersonalAdditivesMaker, :editDisabled)
        global editDisabled = false
        return
    end

    if !isempty(selected)
        if !editDisabled
            lib = getLibrary()
            presets = lib.getPresets()

            preset = get(presets, selected, nothing)
            if preset != nothing
                lib.displayPresetEditor(preset, toolsLayer, true)
            end
        else
            global editDisabled = false
            return
        end
        
        # why
        Timer(0) do timer
            Ahorn.unselectRow!(list)
        end
    end
end

function layersChanged(layers::Array{Ahorn.Layer, 1})
    wantedLayer = get(Ahorn.persistence, "placements_layer", "entities")

    global drawingLayers = layers
    global toolsLayer = Ahorn.getLayerByName(layers, "tools")
    global targetLayer = Ahorn.selectLayer!(layers, wantedLayer, "entities")
end

function mouseMotionAbs(x::Number, y::Number)
    updateSelectionPreviews(x, y)
end

function leftClickAbs(x::Number, y::Number)
    updateSelectionPreviews(x, y)

    for selected in selectionPreviews
        lib = getLibrary()
        preset = lib.createPreset(selected.target)
        lib.displayPresetEditor(preset, toolsLayer)
    end

    Ahorn.redrawLayer!(toolsLayer)
end



function getLibrary()
    # i cant take it anymore
    return Ahorn.eval(Meta.parse("AhornPersonalAdditives"))
end

function updateMaterials!()
    global editDisabled = true

    layer = Ahorn.layerName(targetLayer)
    targetType = layer == "entities" ? "entity" : "trigger"

    selectables = collect(keys(filter(p -> get(last(p), "type", "entity") == targetType, getLibrary().getPresets())))
    sort!(selectables)

    Ahorn.setMaterialList!(selectables, row -> false)

    Timer(0) do timer
        global editDisabled = false
        Ahorn.unselectRow!(Ahorn.materialList)
    end
end

function drawSelections(layer::Ahorn.Layer, room::Ahorn.DrawableRoom, camera::Ahorn.Camera)
    drawnTargets = Set()
    ctx = Ahorn.getSurfaceContext(toolsLayer.surface)

    # Prone to errors with weird pointers, bandaid fix for now
    # This might not actually be needed, but i'm keeping it for now
    if ctx.surface.ptr == C_NULL || ctx.ptr == C_NULL
        return true
    end

    for preview in selectionPreviews
        layer, box, target, node = preview.layerName, preview.rectangle, preview.target, preview.node

        if isa(target, Maple.Entity) && !(target in [row[1] for row in drawnTargets])
            Ahorn.renderEntitySelection(ctx, toolsLayer, target, relevantRoom)
        end

        if isa(target, Maple.Trigger) && !(target in [row[1] for row in drawnTargets])
            Ahorn.renderTriggerSelection(ctx, toolsLayer, target, relevantRoom)
        end

        if !((target, node) in drawnTargets)
            Ahorn.drawRectangle(ctx, box, Ahorn.colors.selection_preview_fc, Ahorn.colors.selection_preview_bc)
        end

        push!(drawnTargets, (target, node))
    end

    return true
end

function updateSelectionPreviews(x::Int, y::Int)
    name = Ahorn.layerName(targetLayer)

    previousPreviews = deepcopy(selectionPreviews)
    empty!(selectionPreviews)
    rect = Ahorn.Rectangle(x, y, 1, 1)
    properlyUpdateSelections!(rect, selectionPreviews, best=true)

    sameSelections = previousPreviews == selectionPreviews

    if !sameSelections
        Ahorn.redrawLayer!(toolsLayer)
    end
end

function properlyUpdateSelections!(rect::Ahorn.Rectangle, selections::Set{Ahorn.SelectedObject}; best::Bool=false, mass::Bool=false)
    retain = Ahorn.modifierShift()

    Ahorn.updateSelections!(selections, relevantRoom, Ahorn.layerName(targetLayer), rect, retain=retain, best=best, mass=mass)
end

getLibrary().initPresets()

end