local INCREASED_POWER_TEXTURE = "ZO_IncreasedPowerTexture"
local DECREASED_POWER_TEXTURE = "ZO_DecreasedPowerTexture"

ZO_UnitVisualizer_ArmorDamage = ZO_UnitAttributeVisualizerModuleBase:Subclass()

function ZO_UnitVisualizer_ArmorDamage:New(...)
    return ZO_UnitAttributeVisualizerModuleBase.New(self, ...)
end

function ZO_UnitVisualizer_ArmorDamage:Initialize(layoutData)
    self.layoutData = layoutData
end

local function ApplyPlatformStyleToIncreasedArmorObject(object, bg, frame)
    ApplyTemplateToControl(object.increasedArmorBg, ZO_GetPlatformTemplate(bg))
    ApplyTemplateToControl(object.increasedArmorFrame, ZO_GetPlatformTemplate(frame))
end

local function ApplyPlatformStyleToDecreasedArmorObject(object, armorOverlay)
    ApplyTemplateToControl(object.decreasedArmorOverlay, ZO_GetPlatformTemplate(armorOverlay))
end

local function ApplyPlatformStyleToIncreasedPowerObject(object, glow)
    ApplyTemplateToControl(object.increasedPowerTexture, ZO_GetPlatformTemplate(INCREASED_POWER_TEXTURE))
    ApplyTemplateToControl(object.increasedPowerGlow, ZO_GetPlatformTemplate(glow))
end

local function ApplyPlatformStyleToDecreasedPowerObject(object)
    ApplyTemplateToControl(object.decreasedPowerTexture, ZO_GetPlatformTemplate(DECREASED_POWER_TEXTURE))
end

