local AddOnName, nsVars = ...
nsVars[AddOnName].localize()

CUSTOM_BACKDROP_TOOLTIP_8_8_1111 = {
  bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  tile = true,
  tileEdge = true,
  tileSize = 8,
  edgeSize = 8,
  insets = { left = 1, right = 1, top = 1, bottom = 1 },
};

CUSTOM_BACKDROP_TOOLTIP_8_12_1111 = {
  bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  tile = true,
  tileEdge = true,
  tileSize = 8,
  edgeSize = 12,
  insets = { left = 1, right = 1, top = 1, bottom = 1 },
};

CUSTOM_BACKDROP_TOOLTIP_16_16_5555 = {
  bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  tile = true,
  tileEdge = true,
  tileSize = 16,
  edgeSize = 16,
  insets = { left = 5, right = 5, top = 5, bottom = 5 },
};

CUSTOM_BACKDROP_TOOLTIP_12_12_4444 = {
  bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  tile = true,
  tileEdge = true,
  tileSize = 12,
  edgeSize = 12,
  insets = { left = 4, right = 4, top = 4, bottom = 4 },
};

CUSTOM_BACKDROP_TOOLTIP_0_16 = {
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  edgeSize = 16,
  tileEdge = true,
};

CUSTOM_BACKDROP_TOOLTIP_0_12_0055 = {
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  edgeSize = 12,
  tileEdge = true,
  insets = { left = 0, right = 0, top = 5, bottom = 5 },
};

CUSTOM_BACKDROP_TOOLTIP_0_16_5555 = {
  edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
  edgeSize = 16,
  tileEdge = true,
  insets = { left = 5, right = 5, top = 5, bottom = 5 },
};

CUSTOM_BACKDROP_ACHIEVEMENTS_0_64 = {
  edgeFile = "Interface\\AchievementFrame\\UI-Achievement-WoodBorder",
  edgeSize = 64,
  tileEdge = true,
};

CUSTOM_BACKDROP_ARENA_32_32 = {
  bgFile = "Interface\\CharacterFrame\\UI-Party-Background",
  edgeFile = "Interface\\ArenaEnemyFrame\\UI-Arena-Border",
  tile = true,
  tileEdge = true,
  tileSize = 32,
  edgeSize = 32,
  insets = { left = 32, right = 32, top = 32, bottom = 32 },
};

CUSTOM_BACKDROP_DIALOG_32_32 = {
  bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
  tile = true,
  tileEdge = true,
  tileSize = 32,
  edgeSize = 32,
  insets = { left = 11, right = 12, top = 12, bottom = 11 },
};

CUSTOM_BACKDROP_GOLD_DIALOG_32_32 = {
  bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
  tile = true,
  tileEdge = true,
  tileSize = 32,
  edgeSize = 32,
  insets = { left = 11, right = 12, top = 12, bottom = 11 },
};

CUSTOM_BACKDROP_WATERMARK_DIALOG_0_16 = {
  edgeFile = "Interface\\DialogFrame\\UI-DialogBox-TestWatermark-Border",
  tileEdge = true,
  edgeSize = 16,
};

CUSTOM_BACKDROP_SLIDER_8_8 = {
  bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
  edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
  tile = true,
  tileEdge = true,
  tileSize = 8,
  edgeSize = 8,
  insets = { left = 3, right = 3, top = 6, bottom = 6 },
};

CUSTOM_BACKDROP_PARTY_32_32 = {
  bgFile = "Interface\\CharacterFrame\\UI-Party-Background",
  edgeFile = "Interface\\CharacterFrame\\UI-Party-Border",
  tile = true,
  tileEdge = true,
  tileSize = 32,
  edgeSize = 32,
  insets = { left = 32, right = 32, top = 32, bottom = 32 },
};

CUSTOM_BACKDROP_TOAST_12_12 = {
  bgFile = "Interface\\FriendsFrame\\UI-Toast-Background",
  edgeFile = "Interface\\FriendsFrame\\UI-Toast-Border",
  tile = true,
  tileEdge = true,
  tileSize = 12,
  edgeSize = 12,
  insets = { left = 5, right = 5, top = 5, bottom = 5 },
};

CUSTOM_BACKDROP_CALLOUT_GLOW_0_16 = {
  edgeFile = "Interface\\TutorialFrame\\UI-TutorialFrame-CalloutGlow",
  edgeSize = 16,
  tileEdge = true,
};

CUSTOM_BACKDROP_CALLOUT_GLOW_0_20 = {
  edgeFile = "Interface\\TutorialFrame\\UI-TutorialFrame-CalloutGlow",
  edgeSize = 20,
  tileEdge = true,
};

