' Imports System
' Imports System.Collections
Imports System.ComponentModel
' Imports System.Drawing
' Imports System.Threading
' Imports System.Windows.Forms

Public Class FibonacciForm
    Inherits System.Windows.Forms.Form

    Private numberToCompute As Integer = 0
    Private highestPercentageReached As Integer = 0

    Public Duration, time1, time2 As Long
    Public nn, val1, val1s As Long
    Private val2 As Single
    Public update1, cnt, cnt1, cancel As Integer
    Public val3 As Double

    Public Sub New()

        InitializeComponent()
        InitializeForm()

    End Sub 'New

    Private Sub StartAsyncButton_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles StartAsyncButton.Click


        If StartAsyncButton.Text = "Start Async" Then
            ' Reset the text in the result label.
            Me.ProgressBar1.Value = 0
            ResultLabel1.Text = [String].Empty
            ResultLabel2.Text = [String].Empty
            time1 = Hour(Now) * 3600 + Minute(Now) * 60 + Second(Now)
            nn = Val(NumericUpDown2.Value)
            update1 = 0
            cancel = 0

            ' Disable the UpDown control until 
            ' the asynchronous operation is done.
            Me.NumericUpDown1.Enabled = False
            Me.NumericUpDown2.Enabled = False


            ' Disable the Start button while 
            ' the asynchronous operation runs.
            Me.StartAsyncButton.Enabled = False

            ' Get the value from the UpDown control.
            numberToCompute = CInt(NumericUpDown1.Value)

            ' Reset the variable for percentage tracking.
            highestPercentageReached = 0


            ' Start the asynchronous operation.
            BackgroundWorker1.RunWorkerAsync(numberToCompute)
            CancelAsyncButton.Text = "Cancel Async"

        End If

    End Sub

    Private Sub CancelAsyncButton_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles CancelAsyncButton.Click


        If CancelAsyncButton.Text = "Cancel Async" Then

            cancel = 1
            ' Enable the End button.
            Me.NumericUpDown1.Enabled = True
            Me.NumericUpDown2.Enabled = True
            StartAsyncButton.Enabled = True
            CancelAsyncButton.Text = "End Async"

        Else
            End

        End If

    End Sub 'CancelAsyncButton

    ' This event handler is where the actual work is done.
    Private Sub backgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        ' Get the BackgroundWorker object that raised this event.
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

        ' Assign the result of the computation
        ' to the Result property of the DoWorkEventArgs
        ' object. This is will be available to the 
        ' RunWorkerCompleted eventhandler.

        time1 = Hour(Now) * 3600 + Minute(Now) * 60 + Second(Now)
        cnt1 = 0
        For cnt2 = 1 To nn
            cnt = cnt2
            val1 = ComputeFibonacci(e.Argument, worker, e)
            time2 = Hour(Now) * 3600 + Minute(Now) * 60 + Second(Now)
            Duration = time2 - time1
            If cancel = 0 Then val2 = Duration / (cnt) : val1s = val1 : cnt1 = cnt
            update1 = 1
            ' Debug.Print("Backgroundworker cnt" + Str(cnt) + " val2" + Str(val2))
        Next cnt2

    End Sub 'backgroundWorker1_DoWork


    ' This event handler updates the progress.

    Private Sub backgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        If update1 = 1 Then
            ' Debug.Print("ProgressChanged cnt " + Str(cnt1))
            ResultLabel1.Text = Str(val1s)
            ResultLabel2.Text = val2
            update1 = 0
        End If
        If cancel = 1 And cnt1 = 0 Then ResultLabel1.Text = "Canceled"
        Me.ProgressBar1.Value = highestPercentageReached
        Me.ResultLabel3.Text = cnt1

        If cnt1 = nn Then
            ' Enable the UpDown control.
            Me.NumericUpDown1.Enabled = True
            Me.NumericUpDown2.Enabled = True

            ' Enable the Start button.
            StartAsyncButton.Enabled = True

            ' Disable the Cancel button.
            CancelAsyncButton.Enabled = True
            CancelAsyncButton.Text = "End Async"


        End If

    End Sub

    ' This is the method that does the actual work. For this
    ' example, it computes a Fibonacci number and
    ' reports progress as it does its work.
    Function ComputeFibonacci( _
        ByVal n As Integer, _
        ByVal worker As BackgroundWorker, _
        ByVal e As DoWorkEventArgs) As Long

        ' The parameter n must be >= 0 and <= 91.
        ' Fib(n), with n > 91, overflows a long.
        If n < 0 OrElse n > 91 Then
            Throw New ArgumentException( _
                "value must be >= 0 and <= 91", "n")
        End If

        Dim result As Long = 0

        ' Abort the operation if the user has canceled.
        ' Note that a call to CancelAsync may have set 
        ' CancellationPending to true just after the
        ' last invocation of this method exits, so this 
        ' code will not have the opportunity to set the 
        ' DoWorkEventArgs.Cancel flag to true. This means
        ' that RunWorkerCompletedEventArgs.Cancelled will
        ' not be set to true in your RunWorkerCompleted
        ' event handler. This is a race condition.
        'If worker.CancellationPending Then
        '      e.Cancel = True
        'Else
        If cancel = 0 Then
            If n < 2 Then
                If n = 0 Then result = 0 Else result = 1
            Else
                result = ComputeFibonacci(n - 1, worker, e) + _
                         ComputeFibonacci(n - 2, worker, e)
            End If

            ' Report progress as a percentage of the total task.
            Dim percentComplete As Integer = _
                CSng(n) / CSng(numberToCompute) * 100 * (cnt / nn)
            ' Debug.Print(n)
            ' worker.ReportProgress(percentComplete)
            If percentComplete > highestPercentageReached Then
                highestPercentageReached = percentComplete
                'Debug.Print(Str(n) + " " + Str(highestPercentageReached))
                worker.ReportProgress(percentComplete)
            End If
        End If


        Return result

    End Function


    Private Sub InitializeForm()

        Dim hh As Single
        '
        'numericUpDown1
        '
        Me.NumericUpDown1.Location = New System.Drawing.Point(16, 16)
        '
        'resultLabel1
        '
        Me.ResultLabel1.Location = New System.Drawing.Point(112, 16)
        Me.ResultLabel1.Size = New System.Drawing.Size(70, 23)
        Me.ResultLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'resultLabel2
        '
        Me.ResultLabel2.Location = New System.Drawing.Point(200, 16)
        Me.ResultLabel2.Size = New System.Drawing.Size(70, 23)
        Me.ResultLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'progressBar1
        '
        Me.ProgressBar1.Location = New System.Drawing.Point(18, 48)
        Me.ProgressBar1.Size = New System.Drawing.Size(256, 8)
        '
        'Label1
        '
        hh = 16
        Me.Label1.Location = New System.Drawing.Point(hh, 72)
        Me.Label1.Size = New System.Drawing.Size(33, 13)
        '
        'NumericUpDown2
        '
        hh = hh + 33 + 10
        Me.NumericUpDown2.Location = New System.Drawing.Point(hh, 72)
        Me.NumericUpDown2.Size = New System.Drawing.Size(48, 20)
        '
        'resultLabel3
        '
        hh = hh + 48 + 10
        Me.ResultLabel3.Location = New System.Drawing.Point(hh, 72)
        Me.ResultLabel3.Size = New System.Drawing.Size(40, 23)
        Me.ResultLabel3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'startAsyncButton
        '
        hh = 16
        Me.StartAsyncButton.Location = New System.Drawing.Point(hh, 102)
        Me.StartAsyncButton.Size = New System.Drawing.Size(80, 23)
        Me.StartAsyncButton.Text = "Start Async"
        '
        'CancelAsyncButton
        '
        hh = hh + 80 + 10
        'Me.CancelAsyncButton.Enabled = False
        Me.CancelAsyncButton.Location = New System.Drawing.Point(hh, 102)
        Me.CancelAsyncButton.Size = New System.Drawing.Size(80, 23)
        Me.CancelAsyncButton.Text = "End Async"
        '
        'backgroundWorker1
        '
        Me.backgroundWorker1.WorkerReportsProgress = True
        Me.backgroundWorker1.WorkerSupportsCancellation = True
        '
        'FibonacciForm
        '
        Me.ClientSize = New System.Drawing.Size(280, 138)

    End Sub 'InitializeComponent

     _
    Shared Sub Main()
        Application.Run(New FibonacciForm)
    End Sub 'Main

End Class 'FibonacciForm