Imports System.Drawing
Imports System.Windows.Forms
Public Class Animator
    Private Const DEFAULT_POPUP_OPACITY = 0.5
    Private Const DEFAULT_POPUP_SIZE = 30
    Private Const DEFAULT_POPUP_FADE_SPEED = 10
    Private Const DEFAULT_POPUP_FADE_INTERVAL = 250

    ''' <summary>
    ''' Time the popup stays visible between the animations
    ''' </summary>
    Public Property AnimationInterval As Integer
    ''' <summary>
    ''' Basevalue for calculating the time the popup takes to animate
    ''' </summary>
    Public Property AnimationSpeed As Integer
    ''' <summary>
    ''' Opacity the popup animates to (From 0.0 to .., back to 0.0)
    ''' </summary>
    Public Property PopupOpacity As Double
    ''' <summary>
    ''' Color of the popup
    ''' </summary>
    ''' <returns></returns>
    Public Property PopupColor As Color
    ''' <summary>
    ''' Size of the popup in width and height
    ''' </summary>
    Public Property PopupSize As Size

    Public Sub New()
        _PopupSize = New Size(DEFAULT_POPUP_SIZE, DEFAULT_POPUP_SIZE)
        _AnimationSpeed = DEFAULT_POPUP_FADE_SPEED
        _AnimationInterval = DEFAULT_POPUP_FADE_INTERVAL
        _PopupOpacity = DEFAULT_POPUP_OPACITY
        _PopupColor = Color.FromArgb(255, 214, 49)
    End Sub

    Public Async Sub Highlight(Position As Point)
        Dim oForm = GetPopup(Position, PopupSize)
        oForm.Show()
        FadeIn(oForm, _PopupOpacity, _AnimationSpeed / 2)
        Await Task.Delay(_AnimationInterval)
        FadeOut(oForm, _AnimationSpeed * 2)
    End Sub

    Private Function GetPopup(CursorPosition As Point, PopupSize As Size) As frmPopup
        Dim oFormLocation = New Point(
            CursorPosition.X - (PopupSize.Width / 2),
            CursorPosition.Y - (PopupSize.Height / 2))

        Return New frmPopup() With {
            .Location = oFormLocation,
            .StartPosition = FormStartPosition.Manual,
            .Size = PopupSize,
            .MaximumSize = PopupSize,
            .MinimumSize = PopupSize,
            .Opacity = 0,
            .ShowInTaskbar = False,
            .BackColor = _PopupColor,
            .TopMost = True
        }
    End Function

    Private Async Sub FadeIn(ByVal o As Form, finalOpacity As Double, ByVal Optional interval As Integer = 80)
        While o.Opacity < finalOpacity
            Await Task.Delay(interval)
            o.Opacity += 0.05
        End While

        o.Opacity = finalOpacity
    End Sub

    Private Async Sub FadeOut(ByVal o As Form, ByVal Optional interval As Integer = 80)
        While o.Opacity > 0.0
            Await Task.Delay(interval)
            o.Opacity -= 0.05
        End While

        o.Opacity = 0
    End Sub
End Class