CUSTOM_BACKDROP_GLUE_TOOLTIP_16_16 = {
  bgFile = "Interface\\Glues\\Common\\Glue-Tooltip-Background",
  edgeFile = "Interface\\Glues\\Common\\Glue-Tooltip-Border",
  tile = true,
  tileEdge = true,
  tileSize = 16,
  edgeSize = 16,
  insets = { left = 10, right = 5, top = 4, bottom = 9 },
};

CUSTOM_BACKDROP_GLUE_TOOLTIP_0_16 = {
  edgeFile = "Interface\\Glues\\Common\\Glue-Tooltip-Border",
  tileEdge = true,
  edgeSize = 16,
};

CUSTOM_BACKDROP_MIXED_TOOLTIP_16_16 = {
  bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
  edgeFile = "Interface\\Glues\\Common\\Glue-Tooltip-Border",
  tile = true,
  tileEdge = true,
  tileSize = 16,
  edgeSize = 16,
  insets = { left = 10, right = 5, top = 4, bottom = 9 },
};

CUSTOM_BACKDROP_TEXT_PANEL_0_16 = {
  edgeFile = "Interface\\Glues\\Common\\TextPanel-Border",
  tileEdge = true,
  edgeSize = 16,
};

CUSTOM_BACKDROP_CHAT_BUBBLE_16_16 = {
  bgFile = "Interface\\Tooltips\\ChatBubble-Background",
  edgeFile = "Interface\\Tooltips\\ChatBubble-Backdrop",
  tile = true,
  tileEdge = true,
  tileSize = 16,
  edgeSize = 16,
  insets = { left = 16, right = 16, top = 16, bottom = 16 },
};

CustomBackdropTemplateMixin = { };

local coordStart = 0.0625;
local coordEnd = 1 - coordStart;
local textureUVs = {			-- keys have to match pieceNames in nineSliceSetup table
  TopLeftCorner = { setWidth = true, setHeight = true, ULx = 0.5078125, ULy = coordStart, LLx = 0.5078125, LLy = coordEnd, URx = 0.6171875, URy = coordStart, LRx = 0.6171875, LRy = coordEnd },
  TopRightCorner = { setWidth = true, setHeight = true, ULx = 0.6328125, ULy = coordStart, LLx = 0.6328125, LLy = coordEnd, URx = 0.7421875, URy = coordStart, LRx = 0.7421875, LRy = coordEnd },
  BottomLeftCorner = { setWidth = true, setHeight = true, ULx = 0.7578125, ULy = coordStart, LLx = 0.7578125, LLy = coordEnd, URx = 0.8671875, URy = coordStart, LRx = 0.8671875, LRy = coordEnd },
  BottomRightCorner = { setWidth = true, setHeight = true, ULx = 0.8828125, ULy = coordStart, LLx = 0.8828125, LLy = coordEnd, URx = 0.9921875, URy = coordStart, LRx = 0.9921875, LRy = coordEnd },
  TopEdge = { setHeight = true, ULx = 0.2578125, ULy = "repeatX", LLx = 0.3671875, LLy = "repeatX", URx = 0.2578125, URy = coordStart, LRx = 0.3671875, LRy = coordStart },
  BottomEdge = { setHeight = true, ULx = 0.3828125, ULy = "repeatX", LLx = 0.4921875, LLy = "repeatX", URx = 0.3828125, URy = coordStart, LRx = 0.4921875, LRy = coordStart },
  LeftEdge = { setWidth = true, ULx = 0.0078125, ULy = coordStart, LLx = 0.0078125, LLy = "repeatY", URx = 0.1171875, URy = coordStart, LRx = 0.1171875, LRy = "repeatY" },
  RightEdge = { setWidth = true, ULx = 0.1328125, ULy = coordStart, LLx = 0.1328125, LLy = "repeatY", URx = 0.2421875, URy = coordStart, LRx = 0.2421875, LRy = "repeatY" },
  Center = { ULx = 0, ULy = 0, LLx = 0, LLy = "repeatY", URx = "repeatX", URy = 0, LRx = "repeatX", LRy = "repeatY" },
};
local defaultEdgeSize = 39;		-- the old default

function CustomBackdropTemplateMixin:OnBackdropLoaded()
  if self.customBackdropInfo then
    -- check for invalid info
    if not self.customBackdropInfo.edgeFile and not self.customBackdropInfo.bgFile then
      self.customBackdropInfo = nil;
      return;
    end
    self:ApplyBackdrop();
    do
      local r, g, b = 1, 1, 1;
      if self.customBackdropColor then
        r, g, b = self.customBackdropColor:GetRGB();
      end
      local a = self.customBackdropColorAlpha or 1;
      self:SetBackdropColor(r, g, b, a);
    end
    do
      local r, g, b = 1, 1, 1;
      if self.customBackdropBorderColor then
        r, g, b = self.customBackdropBorderColor:GetRGB();
      end
      local a = self.customBackdropBorderColorAlpha or 1;
      self:SetBackdropBorderColor(r, g, b, a);
    end
    if self.customBackdropBorderBlendMode then
      self:SetBorderBlendMode(self.customBackdropBorderBlendMode);
    end
  end