do
    local g_increasedArmorPools = {}
    local g_decreasedArmorPools = {}
    local g_increasedPowerPools = {}
    local g_decreasedPowerPool

    local function OnPlayControllingTimeline(animation)
        animation.owner:NotifyTakingControlOf(animation.bar)
    end

    local function ReleaseTimeline(animation)
        animation.owner:NotifyEndingControlOf(animation.bar)
        animation.pool:ReleaseObject(animation.key)
    end

    local function ReleaseTimelineIfReversed(animation)
        if animation:IsPlayingBackward() then
            ReleaseTimeline(animation)
        else
            animation.owner:NotifyEndingControlOf(animation.bar)
        end
    end

    local function ResetControl(control)
        control:SetHidden(true)
        control:SetParent(nil)
        control:ClearAnchors()
    end

    function ZO_UnitVisualizer_ArmorDamage:GetOrCreateIncreaseArmorPool()
        if not g_increasedArmorPools[self.layoutData] then
            local function CreateIncreasedArmor(pool)
                local id = pool:GetNextControlId()
                local increasedArmorBg = CreateControlFromVirtual(self.layoutData.increasedArmorBgContainerTemplate, GuiRoot, self.layoutData.increasedArmorBgContainerTemplate, id)
                local increasedArmorFrame = CreateControlFromVirtual(self.layoutData.increasedArmorFrameContainerTemplate, GuiRoot, self.layoutData.increasedArmorFrameContainerTemplate, id)

                local fadeAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("IncreasedArmorFadeAnimation", increasedArmorFrame)
                fadeAnimation:GetFirstAnimation():SetAnimatedControl(increasedArmorBg)
                fadeAnimation:SetHandler("OnPlay", OnPlayControllingTimeline)
                fadeAnimation:SetHandler("OnStop", ReleaseTimelineIfReversed)

                return { increasedArmorBg = increasedArmorBg, increasedArmorFrame = increasedArmorFrame, fadeAnimation = fadeAnimation }
            end

            local function Reset(container)
                ResetControl(container.increasedArmorBg)
                ResetControl(container.increasedArmorFrame)
            end

            g_increasedArmorPools[self.layoutData] = ZO_ObjectPool:New(CreateIncreasedArmor, Reset)
        end
        return g_increasedArmorPools[self.layoutData]
    end

    function ZO_UnitVisualizer_ArmorDamage:GetOrCreateDecreaseArmorPool()
        if not g_decreasedArmorPools[self.layoutData] then
            local function OnFadeAnimationPlay(animation)
                if animation:IsPlayingBackward() then
                    animation.decreasedArmorOverlay.smallAnimation:PlayBackward()
                    animation.decreasedArmorOverlay.smallGlowAnimation:PlayBackward()

                    animation.decreasedArmorOverlay.normalAnimation:PlayBackward()
                    animation.decreasedArmorOverlay.normalGlowAnimation:PlayBackward()

                    animation.decreasedArmorOverlay.expandedAnimation:PlayBackward()
                    animation.decreasedArmorOverlay.expandedGlowAnimation:PlayBackward()
                end
                OnPlayControllingTimeline(animation)
            end
            local function CreateDecreasedArmor(pool)
                local decreasedArmorOverlay = ZO_ObjectPool_CreateControl(self.layoutData.decreasedArmorOverlayContainerTemplate, pool, GuiRoot)

                local fadeAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("DecreasedArmorFadeAnimation", decreasedArmorOverlay)
                fadeAnimation:SetHandler("OnPlay", OnFadeAnimationPlay)
                fadeAnimation:SetHandler("OnStop", ReleaseTimelineIfReversed)
                fadeAnimation.decreasedArmorOverlay = decreasedArmorOverlay

                return { decreasedArmorOverlay = decreasedArmorOverlay, fadeAnimation = fadeAnimation }
            end

            local function Reset(container)
                ResetControl(container.decreasedArmorOverlay)
            end

            g_decreasedArmorPools[self.layoutData] = ZO_ObjectPool:New(CreateDecreasedArmor, Reset)
        end
        return g_decreasedArmorPools[self.layoutData]
    end

    function ZO_UnitVisualizer_ArmorDamage:GetOrCreateIncreasePowerPool()
        if not g_increasedPowerPools[self.layoutData] then
            local function OnIncreasedPowerFadeStopped(animation)
                if animation:IsPlayingBackward() then
                    animation.loopingAnimation:Stop()
                else
                    animation.owner:NotifyEndingControlOf(animation.bar)
                end
            end

            local function CreateIncreasedPower(pool)
                local id = pool:GetNextControlId()
                local increasedPowerTexture = CreateControlFromVirtual(INCREASED_POWER_TEXTURE..self.layoutData.type, GuiRoot, INCREASED_POWER_TEXTURE, id)
                local increasedPowerGlow = CreateControlFromVirtual(self.layoutData.increasedPowerGlowTemplate, GuiRoot, self.layoutData.increasedPowerGlowTemplate, id)

                local fadeAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("IncreasedPowerFadeAnimation", increasedPowerTexture)
                fadeAnimation:GetLastAnimation():SetAnimatedControl(increasedPowerGlow)
                fadeAnimation:SetHandler("OnPlay", OnPlayControllingTimeline)
                fadeAnimation:SetHandler("OnStop", OnIncreasedPowerFadeStopped)

                local loopingAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("IncreasedPowerAnimation", increasedPowerTexture)
                fadeAnimation.loopingAnimation = loopingAnimation
                loopingAnimation:SetHandler("OnStop", ReleaseTimeline)

                return { increasedPowerTexture = increasedPowerTexture, increasedPowerGlow = increasedPowerGlow, fadeAnimation = fadeAnimation, loopingAnimation = loopingAnimation }
            end

            local function Reset(container)
                ResetControl(container.increasedPowerTexture)
                ResetControl(container.increasedPowerGlow)
            end

            g_increasedPowerPools[self.layoutData] = ZO_ObjectPool:New(CreateIncreasedPower, Reset)
        end
        return g_increasedPowerPools[self.layoutData]
    end

    function ZO_UnitVisualizer_ArmorDamage:GetOrCreateDecreasePowerPool()
        if not g_decreasedPowerPool then
            local function CreateDecreasedPower(pool)
                local decreasedPowerTexture = ZO_ObjectPool_CreateControl(DECREASED_POWER_TEXTURE, pool, GuiRoot)

                local fadeAnimation = ANIMATION_MANAGER:CreateTimelineFromVirtual("DecreasedPowerFadeAnimation", decreasedPowerTexture)
                fadeAnimation:SetHandler("OnPlay", OnPlayControllingTimeline)
                fadeAnimation:SetHandler("OnStop", ReleaseTimelineIfReversed)

                return { decreasedPowerTexture = decreasedPowerTexture, fadeAnimation = fadeAnimation }
            end

            local function Reset(container)
                ResetControl(container.decreasedPowerTexture)
            end

            g_decreasedPowerPool = ZO_ObjectPool:New(CreateDecreasedPower, Reset)
        end
        return g_decreasedPowerPool
    end
