local SharedMedia = LibStub("LibSharedMedia-3.0");
local L = WeakAuras.L;

local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;

local function createOptions(id, data)
  local options = {
    displayText = {
      type = "input",
      width = "double",
      desc = function()
        local ret = L["Dynamic text tooltip"];
        ret = ret .. WeakAuras.GetAdditionalProperties(data);
        return ret
      end,
      multiline = true,
      name = L["Display Text"],
      order = 10,
      get = function()
        local ret = data.displayText;
        for symbol, v in pairs(WeakAuras.dynamic_texts) do
          ret = ret:gsub("(%"..symbol..")", "|cFFFF0000%1|r");
        end
        return ret;
      end,
      set = function(info, v)
        v = v:gsub("|cFFFF0000", "");
        v = v:gsub("|r", "");
        data.displayText = v;
        WeakAuras.Add(data);
        WeakAuras.SetThumbnail(data);
        WeakAuras.SetIconNames(data);
        WeakAuras.ResetMoverSizer();
      end
    },
    customTextUpdate = {
      type = "select",
      width = "double",
      hidden = function() return not data.displayText:find("%%c"); end,
      name = L["Update Custom Text On..."],
      values = WeakAuras.text_check_types,
      order = 36
    },
    -- code editor added below
    progressPrecision = {
      type = "select",
      order = 39,
      name = L["Remaining Time Precision"],
      values = WeakAuras.precision_types,
      get = function() return data.progressPrecision or 1 end,
      hidden = function()
        return not (data.displayText:find("%%p") or data.displayText:find("%%t"));
      end,
      disabled = function()
        return not data.displayText:find("%%p");
      end
    },
    totalPrecision = {
      type = "select",
      order = 39.5,
      name = L["Total Time Precision"],
      values = WeakAuras.precision_types,
      get = function() return data.totalPrecision or 1 end,
      hidden = function()
        return not (data.displayText:find("%%p") or data.displayText:find("%%t"));
      end,
      disabled = function()
        return not data.displayText:find("%%t");
      end
    },
    color = {
      type = "color",
      name = L["Text Color"],
      hasAlpha = true,
      order = 40
    },
    justify = {
      type = "select",
      name = L["Justify"],
      order = 43,
      values = WeakAuras.justify_types
    },
    font = {
      type = "select",
      dialogControl = "LSM30_Font",
      name = L["Font"],
      order = 45,
      values = AceGUIWidgetLSMlists.font
    },
    fontSize = {
      type = "range",
      name = L["Size"],
      order = 47,
      min = 6,
      softMax = 72,
      step = 1
    },
    automaticWidth = {
      type = "select",
      name = L["Width"],
      order = 47.1,
      values = WeakAuras.text_automatic_width
    },
    fixedWidth = {
      name = L["Width"],
      order = 47.2,
      type = "range",
      min = 1,
      softMax = screenWidth,
      bigStep = 1,
      hidden = function() return data.automaticWidth  ~= "Fixed" end
    },
    wordWrap = {
      type = "select",
      name = L["Overflow"],
      order = 47.2,
      values = WeakAuras.text_word_wrap,
      hidden = function() return data.automaticWidth  ~= "Fixed" end
    },
    outline = {
      type = "select",
      name = L["Outline"],
      order = 48,
      values = WeakAuras.font_flags
    },
  };

  WeakAuras.AddCodeOption(options, data, L["Custom Function"], "customText", 37, function() return not data.displayText:find("%%c") end, {"customText"}, false);

  return {
    text = options;
    position = WeakAuras.PositionOptions(id, data, true);
  };
end

