--[[
  @package    eg4-crank-ui-2
  @file       icon-menu.lua
  @brief      Supports the icon menu screen and navigation.
]]


local LAYER = "icons_page_layer"
local GROUP = LAYER..".icons"
local NAVIGATION = "icons_menu_frame_layer.navigation"
local icons_per_page = 6
local total_pages = 1

---
--- @brief  Handle the callback to navigate and update the page navigation.
--- @param  mapargs  The map arguments from the callback
function cb_icon_menu_navigate(mapargs)
  if total_pages == 0 then return end

  local current_page = get_page_index(mapargs.context_screen)
  current_page = current_page + (mapargs.dir or 0)
  if current_page == 0 then
    current_page = 1
  elseif current_page > total_pages then
    current_page = total_pages
  end

  local data = {}
  data[mapargs.context_screen.."."..LAYER..".grd_scroll_enabled"] = 0
  data[NAVIGATION..".up.alpha_disabled"] = current_page == 1 and gre.get_value(NAVIGATION..".control_inactive_alpha") or 255
  data[NAVIGATION..".up.grd_active"] = current_page == 1 and 0 or 1
  data[NAVIGATION..".down.alpha_disabled"] = current_page == total_pages and gre.get_value(NAVIGATION..".control_inactive_alpha") or 255
  data[NAVIGATION..".down.grd_active"] = current_page == total_pages and 0 or 1
  data[mapargs.context_screen..".paging_rich_text"] = make_page_text(current_page, total_pages)
  gre.set_data(data)

  animate_scroll(mapargs.context_screen.."."..LAYER, get_screen_height() * (1 - current_page))
end

---
--- @brief  Update the icon menu visibility.
--- @param  context_screen  The context screen
local function update_visibility(context_screen)
  local data = {}
  for _,obj in ipairs(GROUP:get_children()) do
    obj = tostring(obj)
    local fn = _G["show_"..obj:object_name()]
    if type(fn) == "function" then
      data[obj..".grd_hidden"] = not fn(context_screen)
    end
    local fn = _G["active_"..obj:object_name()]
    if type(fn) == "function" then
      data[obj..".grd_active"] = fn() and 1 or 0
      data[obj..".alpha_active"] = fn() and 255 or 85
    end
  end
  gre.set_data(data)
end

---
--- @brief  Update the menu icon grid.
--- @param  mapargs  The map arguments from the callback
function cb_update_icon_menu_grid(mapargs)

  update_visibility(mapargs.context_screen)

  local data = {}
  local visible = GROUP:get_visible_children()

  local pending_placement = {}
  for _,obj in ipairs(visible) do
    pending_placement[tostring(obj)] = true
  end

  local list = {}
  local favourites = get_icons_menu_favourites_list()
  for _,control in ipairs(favourites) do
    control = GROUP.."."..control
    if pending_placement[control] then
      table.insert(list, control)
      pending_placement[control] = nil
      data[control..".favourite_alpha"] = 255
    end
  end

  for _,control in ipairs(visible) do
    local control = tostring(control)
    if pending_placement[control] then
      table.insert(list, control)
      data[control..".favourite_alpha"] = 0
    end
  end

  data[NAVIGATION..".grd_hidden"] = #list <= 6
  data[mapargs.context_screen.."."..LAYER..".grd_yoffset"] = 0

  local x = 0
  local y = 0
  local h = 0
  local max_width = gre.get_layer_attrs(mapargs.context_screen.."."..LAYER, "width").width
  for _,obj in ipairs(list) do
    data[obj..".grd_x"] = x
    data[obj..".grd_y"] = y
    local height = gre.get_value(obj..".grd_height")
    if height > h then h = height end
    local width = gre.get_value(obj..".grd_width")
    x = x + width
    if x + width > max_width then
      x = 0
      y = y + h
      h = 0
    end
  end
  gre.set_data(data)

  total_pages = math.ceil(#list / icons_per_page)
  cb_icon_menu_navigate(mapargs)
end