end

function ZO_UnitVisualizer_ArmorDamage:GetInitialStatValue(stat, attribute, powerType)
    return self:GetInitialValueAndMarkMostRecent(ATTRIBUTE_VISUAL_INCREASED_STAT, stat, attribute, powerType)
         + self:GetInitialValueAndMarkMostRecent(ATTRIBUTE_VISUAL_DECREASED_STAT, stat, attribute, powerType)
end

function ZO_UnitVisualizer_ArmorDamage:CreateInfoTable(control, stat, attribute, power, playIncreaseAnimation, playDecreaseAnimation)
    if control then
        local value = self:GetInitialStatValue(stat, attribute, power)
        return { value = value, lastValue = value, playIncreaseAnimation = playIncreaseAnimation, playDecreaseAnimation = playDecreaseAnimation, barSizeState = ATTRIBUTE_BAR_STATE_NORMAL }
    end
    return nil
end

function ZO_UnitVisualizer_ArmorDamage:OnAdded(healthBarControl, magickaBarControl, staminaBarControl)
    self.barControls =
    {
        [STAT_ARMOR_RATING] = healthBarControl,
        [STAT_POWER] = healthBarControl,
    }

    if IsPlayerActivated() then
        self:InitializeBarValues()
    end

    local function OnSizeChanged(bar, size, instant)
        if bar == healthBarControl then
            local armorRatingInfo = self.barInfo and self.barInfo[STAT_ARMOR_RATING]
            if armorRatingInfo then
                armorRatingInfo.barSizeState = size
                if armorRatingInfo.currentAnimation and armorRatingInfo.currentAnimation.decreasedArmorOverlay then
                    self:UpdateDecreasedArmorEffect(bar, armorRatingInfo, instant)
                end
            end
        end
    end

    self:GetOwner():RegisterCallback("AttributeBarSizeChangingStart", OnSizeChanged)
    EVENT_MANAGER:RegisterForEvent("ZO_UnitVisualizer_ArmorDamage" .. self:GetModuleId(), EVENT_PLAYER_ACTIVATED, function() self:InitializeBarValues() end)
end

function ZO_UnitVisualizer_ArmorDamage:InitializeBarValues()
    local healthBarControl = self.barControls[STAT_ARMOR_RATING]

    if self.barInfo == nil then
        self.barInfo =
        {
            [STAT_ARMOR_RATING] = self:CreateInfoTable(healthBarControl, STAT_ARMOR_RATING, ATTRIBUTE_HEALTH, COMBAT_MECHANIC_FLAGS_HEALTH, self.PlayArmorIncreaseAnimation, self.PlayArmorDecreaseAnimation),
            [STAT_POWER] = self:CreateInfoTable(healthBarControl, STAT_POWER, ATTRIBUTE_HEALTH, COMBAT_MECHANIC_FLAGS_HEALTH, self.PlayPowerIncreaseAnimation, self.PlayPowerDecreaseAnimation),
        }
    else
        self.barInfo[STAT_ARMOR_RATING].value = self:GetInitialStatValue(STAT_ARMOR_RATING, ATTRIBUTE_HEALTH, COMBAT_MECHANIC_FLAGS_HEALTH)
        self.barInfo[STAT_POWER].value = self:GetInitialStatValue(STAT_POWER, ATTRIBUTE_HEALTH, COMBAT_MECHANIC_FLAGS_HEALTH)
    end

    for stat, bar in pairs(self.barControls) do
        self:OnValueChanged(bar, self.barInfo[stat], stat, ANIMATION_INSTANT)
    end
