-- luafiler (c) 2006 mallchin, http://www.mallchin.com/luafm/
-- You are free to distribute this file without modifications.

function render_alert(msg, colour)
  local alert_width = (string.len(msg) * 8)
  local alert_height = 8
  render_centrebox((alert_width + 20), 20, purple, 1, white)
  screen:print((((screen_width - alert_width) / 2) + shadow_xoffset), (((screen_height - alert_height) / 2) + shadow_yoffset), msg, black)
  screen:print(((screen_width - alert_width) / 2), ((screen_height - alert_height) / 2), msg, colour)
end

function render_confirm(msg, colour, confirm_option_default)

  -- render file operations
  if skip_finish_file_operations then
    render_file_operations(selected_operation)
  end

  msgconfirm = msg
  msgcolour = colour
  alert_width = (string.len(msg) * 8)
  alert_height = 8
  msgyes = "YES"
  msgyes_width = (string.len(msgyes) * 8)
  msgno = "NO"
  msgno_width = (string.len(msgno) * 8)

  if confirm_option_default then
    confirm_option = true
    msgyes_colour = oncol
    msgno_colour = offcol
  else
    confirm_option = false
    msgyes_colour = offcol
    msgno_colour = oncol
  end
  
  -- render box
  render_centrebox((alert_width + 20), 40, purple, 1, white)

  -- render message
  screen:print((((screen_width - alert_width) / 2) + shadow_xoffset), ((((screen_height - alert_height) / 2) - 8) + shadow_yoffset), msgconfirm, black)
  screen:print(((screen_width - alert_width) / 2), (((screen_height - alert_height) / 2) - 8), msgconfirm, msgcolour)

  -- render yes/no
  screen:print(((((screen_width - msgyes_width) / 2) - 24) + shadow_xoffset), ((((screen_height - alert_height) / 2) + 8) + shadow_yoffset), msgyes, black)
  screen:print((((screen_width - msgyes_width) / 2) - 24), (((screen_height - alert_height) / 2) + 8), msgyes, msgyes_colour)
  screen:print(((((screen_width - msgno_width) / 2) + 24) + shadow_xoffset), ((((screen_height - alert_height) / 2) + 8) + shadow_yoffset), msgno, black)
  screen:print((((screen_width - msgno_width) / 2) + 24), (((screen_height - alert_height) / 2) + 8), msgno, msgno_colour)

  padmode = "confirm"

end

function render_file_operations(selected_operation)

  -- file operations
  file_operations = {}
  if table.getn(selected_files) >= 1 and on_ms(currentdir) then
    table.insert(file_operations, { name = "Cut item(s)", action = "file_cut()" })
  end
  if table.getn(selected_files) >= 1 then
    table.insert(file_operations, { name = "Copy item(s)", action = "file_copy()" })
  end
  if ((table.getn(cut_files) >= 1 and get_filepath(cut_files[1]) ~= currentdir) or (table.getn(copy_files) >= 1 and get_filepath(copy_files[1]) ~= currentdir)) and on_ms(currentdir) then
    table.insert(file_operations, { name = "Paste item(s)", action = "file_paste()" })
  end
  if table.getn(selected_files) >= 1 and on_ms(currentdir) then
    table.insert(file_operations, { name = "Delete item(s)", action = "confirm_file_delete()" })
  end
--  if table.getn(selected_files) == 0 then
--    table.insert(file_operations, { name = "Rename item", action = "file_rename()" })
--  end
  table.insert(file_operations, { name = "Select all", action = "file_select(\"" .. add_trailing_slash(currentdir) .. "\", nil, \"all\")" })
  if table.getn(selected_files) >= 1 then
    table.insert(file_operations, { name = "Unselect all", action = "file_select(\"" .. add_trailing_slash(currentdir) .. "\", nil, \"none\")" })
  end
  table.insert(file_operations, { name = "Cancel", action = "" })
  if showquit == 1 then
    table.insert(file_operations, { name = "Quit", action = "confirm_end_app()" })
  end

  if table.getn(file_operations) > 1 then

    msg = "Select option:"
    local alert_width = (string.len(msg) * 8)
    for k,v in pairs(file_operations) do
      if (string.len(v.name) * 8) > alert_width then
        alert_width = (string.len(v.name) * 8)
      end
    end
    local alert_height = ((table.getn(file_operations) * 14) + 10)

    -- render box
    render_centrebox((alert_width + 20), (alert_height + 20), purple, 1, white)

    -- render message
    screen:print((((screen_width - alert_width) / 2) + shadow_xoffset), (((screen_height - alert_height) / 2) + shadow_yoffset), msg, black)
    screen:print(((screen_width - alert_width) / 2), ((screen_height - alert_height) / 2), msg, white)

    -- render file operations
    local xpos = ((screen_width - alert_width) / 2)
    local ypos = (((screen_height - alert_height) / 2) + 14)
    for k,v in pairs(file_operations) do
      screen:print((xpos + shadow_xoffset), (ypos + shadow_yoffset), v.name, black)
      if k == selected_operation then
        screen:print(xpos, ypos, v.name, oncol)
      else
        screen:print(xpos, ypos, v.name, offcol)
      end
      ypos = ypos + 14
    end

    padmode = "file_operations"

  else

    render_alert("No files selected", white)

  end

