class FrameWithPointer(Container):
    pointerOffset = None
    skinCache = {}

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        skinName = attributes.get('skinName', 'general')
        actualSkinClass = SKIN_NAME_TO_CLASS.get(skinName)
        if not FrameWithPointer.skinCache.get(skinName):
            FrameWithPointer.skinCache[skinName] = actualSkinClass()
        self.skin = FrameWithPointer.skinCache[skinName]
        self._pointer = SpriteUnderlay(
            texturePath=
            'res:/UI/Texture/classes/FrameWithPointer/pointer_down_02.png',
            parent=self,
            colorType=attributes.colorType or uiconst.COLORTYPE_UIHILIGHTGLOW,
            opacity=0.95)
        self._background = FrameUnderlay(
            name='__underlay',
            bgParent=self,
            cornerSize=self.skin.backgroundCornerSize,
            offset=self.skin.backgroundOffset,
            texturePath=self.skin.backgroundTexture,
            colorType=attributes.colorType or uiconst.COLORTYPE_UIHILIGHTGLOW,
            opacity=0.95)

    def SetColor(self, color):
        self._background.color = color
        self._pointer.color = color

    def SetAlpha(self, alphaValue):
        self._background.SetAlpha(alphaValue)
        self._pointer.SetAlpha(alphaValue)

    def UpdatePointerPosition(self, positionFlag):
        if positionFlag == uiconst.POINTER_NONE:
            self._pointer.display = False
            return (0, 0)
        SIZE = 24
        BACKOFFSET = 8
        x, y = positionFlag
        self._pointer.displayX = [
            -SIZE + BACKOFFSET, 0, (self.displayWidth - SIZE) / 2,
            self.displayWidth - SIZE, self.displayWidth - BACKOFFSET
        ][x]
        self._pointer.displayY = [
            -SIZE + BACKOFFSET, 0, (self.displayHeight - SIZE) / 2,
            self.displayHeight - SIZE, self.displayHeight - BACKOFFSET
        ][y]
        self._pointer.displayWidth = SIZE
        self._pointer.displayHeight = SIZE
        if y == 0:
            if x == 0:
                self._pointer.displayX = -11
                self._pointer.displayY = -11
                resPath = self.skin.topLeftTexture
                self.pointerOffset = [
                    self._pointer.displayX + 5, self._pointer.displayY + 5
                ]
            elif x == 4:
                self._pointer.displayX = self.displayWidth - 13
                self._pointer.displayY = -11
                resPath = self.skin.topRightTexture
                self.pointerOffset = [
                    self._pointer.displayX + 19, self._pointer.displayY + 5
                ]
            else:
                resPath = self.skin.upTexture
                self.pointerOffset = [
                    self._pointer.displayX + SIZE / 2,
                    self._pointer.displayY + 10
                ]
        elif y == 4:
            if x == 0:
                self._pointer.displayX = -11
                self._pointer.displayY = self.displayHeight - 13
                resPath = self.skin.bottomLeftTexture
                self.pointerOffset = [
                    self._pointer.displayX + 5, self._pointer.displayY + 19
                ]
            elif x == 4:
                self._pointer.displayX = self.displayWidth - 13
                self._pointer.displayY = self.displayHeight - 13
                resPath = self.skin.bottomRightTexture
                self.pointerOffset = [
                    self._pointer.displayX + 19, self._pointer.displayY + 19
                ]
            else:
                resPath = self.skin.downTexture
                self.pointerOffset = [
                    self._pointer.displayX + SIZE / 2,
                    self._pointer.displayY + 14
                ]
        elif x == 0:
            resPath = self.skin.leftTexture
            self.pointerOffset = [
                self._pointer.displayX + 10, self._pointer.displayY + SIZE / 2
            ]
        elif x == 4:
            resPath = self.skin.rightTexture
            self.pointerOffset = [
                self._pointer.displayX + 14, self._pointer.displayY + SIZE / 2
            ]
        self._pointer.SetTexturePath(resPath)
        self._pointer.display = True
        return self.pointerOffset