end

function CustomBackdropTemplateMixin:OnBackdropSizeChanged()
  if self.customBackdropInfo then
    self:SetupTextureCoordinates();
  end
end

function CustomBackdropTemplateMixin:GetEdgeSize()
  if self.customBackdropInfo.edgeSize and self.customBackdropInfo.edgeSize > 0 then
    return self.customBackdropInfo.edgeSize;
  else
    return defaultEdgeSize;
  end
end

local function GetCustomBackdropCoordValue(coord, pieceSetup, repeatX, repeatY)
  local value = pieceSetup[coord];
  if value == "repeatX" then
    return repeatX;
  elseif value == "repeatY" then
    return repeatY;
  else
    return value;
  end
end

local function SetupCustomBackdropTextureCoordinates(region, pieceSetup, repeatX, repeatY)
  region:SetTexCoord(	GetCustomBackdropCoordValue("ULx", pieceSetup, repeatX, repeatY), GetCustomBackdropCoordValue("ULy", pieceSetup, repeatX, repeatY),
      GetCustomBackdropCoordValue("LLx", pieceSetup, repeatX, repeatY), GetCustomBackdropCoordValue("LLy", pieceSetup, repeatX, repeatY),
      GetCustomBackdropCoordValue("URx", pieceSetup, repeatX, repeatY), GetCustomBackdropCoordValue("URy", pieceSetup, repeatX, repeatY),
      GetCustomBackdropCoordValue("LRx", pieceSetup, repeatX, repeatY), GetCustomBackdropCoordValue("LRy", pieceSetup, repeatX, repeatY));
end

function CustomBackdropTemplateMixin:SetupTextureCoordinates()
  local width = self:GetWidth();
  local height = self:GetHeight();
  local effectiveScale = self:GetEffectiveScale();
  local edgeSize = self:GetEdgeSize();
  local edgeRepeatX = max(0, (width / edgeSize) * effectiveScale - 2 - coordStart);
  local edgeRepeatY = max(0, (height / edgeSize) * effectiveScale - 2 - coordStart);

  for pieceName, pieceSetup in pairs(textureUVs) do
    local region = self[pieceName];
    if region then
      if pieceName == "Center" then
        local repeatX = 1;
        local repeatY = 1;
        if self.customBackdropInfo.tile then
          local divisor = self.customBackdropInfo.tileSize;
          if not divisor or divisor == 0 then
            divisor = edgeSize;
          end
          if divisor ~= 0 then
            repeatX = (width / divisor) * effectiveScale;
            repeatY = (height / divisor) * effectiveScale;
          end
        end
        SetupCustomBackdropTextureCoordinates(region, pieceSetup, repeatX, repeatY);
      else
        SetupCustomBackdropTextureCoordinates(region, pieceSetup, edgeRepeatX, edgeRepeatY);
      end
    end
  end
end

function CustomBackdropTemplateMixin:SetupPieceVisuals(piece, setupInfo, pieceLayout)
  local textureInfo = textureUVs[setupInfo.pieceName];
  local tileVerts = false;
  local file;
  if setupInfo.pieceName == "Center" then
    file = self.customBackdropInfo.bgFile;
    tileVerts = self.customBackdropInfo.tile;
  else
    if self.customBackdropInfo.tileEdge ~= false then
      tileVerts = true;
    end
    file = self.customBackdropInfo.edgeFile;
  end
  piece:SetTexture(file, tileVerts, tileVerts);

  local cornerWidth = textureInfo.setWidth and self:GetEdgeSize() or 0;
  local cornerHeight = textureInfo.setHeight and self:GetEdgeSize() or 0;
  piece:SetSize(cornerWidth, cornerHeight);
end

function CustomBackdropTemplateMixin:SetBorderBlendMode(blendMode)
  if not self.customBackdropInfo then
    return;
  end
  for pieceName in pairs(textureUVs) do
    local region = self[pieceName];
    if region and pieceName ~= "Center" then
      region:SetBlendMode(blendMode);
    end
  end
end

function CustomBackdropTemplateMixin:HasBackdropInfo(customBackdropInfo)
  return self.customBackdropInfo == customBackdropInfo;
end