end

function render_centrebox(width, height, colour, border_width, border_colour)

  -- shadow
  if border_width >= 1 then
    screen:fillRect((((screen_width - (width + (border_width * 2))) / 2) + 1), (((screen_height - (height + (border_width * 2))) / 2) + 1), (width + (border_width * 2)), (height + (border_width * 2)), black)
  else
    screen:fillRect((((screen_width - width) / 2) + 1), (((screen_height - height) / 2) + 1), width, height, colour)
  end

  -- box
  if border_width >= 1 then
    screen:fillRect(((screen_width - (width + (border_width * 2))) / 2), ((screen_height - (height + (border_width * 2))) / 2), (width + (border_width * 2)), (height + (border_width * 2)), border_colour)
  end
  screen:fillRect(((screen_width - width) / 2), ((screen_height - height) / 2), width, height, colour)

end

function render_filename(filename)

  if string.len(filename) > max_filechars then

    if filename_scroll > 0 and init_itempause and currentitem == filename then

      if padmode == "filelist" then

        if filename_scroll_pointer == 1 then scroll_l = true else scroll_l = false end
        if filename_scroll_pointer + max_filechars == string.len(filename) then scroll_r = true else scroll_r = false end

        -- breakpoint reached
        if (itemtimer:time() >= filename_scroll and not scroll_l and not scroll_r and not scroll_boundary) or ((scroll_l or scroll_r) and scroll_boundary) then

          if filename_scroll_direction == 0 then
            filename_scroll_pointer = filename_scroll_pointer + 1
          elseif filename_scroll_direction == 1 then
            filename_scroll_pointer = filename_scroll_pointer - 1
          end

	  scroll_boundary = false

          -- reset timer
	  itemtimer:reset()
          itemtimer:stop()

          -- start timer
          itemtimer:start()

        elseif itemtimer:time() >= (filename_scroll * 4) and (scroll_l or scroll_r) then

	  if scroll_l then
            filename_scroll_direction = 0
	  end

	  if scroll_r then
	    filename_scroll_direction = 1
	  end

	  scroll_boundary = true

          -- reset timer
	  itemtimer:reset()
          itemtimer:stop()

          -- start timer
          itemtimer:start()

        end

      end

      return string.sub(filename, filename_scroll_pointer, (max_filechars + filename_scroll_pointer))

    else

      if padmode == "filelist" then

        -- start timer
        if itemtimer:time() == 0 then
          itemtimer:start()
        end

        -- pause
        if itemtimer:time() >= 750 then

          -- start scrolling
  	  init_itempause = true

          -- reset timer
	  itemtimer:reset()
          itemtimer:stop()

          -- start timer
          itemtimer:start()

        end

      end

      return string.sub(filename, 1, (max_filechars - 3)) .. "..."

    end

  else

    return filename

  end

end

function reset_filename_scroller()

  -- reset filename scroll pointer
  filename_scroll_pointer = 1

  -- reset filename scroll direction
  filename_scroll_direction = 0

  -- reset initial item pause
  init_itempause = false

  -- reset timer
  itemtimer:reset()
  itemtimer:stop()

end

function render_selected_files()
  local y = 170
  for k,v in pairs(selected_files) do
    screen:print((10 + shadow_xoffset), (y + shadow_yoffset), k .. " = " .. v, black)
    screen:print(10, y, k .. " = " .. v, white)
    y = y + 10
  end
end

function render_filesize(filesize)
  if filesize >= (1024 * 1024 * 1024) then
    return string.format("%.0f", (filesize / 1024 / 1024 / 1024)) .. " Gb"
  elseif filesize >= (1024 * 1024) then
    return string.format("%.0f", (filesize / 1024 / 1024)) .. " Mb"
  elseif filesize >= (1024) then
    return string.format("%.0f", (filesize / 1024)) .. " Kb"
  elseif filesize <= 1023 then
--    return filesize .. " b "
    return "1 Kb"
  end
end