class GlowSprite(Container):
    default_name = 'GlowSprite'
    default_texturePath = ''
    default_state = uiconst.UI_NORMAL
    default_align = uiconst.TOPLEFT
    default_glowExpand = 0
    default_color = None
    default_rotation = 0.0
    default_iconOpacity = 0.9
    default_gradientStrength = 1.0
    default_color = None

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        self.texturePath = attributes.Get('texturePath', self.default_texturePath)
        self.color = attributes.Get('color', None)
        self.rotation = attributes.Get('rotation', self.default_rotation)
        self.iconOpacity = attributes.Get('iconOpacity', self.default_iconOpacity)
        self.gradientStrength = attributes.get('gradientStrength', self.default_gradientStrength)
        self.color = attributes.get('color', self.default_color)
        self._glowAmount = 0.0
        self.spriteEffect = None
        self.glowExpand = None
        self.icon = SpriteUnderlay(bgParent=self, name='icon', state=uiconst.UI_DISABLED, align=uiconst.TOALL, blendMode=trinity.TR2_SBM_ADD, opacity=self.iconOpacity, colorType=uiconst.COLORTYPE_UIHILIGHTGLOW, color=self.color, texturePath=self.texturePath, rotation=self.rotation)
        self.glowIcon = None
        self.bgGradient = None

    def ConstructGlow(self):
        if not self.glowIcon:
            self.OnSizeUpdate()
            self.glowIcon = SpriteUnderlay(name='glowIcon', bgParent=self, state=uiconst.UI_DISABLED, colorType=uiconst.COLORTYPE_UIHILIGHTGLOW, spriteEffect=self.spriteEffect, padding=-self.glowExpand, blendMode=trinity.TR2_SBM_ADDX2, opacity=0.0, texturePath=self.texturePath, rotation=self.rotation, color=self.color)
            self.bgGradient = SpriteUnderlay(name='bgGradient', bgParent=self, texturePath='res:/UI/Texture/shared/circularGradient.png', opacity=0.0, padding=-self.glowExpand, color=self.color)

    def UpdateSpriteEffect(self, size):
        """
        Use BLUR effect for small icons and GLOW for larger
        """
        if size > 20:
            self.spriteEffect = trinity.TR2_SFX_GLOW
        else:
            self.spriteEffect = trinity.TR2_SFX_BLUR

    def OnSizeUpdate(self):
        w, h = self.GetAbsoluteSize()
        size = max(w, h)
        self.UpdateSpriteEffect(size)
        self.UpdateGlowExpand(size)

    def _OnResize(self, *args):
        self.OnSizeUpdate()

    def UpdateGlowExpand(self, size):
        """
        Make glow expand more for larger icons
        """
        g = size / 20
        g = max(1, min(g, 3))
        self.glowExpand = g
        if self.glowIcon:
            self.glowIcon.padding = (-g,
             -g,
             -g,
             -g)
            self.bgGradient.padding = (-g,
             -g,
             -g,
             -g)

    def SetTexturePath(self, texturePath):
        self.texturePath = texturePath
        self.icon.SetTexturePath(texturePath)
        if self.glowIcon:
            self.glowIcon.SetTexturePath(texturePath)

    def LoadTexture(self, texturePath):
        self.SetTexturePath(texturePath)

    def LoadIcon(self, iconNo, ignoreSize = False):
        texturePath, _ = Icon.ConvertIconNoToResPath(iconNo)
        self.SetTexturePath(texturePath)

    def LoadIconByTypeID(self, typeID, itemID, *args, **kw):
        """ Hack needed since loading texturePaths by typeID/itemID is locked within the Icon class """
        icon = Icon(typeID=typeID, itemID=itemID)
        self.SetTexturePath(icon.texturePath)

    def SetRGBA(self, *color):
        self.color = color
        if self.glowIcon:
            self.glowIcon.SetFixedColor(color)
            self.bgGradient.SetFixedColor(color)

    def SetRGB(self, *args):
        self.SetRGBA(*args)

    def GetRGBA(self):
        return self.icon.GetRGBA()

    def OnMouseEnter(self, *args):
        uicore.animations.MorphScalar(self, 'glowAmount', self.glowAmount, 1.0, duration=uiconst.TIME_ENTRY)

    def OnMouseExit(self, *args):
        uicore.animations.MorphScalar(self, 'glowAmount', self.glowAmount, 0.0, duration=uiconst.TIME_EXIT)

    def OnMouseDown(self, *args):
        uicore.animations.MorphScalar(self, 'glowAmount', self.glowAmount, 1.5, duration=0.1)

    def OnMouseUp(self, *args):
        uicore.animations.MorphScalar(self, 'glowAmount', self.glowAmount, 1.0, duration=0.3)

    @property
    def glowAmount(self):
        return self._glowAmount

    @glowAmount.setter
    def glowAmount(self, value):
        self.ConstructGlow()
        self._glowAmount = value
        self.icon.opacity = self.iconOpacity + value * 0.5
        self.glowIcon.opacity = value * 0.2
        self.bgGradient.opacity = value * 0.3 * self.gradientStrength
        self.glowIcon.display = value > 0.0001

    def SetRotation(self, value):
        self.rotation = value
        self.icon.rotation = value
        if self.glowIcon:
            self.glowIcon.rotation = value