-- Rykord Vertical Track FX List --
--NOTES--

-- want to make buttons resizable
-- start window on a specific position (maybe preset position, maybe last position)


--NONCODE SKELETON


--SKELETON--

-- windowposition ✅
-- window size

-- if CountSelectedTracks == 1
        -- for fx (0,i) 
            -- create blue button with the name of the fx ✅
                -- if left click the button opens the fx window ✅
                -- if right click the button deletes the fx ✅
                -- if left drag the button is draggable and drags the fx ✅
                -- if alt left click the fx is bypassed

    -- gray button to add fx with spacing from other buttons and other color
        -- if pressed ✅
            -- inserts fx at i + 1 ✅

-- if CountSelectedTracks > 1  
    -- black buttton saying "MULTIPLE TRACKS ARE SELECTED", button is unclickable

-- if CountSelectedTracks == 0
    -- black button saying "SELECT A TRACK", button is unclickable

-- let keyboard shortcuts through

--FUNCTIONS--
local profiler = dofile(reaper.GetResourcePath() ..
  '/Scripts/ReaTeam Scripts/Development/cfillion_Lua profiler.lua')
reaper.defer = profiler.defer

function print(...)
    reaper.ShowConsoleMsg(table.concat({...}, "\t") .. "\n")
end

function hasStateChanged()
    local selected_track = reaper.GetSelectedTrack(0, 0)
    local fx_count = (selected_track and reaper.TrackFX_GetCount(selected_track)) or 0
    
    if selected_track ~= prev_selected_track or fx_count ~= prev_fx_count then
        prev_selected_track = selected_track
        prev_fx_count = fx_count
        return true
    end
    return false
end

function IsAltKeyDown()
    local keyState = reaper.JS_Mouse_GetState(0)
    local altIsPressed = keyState & 8
    
    return altIsPressed ~= 0
end

function main()

    if hasStateChanged() then
    local _, open = reaper.ImGui_Begin(ctx, "FX LIST", true)
     
    reaper.ImGui_PushFont(ctx, font_1)

    reaper.ImGui_SetNextWindowPos(ctx, x_position, y_position)

    if dock_position then
        reaper.ImGui_SetNextWindowDockID(ctx, -8) --CURRENT DOCK POSITION IS UNDER (DOCKID == -7)! 
    end

    window_width, window_height = reaper.ImGui_GetWindowSize(ctx)

    button_width = window_width * 0.4  --SHOULD THESE BE GLOBAL?
    button_height = window_height * 0.12 --SHOULD THESE BE GLOBAL?
    
    reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_FrameRounding(), 8)

    fx_list()
    
    reaper.ImGui_PopStyleVar(ctx, 1)
    reaper.ImGui_PopFont(ctx)

    if open then
        reaper.ImGui_End(ctx)
        reaper.defer(main)
    else
        local last_x_position, last_y_position = reaper.ImGui_GetWindowPos(ctx)
        reaper.SetExtState("RYKORD_TRACK_FX", "x_pos", last_x_position, true)
        reaper.SetExtState("RYKORD_TRACK_FX", "y_pos", last_y_position, true)

        local last_dock_position = reaper.ImGui_GetWindowDockID(ctx)
        reaper.SetExtState("RYKORD_TRACK_FX", "dock_position", last_dock_position, true)
        reaper.ImGui_End(ctx)
    end

end

end

function swap_fx(track, new_index, source_index)
    reaper.TrackFX_CopyToTrack(track, source_index, track, new_index, true)

    if source_index > new_index then
        reaper.TrackFX_CopyToTrack(track, new_index + 1, track, source_index, true)
    elseif source_index < new_index then
        reaper.TrackFX_CopyToTrack(track, new_index + -1, track, source_index, true)
    end
end