local function createThumbnail(parent)
  local borderframe = CreateFrame("FRAME", nil, parent);
  borderframe:SetWidth(32);
  borderframe:SetHeight(32);

  local border = borderframe:CreateTexture(nil, "OVERLAY");
  border:SetAllPoints(borderframe);
  border:SetTexture("Interface\\BUTTONS\\UI-Quickslot2.blp");
  border:SetTexCoord(0.2, 0.8, 0.2, 0.8);

  local mask = CreateFrame("ScrollFrame", nil, borderframe);
  borderframe.mask = mask;
  mask:SetPoint("BOTTOMLEFT", borderframe, "BOTTOMLEFT", 2, 2);
  mask:SetPoint("TOPRIGHT", borderframe, "TOPRIGHT", -2, -2);

  local content = CreateFrame("Frame", nil, mask);
  borderframe.content = content;
  content:SetPoint("CENTER", mask, "CENTER");
  mask:SetScrollChild(content);

  local text = content:CreateFontString(nil, "OVERLAY");
  borderframe.text = text;
  text:SetNonSpaceWrap(true);

  borderframe.values = {};

  return borderframe;
end

local function modifyThumbnail(parent, borderframe, data, fullModify, size)
  local mask, content, text = borderframe.mask, borderframe.content, borderframe.text;

  size = size or 28;

  local fontPath = SharedMedia:Fetch("font", data.font) or data.font;
  text:SetFont(fontPath, data.fontSize, data.outline and "OUTLINE" or nil);
  text:SetTextHeight(data.fontSize);
  text:SetText(data.displayText);
  text:SetTextColor(data.color[1], data.color[2], data.color[3], data.color[4]);
  text:SetJustifyH(data.justify);

  text:ClearAllPoints();
  text:SetPoint("CENTER", UIParent, "CENTER");
  content:SetWidth(math.max(text:GetStringWidth(), size));
  content:SetHeight(math.max(text:GetStringHeight(), size));
  text:ClearAllPoints();
  text:SetPoint("CENTER", content, "CENTER");

  local function rescroll()
    content:SetWidth(math.max(text:GetStringWidth(), size));
    content:SetHeight(math.max(text:GetStringHeight(), size));
    local xo = 0;
    if(data.justify == "CENTER") then
      xo = mask:GetHorizontalScrollRange() / 2;
    elseif(data.justify == "RIGHT") then
      xo = mask:GetHorizontalScrollRange();
    end
    mask:SetHorizontalScroll(xo);
    mask:SetVerticalScroll(mask:GetVerticalScrollRange() / 2);
  end

  rescroll();
  mask:SetScript("OnScrollRangeChanged", rescroll);

  local function UpdateText()
    local textStr = data.displayText;
    textStr = WeakAuras.ReplacePlaceHolders(textStr, borderframe);
    text:SetText(textStr);
    rescroll();
  end

  function borderframe:SetIcon(path)
    local icon = (
      WeakAuras.CanHaveAuto(data)
      and path ~= ""
      and path
      or data.displayIcon
      or "Interface\\Icons\\INV_Misc_QuestionMark"
      );
    borderframe.values.icon = "|T"..icon..":12:12:0:0:64:64:4:60:4:60|t";
    UpdateText();
  end

  function borderframe:SetName(name)
    borderframe.values.name = WeakAuras.CanHaveAuto(data) and name or data.id;
    UpdateText();
  end

  UpdateText();
end

local function createIcon()
  local data = {
    outline = true,
    color = {1, 1, 0, 1},
    justify = "CENTER",
    font = "Friz Quadrata TT",
    fontSize = 12,
    displayText = "World\nof\nWarcraft";
  };

  local thumbnail = createThumbnail(UIParent);
  modifyThumbnail(UIParent, thumbnail, data);
  thumbnail.mask:SetPoint("BOTTOMLEFT", thumbnail, "BOTTOMLEFT", 3, 3);
  thumbnail.mask:SetPoint("TOPRIGHT", thumbnail, "TOPRIGHT", -3, -3);

  return thumbnail;
end

local templates = {
  {
    title = L["Default"],
    description = L["Displays a text, works best in combination with other displays"],
    data = {
    };
  }
}

WeakAuras.RegisterRegionOptions("text", createOptions, createIcon, L["Text"], createThumbnail, modifyThumbnail, L["Shows one or more lines of text, which can include dynamic information such as progress or stacks"], templates);