function CustomBackdropTemplateMixin:ClearBackdrop()
  if self.customBackdropInfo then
    for pieceName in pairs(textureUVs) do
      local region = self[pieceName];
      if region then
        region:SetTexture(nil);
      end
    end
    self.customBackdropInfo = nil;
  end
end

function CustomBackdropTemplateMixin:ApplyBackdrop()
  local x, y, x1, y1 = 0, 0, 0, 0;
  if self.customBackdropInfo.bgFile then
    local edgeSize = self:GetEdgeSize();
    x = -edgeSize;
    y = edgeSize;
    x1 = edgeSize;
    y1 = -edgeSize;
    local insets = self.customBackdropInfo.insets;
    if insets then
      x = x + (insets.left or 0);
      y = y - (insets.top or 0);
      x1 = x1 - (insets.right or 0);
      y1 = y1 + (insets.bottom or 0);
    end
  end
  local layout = {
    TopLeftCorner =	{  },
    TopRightCorner =	{  },
    BottomLeftCorner =	{  },
    BottomRightCorner =	{  },
    TopEdge = {  },
    BottomEdge = {  },
    LeftEdge = {  },
    RightEdge = {  },
    Center = { layer = "BACKGROUND", x = x, y = y, x1 = x1, y1 = y1 },
    setupPieceVisualsFunction = CustomBackdropTemplateMixin.SetupPieceVisuals,
  };
  NineSliceUtil.ApplyLayout(self, layout);
  self:SetBackdropColor(1, 1, 1, 1);
  self:SetBackdropBorderColor(1, 1, 1, 1);
  self:SetupTextureCoordinates();
end

-- backwards compatibility API starts here
function CustomBackdropTemplateMixin:SetBackdrop(customBackdropInfo)
  if customBackdropInfo then
    if self:HasBackdropInfo(customBackdropInfo) then
      return;
    end

    if not customBackdropInfo.edgeFile and not customBackdropInfo.bgFile then
      self:ClearBackdrop();
      return;
    end

    self.customBackdropInfo = customBackdropInfo;
    self:ApplyBackdrop();
  else
    self:ClearBackdrop();
  end
end

function CustomBackdropTemplateMixin:GetBackdrop()
  if self.customBackdropInfo then
    -- make a copy because it will be altered to match old API output
    local customBackdropInfo = CopyTable(self.customBackdropInfo);
    -- fill in defaults
    if not customBackdropInfo.bgFile then
      customBackdropInfo.bgFile = "";
    end
    if not customBackdropInfo.edgeFile then
      customBackdropInfo.edgeFile = "";
    end
    if customBackdropInfo.tile == nil then
      customBackdropInfo.tile = false;
    end
    if customBackdropInfo.tileSize == nil then
      customBackdropInfo.tileSize = 0;
    end
    if customBackdropInfo.tileEdge == nil then
      customBackdropInfo.tileEdge = true;
    end
    if not customBackdropInfo.edgeSize then
      customBackdropInfo.edgeSize = self:GetEdgeSize();
    end
    if not customBackdropInfo.insets then
      customBackdropInfo.insets = { };
    end
    if not customBackdropInfo.insets.left then
      customBackdropInfo.insets.left = 0;
    end
    if not customBackdropInfo.insets.right then
      customBackdropInfo.insets.right = 0;
    end
    if not customBackdropInfo.insets.top then
      customBackdropInfo.insets.top = 0;
    end
    if not customBackdropInfo.insets.bottom then
      customBackdropInfo.insets.bottom = 0;
    end
    return customBackdropInfo;
  end
  return nil;
end

function CustomBackdropTemplateMixin:GetBackdropColor()
  if not self.customBackdropInfo then
    return;
  end
  if self.Center then
    return self.Center:GetVertexColor();
  end
end

function CustomBackdropTemplateMixin:SetBackdropColor(r, g, b, a)
  if not self.customBackdropInfo then
    -- Ideally this would throw an error here but the old API just failed silently
    return;
  end
  if self.Center then
    self.Center:SetVertexColor(r, g, b, a or 1);
  end
end

function CustomBackdropTemplateMixin:GetBackdropBorderColor()
  if not self.customBackdropInfo then
    return
  end
  -- return the vertex color of any valid region
  for pieceName in pairs(textureUVs) do
    local region = self[pieceName];
    if region and pieceName ~= "Center" then
      return region:GetVertexColor();
    end
  end
end

function CustomBackdropTemplateMixin:SetBackdropBorderColor(r, g, b, a)
  if not self.customBackdropInfo then
    -- Ideally this would throw an error here but the old API just failed silently
    return;
  end
  for pieceName in pairs(textureUVs) do
    local region = self[pieceName];
    if region and pieceName ~= "Center" then
      region:SetVertexColor(r, g, b, a or 1);
    end
  end
end

gexport()