end

function ZO_UnitVisualizer_ArmorDamage:OnUnitChanged()
    self:InitializeBarValues()
end

function ZO_UnitVisualizer_ArmorDamage:IsUnitVisualRelevant(visualType, stat, attribute, powerType)
    if visualType == ATTRIBUTE_VISUAL_INCREASED_STAT or visualType == ATTRIBUTE_VISUAL_DECREASED_STAT then
        return self.barInfo and self.barInfo[stat] ~= nil
    end
    return false
end

function ZO_UnitVisualizer_ArmorDamage:OnUnitAttributeVisualAdded(visualType, stat, attribute, powerType, value)
    self.barInfo[stat].value = self.barInfo[stat].value + value
    self:OnValueChanged(self.barControls[stat], self.barInfo[stat], stat)
end

function ZO_UnitVisualizer_ArmorDamage:OnUnitAttributeVisualUpdated(visualType, stat, attribute, powerType, oldValue, newValue)
    self.barInfo[stat].value = self.barInfo[stat].value + (newValue - oldValue)
    self:OnValueChanged(self.barControls[stat], self.barInfo[stat], stat)
end

function ZO_UnitVisualizer_ArmorDamage:OnUnitAttributeVisualRemoved(visualType, stat, attribute, powerType, value)
    self.barInfo[stat].value = self.barInfo[stat].value - value
    self:OnValueChanged(self.barControls[stat], self.barInfo[stat], stat)
end

function ZO_UnitVisualizer_ArmorDamage:PlayArmorIncreaseAnimation(bar, info, instant)
    local pool = self:GetOrCreateIncreaseArmorPool()
    local container, key = pool:AcquireObject()
    ApplyPlatformStyleToIncreasedArmorObject(container, self.layoutData.increasedArmorBgContainerTemplate, self.layoutData.increasedArmorFrameContainerTemplate)

    local increasedArmorBg = container.increasedArmorBg
    local increasedArmorFrame = container.increasedArmorFrame
    local fadeAnimation = container.fadeAnimation

    fadeAnimation.key = key
    fadeAnimation.owner = self:GetOwner()
    fadeAnimation.pool = pool
    fadeAnimation.bar = bar
    fadeAnimation.instant = instant

    fadeAnimation:GetAnimation(2):SetAnimatedControl(bar.bgContainer)

    increasedArmorBg:SetParent(bar)
    increasedArmorBg:SetHidden(false)

    local increasedArmorOffsets = self.layoutData.increasedArmorOffsets
    local currentOffsets = IsInGamepadPreferredMode() and increasedArmorOffsets.gamepad or increasedArmorOffsets.keyboard
    if not currentOffsets then
        currentOffsets = increasedArmorOffsets.shared
    end

    increasedArmorBg:SetAnchor(TOPLEFT, bar.bgContainer, TOPLEFT, currentOffsets.left, currentOffsets.top)
    increasedArmorBg:SetAnchor(BOTTOMRIGHT, bar.bgContainer, BOTTOMRIGHT, currentOffsets.right, currentOffsets.bottom)

    increasedArmorFrame:SetParent(bar)
    increasedArmorFrame:SetHidden(false)
    
    if instant then
        increasedArmorFrame:SetAnchor(TOPLEFT, bar.bgContainer, TOPLEFT, currentOffsets.left, currentOffsets.top)
        increasedArmorFrame:SetAnchor(BOTTOMRIGHT, bar.bgContainer, BOTTOMRIGHT, currentOffsets.right, currentOffsets.bottom)
        increasedArmorFrame:SetAlpha(1)
        bar.bgContainer:SetAlpha(1)
        increasedArmorBg:SetAlpha(1)

        --this is only meant to advance the playhead to the end so that playing it backwards later works
        fadeAnimation:PlayInstantlyToEnd()
    else
        increasedArmorFrame:SetAnchor(TOPLEFT, bar.bgContainer, TOPLEFT)
        increasedArmorFrame:SetAnchor(BOTTOMRIGHT, bar.bgContainer, BOTTOMRIGHT)

        fadeAnimation:GetAnimation(4):SetTranslateOffsets(-150, -15, currentOffsets.left, currentOffsets.top)
        fadeAnimation:GetAnimation(5):SetTranslateOffsets(150, 15, currentOffsets.right, currentOffsets.bottom)

        fadeAnimation:PlayFromStart()
    end

    return fadeAnimation
