-- This code was adapted from EvilFactory's Performance Fix mod.
-- https://steamcommunity.com/sharedfiles/filedetails/?id=2701251094

local function updateServerMessageScrollBasedOnCaret(textBox, listBox)
    local caretY = textBox.CaretScreenPos.Y;
    local bottomCaretExtent = textBox.Font.LineHeight * 1.5
    local topCaretExtent = -textBox.Font.LineHeight * 0.5

    if caretY + bottomCaretExtent > listBox.Rect.Bottom then
        listBox.ScrollBar.BarScroll
            = (caretY - textBox.Rect.Top - listBox.Rect.Height + bottomCaretExtent)
              / (textBox.Rect.Height - listBox.Rect.Height)
    elseif (caretY + topCaretExtent < listBox.Rect.Top) then
        listBox.ScrollBar.BarScroll
            = (caretY - textBox.Rect.Top + topCaretExtent)
              / (textBox.Rect.Height - listBox.Rect.Height)
    end
end

local function CreateMultiLineTextBox(rectransform, text, size)
    local multineListBox = GUI.ListBox(GUI.RectTransform(Vector2(1, size or 0.2), rectransform))

    local textBox = GUI.TextBox(GUI.RectTransform(Vector2(1, 1), multineListBox.Content.RectTransform), text, nil, nil, nil, true, "GUITextBoxNoBorder") 

    textBox.add_OnSelected(function ()
        updateServerMessageScrollBasedOnCaret(textBox, multineListBox)
    end)

    textBox.OnTextChangedDelegate = function ()
        local textSize = textBox.Font.MeasureString(textBox.WrappedText);
        textBox.RectTransform.NonScaledSize = Point(textBox.RectTransform.NonScaledSize.X, math.max(multineListBox.Content.Rect.Height, textSize.Y + 10))
        multineListBox.UpdateScrollBarSize()

        return true;
    end

    textBox.OnEnterPressed = function ()
        local str = textBox.Text
        local caretIndex = textBox.CaretIndex

        textBox.Text = str:sub(1, caretIndex) .. "\n" .. str:sub(caretIndex + 1)
        textBox.CaretIndex = caretIndex + 1

        return true
    end

    return textBox
end

return CreateMultiLineTextBox