Option Strict Off
Imports System.Collections
Imports Microsoft.Win32
Imports System.Text.RegularExpressions
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Security
Imports System.ComponentModel
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.ConstrainedExecution
Imports System.Security.Permissions

Public Class Class1
    Implements GOverlayPlugin.Interfaces.IPlugin
    Public testvar As Integer = 1
    Public lastimagetime As DateTime = DateTime.Now
    Public lastimagenum = 0
    Public lastrandom = 0

    Private objHost As GOverlayPlugin.Interfaces.IHost
    Public PluginName As String = "Slideshow"
    Public LastCache As New System.Collections.Hashtable

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

    Public ReadOnly Property Description() As String Implements GOverlayPlugin.Interfaces.IPlugin.Description
        'Return your plugin name
        Get
            Return "This plugin allows to show a slideshow of pictures on the device. GOverlay is required to be running for it to work and you will have to overwrite all the images on the device for it to work." & vbNewLine & vbNewLine & _
                "Developed by TheLaGmAn"
        End Get
    End Property

    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

    
    Function CallBack(method As String) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.CallBacks
        'Send the request to upload all the files
        'objHost.DebugMessage("ETS2 Plugin - Callback Requested")
        'objHost.DebugMessage("ETS2 Plugin - " & method)
        Try

            Dim returnHT As Hashtable = New Hashtable

            Dim value = 0

            'value = MixSensors(method)

            returnHT("value") = value

            Return returnHT
        Catch ex As Exception
            objHost.DebugMessage("Plugin error: " & ex.Message & ": " & ex.StackTrace)
        End Try
    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)        
        Try

            Dim sensors As New System.Collections.Generic.Dictionary(Of String, String)

            sensors.Add("SS.SlideShow", "SlideShow")

            Return sensors
        Catch ex As Exception
            objHost.DebugMessage("Error loading sensors:" & ex.Message & ": " & ex.StackTrace)
            'MsgBox(ex.Message & ":: " & ex.StackTrace)
        End Try
    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

    Function ComboBoxes() As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.ComboBoxes
        'Create custom ComboBox for your configuration to use
        Dim boxes As New Hashtable

        Return boxes
    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
        elementData("width") = 320
        elementData("height") = 240
        elementData("font_style") = 0
        elementData("basic_color") = 0
        elementData("font_size") = 1
        elementData("font_color") = 0
        elementData("font_transform") = 0

        Return elementData
    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

        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 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("itime") = "15"
        options("irandom") = 0
        options("i1") = "1"
        options("i2") = "50"
        options("i3") = "52"
        options("i4") = "54"
        options("i5") = "56"
        options("i6") = "58"
        options("i7") = "60"
        options("i8") = "62"
        options("i9") = "64"
        options("i10") = "66"

        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 _)
        Dim pos = 13
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Time Between images in seconds", "itime"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"ComboYesNo", "Random slideshow?", "irandom"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #1", "i1"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #2", "i2"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #3", "i3"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #4", "i4"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #5", "i5"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #6", "i6"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #7", "i7"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #8", "i8"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #9", "i9"}))
        pos = pos - 1
        options.Add(pos, New ArrayList({"Text", "Pos of Image #10", "i10"}))

        Return options
    End Function

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

        Dim dt1970 As DateTime = New DateTime(1970, 1, 1)
        Dim current As DateTime = DateTime.Now
        Dim span As TimeSpan = current - lastimagetime
        Dim passed_between = span.TotalMilliseconds.ToString()
        passed_between = passed_between / 1000



        Dim selectedtime As Integer = objHost.AccessHost("plugin_options", PluginName, "itime", "")

        Dim rand As Integer = objHost.AccessHost("plugin_options", PluginName, "irandom", "")
        'objHost.DebugMessage("random: " & rand)

        'objHost.DebugMessage("check " & passed_between & " vs " & selectedtime)

        Dim commandList2 As New ArrayList()

        If passed_between > selectedtime Then
            lastimagetime = DateTime.Now

            Dim image_number = 0

            If rand = 1 Then
                'objHost.DebugMessage("passed time: random")
                Dim keep = True
                Dim RandomNumber = Int((10 - 1 + 1) * Rnd()) + 1
                If RandomNumber = lastrandom Then
                    RandomNumber = Int((10 - 1 + 1) * Rnd()) + 1
                End If
                lastrandom = RandomNumber
                image_number = RandomNumber
                image_number = objHost.AccessHost("plugin_options", PluginName, "i" & image_number, "")
                'objHost.DebugMessage("random got: " & RandomNumber)
            Else
                'objHost.DebugMessage("passed time: linear")
                image_number = lastimagenum + 1
                lastimagenum = lastimagenum + 1
                If (image_number > 0 And image_number < 11) Then
                    image_number = objHost.AccessHost("plugin_options", PluginName, "i" & image_number, "")
                Else
                    lastimagenum = 0
                    image_number = objHost.AccessHost("plugin_options", PluginName, "i1", "")
                End If
            End If


            objHost.DebugMessage("show image: " & image_number)
            commandList2.Add(New ArrayList({"clear"}))
            commandList2.Add(New ArrayList({"wait", 200}))
            commandList2.Add(New ArrayList({"image", 0, 0, image_number}))
        End If



        Return commandList2

    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

    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