end

function ZO_UnitVisualizer_ArmorDamage:PlayArmorDecreaseAnimation(bar, info, instant)
    local pool = self:GetOrCreateDecreaseArmorPool()
    local container, key = pool:AcquireObject()
    ApplyPlatformStyleToDecreasedArmorObject(container, self.layoutData.decreasedArmorOverlayContainerTemplate)

    local animation = container.fadeAnimation
    animation.key = key
    animation.owner = self:GetOwner()
    animation.pool = pool
    animation.bar = bar
    animation.instant = instant

    local decreasedArmorOverlay = container.decreasedArmorOverlay
    decreasedArmorOverlay:SetParent(bar)
    decreasedArmorOverlay:SetHidden(false)
    decreasedArmorOverlay:SetAnchor(CENTER, bar, CENTER)

    ZO_Animation_PlayFromStartOrInstantlyToEnd(animation, instant)

    self:UpdateDecreasedArmorEffect(bar, info, ANIMATION_INSTANT, decreasedArmorOverlay)

    return animation
end

local SMALL_OFFSET = 0
local NORMAL_OFFSET = 1300
local EXPAND_OFFSET = 1700

function ZO_UnitVisualizer_ArmorDamage:UpdateDecreasedArmorEffect(bar, info, instant, decreasedArmorOverlay)
    decreasedArmorOverlay = decreasedArmorOverlay or info.currentAnimation.decreasedArmorOverlay

    local barSizeState = info.barSizeState

    if instant then
        if barSizeState == ATTRIBUTE_BAR_STATE_NORMAL then
            decreasedArmorOverlay.smallAnimation:PlayInstantlyToEnd()
            decreasedArmorOverlay.smallGlowAnimation:PlayInstantlyToEnd()

            decreasedArmorOverlay.normalAnimation:PlayInstantlyToEnd()
            decreasedArmorOverlay.normalGlowAnimation:PlayInstantlyToEnd()

            decreasedArmorOverlay.expandedAnimation:PlayInstantlyToStart()
            decreasedArmorOverlay.expandedGlowAnimation:PlayInstantlyToStart()
        elseif barSizeState == ATTRIBUTE_BAR_STATE_EXPANDED then
            decreasedArmorOverlay.smallAnimation:PlayInstantlyToEnd()
            decreasedArmorOverlay.smallGlowAnimation:PlayInstantlyToEnd()

            decreasedArmorOverlay.normalAnimation:PlayInstantlyToEnd()
            decreasedArmorOverlay.normalGlowAnimation:PlayInstantlyToEnd()

            decreasedArmorOverlay.expandedAnimation:PlayInstantlyToEnd()
            decreasedArmorOverlay.expandedGlowAnimation:PlayInstantlyToEnd()
        elseif barSizeState == ATTRIBUTE_BAR_STATE_SHRUNK then
            decreasedArmorOverlay.smallAnimation:PlayInstantlyToEnd()
            decreasedArmorOverlay.smallGlowAnimation:PlayInstantlyToEnd()

            decreasedArmorOverlay.normalAnimation:PlayInstantlyToStart()
            decreasedArmorOverlay.normalGlowAnimation:PlayInstantlyToStart()

            decreasedArmorOverlay.expandedAnimation:PlayInstantlyToStart()
            decreasedArmorOverlay.expandedGlowAnimation:PlayInstantlyToStart()
        end
    else
        decreasedArmorOverlay.smallAnimation:Stop()
        decreasedArmorOverlay.smallGlowAnimation:Stop()

        decreasedArmorOverlay.normalAnimation:Stop()
        decreasedArmorOverlay.normalGlowAnimation:Stop()

        decreasedArmorOverlay.expandedAnimation:Stop()
        decreasedArmorOverlay.expandedGlowAnimation:Stop()

        if barSizeState == ATTRIBUTE_BAR_STATE_NORMAL then
            decreasedArmorOverlay.smallAnimation:PlayForward()
            decreasedArmorOverlay.smallGlowAnimation:PlayForward()

            decreasedArmorOverlay.normalAnimation:PlayForward()
            decreasedArmorOverlay.normalGlowAnimation:PlayForward()

            decreasedArmorOverlay.expandedAnimation:PlayBackward()
            decreasedArmorOverlay.expandedGlowAnimation:PlayBackward()
        elseif barSizeState == ATTRIBUTE_BAR_STATE_EXPANDED then
            decreasedArmorOverlay.smallAnimation:PlayForward()
            decreasedArmorOverlay.smallGlowAnimation:PlayForward()

            decreasedArmorOverlay.normalAnimation:PlayForward()
            decreasedArmorOverlay.normalGlowAnimation:PlayForward()

            decreasedArmorOverlay.expandedAnimation:PlayForward()
            decreasedArmorOverlay.expandedGlowAnimation:PlayForward()
        elseif barSizeState == ATTRIBUTE_BAR_STATE_SHRUNK then
            decreasedArmorOverlay.smallAnimation:PlayForward()
            decreasedArmorOverlay.smallGlowAnimation:PlayForward()

            decreasedArmorOverlay.normalAnimation:PlayBackward()
            decreasedArmorOverlay.normalGlowAnimation:PlayBackward()

            decreasedArmorOverlay.expandedAnimation:PlayBackward()
            decreasedArmorOverlay.expandedGlowAnimation:PlayBackward()
        end
    end