function render_filelist()

  -- display background image
  screen:blit(0, 0, background, 0, 0, background:width(), background:height(), false)

  -- print current directory
  screen:print((10 + shadow_xoffset), (10 + shadow_yoffset), "[" .. currentdir .. "/]", black)
  screen:print(10, 10, "[" .. currentdir .. "/]", white)

  -- print freespace
--  screen:print((10 + shadow_xoffset), (10 + shadow_yoffset), pad_string("left", 58, "(" .. render_filesize(System.getFreeMemory()) .. " free)"), black)
--  screen:print(10, 10, pad_string("left", 58, "(" .. render_filesize(System.getFreeMemory()) .. " free)"), white)

  local xposname = 10
  local xpossize = 420
  local ypos = 20
  
  i = 1
  i2 = start_pointer
  if num_files < num_listings then
    end_pointer = num_files
  else
    end_pointer = num_listings
  end
  while i <= end_pointer do

    -- concatenate path/file
    local path_file = currentdir .. "/" .. files[i2]["name"]

    -- render text
    if i2 == menu_pointer then
      showcol = oncol
      currentitem = files[i2]["name"]
    elseif in_array(cut_files, path_file) then
      showcol = cutcol
    elseif in_array(copy_files, path_file) then
      showcol = copycol
    elseif in_array(selected_files, path_file) then
      showcol = selectedcol
    else
      showcol = offcol
    end
    local tmpfilename = render_filename(files[i2]["name"])
    screen:print((xposname + shadow_xoffset), (ypos + shadow_yoffset), tmpfilename, black)
    screen:print(xposname, ypos, tmpfilename, showcol)
    if files[i2]["directory"] == true then
      screen:print((xpossize + shadow_xoffset), (ypos + shadow_yoffset), pad_string("left", 7, "<dir>"), black)
      screen:print(xpossize, ypos, pad_string("left", 7, "<dir>"), showcol)
    else
      screen:print((xpossize + shadow_xoffset), (ypos + shadow_yoffset), pad_string("left", 7, render_filesize(files[i2]["size"])), black)
      screen:print(xpossize, ypos, pad_string("left", 7, render_filesize(files[i2]["size"])), showcol)
    end
    ypos = ypos + 10
    i = i + 1
    i2 = i2 + 1
  end

  -- render selected files
--  render_selected_files()

  -- render tagline
  render_tagline()

end

function render_statmsg(msg, colour)
  if debug then screen:print(10, 250, msg, colour) end
end

function render_tagline()
  if not debug then
--  screen:print(10, 250, "mp=" .. menu_pointer .. ", sp=" .. start_pointer .. ", ep=" .. end_pointer, white)
    local msg = "Nav=Up/Down | Enter=Cross | Cancel=Circle | Help=Select"
    screen:print((((screen_width - (string.len(msg) * 8)) / 2) + shadow_xoffset), (255 + shadow_yoffset), msg, black)
    screen:print(((screen_width - (string.len(msg) * 8)) / 2), 255, msg, grey)
  end
end

function render_drives()

  -- null currentdir
  currentdir = ""

  -- get spacer
  local spacernum = 0
  for k,v in pairs(drives) do
    if string.len(v) > spacernum then spacernum = string.len(v) end
  end
  spacernum = spacernum + 2

  -- fake file array
  files = {}

  -- fake files
  for k,v in pairs(drives) do

    -- ugly hack for enabling drives
    if (v == "disc0:/" and enable_disc0 == 1) or (v == "flash0:/" and enable_flash0 == 1) or (v == "flash1:/" and enable_flash1 == 1) or (v == "ms0:/" and enable_ms0 == 1) then

      -- ugly hack to check for umd
      if (v ~= "disc0:/") or (v == "disc0:/" and System.isUmdInserted()) then

        -- concatenate fake filename
        local fakefilename = v
        i = string.len(fakefilename)
        while i <= spacernum do
          fakefilename = fakefilename .. " "
        i = i + 1
        end
        fakefilename = fakefilename .. "(" .. k .. ")"

        local fakefile = {}
        fakefile.name = fakefilename
        fakefile.directory = true
        fakefile.size = 1024
        fakefile.action_cross = "change_drive(\"" .. v .. "\")"
        fakefile.action_square = ""
        fakefile.action_triangle = ""
        table.insert(files, fakefile)

      end

    end

  end

  -- sort file array
  table.sort(files, filesort)

  -- count files
  num_files = table.getn(files)

  -- update menu pointer
  if menu_pointer >= (num_files + 1) then
    menu_pointer = 1
  end

  -- reset start pointer
  start_pointer = 1

  -- null selected files array
  selected_files = {}

  -- render files
  render_filelist()

  -- flip screen
  screen.flip()
  screen.waitVblankStart()

end
