local drawMessage = (function()

  -- Configuration options
  local TEXT_COLOR = gr.createColor(200, 200, 200, 255)
  local BACKGROUND_COLOR = gr.createColor(20, 20, 20, 200)

  local WIDTH_PERCENT = 0.25
  local WIDTH_BASE_PERCENT = 0.5

  local HEIGHT_PERCENT = 0.10
  local HEIGHT_BASE_PERCENT = 0.20

  local FONT = gr.Fonts[1]
  local PADDING = 5
  -- End configuration options

  local TEXT_LEFT, TEXT_RIGHT = (function()
    local width = gr.getScreenWidth()
    local baseX = width * WIDTH_BASE_PERCENT
    local dx = width * WIDTH_PERCENT / 2
    return baseX - dx, baseX + dx
  end)()

  local TEXT_TOP, TEXT_BOTTOM = (function()
    local height = gr.getScreenHeight()
    local baseY = height * HEIGHT_BASE_PERCENT
    local dy = height * HEIGHT_PERCENT / 2
    return baseY - dy, baseY + dy
  end)()

  local BACKGROUND_LEFT   = TEXT_LEFT   - PADDING
  local BACKGROUND_RIGHT  = TEXT_RIGHT  + PADDING
  local BACKGROUND_TOP    = TEXT_TOP    - PADDING
  local BACKGROUND_BOTTOM = TEXT_BOTTOM + PADDING

  return function(text)
    if not hu.HUDDrawn then return end -- don't draw if the HUD is disabled
    local oldColor = gr.getColor(true)
    local oldFont = gr.CurrentFont
    gr.setColor(BACKGROUND_COLOR)
    gr.drawRectangle(BACKGROUND_LEFT, BACKGROUND_TOP, BACKGROUND_RIGHT, BACKGROUND_BOTTOM)
    gr.CurrentFont = FONT
    gr.setColor(TEXT_COLOR)
    gr.drawString(text, TEXT_LEFT, TEXT_TOP, TEXT_RIGHT, TEXT_BOTTOM)
    -- Restore the original graphics settings
    gr.CurrentFont = oldFont
    gr.setColor(oldColor)
  end

end)()

local getMessage, setMessage = (function()

  local text, timeout = 0

  local function getMessage()
    return mn.getMissionTime() < timeout and text or nil
  end

  local function setMessage(message, duration)
    text = message
    timeout = mn.getMissionTime() + duration
  end

  return getMessage, setMessage

end)()

local function draw()
  local message = getMessage()
  if message then drawMessage(message) end
end

local send = (function()

  local DURATION_PER_CHARACTER = 0.07
  local MINIMUM_DURATION = 2

  local function calculateDuration(text)
    return math.max(DURATION_PER_CHARACTER * utf8.len(text), MINIMUM_DURATION)
  end

  return function(message, duration)
    if not message:isValid() then
      ba.warning('Invalid message given to better-training-msg')
      return
    end
    local text = ba.replaceTokens(message:getMessage(true))
    mn.addMessageToScrollback(text, SCROLLBACK_SOURCE_TRAINING)
    if not duration then
      duration = calculateDuration(text)
    elseif duration < 0 then
      duration = math.huge 
    end
    setMessage(text, duration)
    if duration ~= 0 then
      local voice = message.VoiceFile
      if voice and voice:isValid() then voice:play() end
    end
  end

end)()

local function clear()
  setMessage(nil, 0)
end

return { draw = draw, send = send, clear = clear }

