
--[[
  @package    eg4-crank-ui
  @file       sign-update-progress.lua
  @brief      Handles sign update event for the user interface
]]

local info = {}

--- Note: Command test message
--- running_detected_extracting
--- $ ./iogen g4_frontend - sign_update_progress 1s0:text "return { signAddress = 1, finalStatus = 'RUNNING', stage = 'DETECTED', subStage = 'EXTRACTING', percentage = 0 }"
---


local SCREEN = "bd_sign_update_progress"
local LAYER = "sign_update_progress_layer"
local GROUP = "menu_items"

---
--- @brief  Actions to perform when hiding the sign update progress screen.
function cb_hide_sign_update_progress(mapargs)
  CancelHoldAtNormal(SCREEN)
end

---
--- @brief  Actions to perform when showing the sign update progress screen.
function cb_show_sign_update_progress()
  StartHoldAtNormal(SCREEN)
end

---
--- @brief  Update the sign update progress list screen.
local function update_progress_screen()
  local control = LAYER.."."..GROUP..".items"

  if info.pb_x == nil then
    info.pb_x = gre.get_value(control..".pb_x")
    info.pb_width = gre.get_value(control..".pb_width")
  end

  local data = {}
  local rows = 0
  local lowest_percentage = 100
  for sign_address, status in sorted_pairs(info.data) do
    rows = rows + 1
    data[control..".sign_address."..rows..".1"] = "#"..sign_address

    local state = status.finalStatus:lower()
    local stage = status.stage:lower()
    local sub_stage = status.subStage:lower()
    local item = state.."_"..stage.."_"..sub_stage
    local text = gre.get_value(control..".status_"..item) or gre.get_value(control..".status_"..state.."_"..stage) or gre.get_value(control..".status_"..state) or item
    data[control..".status."..rows..".1"] = text:gsub("\\n", "\n")
    data[control.."fade."..rows..".1"] = 0

    local width = status.percentage * info.pb_width / 100
    data[control..".width."..rows..".1"] = width
    data[control..".x."..rows..".1"] = width - info.pb_width + info.pb_x
    data[control..".percentage."..rows..".1"] = status.percentage.."%"

    if status.percentage >= 0 and status.percentage < lowest_percentage then
      lowest_percentage = status.percentage
    end

  end
  gre.set_data(data)

  local height = gre.get_table_cell_attrs(control, 1, 1, "height").height
  gre.set_table_attrs(control, { height = rows * height, rows = rows })

  CBMenuUpdate()

end

---
--- @brief  Process the sign update progress message.
function cb_process_sign_update_progress(mapargs)

  local status = loadstring(mapargs.context_event_data.text)()

  if info.cleanup then info = {} end
  if not info.data then info.data = {} end
  info.data[status.signAddress] = status

  ScreenTransition(SCREEN)

  if mapargs.context_screen == SCREEN or gre.env("active_screen") == SCREEN then
    SBCInitialiseScrollbar(mapargs)
  end

  update_progress_screen()
end

---
--- @brief  Check if the display screen should be shown at the end of the update process.
function display_sign_update_progress()
  info.cleanup = true
  if next(info.data) == nil then return end
  ScreenTransition(SCREEN)
end
