Imports System.ComponentModel
Imports System.ServiceModel
Imports System.Threading
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference

Public NotInheritable Class frmSplash
    Private _Worker As New BackgroundWorker()
    Private _ChannelFactory As ChannelFactory(Of IEDMIServiceChannel)
    Private _Channel As IEDMIServiceChannel
    Private _Logger As Logger

    Private _CurrentRetry As Integer = 0

    Private Const SLEEP_TIME = 600
    Private Const INIT_STEPS = 4
    Private Const MAX_RETRIES = 10
    Private Const OPEN_TIMEOUT = 10

    Private Sub frmSplash_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        lblProductName.Text = My.Application.Info.ProductName
        lblCopyright.Text = My.Application.Info.Copyright
        lblVersion.Text = String.Format("Version {0}", My.Application.Info.Version.ToString)

        BringToFront()

        Dim oService As New ClassService(My.LogConfig)
        Dim oConnectionURLExists As Boolean = My.SysConfig.ServiceConnection <> String.Empty

        'Dim oInit As New ClassInit()
        'Dim oConnectionURLExists = oInit.TestConnectionURLExists()

        If Not oConnectionURLExists Then
            Dim oResult = frmConfigService.ShowDialog()

            If oResult = DialogResult.Cancel Then
                MsgBox("Es wurde keine Dienst-Verbindungsurl hinterlegt. Die Anwendung wird beendet.")
                Application.Exit()
            Else
                StartWorker()
            End If
        Else
            StartWorker()
        End If
    End Sub

    Private Function SetProgress(_step As Integer)
        Return _step * (100 / INIT_STEPS)
    End Function

#Region "Worker"
    Private Enum WorkerResult
        AllGood
        ServiceOffline
    End Enum


    Private Sub StartWorker()
        AddHandler _Worker.DoWork, AddressOf bw_DoWork
        AddHandler _Worker.ProgressChanged, AddressOf bw_ProgressChanged
        AddHandler _Worker.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted

        _Worker.WorkerReportsProgress = True
        _Worker.RunWorkerAsync()
    End Sub

    Private Sub bw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
        Dim oService As New ClassService(My.LogConfig)

        _Worker.ReportProgress(SetProgress(1), "Connecting to service..")

        Dim oConnectionSuccessful = False

        e.Result = WorkerResult.AllGood

        _ChannelFactory = oService.GetChannelFactory()
        _Channel = _ChannelFactory.CreateChannel()

        'Dim oServiceOnline = Await oService.TestConnectionAsync()
        Dim oServiceState = oService.TestConnection()

        If oServiceState <> ClassService.ConnectionTestResult.Successful Then
            e.Result = WorkerResult.ServiceOffline
            Return
        End If

        Thread.Sleep(SLEEP_TIME)

        ' TODO: Initialize Usersettings and populate My.Application.User

        _Worker.ReportProgress(SetProgress(2), "Initializing User Settings..")
        Thread.Sleep(SLEEP_TIME)

        _Worker.ReportProgress(SetProgress(3), "Connecting to mainframe..")
        Thread.Sleep(SLEEP_TIME)

        _Worker.ReportProgress(SetProgress(4), "Setting up neural network..")
        Thread.Sleep(SLEEP_TIME)
    End Sub

    Private Sub bw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
        pbStatus.Value = e.ProgressPercentage
        lblStatus.Text = e.UserState.ToString()
    End Sub

    Private Sub bw_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
        ' Bei Fehler MsgBox anzeigen und Programm beenden
        If e.Error IsNot Nothing Then
            MsgBox(e.Error.Message, MsgBoxStyle.Critical, "Unhandled Error")
            Application.Exit()
        ElseIf e.Result <> WorkerResult.AllGood Then
            Dim oErrorMessage

            Select Case e.Result
                Case WorkerResult.ServiceOffline
                    oErrorMessage = "Service is offline!"
                Case Else
                    oErrorMessage = "Unknown Error"
            End Select

            MsgBox($"Application could not be started{vbNewLine}Reason: {oErrorMessage}", MsgBoxStyle.Critical, "Critical Error")
            Application.Exit()
        End If

        My.ChannelFactory = _ChannelFactory
        My.Channel = _Channel

        ' Wenn kein Fehler, Splashscreen schließen
        Me.Close()
    End Sub
#End Region
End Class