function fx_list()

    if reaper.CountSelectedTracks(0) == 1 then
        local selected_track = reaper.GetSelectedTrack(0, 0)
        local num_of_fx = reaper.TrackFX_GetCount(selected_track)

        --FX BUTTONS--
        for i = 0, num_of_fx - 1 do
            
            local _, fx_name = reaper.TrackFX_GetFXName(selected_track, i) --VERIFICAR SE FX TAMBÉM TÊM 0 INDEX
            
            if reaper.TrackFX_GetEnabled(selected_track, i) then
                reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), 0xF5CB5CFF)
                reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), 0x000000FF)
            else
                reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), 0xCFDBD5FF)
                reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), 0x000000FF)
            end
           
            local fx_button_left_click = reaper.ImGui_Button(ctx,  fx_name .. '##' .. i, button_width, button_height)
            local fx_button_right_click = reaper.ImGui_IsItemClicked(ctx, reaper.ImGui_MouseButton_Right())
            local fx_button_middle_click = reaper.ImGui_IsItemClicked(ctx, reaper.ImGui_MouseButton_Middle())
            
            if reaper.ImGui_BeginDragDropSource(ctx) then
                    reaper.ImGui_SetDragDropPayload(ctx, "DND_FX", i) -- "DND_FX" is a type identifier for the payload
                    reaper.ImGui_Button(ctx, fx_name .. '##' .. i, button_width, button_height) -- This will be the preview of the drag and drop
                    reaper.ImGui_EndDragDropSource(ctx)
                end
            
            if reaper.ImGui_BeginDragDropTarget(ctx) then
                if reaper.ImGui_AcceptDragDropPayload(ctx, "DND_FX") then
                    local _, _, payload, _, _= reaper.ImGui_GetDragDropPayload(ctx)
                    local old_index = tonumber(payload)
                    -- Swap the effects here using your own function
                    swap_fx(selected_track, i, old_index)
                    
                end
                reaper.ImGui_EndDragDropTarget(ctx)
            end
            
            reaper.ImGui_PopStyleColor(ctx, 2)

            if fx_button_left_click then
                reaper.TrackFX_SetOpen(selected_track, i, true)
            
            elseif fx_button_middle_click then
                if reaper.TrackFX_GetEnabled(selected_track, i) == true then
                reaper.TrackFX_SetEnabled(selected_track, i, false)
                
                else
                    reaper.TrackFX_SetEnabled(selected_track, i, true)
                end

            elseif fx_button_right_click then
                reaper.TrackFX_Delete(selected_track, i)
            
            end
        end
        
        --ADD FX BUTTON--
        reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), 0xB3B6B7A1)

        local add_fx_press = reaper.ImGui_Button(ctx, "ADD FX", button_width, button_height)
            if add_fx_press then
                reaper.Main_OnCommand(40271, 0)
            end
        
        reaper.ImGui_PopStyleColor(ctx)

    elseif reaper.CountSelectedTracks(0) > 1 then
        reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), 0x373F47FF)
        reaper.ImGui_Button(ctx, "MULTIPLE TRACKS SELECTED \n  SELECT A SINGLE TRACK", 300, 60)
        reaper.ImGui_PopStyleColor(ctx)

    elseif reaper.CountSelectedTracks(0) == 0 then
        reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), 0x373F47FF)
        reaper.ImGui_Button(ctx, "  NO TRACK SELECTED \nSELECT A SINGLE TRACK", 300, 60)
        reaper.ImGui_PopStyleColor(ctx)
    end
    
    if reaper.JS_Window_GetFocus() ~= main_window then
        if reaper.ImGui_IsWindowFocused(ctx) and not reaper.ImGui_IsItemActive(ctx) and not  reaper.ImGui_IsAnyMouseDown(ctx) then
            reaper.JS_Window_SetFocus(main_window)
        end
    end
end

--RUN--
profiler.attachToWorld()
x_position = tonumber(reaper.GetExtState("RYKORD_TRACK_FX", "x_pos"))
y_position = tonumber(reaper.GetExtState("RYKORD_TRACK_FX", "y_pos"))
dock_position = tonumber(reaper.GetExtState("RYKORD_TRACK_FX", "dock_position"))
window_width = nil
window_height = nil
prev_selected_track = nil
prev_fx_count = nil
main_window = reaper.GetMainHwnd()
font_1 = reaper.ImGui_CreateFont("C:\\Users\\franc\\Desktop\\Portable reapers\\REAPER (x64)\\Scripts\\Rykord Scripts\\SFPRODISPLAYREGULAR.OTF", 20)

ctx = reaper.ImGui_CreateContext("ctx")

reaper.ImGui_Attach(ctx, font_1)

main()
profiler.run()



i have this reaper lua script using reaimgui. I want the fx_list to be created and drawn the first time of the loop, but if the  track is the same, i don't want it to be redrawn, i just want it to be the same as the previous frame to save cpu resources