end


function ZO_UnitVisualizer_ArmorDamage:PlayPowerIncreaseAnimation(bar, info, instant)
    local pool = self:GetOrCreateIncreasePowerPool()
    local container, key = pool:AcquireObject()

    local increasedPowerTexture = container.increasedPowerTexture
    local increasedPowerGlow = container.increasedPowerGlow
    local loopingAnimation = container.loopingAnimation
    local fadeAnimation = container.fadeAnimation

    loopingAnimation.key = key
    loopingAnimation.owner = self:GetOwner()
    loopingAnimation.pool = pool
    loopingAnimation.bar = bar

    fadeAnimation.owner = self:GetOwner()
    fadeAnimation.bar = bar
    fadeAnimation.instant = instant

    increasedPowerTexture:SetParent(bar)
    increasedPowerTexture:SetHidden(false)
    increasedPowerTexture:SetAnchor(LEFT, bar, LEFT, -80, 0)
    increasedPowerTexture:SetAnchor(RIGHT, bar, RIGHT, 80, 0)

    increasedPowerGlow:SetParent(bar)
    increasedPowerGlow:SetHidden(false)
    increasedPowerGlow:SetAnchor(LEFT, bar, LEFT, -18)
    increasedPowerGlow:SetAnchor(RIGHT, bar, RIGHT, 18)
    ApplyPlatformStyleToIncreasedPowerObject(container, self.layoutData.increasedPowerGlowTemplate)

    loopingAnimation:PlayFromStart()
    fadeAnimation:PlayFromStart()

    return fadeAnimation
