Option Strict Off
Imports System.Collections
Public Class Class1
    Implements GOverlayPlugin.Interfaces.IPlugin
    Public testvar As Integer = 1

    Private objHost As GOverlayPlugin.Interfaces.IHost
    Public PluginName As String = "GOverlay Example Plugin 1"

    Public Sub Initialize(ByVal Host As GOverlayPlugin.Interfaces.IHost) Implements GOverlayPlugin.Interfaces.IPlugin.Initialize
        objHost = Host
    End Sub

    Public ReadOnly Property Name() As String Implements GOverlayPlugin.Interfaces.IPlugin.Name
        'Return your plugin name
        Get
            Return PluginName
        End Get
    End Property

    Public ReadOnly Property Display() As String Implements GOverlayPlugin.Interfaces.IPlugin.Display
        'Return the display this plugin belongs to
        Get
            Return "lcdsys"
        End Get
    End Property

    Public ReadOnly Property Description() As String Implements GOverlayPlugin.Interfaces.IPlugin.Description
        'Return the display this plugin belongs to
        Get
            Return "Example plugin"
        End Get
    End Property

    Function CallBack(method As String) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.CallBacks
        Try
            Dim returnHT As Hashtable = New Hashtable

            Dim value As Integer = 0

            If method = "willrequestvalues" Then
                'Comes here once per run (only if sensors are used thru here)                
            ElseIf method = "willrequestdisplay" Then
                'objHost.DebugMessage("wrd")
            Else
                'objHost.DebugMessage("grabdata: " & method & " >>> " & hwinfo(method)("value"))
                value = 123
            End If

            returnHT("value") = value

            Return returnHT
        Catch ex As Exception
            objHost.DebugMessage("Error grabbing action : " & method)
        End Try
    End Function

    Function ComboBoxes() As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.ComboBoxes
        'Create custom ComboBox for your configuration to use
        Dim boxes As New Hashtable
        Dim myboxOptions As New Hashtable
        'Set each one of the Combobox options as value, Display Name
        myboxOptions.Add("op1", "My Option 1")
        myboxOptions.Add("op2", "My Option 2")

        'Add the combobox options as the combobox "PLUG.optioncustom1"
        boxes.Add("PLUG.optioncustom1", myboxOptions)
        Return boxes
    End Function

    Function AvailableSensors(pluginOptions As Hashtable) As System.Collections.Generic.Dictionary(Of String, String) Implements GOverlayPlugin.Interfaces.IPlugin.AvailableSensors
        'Create the list of the sensors/elements this plugin has
        'You can access your pluginOptions here as pluginOptions(your_option)    

        'Options: SensorTag, Sensor Display-Name
        Dim sensors As New System.Collections.Generic.Dictionary(Of String, String)
        sensors.Add("PLUG.number", "All features")
        Return sensors
    End Function

    Function LCDSys2_AvailableSensors(pluginOptions As Hashtable) As System.Collections.Generic.Dictionary(Of String, String) Implements GOverlayPlugin.Interfaces.IPlugin.LCDSys2_AvailableSensors
        Return AvailableSensors(pluginOptions)
    End Function

    Function SensorHasCustomDraw(sensor_name As String) As Boolean Implements GOverlayPlugin.Interfaces.IPlugin.SensorHasCustomDraw
        'All sensors are drawn with GOverlay default drawing
        Return True
    End Function

    Public Function PluginOptionsDefault() As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.PluginOptionsDefault
        'Set the default values you want to have on plugin, if the user doesnt change any option, he will have this settings
        Dim options As New Hashtable
        options("timeout") = 5
        Return options
    End Function
    Public Function PluginOptions(pluginCurrentOptions As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.PluginOptions
        'Set the options the user will have when going to the plugins tab and clicking on your plugin
        'The availalbe option_type are teh same as CreateOptions function
        Dim options As New Hashtable
        'Option: option_index as integer, option_data as ArrayList
        'Option_Data: option_type as string, option_label as string, option_name as string (no spaces, no _)
        options.Add(0, New ArrayList({"Text", "Plugin Timeout", "timeout"}))
        Return options
    End Function
    Public Function CreateOptions(sensorId As String, elementData As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.CreateOptions
        'Set the options the user will have when clicking on the element
        'The available option_types are:
        'Text: Input text
        'Combo3: Combo with options (Enabled=0, Disabled=1)
        'Sensors: Combo with available sensors
        'ColorBasic: Combo with basic colors for the regular text font
        'ColorRGB: Combo with common RGB colors = 16bitinteger
        'ComboOnOff: Combo with options (Disabled=0, Enabled=1)
        'ComboYesNo: Combo with options (Yes=Yes, No=No)
        'TextSize: Combo with options (Extra Small=4, Very Small=5, Small=10, Normal=15, Big=20, Very Big=30, Extreme=40)
        'FontStyle2: Combo with options (Regular Font=0, Square Font=1, Numbers Font 1=2
        'Orientation: Combo with options (Horizontal=0, Vertical=1)
        'Here you can also load your custom comboboxes

        Dim options As New Hashtable
        If sensorId = "PLUG.number" Then
            'Option: option_index as integer, option_data as ArrayList
            'Option_Data: option_type as string, option_label as string, option_name as string (no spaces, no _), help text
            options.Add(0, New ArrayList({"Text", "Max Number", "maxnum", "help #1"}))
            options.Add(1, New ArrayList({"Text", "Width", "width", "help #2"}))
            options.Add(2, New ArrayList({"ComboYesNo", "Test Option", "testoption", "help #3"}))
            options.Add(3, New ArrayList({"PLUG.optioncustom1", "Custom combo", "testoptionCombo", "help #4"}))
        End If

        Return options

    End Function

    Public Function LCDSys2_CreateOptions(sensorId As String, elementData As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.LCDSys2_CreateOptions
        'Set the options the user will have when clicking on the element
        'The available option_types are:
        'Text: Input text
        'Combo3: Combo with options (Enabled=0, Disabled=1)
        'Sensors: Combo with available sensors
        'ColorRGB: Combo with common RGB colors = 16bitinteger
        'ComboOnOff: Combo with options (Disabled=0, Enabled=1)
        'ComboYesNo: Combo with options (Yes=Yes, No=No)
        'FontStyle: Combo with options of the fonts the user has installed
        'Orientation: Combo with options (Horizontal=0, Vertical=1)
        'Alignment: Left=-1,Center=0,Right=1
        'Here you can also load your custom comboboxes

        'No options because GOverlay draws instead of us
        Return New Hashtable
    End Function

    Public Function SetDefaultOptions(sensorId As String, elementData As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.SetDefaultOptions
        'Set the default values you want to have on your sensor when its created, if the user doesnt change any option, he will have this settings

        If sensorId = "PLUG.number" Then
            elementData("width") = 100
            elementData("height") = 41
            elementData("maxnum") = 5
        Else
            elementData("width") = 50   'There must be at least one width and height set, otherwise the element wont show on the display-emulator window because it has no size
            elementData("height") = 50
        End If

        Return elementData
    End Function
    Public Function DisplayOnLCD(sensorId As String, elementData As Hashtable, pluginOptions As Hashtable, cacheRuns As Integer) As ArrayList Implements GOverlayPlugin.Interfaces.IPlugin.DisplayOnLCD
        'Function triggered every X refresh rate time.
        'Keep in mind that constat-drawing to the LCD requires time, so its best to only draw if the value changes, do not keep drawing the same number over an over in the same position, it is a bad use of resources.
        'Keep a value of the previous displayed value and compare it with the new one, if both values are the same, there is no need to request a new draw to the LCD.

        '------------------------------------------------------------------------------
        ' Incoming variables to DisplayOnLCD
        '------------------------------------------------------------------------------

        'sensorId is your sensor name defined in AvailableSensors
        'elementData is all the configuration of the element, by default it has: x, y, width, height, you can create more configurations in the CreateOptions function
        'pluginOptions contains your plugin configuration created in the function PluginOptions, this is a global list so you can interact with others plugins configuration, so to load yours, use: pluginOptions(PluginName)
        'cacheRuns counts the number of passes with cache enabled, it resets to zero when the values should be refreshed


        '------------------------------------------------------------------------------
        ' Accessing the Host for getting and setting information from within our plugin
        '------------------------------------------------------------------------------

        'Grab or Set some information from GOverlay to use as needed
        'AccessHost is as follows:
        'Method: retrieve or set
        'Variable: The variable you will work on, available variables:
        '->"LCDSys_Vars": Contains a HashTable of general GOverlay-LCDSysInfo information, some of them:
        '  ->"device_init_ok": Will be True or False depending if LCDSysInfo is inited
        '  ->"Settings_Cache_Enabled": Will be True or False depending if the LCDSysInfo Cache is enabled
        '  ->"Settings_Cache_Max": Will contain the integer value of the max-cache runs
        '->"LCDSys_ICO": Contains Icons->Destination numbers references, for example, you can grab the destination number of the icon for the CPUInfoBox Background, Some of them:
        '  ->"dot"
        '  ->"arrow_down"
        '  ->"arrow_up"
        '  ->"box_cpu"
        '  ->"box_gpu"
        '  ->"box_hdd_on"
        '  ->"box_hdd_off"
        ' "LCDSys_Cache": Contains some Cached values as Hashtable, it is used to store the previous draw-value so we wont re-draw again if the value is the same (to save resources), this gets Reset every X runs defined in GOverlay, so you can store your values and if they dont exist anymore, you can re-draw again.
        '  ->"sensor1_12323546464" contains "1234": This would be the sensor1 value for the element Id 12323546464 draw on the screen the value "1234", so if our new value is not "1234", re-draw
        ' "GLOBAL_GeneralVars": Contains some general information of GOverlay
        '  ->"lcdsys_windows_elements": Contains a Hashtable with all the available elements for LCDSysInfo on the OnWindows Tab
        '  ->"lcdsys_gaming_elements": Contains a Hashtable with all the available elements for LCDSysInfo on the WhileGaming Tab
        '  ->"lcdsys_windows_inited" will be zero after screen clear, so it is useful to only draw background images when this value is zero, after the first pass, this value will be 1
        '  ->"lcdsys_dotype" will be "lcdsys_gaming_elements" when the display is in gaming mode and "lcdsys_windows_elements" when the display is in windows mode
        '  ->"lcdsys_first_run" will be 1 after the first run of the program, before that, the key wont exist
        '->"GLOBAL_CachedValues" is a Hashtable containing the values for all the sensors gathered, if the user is using the Latency element, you will be able to read the latency using this variable since it will be cached in here.
        '  ->"[ping]" might be 123 meaning that the last-readed latency was 123
        '->"GameRunning": Will be True when a game is running and False when no game is running (needs RTSS to work)
        '->"SkypeEnabled": Will be True when Skype is Enabled in the settings and False when is not
        '->"SkypeSplash":  Will be True when this setting is enabled and False when is not
        '->"TSEnabled" Then : Will be True when Teamspeak is Enabled in the settings and False when is not
        '->"TSRunning" Then : Will be True when Teamspeak is running and False when is not
        '->"GOverlayVersion": Will be the current GOverlay Version
        'Sub-Variable: If you want to retrieve a value inside a HashTable, write it here, otherwise set it to "" and it will return the whole HashTable.
        '-> Example: objHost.AccessHost("retrieve","GLOBAL_GeneralVars","lcdsys_first_run",""): Would retrieve 1 if the key exists
        '-> Example: objHost.AccessHost("retrieve","GLOBAL_GeneralVars","",""): Would retrieve the Hashtable that contains the "lcdsys_first_run" key
        'Set-Value: If you are using the "set" method you can change the values by setting here the new value, otherwise set it to ""
        '-> Example: objHost.AccessHost("retrieve","GLOBAL_GeneralVars","lcdsys_first_run","1"): Would set the variable "lcdsys_first_run" to 1

        '------------------------------------------------------------------------------
        'Some Examples connecting to our Host
        '------------------------------------------------------------------------------

        'allSensorsData contains all the running sensors values for you to use if needed so you dont have to grab those sensors yourself.
        Dim allSensorsData As System.Collections.Hashtable = objHost.AccessHost("retrieve", "GLOBAL_CachedValues", "", "")

        If allSensorsData.ContainsKey("[ping]") Then
            objHost.DebugMessage("Our plugin has access to the Latest-Latency report, which is: " & allSensorsData("[ping]"))
        End If

        Dim justGetPing = objHost.AccessHost("retrieve", "GLOBAL_CachedValues", "[ping]", "")
        If (justGetPing Is Nothing) Then
            objHost.DebugMessage("Our plugin has access to the Latest-Latency report without grabing all the sensors, which is: " & allSensorsData("[ping]"))
        End If

        'Grabing our variable (at first it wont exist)
        Dim GetMyVariableBack As Integer = objHost.AccessHost("retrieve", "LCDSys_Cache", "this_is_my_personal_variable", "")
        Dim MaxCache As Integer = objHost.AccessHost("retrieve", "LCDSys_Vars", "Settings_Cache_Max", "")
        Dim TimeToReset As Integer = MaxCache - cacheRuns
        objHost.DebugMessage("My personal variable is " & GetMyVariableBack & " and will get reset in " & TimeToReset & " runs")

        'Setting a variable in the LCDSys_Cache
        objHost.AccessHost("set", "LCDSys_Cache", "this_is_my_personal_variable", 123)

        '------------------------------------------------------------------------------
        'Some examples drawing on the screen
        '------------------------------------------------------------------------------

        If sensorId = "PLUG.number" Then
            Dim x = elementData("x")    'grab X position of the element
            Dim y = elementData("y")    'grab Y position of the element
            Dim arr As New ArrayList

            'You can read your element options in elementData.
            'Remember to check if the values entered are valid, you could be asking for an integer value and the user enters a text.

            testvar = testvar + 1
            If testvar > CInt(elementData("maxnum")) Then
                testvar = 0
            End If

            Dim commandList As New ArrayList()

            'Draw Text (command as string, x as integer, y as integer, text as string, reserve_width as integer, unused as bool, unused as bool, unused as integer, basic_color as integer
            commandList.Add(New ArrayList({"text", x, y, "Test Number " & testvar, 0, False, False, 0, 0}))

            'Square Text (command as string, text as string, x as integer, y as integer, font_width_pixels as integer, font_height_pixels as integer, font_spacing as integer, 16bitcolor as integer)
            'You will need to clear this lines before drawing agian, to clear you can repeat this same draw but with a black color and then draw over it with the text color
            'The font width and height is recommended as width, width*2
            commandList.Add(New ArrayList({"text_square", "Square Font", 0, 50, 10, 10 * 2, 3, convertcolorto16bit(153, 23, 36)}))

            'Wait in milliseconds (command as string, milliseconds to wait)
            commandList.Add(New ArrayList({"wait", 10}))

            'Text Image (command as string, x as integer, y as integer, text as string, font_number)
            'font_number: 2, 3, 4, 5
            commandList.Add(New ArrayList({"text_image", 0, 100, "12345", 3}))

            commandList.Add(New ArrayList({"wait", 10}))

            'Draw Image (command as string, x as integer, y as integer, imagedest as integer)
            commandList.Add(New ArrayList({"image", 0, 130, 164}))

            commandList.Add(New ArrayList({"wait", 10}))

            'Draw Lines (command as string, lines as ArrayList, line_color as string)
            'lines: (x as integer, y as integer)
            'Lines are connected to eachother, pairs of two
            Dim lines As New ArrayList
            lines.Add(New ArrayList({250, 10}))
            lines.Add(New ArrayList({260, 30}))
            commandList.Add(New ArrayList({"draw_lines", lines, convertcolorto16bit(27, 160, 232)}))

            commandList.Add(New ArrayList({"wait", 20}))

            'Draw Rectangle (command as string, x as integer, y as integer, x2 as integer, y2 as integer, line_width as integer, 16bitcolor as integer)
            commandList.Add(New ArrayList({"draw_rectangle", 200, 50, 250, 80, 1, convertcolorto16bit(253, 23, 36)}))

            commandList.Add(New ArrayList({"wait", 10}))

            'Fill Rectangle (command as string, x as integer, y as integer, x2 as integer, y2 as integer, 16bitcolor as integer)
            commandList.Add(New ArrayList({"fill_rectangle", 200, 100, 250, 150, convertcolorto16bit(219, 214, 70)}))

            commandList.Add(New ArrayList({"wait", 20}))

            commandList.Add(New ArrayList({"log", "My plugin option is: " & pluginOptions(PluginName)("timeout")}))


            Return commandList
        End If

        Return New ArrayList()
    End Function

    Public Function LCDSys2_DisplayOnLCD(sensorId As String, elementData As Hashtable, pluginOptions As Hashtable, cacheRuns As Integer) As ArrayList Implements GOverlayPlugin.Interfaces.IPlugin.LCDSys2_DisplayOnLCD

        If sensorId = "PLUG.number" Then
            Dim x = elementData("x")    'grab X position of the element
            Dim y = elementData("y")    'grab Y position of the element
            Dim arr As New ArrayList

            'You can read your element options in elementData.
            'Remember to check if the values entered are valid, you could be asking for an integer value and the user enters a text.

            testvar = testvar + 1
            If testvar > CInt(elementData("maxnum")) Then
                testvar = 0
            End If

            objHost.LCDSys2_Draw_Text_Font(x, y, "Test number" & testvar, 100, 65535, 0, "Arial_20px.bin")
            objHost.LCDSys2_Draw_Icon(0, 130, "weather_cloudy_night_02.png")

            Dim lines As New ArrayList
            lines.Add(New ArrayList({250, 10, 65535}))
            lines.Add(New ArrayList({260, 30, 2990}))
            objHost.LCDSys2_Draw_Lines(lines, True, convertcolorto16bit(27, 160, 232))

            objHost.LCDSys2_Draw_Rectangle(200, 50, 250, 80, convertcolorto16bit(253, 23, 36), 1, 0)

            objHost.LCDSys2_Draw_Rectangle(200, 100, 250, 150, convertcolorto16bit(219, 214, 70), 0, 0)

        End If
        Return New ArrayList
    End Function


    Public Function convertcolorto16bit(cr, cg, cb)

        Dim R As Double
        Dim G As Double
        Dim B As Double

        R = cr / 256 * 32
        G = cg / 256 * 64
        B = cb / 256 * 32

        R = Math.Floor(R)
        G = Math.Floor(G)
        B = Math.Floor(B)

        Dim final As Int32 = (CInt(R) << 11)
        final = final + Int(G << 5)
        final = final + Int(B)

        Return final

    End Function
End Class