module XaphanHelperFlagSwapBlock

using ..Ahorn, Maple

@mapdef Entity "XaphanHelper/FlagSwapBlock" FlagSwapBlock(x1::Integer, y1::Integer, x2::Integer=x1+16, y2::Integer=y1, width::Integer=16, height::Integer=16, directory::String="objects/swapblock", speed::Integer=360, flag::String="", toggle::Bool=false, particleColor1::String="FBF236", particleColor2::String="6ABE30")

function swapFinalizer(entity)
    x, y = Ahorn.position(entity)

    width = Int(get(entity.data, "width", 8))
    height = Int(get(entity.data, "height", 8))

    entity.data["nodes"] = [(x + width, y)]
end

const placements = Ahorn.PlacementDict(
    "Flag Swap Block (Xaphan Helper)" => Ahorn.EntityPlacement(
        FlagSwapBlock,
        "rectangle",
        Dict{String, Any}(),
        swapFinalizer
    )
)

Ahorn.nodeLimits(entity::FlagSwapBlock) = 1, 1

Ahorn.minimumSize(entity::FlagSwapBlock) = 16, 16
Ahorn.resizable(entity::FlagSwapBlock) = true, true

function Ahorn.selection(entity::FlagSwapBlock)
    x, y = Ahorn.position(entity)
    stopX, stopY = Int.(entity.data["nodes"][1])

    width = Int(get(entity.data, "width", 8))
    height = Int(get(entity.data, "height", 8))

    return [Ahorn.Rectangle(x, y, width, height), Ahorn.Rectangle(stopX, stopY, width, height)]
end

function renderTrail(ctx, x::Number, y::Number, width::Number, height::Number, directory::String)
    trailFrame = "$(directory)/target"
    tilesWidth = div(width, 8)
    tilesHeight = div(height, 8)

    if directory == "objects/swapblock" 
        for i in 2:tilesWidth - 1
            Ahorn.drawImage(ctx, trailFrame, x + (i - 1) * 8, y + 2, 6, 0, 8, 6)
            Ahorn.drawImage(ctx, trailFrame, x + (i - 1) * 8, y + height - 8, 6, 14, 8, 6)
        end

        for i in 2:tilesHeight - 1
            Ahorn.drawImage(ctx, trailFrame, x + 2, y + (i - 1) * 8, 0, 6, 6, 8)
            Ahorn.drawImage(ctx, trailFrame, x + width - 8, y + (i - 1) * 8, 14, 6, 6, 8)
        end

        for i in 2:tilesWidth - 1, j in 2:tilesHeight - 1
            Ahorn.drawImage(ctx, trailFrame, x + (i - 1) * 8, y + (j - 1) * 8, 6, 6, 8, 8)
        end

        Ahorn.drawImage(ctx, trailFrame, x + width - 8, y + 2, 14, 0, 6, 6)
        Ahorn.drawImage(ctx, trailFrame, x + width - 8, y + height - 8, 14, 14, 6, 6)
        Ahorn.drawImage(ctx, trailFrame, x + 2, y + 2, 0, 0, 6, 6)
        Ahorn.drawImage(ctx, trailFrame, x + 2, y + height - 8, 0, 14, 6, 6)
    else
        for i in 2:tilesWidth - 1
            Ahorn.drawImage(ctx, trailFrame, x + (i - 1) * 8, y, 8, 0, 8, 8)
            Ahorn.drawImage(ctx, trailFrame, x + (i - 1) * 8, y + height - 8, 8, 16, 8, 8)
        end
    
        for i in 2:tilesHeight - 1
            Ahorn.drawImage(ctx, trailFrame, x, y + (i - 1) * 8, 0, 8, 8, 8)
            Ahorn.drawImage(ctx, trailFrame, x + width - 8, y + (i - 1) * 8, 16, 8, 8, 8)
        end
    
        for i in 2:tilesWidth - 1, j in 2:tilesHeight - 1
            Ahorn.drawImage(ctx, trailFrame, x + (i - 1) * 8, y + (j - 1) * 8, 8, 8, 8, 8)
        end
    
        Ahorn.drawImage(ctx, trailFrame, x + width - 8, y, 16, 0, 8, 8)
        Ahorn.drawImage(ctx, trailFrame, x + width - 8, y + height - 8, 16, 16, 8, 8)
        Ahorn.drawImage(ctx, trailFrame, x, y, 0, 0, 8, 8)
        Ahorn.drawImage(ctx, trailFrame, x, y + height - 8, 0, 16, 8, 8)
    end
end

function renderSwapBlock(ctx::Ahorn.Cairo.CairoContext, x::Number, y::Number, width::Number, height::Number, directory::String)
    frame = "$(directory)/blockRed"
    midResource = "$(directory)/midBlockRed00"
    midSprite = Ahorn.getSprite(midResource, "Gameplay")
    
    tilesWidth = div(width, 8)
    tilesHeight = div(height, 8)

    for i in 2:tilesWidth - 1
        Ahorn.drawImage(ctx, frame, x + (i - 1) * 8, y, 8, 0, 8, 8)
        Ahorn.drawImage(ctx, frame, x + (i - 1) * 8, y + height - 8, 8, 16, 8, 8)
    end

    for i in 2:tilesHeight - 1
        Ahorn.drawImage(ctx, frame, x, y + (i - 1) * 8, 0, 8, 8, 8)
        Ahorn.drawImage(ctx, frame, x + width - 8, y + (i - 1) * 8, 16, 8, 8, 8)
    end

    for i in 2:tilesWidth - 1, j in 2:tilesHeight - 1
        Ahorn.drawImage(ctx, frame, x + (i - 1) * 8, y + (j - 1) * 8, 8, 8, 8, 8)
    end

    Ahorn.drawImage(ctx, frame, x, y, 0, 0, 8, 8)
    Ahorn.drawImage(ctx, frame, x + width - 8, y, 16, 0, 8, 8)
    Ahorn.drawImage(ctx, frame, x, y + height - 8, 0, 16, 8, 8)
    Ahorn.drawImage(ctx, frame, x + width - 8, y + height - 8, 16, 16, 8, 8)

    Ahorn.drawImage(ctx, midSprite, x + div(width - midSprite.width, 2), y + div(height - midSprite.height, 2))
end

function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::FlagSwapBlock, room::Maple.Room)
    directory = get(entity.data, "directory", "objects/swapblock")
    sprite = get(entity.data, "sprite", "block")
    startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
    stopX, stopY = Int.(entity.data["nodes"][1])

    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))

    renderSwapBlock(ctx, stopX, stopY, width, height, directory)
    Ahorn.drawArrow(ctx, startX + width / 2, startY + height / 2, stopX + width / 2, stopY + height / 2, Ahorn.colors.selection_selected_fc, headLength=6)
end

function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::FlagSwapBlock, room::Maple.Room)
    directory = get(entity.data, "directory", "objects/swapblock")
    sprite = get(entity.data, "sprite", "block")

    startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
    stopX, stopY = Int.(entity.data["nodes"][1])

    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))

    renderTrail(ctx, min(startX, stopX), min(startY, stopY), abs(startX - stopX) + width, abs(startY - stopY) + height, directory)
    renderSwapBlock(ctx, startX, startY, width, height, directory)
end

end