'*****************************************************
'   Code by ROF Electronics @2015-017
'   Coder: Bruno Fascendini (info@rofelectronics.com)
'   Use at your own risk without warranty
'*****************************************************

Imports System
Imports System.Collections
Imports System.Windows
Imports System.Runtime.InteropServices
Imports System.Diagnostics

Public Class LEDWiz
    Implements IDisposable

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
    Public Structure LWZDEVICELIST
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=LWZ_MAX_DEVICES)> _
        Public handle As System.UInt32()
        Public numdevices As Integer
    End Structure

    <DllImport("LEDWiz", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Sub LWZ_SBA(ByVal device As System.UInt32, ByVal bank0 As System.UInt32, ByVal bank1 As System.UInt32, ByVal bank2 As System.UInt32, ByVal bank3 As System.UInt32, ByVal globalPulseSpeed As System.UInt32)
    End Sub

    <DllImport("LEDWiz", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Sub LWZ_PBA(ByVal device As System.UInt32, ByVal brightness As System.UInt32)
    End Sub

    <DllImport("LEDWiz", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Sub LWZ_REGISTER(ByVal h As System.UInt32, ByVal hwnd As System.UInt32)
    End Sub

    <DllImport("LEDWiz", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Sub LWZ_SET_NOTIFY(ByVal notifyProc As MulticastDelegate, ByVal list As System.UInt32)
    End Sub

    Public Delegate Sub NotifyDelegate(ByVal reason As Integer, ByVal newDevice As System.UInt32)

    Private Shared MainWindow As IntPtr = IntPtr.Zero
    Private Shared deviceList As LWZDEVICELIST
    Private Const LWZ_MAX_DEVICES As Integer = 16
    Private Const LWZ_ADD As Integer = 1
    Private Const LWZ_DELETE As Integer = 2

    Public Enum AutoPulseMode As UInteger
        RampUpRampDown = 129
        OnOff = 130
        OnRampDown = 131
        RampUpDown = 132
    End Enum

    Public Sub New(ByVal hwnd As IntPtr)
        MainWindow = hwnd
        deviceList.handle = New UInt32() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        deviceList.numdevices = 0
    End Sub

    Public Shared Sub Notify(ByVal reason As Integer, ByVal newDevice As System.UInt32)
        If reason = LWZ_ADD Then
            LWZ_REGISTER(newDevice, CType(MainWindow.ToInt32, System.UInt32))
        End If
        If reason = LWZ_DELETE Then
        End If
    End Sub

    Public Sub StartupLighting()
        Try
            Dim del As NotifyDelegate = AddressOf Notify
            Dim ptr As IntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(GetType(LWZDEVICELIST)))
            Marshal.StructureToPtr(deviceList, ptr, True)
            LWZ_SET_NOTIFY(del, CType(ptr.ToInt32, System.UInt32))
            deviceList = CType(Marshal.PtrToStructure(ptr, GetType(LWZDEVICELIST)), LWZDEVICELIST)
            Marshal.FreeCoTaskMem(ptr)
        Catch e As Exception
            System.Windows.Forms.MessageBox.Show(e.Message, "LEDWiz Error")
        End Try
    End Sub

    Public Sub ShutdownLighting()
        For i As Integer = 0 To deviceList.numdevices - 1
            LWZ_SBA(DeviceHandles(i), 0, 0, 0, 0, 2)
        Next
    End Sub

    Public Sub SBA(ByVal id As System.UInt32, ByVal bank1 As System.UInt32, ByVal bank2 As System.UInt32, ByVal bank3 As System.UInt32, ByVal bank4 As System.UInt32, ByVal globalPulseSpeed As System.UInt32)
        LWZ_SBA(DeviceHandles(id), bank1, bank2, bank3, bank4, globalPulseSpeed)
    End Sub

    Public Sub PBA(ByVal id As Integer, ByVal val As Byte())
        Dim ptr As IntPtr = Marshal.AllocCoTaskMem(val.Length)
        Marshal.Copy(val, 0, ptr, val.Length)
        LWZ_PBA(DeviceHandles(id), CType(ptr.ToInt32, System.UInt32))
        Marshal.FreeCoTaskMem(ptr)
    End Sub

    Private disposedValue As Boolean = False        ' To detect redundant calls

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: free unmanaged resources when explicitly called
                ShutdownLighting()
                LWZ_SET_NOTIFY(CType(Nothing, System.MulticastDelegate), 0)
            End If

            ' TODO: free shared unmanaged resources
        End If
        Me.disposedValue = True
    End Sub

#Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

    Public ReadOnly Property NumDevices() As Integer
        Get
            Return deviceList.numdevices
        End Get
    End Property

    Public ReadOnly Property DeviceHandles() As System.UInt32()
        Get
            Return deviceList.handle
        End Get
    End Property
End Class
