Option Strict On

Imports Mbark.Threading
Imports Mbark.UI

Imports System.Drawing
Imports System.Delegate
Imports System.IO
Imports System.Text
Imports System.Threading
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Tcp
Imports System.Xml.Serialization

Imports Olympus
Imports MVSmartControl
Imports MVVideoSourceControl

Imports Belikov
Imports Belikov.GenuineChannels
Imports Belikov.GenuineChannels.BroadcastEngine
Imports Belikov.GenuineChannels.DotNetRemotingLayer


Namespace Mbark.Sensors
    Public Class OlympusCamera
        Inherits BaseSensor

#Region " Windows Form Designer generated code "

        Public Sub New()
            MyBase.New()

            'This call is required by the Windows Form Designer.
            InitializeComponent()

            'Add any initialization after the InitializeComponent() call
            UserNew()
        End Sub

        'UserControl overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.

        Friend WithEvents mOlympusMessageCtrl As Syncfusion.Windows.Forms.Tools.GradientLabel
        Friend WithEvents MVLiveControl As AxMVSmartControl.AxMVSmartControl
        Friend WithEvents CVideoSourceComboBox As AxMVVideoSourceControl.AxCVideoSourceComboBox
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(OlympusCamera))
            Me.mOlympusMessageCtrl = New Syncfusion.Windows.Forms.Tools.GradientLabel
            Me.MVLiveControl = New AxMVSmartControl.AxMVSmartControl
            Me.CVideoSourceComboBox = New AxMVVideoSourceControl.AxCVideoSourceComboBox
            Me.InnerPanel.SuspendLayout()
            CType(Me.OuterPanel, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.OuterPanel.SuspendLayout()
            Me.MainPanel.SuspendLayout()
            CType(Me.MVLiveControl, System.ComponentModel.ISupportInitialize).BeginInit()
            CType(Me.CVideoSourceComboBox, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.SuspendLayout()
            '
            'ActivateSensorButton
            '
            Me.ActivateSensorButton.Name = "ActivateSensorButton"
            '
            'CancelSensorButton
            '
            Me.CancelSensorButton.Name = "CancelSensorButton"
            '
            'TimeoutIndicator
            '
            Me.TimeoutIndicator.Name = "TimeoutIndicator"
            '
            'InnerPanel
            '
            Me.InnerPanel.Name = "InnerPanel"
            '
            'OuterPanel
            '
            Me.OuterPanel.Name = "OuterPanel"
            '
            'MainPanel
            '
            Me.MainPanel.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
            Me.MainPanel.BackColor = System.Drawing.SystemColors.Control
            Me.MainPanel.Controls.Add(Me.CVideoSourceComboBox)
            Me.MainPanel.Controls.Add(Me.MVLiveControl)
            Me.MainPanel.Controls.Add(Me.mOlympusMessageCtrl)
            Me.MainPanel.Dock = System.Windows.Forms.DockStyle.Fill
            Me.MainPanel.Location = New System.Drawing.Point(0, 0)
            Me.MainPanel.Name = "MainPanel"
            Me.MainPanel.Size = New System.Drawing.Size(294, 166)
            '
            'mOlympusMessageCtrl
            '
            Me.mOlympusMessageCtrl.BackgroundColor = New Syncfusion.Drawing.BrushInfo(Syncfusion.Drawing.GradientStyle.Vertical, System.Drawing.Color.FromArgb(CType(237, Byte), CType(240, Byte), CType(247, Byte)), System.Drawing.SystemColors.ActiveCaptionText)
            Me.mOlympusMessageCtrl.BorderSides = CType((((System.Windows.Forms.Border3DSide.Left Or System.Windows.Forms.Border3DSide.Top) _
                        Or System.Windows.Forms.Border3DSide.Right) _
                        Or System.Windows.Forms.Border3DSide.Bottom), System.Windows.Forms.Border3DSide)
            Me.mOlympusMessageCtrl.BorderStyle = System.Windows.Forms.Border3DStyle.Bump
            Me.mOlympusMessageCtrl.Dock = System.Windows.Forms.DockStyle.Fill
            Me.mOlympusMessageCtrl.Font = New System.Drawing.Font("Microsoft Sans Serif", 14.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
            Me.mOlympusMessageCtrl.Location = New System.Drawing.Point(0, 0)
            Me.mOlympusMessageCtrl.Name = "mOlympusMessageCtrl"
            Me.mOlympusMessageCtrl.Size = New System.Drawing.Size(294, 166)
            Me.mOlympusMessageCtrl.TabIndex = 6
            Me.mOlympusMessageCtrl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
            '
            'MVLiveControl
            '
            Me.MVLiveControl.ContainingControl = Me
            Me.MVLiveControl.Dock = System.Windows.Forms.DockStyle.Fill
            Me.MVLiveControl.Location = New System.Drawing.Point(0, 0)
            Me.MVLiveControl.Name = "MVLiveControl"
            Me.MVLiveControl.OcxState = CType(resources.GetObject("MVLiveControl.OcxState"), System.Windows.Forms.AxHost.State)
            Me.MVLiveControl.Size = New System.Drawing.Size(294, 166)
            Me.MVLiveControl.TabIndex = 7
            '
            'CVideoSourceComboBox
            '
            Me.CVideoSourceComboBox.ContainingControl = Me
            Me.CVideoSourceComboBox.Location = New System.Drawing.Point(72, 120)
            Me.CVideoSourceComboBox.Name = "CVideoSourceComboBox"
            Me.CVideoSourceComboBox.OcxState = CType(resources.GetObject("CVideoSourceComboBox.OcxState"), System.Windows.Forms.AxHost.State)
            Me.CVideoSourceComboBox.Size = New System.Drawing.Size(192, 24)
            Me.CVideoSourceComboBox.TabIndex = 8
            Me.CVideoSourceComboBox.Visible = False
            '
            'OlympusCamera
            '
            Me.Name = "OlympusCamera"
            Me.InnerPanel.ResumeLayout(False)
            CType(Me.OuterPanel, System.ComponentModel.ISupportInitialize).EndInit()
            Me.OuterPanel.ResumeLayout(False)
            Me.MainPanel.ResumeLayout(False)
            CType(Me.MVLiveControl, System.ComponentModel.ISupportInitialize).EndInit()
            CType(Me.CVideoSourceComboBox, System.ComponentModel.ISupportInitialize).EndInit()
            Me.ResumeLayout(False)

        End Sub

#End Region

        Private Const ZoomPropertyName As String = "Zoom"
        Private Const ResolutionPropertyName As String = "Resolution"
        Private Const WBPropertyName As String = "WB"
        Private Const LCDPropertyName As String = "LCD"
        Private Const FlashPropertyName As String = "Flash"
        Private Const ExposurePropertyName As String = "Exposure"

        Private Const ConfigurationExpirationTime As Integer = 150000

        Private mGtcpChannel As GenuineTcp.GenuineTcpChannel
        Private mCamera As IFaceSensor
        Private mCaptureIndex As Integer = 0
        Private mIsConfigured As Boolean = False
        Private mUseNineCameraRig As Boolean

        Private mActive As Boolean = True
        Protected Delegate Function ProcessDelegate() As Object
        Protected Delegate Function CaptureDelegate(ByVal CmdGuid As Guid) As Object
        Protected Delegate Sub ConfigurationDelegate(ByVal config As SensorConfiguration)

        Private mGtcpChannelIsRegistered As Boolean
        Private Sub UserNew()
            CreateCamera()
        End Sub

        Private CameraServerURL As String = "OlympusServerURL.txt"
        Private Sub CreateCamera()

            Try
                If Not mIsAlreadyConnected Then
                    Dim serializer As New XmlSerializer(GetType(OlympusSettings))
                    Dim settingsFile As New StreamReader(IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configurations\OlympusSettings.xml"))
                    Dim settings As OlympusSettings = DirectCast(serializer.Deserialize(settingsFile), OlympusSettings)
                    ConfigURL = settings.CameraServerURL
                    mUseNineCameraRig = settings.UseNineCameraRig

                    Dim connectionProperties As IDictionary = New Hashtable
                    connectionProperties("MaxTimeSpanToReconnect") = "10000"
                    connectionProperties("ReconnectTries") = "10"
                    mGtcpChannel = New GenuineTcp.GenuineTcpChannel(connectionProperties, Nothing, Nothing)
                    ChannelServices.RegisterChannel(mGtcpChannel)
                    mGtcpChannelIsRegistered = True

                    mCamera = DirectCast(Activator.GetObject(GetType(IFaceSensor), ConfigURL), IFaceSensor)

                    WritableRequiresReview = True
                    WritableHasLivePreview = False
                    WritableDownloadIsCancellable = True
                    WritablePercentDownloadedIsMeaningful = True
                    WritableRequiresConfiguration = True

                    WritableHasConfigurationClass = True
                    WritableConfigurationClassName = "Mbark.Sensors.OlympusConfiguration"
                    InitializeMontiVision()
                End If
            Catch ex As DirectoryNotFoundException
                PrettyPrintException(UICulture, ex)
            End Try


        End Sub

        Public Overrides ReadOnly Property IsActive() As Boolean
            Get
                Return mActive
            End Get
        End Property

        Private mName As String = "Olympus Camera"
        Public Overrides ReadOnly Property FriendlyName() As String
            Get
                Return mName
            End Get
        End Property

        Private mConfigURL As String
        Private Property ConfigURL() As String
            Get
                Return mConfigURL
            End Get
            Set(ByVal value As String)
                mConfigURL = value
            End Set
        End Property

        Private mIsAlreadyConnected As Boolean = False

        Private mModality As SensorModality = SensorModality.Face
        Public Overrides ReadOnly Property Modality() As SensorModality
            Get
                Return mModality
            End Get
        End Property


#Region "       Initialization         "
        Public Overrides ReadOnly Property InitializationCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static init As AsyncCommandTemplate
                If init Is Nothing Then
                    init = New AsyncCommandTemplate
                    With init
                        .TargetMethod = CreateDelegate(GetType(ProcessDelegate), Me, "Initialization")
                        .ExpirationTime = 307000
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return init
            End Get
        End Property

        'Initialization helper function 
        Private Function Initialization() As Object
            DisplayInstruction()
            WritableRequiresRecovery = False
            If mCamera Is Nothing Then CreateCamera()
            Dim expectedCameraCount As Integer
            If Not mUseNineCameraRig Then expectedCameraCount = 1 Else expectedCameraCount = 9

            Try
                With mCamera
                    If Not mIsAlreadyConnected Then
                        If .Init(mUseNineCameraRig) Then
                            If mCamera.CameraCount <> expectedCameraCount Then
                                WritableRequiresRecovery = True
                                MarkAsOffline()
                                Throw New InitializationFailureException("Olympus: Initialization failed.")
                            End If
                            mIsAlreadyConnected = True
                            MVLiveControl.Visible = True
                            MarkAsOnline()
                        Else
                            WritableRequiresRecovery = True
                            MarkAsOffline()
                            Throw New InitializationFailureException("Olympus: Initialization failed.")
                        End If
                    End If
                End With
            Catch ex As Exception
                MarkAsOffline()
                WritableRequiresRecovery = True
                Throw (New InitializationFailureException("Olympus: Initialization failed.", ex))
            End Try

        End Function
        Private mSensorProperties As New SensorProperties
        Private Sub SensorProperties()
            mSensorProperties.Manufacturer = "Olympus"
            'Private mModuleVersion As String = "3.4"
            'Private mModuleName As String = "Camedia SDK"
            mSensorProperties.Modality = Modality
        End Sub
#End Region

#Region "       Configuration         "
        Public Overrides ReadOnly Property ConfigurationCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static config As AsyncCommandTemplate
                If config Is Nothing Then
                    config = New AsyncCommandTemplate
                    With config
                        .TargetMethod = CreateDelegate(GetType(ConfigurationDelegate), Me, "Configure")
                        .ExpirationTime = ConfigurationExpirationTime
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return config
            End Get
        End Property

        Public Sub Configure(ByVal config As SensorConfiguration)

            If config Is Nothing Then
                mIsConfigured = True
                MyBase.MarkAsOnline()
                Return
            End If

            Try
                If Not mIsConfigured Then
                    Dim oc As OlympusConfiguration = DirectCast(config, OlympusConfiguration)
                    Dim cameraProperties As New Hashtable
                    With cameraProperties
                        .Add(ZoomPropertyName, oc.Zoom)
                        .Add(ResolutionPropertyName, oc.Resolution)
                        .Add(WBPropertyName, oc.WhiteBalance)
                        .Add(LCDPropertyName, oc.LCD)
                        .Add(FlashPropertyName, oc.Flash)
                        .Add(ExposurePropertyName, oc.Exposure)
                    End With
                    mCamera.SaveCaptureProperties(cameraProperties)
                    mIsConfigured = True
                End If
                MyBase.MarkAsOnline()
            Catch ex As Exception
                Debugging.Break(ex)
            End Try
        End Sub
#End Region

#Region "       Uninitialization        "
        Public Overrides Sub Uninitialize()
            Try
                MVLiveControl.Visible = False
                MyBase.Uninitialize()

                If Me.mGtcpChannelIsRegistered Then
                    ChannelServices.UnregisterChannel(mGtcpChannel)
                    mGtcpChannelIsRegistered = False
                End If

                mIsAlreadyConnected = False

            Catch ex As Exception
                Debugging.Break(ex)
            End Try

        End Sub

        Public Overrides Sub DeleteInternalImages()
            If mIsAlreadyConnected Then mCamera.DeleteAll(mUseNineCameraRig)
        End Sub
#End Region

#Region "       Capture         "
        Public Overrides ReadOnly Property CaptureCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static Capture As AsyncCommandTemplate
                If Capture Is Nothing Then
                    Capture = New AsyncCommandTemplate
                    With Capture
                        .TargetMethod = CreateDelegate(GetType(ProcessDelegate), Me, "CaptureImage")
                        .ExpirationTime = 200000
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return Capture
            End Get
        End Property

        Private mIndexTable As New Hashtable
#Region "CaptureImage"
        Private Function CaptureImage() As Object
            Dim ErrorCase As Integer = 1
            Dim PictureIndexList() As Integer
            Dim Thumbnail As Bitmap = Nothing
            Try
                With mCamera
                    mOlympusMessageCtrl.Visible = True
                    MVLiveControl.Visible = False

                    If Not mIsAlreadyConnected Then ErrorCase = 1
                    'Must Open connection before capture
                    'If Not .RequireConnect Then ErrorCase = 1
                    'Check if the camera have space for storage
                    'If .IsFull Then ErrorCase = 2

                    DisplayInstruction(SensorMessages.Messages.CapturingBiometricDataDotDotDot)

                    'capture images
                    If .Capture(mUseNineCameraRig) Then
                        PictureIndexList = .GetPictureIndexList
                        Dim ThumbnailImages(.CameraCount - 1)()() As Byte
                        Dim CameraID() As String
                        DisplayInstruction(SensorMessages.Messages.DownloadingThumbnailsDotDotDot)
                        'Download Thumbnail
                        If .DownloadThumbnail(PictureIndexList) Then
                            ThumbnailImages = .Thumbnails
                            CameraID = .GetCameraID
                            If mUseNineCameraRig Then
                                Thumbnail = SetThumbnails(ThumbnailImages, CameraID)
                            Else
                                Dim NewBitmap As New Bitmap(120, 160)
                                Dim g As Graphics = Graphics.FromImage(NewBitmap)
                                g.DrawImage(CovertImageToBitmap(ThumbnailImages(0)(0)), 0, 0)
                                Thumbnail = NewBitmap
                            End If
                            DisplayInstruction()
                            mCaptureIndex += 1
                            WritableLatestThumbnail = Thumbnail
                            Dim SplitIDName() As String = System.Threading.Thread.CurrentThread.Name.ToString.Split(" ".ToCharArray)
                            Dim CommandID As New Guid(SplitIDName(1))
                            mIndexTable.Add(CommandID, PictureIndexList)
                            Me.LastReviewImageAcceptable = True
                            MarkAsOnline()
                            MVLiveControl.Visible = True
                            Return Nothing
                        Else
                            ErrorCase = 1
                        End If
                    Else
                        ErrorCase = 1
                    End If
                End With
                'error exceptions
                DisplayInstruction(SensorMessages.Messages.CaptureFailure)
                Select Case ErrorCase
                    Case 1
                        mIsAlreadyConnected = False
                        MarkAsOffline()
                        Throw New SensorException
                    Case 2
                        MarkAsOnline()
                        Throw New CaptureFailureException
                End Select
            Catch ex As Exception
                mIsAlreadyConnected = False
                MarkAsOffline()
                Throw New SensorException("Olympus: Recording failed.", ex)
            Finally
                DisplayInstruction()
            End Try
        End Function
#End Region

        Private Function CovertImageToBitmap(ByVal bytearray() As Byte) As Image
            Dim s As MemoryStream
            s = New MemoryStream(bytearray)
            Dim img As Image = Bitmap.FromStream(s)
            img.RotateFlip(RotateFlipType.Rotate90FlipNone)
            Return img
        End Function
        'Create and sort thumbnails into one bitmap object
        Private Function SetThumbnails(ByVal ImgByteArray()()() As Byte, ByVal CamID() As String) As Bitmap
            Dim NewBitmap As New Bitmap(400, 520)
            Dim g As Graphics = Graphics.FromImage(NewBitmap)
            Dim s As MemoryStream
            Dim Index, x, y As Integer
            Dim SpacePadding As Integer = 10
            For c As Integer = 0 To ImgByteArray.Length - 1
                For i As Integer = 0 To ImgByteArray(c).Length - 1

                    Dim img As Image = CovertImageToBitmap(ImgByteArray(c)(i))
                    Index = CInt(CamID(c))

                    'Row
                    Select Case Index
                        Case 1, 4, 7
                            x = SpacePadding
                        Case 2, 5, 8
                            x = img.Width + (SpacePadding * 2)
                        Case 3, 6, 9
                            x = (img.Width * 2) + (SpacePadding * 3)
                    End Select
                    'Column
                    Select Case Index
                        Case 1, 2, 3
                            y = SpacePadding
                        Case 4, 5, 6
                            y = img.Height + (SpacePadding * 2)
                        Case 7, 8, 9
                            y = (img.Height * 2) + (SpacePadding * 3)
                    End Select
                    g.DrawImage(img, x, y)
                Next
            Next
            Return NewBitmap
        End Function
#End Region

#Region "       Download        "
        Private mDownloadedImages As CaptureResultCollection

        Protected Overrides Function CreateDownloadCommand(ByVal id As Guid) As AsyncCommand
            Dim DownloadCommand As New AsyncCommand(DownloadCommandTemplate)
            DownloadCommand.TargetMethodArg(0) = id
            Return DownloadCommand
        End Function
        Private mExpirtaionTime As Integer = 150000
        Public Overrides ReadOnly Property DownloadCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static download As AsyncCommandTemplate
                If download Is Nothing Then
                    download = New AsyncCommandTemplate
                    With download
                        .TargetMethod = CreateDelegate(GetType(DownloadDelegate), Me, "DownloadImage")
                        Dim args As Object() = {Guid.Empty}
                        .TargetMethodArgs(args)
                        .ExpirationTime = mExpirtaionTime
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return download
            End Get
        End Property
        Public Overrides Function CancelDownload() As Boolean
            WritableLatestDownloadWasSuccessful = False
            WritableLatestDownloadWasCanceled = True
            System.Threading.Thread.Sleep(1000)
            WritablePercentDownloaded = 0
        End Function
        Private Sub ResetDownloadFlags()
            WritableIsTimeOut = False
            WritableLatestDownloadWasSuccessful = False
            WritableLatestDownloadWasCanceled = False
            mCamera.IsDownloadCanceled = False
            WritablePercentDownloaded = 0
            mDownloadedImages = Nothing
        End Sub

        Private Delegate Function DownloadDelegate(ByVal id As Guid) As Object

        Private Function DownloadImage(ByVal id As Guid) As Object

            ResetDownloadFlags()
            'Start Download asynchronously
            Dim ac As New DownloadDelegate(AddressOf BackGroundDownloadPerImage)
            ac.BeginInvoke(id, AddressOf HandleDownloadCallback, ac)

            Dim StartTime As Double = DateTime.Now.TimeOfDay.TotalMilliseconds
            Dim ElapsedTime As Double

            While Not mCamera.IsDownloadCanceled AndAlso Not LatestDownloadWasSuccessful AndAlso Not IsTimeout
                WaitWithDoEvents(100, 10)
                ElapsedTime = DateTime.Now.TimeOfDay.TotalMilliseconds - StartTime
                If ElapsedTime > CDbl(mExpirtaionTime) Then WritableIsTimeOut = True
            End While

            If LatestDownloadWasSuccessful Or mCamera.IsDownloadCanceled Then
                MarkAsOnline()
                If LatestDownloadWasCanceled Then WritableLatestDownloadWasSuccessful = False
            Else
                mIsAlreadyConnected = False
                MarkAsOnline()
                Throw New DownloadFailureException
            End If
            Return mDownloadedImages
        End Function

        Private Function BackGroundDownloadPerImage(ByVal id As Guid) As Object
            Dim ImageArray() As Byte
            Dim ExifArray As New ExifProperties
            Dim IndexList() As Integer
            Dim RetVal As Boolean
            Dim CaptureResultList As New CaptureResultCollection
            With mCamera
                IndexList = CType(mIndexTable.Item(id), Integer())
                For c As Integer = 0 To .CameraCount - 1
                    If Not LatestDownloadWasCanceled Then
                        Dim result As New CaptureResult
                        ImageArray = .Picture(c, IndexList(c))
                        If Not ImageArray Is Nothing Then
                            result.ImageProperties.Timestamp = DateTime.UtcNow
                            ExifArray = ExifReader.ExtractExifHeader(ImageArray)
                            WritablePercentDownloaded += 1.0! / .CameraCount
                        Else
                            WritableLatestDownloadWasSuccessful = False
                            Return Nothing
                        End If
                        Dim s As New MemoryStream(ImageArray)
                        result.ImageProperties.Image = New Bitmap(s)
                        result.SensorProperties = mSensorProperties
                        result.SensorProperties.ExifProperties = ExifArray
                        CaptureResultList.Results.Add(result)
                    Else
                        mCamera.IsDownloadCanceled = True
                        Return Nothing
                    End If
                Next
                WritableLatestDownloadWasSuccessful = True
                MarkAsOnline()
                Return CaptureResultList
            End With
        End Function

        Private Sub HandleDownloadCallback(ByVal ar As IAsyncResult)
            Dim ac As DownloadDelegate = DirectCast(ar.AsyncState, DownloadDelegate)
            Dim obj As Object = ac.EndInvoke(ar)
            If Not obj Is Nothing Then
                mDownloadedImages = CType(obj, CaptureResultCollection)
            End If
        End Sub
#End Region

        Private Sub DisplayInstruction(Optional ByVal str As String = Nothing)
            mOlympusMessageCtrl.Text = str
            mOlympusMessageCtrl.Font = GlobalUISettings.Defaults.Fonts.LargeBold
            Refresh()
        End Sub

        Protected Overrides Sub OnLayout(ByVal levent As LayoutEventArgs)
            MyBase.OnLayout(levent)
            If NearestForm Is Nothing Then Return
            MyBase.RefreshAutomaticLayout(NearestForm.CreateGraphics)
        End Sub

#Region "Test code"
        Friend WithEvents CaptureTestTimer As New System.Timers.Timer
        Private Sub startTestTimer()
            Debugging.WriteLine("Started Timer")
            'CaptureTestTimer.Interval = 28255
            CaptureTestTimer.Interval = 28000
            CaptureTestTimer.Start()
        End Sub

        Private Sub CaptureTestTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles CaptureTestTimer.Elapsed
            CaptureTestTimer.Stop()
            Debugging.WriteLine(Date.Now & " Stopped Timer")
            MyBase.ActivateCaptureNow()
        End Sub
#End Region

        Private mDefaultMonitVisionConfig As String = "LivePreivew.mvp"
        Private Sub InitializeMontiVision()
            Try
                Dim path As String = AppDomain.CurrentDomain.BaseDirectory & mDefaultMonitVisionConfig
                If Not File.Exists(path) Then
                    File.Copy("c:\MBARK\Third-Party Libraries\MontiVision\" & mDefaultMonitVisionConfig, _
                               AppDomain.CurrentDomain.BaseDirectory & mDefaultMonitVisionConfig)
                End If
                ' Get video source filter
                Dim setsource As MVSmartControl.IMVSCSetSourceFilter = CType(MVLiveControl.GetOcx(), MVSmartControl.IMVSCSetSourceFilter)
                setsource.SetSourceFilter("VideoSource", CVideoSourceComboBox.SelectedDevice)

                ' Get video graphic filter
                Dim graph As MVSmartControl.IMVSCFilterGraph = CType(MVLiveControl.GetOcx(), MVSmartControl.IMVSCFilterGraph)

                ' Load the graph from a configuration file
                Dim configurationFile As String = IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), mDefaultMonitVisionConfig)
                graph.LoadConfig(configurationFile)

                Dim currentDevice As String = CVideoSourceComboBox.SelectedDevice
                Dim cameraControl As MVSmartControl.IMVSCCameraControl = CType(MVLiveControl.GetOcx(), MVSmartControl.IMVSCCameraControl)
                cameraControl.Load("VideoSource", "SensorController", currentDevice, True)

                'Get Live Image
                graph.Start()
            Catch ex As Exception
                Debugging.WriteLine(ex.Source)
            End Try
        End Sub
    End Class

    <Serializable()> Public Class OlympusConfiguration
        Inherits SensorConfiguration

        'C5050Z: 7.1 ~ 21.3 ; C5060: 5.7 ~ 22.9
        Public Zoom As String = "15"
        Public Resolution As Integer = &H10
        Public Flash As Integer = 2
        Public LCD As Integer = 2
        Public Exposure As Integer = 3
        Public WhiteBalance As Integer = 4

        Public Overrides Function Clone() As Object
            Dim newConfiguration As New OlympusConfiguration
            With newConfiguration
                .Zoom = Zoom
                .Resolution = Resolution
                .Flash = Flash
                .LCD = LCD
                .Exposure = Exposure
                .WhiteBalance = WhiteBalance
            End With
            Return newConfiguration
        End Function

    End Class

    <Serializable()> Public Class OlympusSettings
        Public CameraServerURL As String
        Public UseNineCameraRig As Boolean
    End Class

End Namespace