#Region "Native API Signatures and Types"

    ''' <summary>
    ''' Access rights for file mapping objects
    ''' http://msdn.microsoft.com/en-us/library/aa366559.aspx
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum FileMapAccess
        FILE_MAP_COPY = 1
        FILE_MAP_WRITE = 2
        FILE_MAP_READ = 4
        FILE_MAP_ALL_ACCESS = &HF001F
    End Enum


    ''' <summary>
    ''' Represents a wrapper class for a file mapping handle. 
    ''' </summary>
    ''' <remarks></remarks>
    <SuppressUnmanagedCodeSecurity(), _
    HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort:=True)> _
    Friend NotInheritable Class SafeFileMappingHandle
        Inherits SafeHandleZeroOrMinusOneIsInvalid

        <SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode:=True)> _
        Private Sub New()
            MyBase.New(True)
        End Sub

        <SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode:=True)> _
        Public Sub New(ByVal handle As IntPtr, ByVal ownsHandle As Boolean)
            MyBase.New(ownsHandle)
            MyBase.SetHandle(handle)
        End Sub

        <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), _
        DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Private Shared Function CloseHandle(ByVal handle As IntPtr) _
        As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function

        Protected Overrides Function ReleaseHandle() As Boolean
            Return SafeFileMappingHandle.CloseHandle(MyBase.handle)
        End Function

    End Class


    Friend ReadOnly INVALID_HANDLE_VALUE As New IntPtr(-1)


    ''' <summary>
    ''' The class exposes Windows APIs used in this code sample.
    ''' </summary>
    ''' <remarks></remarks>
    <SuppressUnmanagedCodeSecurity()> _
    Friend Class NativeMethod

        ''' <summary>
        ''' Opens a named file mapping object.
        ''' </summary>
        ''' <param name="dwDesiredAccess">
        ''' The access to the file mapping object. This access is checked against 
        ''' any security descriptor on the target file mapping object.
        ''' </param>
        ''' <param name="bInheritHandle">
        ''' If this parameter is TRUE, a process created by the CreateProcess 
        ''' function can inherit the handle; otherwise, the handle cannot be 
        ''' inherited.
        ''' </param>
        ''' <param name="lpName">
        ''' The name of the file mapping object to be opened.
        ''' </param>
        ''' <returns>
        ''' If the function succeeds, the return value is an open handle to the 
        ''' specified file mapping object.
        ''' </returns>
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Public Shared Function OpenFileMapping( _
            ByVal dwDesiredAccess As FileMapAccess, _
            ByVal bInheritHandle As Boolean, _
            ByVal lpName As String) _
            As SafeFileMappingHandle
        End Function


        ''' <summary>
        ''' Maps a view of a file mapping into the address space of a calling 
        ''' process.
        ''' </summary>
        ''' <param name="hFileMappingObject">
        ''' A handle to a file mapping object. The CreateFileMapping and 
        ''' OpenFileMapping functions return this handle.
        ''' </param>
        ''' <param name="dwDesiredAccess">
        ''' The type of access to a file mapping object, which determines the 
        ''' protection of the pages.
        ''' </param>
        ''' <param name="dwFileOffsetHigh">
        ''' A high-order DWORD of the file offset where the view begins.
        ''' </param>
        ''' <param name="dwFileOffsetLow">
        ''' A low-order DWORD of the file offset where the view is to begin.
        ''' </param>
        ''' <param name="dwNumberOfBytesToMap">
        ''' The number of bytes of a file mapping to map to the view. All bytes 
        ''' must be within the maximum size specified by CreateFileMapping.
        ''' </param>
        ''' <returns>
        ''' If the function succeeds, the return value is the starting address of
        ''' the mapped view.
        ''' </returns>
        <DllImport("Kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Public Shared Function MapViewOfFile( _
            ByVal hFileMappingObject As SafeFileMappingHandle, _
            ByVal dwDesiredAccess As FileMapAccess, _
            ByVal dwFileOffsetHigh As UInt32, _
            ByVal dwFileOffsetLow As UInt32, _
            ByVal dwNumberOfBytesToMap As UInt32) _
            As IntPtr
        End Function


        ''' <summary>
        ''' Unmaps a mapped view of a file from the calling process's address 
        ''' space.
        ''' </summary>
        ''' <param name="lpBaseAddress">
        ''' A pointer to the base address of the mapped view of a file that is to 
        ''' be unmapped.
        ''' </param>
        ''' <returns></returns>
        <DllImport("Kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Public Shared Function UnmapViewOfFile( _
            ByVal lpBaseAddress As IntPtr) _
            As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function

    End Class

#End Region
End Class