end

function ZO_UnitVisualizer_ArmorDamage:PlayPowerDecreaseAnimation(bar, info, instant)
    local pool = self:GetOrCreateDecreasePowerPool()
    local container, key = pool:AcquireObject()
    ApplyPlatformStyleToDecreasedPowerObject(container)

    local animation = container.fadeAnimation
    animation.key = key
    animation.owner = self:GetOwner()
    animation.pool = pool
    animation.bar = bar
    animation.instant = instant

    local decreasedPowerTexture = container.decreasedPowerTexture
    decreasedPowerTexture:SetParent(bar)
    decreasedPowerTexture:SetHidden(false)
    decreasedPowerTexture:SetAnchor(LEFT, bar, LEFT, -150, 0)
    decreasedPowerTexture:SetAnchor(RIGHT, bar, RIGHT, 150, 0)

    animation:PlayFromStart()

    return animation
end

function ZO_UnitVisualizer_ArmorDamage:OnValueChanged(bar, info, stat, instant)
    local value = info.value
    local lastValue = info.lastValue
    info.lastValue = value

    if value < 0 then
        if info.currentAnimation then
            info.currentAnimation.instant = instant

            if lastValue > 0 then
                ZO_Animation_PlayBackwardOrInstantlyToStart(info.currentAnimation, instant)
                if instant then
                    bar.bgContainer:SetAlpha(1)
                end
            else
                if instant then
                    info.currentAnimation:PlayInstantlyToEnd()
                end
                return -- already playing the correct animation
            end
        end

        info.currentAnimation = info.playDecreaseAnimation(self, bar, info, instant)
    elseif value > 0 then
        if info.currentAnimation then
            info.currentAnimation.instant = instant

            if lastValue < 0 then
                ZO_Animation_PlayBackwardOrInstantlyToStart(info.currentAnimation, instant)
            else
                if instant then
                    info.currentAnimation:PlayInstantlyToEnd()
                end
                return -- already playing the correct animation
            end
        end

        info.currentAnimation = info.playIncreaseAnimation(self, bar, info, instant)
    else
        if info.currentAnimation then
            info.currentAnimation.instant = instant

            ZO_Animation_PlayBackwardOrInstantlyToStart(info.currentAnimation, instant)
            if instant and lastValue > 0 then
                bar.bgContainer:SetAlpha(1)
            end
            info.currentAnimation = nil
        end
    end
end

function ZO_UnitVisualizer_ArmorDamage:ApplyPlatformStyle()
    local increaseArmorPool = self:GetOrCreateIncreaseArmorPool()
    local decreaseArmorPool = self:GetOrCreateDecreaseArmorPool()
    local increasePowerPool = self:GetOrCreateIncreasePowerPool()
    local decreasePowerPool = self:GetOrCreateDecreasePowerPool()

    local activeObjects = increaseArmorPool:GetActiveObjects()
    for _, object in pairs(activeObjects) do
        ApplyPlatformStyleToIncreasedArmorObject(object, self.layoutData.increasedArmorBgContainerTemplate, self.layoutData.increasedArmorFrameContainerTemplate)
    end

    activeObjects = decreaseArmorPool:GetActiveObjects()
    for _, object in pairs(activeObjects) do
        ApplyPlatformStyleToDecreasedArmorObject(object, self.layoutData.decreasedArmorOverlayContainerTemplate)
    end

    activeObjects = increasePowerPool:GetActiveObjects()
    for _, object in pairs(activeObjects) do
        ApplyPlatformStyleToIncreasedPowerObject(object, self.layoutData.increasedPowerGlowTemplate)
    end

    activeObjects = decreasePowerPool:GetActiveObjects()
    for _, object in pairs(activeObjects) do
        ApplyPlatformStyleToDecreasedPowerObject(object)
    end
end