Imports System.IO
Imports System.Security.Cryptography
Imports System.Collections.Generic

Public Class ProgressForm
    Private Shared _InputStream As Stream
    Private Shared _OutputStream As Stream
    Private Shared _AllowClose As Boolean = False

    Public Sub New(ByVal InputStream As Stream, ByVal OutputStream As Stream)
        InitializeComponent()

        _InputStream = InputStream
        _OutputStream = OutputStream

        backgroundWorkerEncryption.RunWorkerAsync()
    End Sub

    Private Sub backgroundWorkerEncryption_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles backgroundWorkerEncryption.DoWork
        If _InputStream.Length = 0 Then Exit Sub

        Dim TDES As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider

        Using Writer As BinaryWriter = New BinaryWriter(_OutputStream)
            Dim Buf(Globals.ChunkSize - 1) As Byte
            Dim SourceChunkSizeList As List(Of Integer) = New List(Of Integer)
            Dim EncryptedChunkSizeList As List(Of Integer) = New List(Of Integer)
            Dim ReadBytes As Integer
            Dim nTotalReadBytes As Long = 0

            While True
                ReadBytes = _InputStream.Read(Buf, 0, Buf.Length)

                If ReadBytes <= 0 Then Exit While

                If backgroundWorkerEncryption.CancellationPending Then Exit While

                Dim EncryptedData() As Byte = Globals.Encrypt(Buf, ReadBytes)
                _OutputStream.Write(EncryptedData, 0, EncryptedData.Length)

                SourceChunkSizeList.Add(ReadBytes)
                EncryptedChunkSizeList.Add(EncryptedData.Length)

                nTotalReadBytes = nTotalReadBytes + ReadBytes
                backgroundWorkerEncryption.ReportProgress(nTotalReadBytes * 100 / _InputStream.Length)
            End While

            For Each SourceChunkSize As Integer In SourceChunkSizeList
                Writer.Write(SourceChunkSize)
            Next

            For Each EncryptedChunkSize As Integer In EncryptedChunkSizeList
                Writer.Write(EncryptedChunkSize)
            Next

            Writer.Write(CType(EncryptedChunkSizeList.Count, Integer))
        End Using
    End Sub

    Private Sub backgroundWorkerEncryption_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles backgroundWorkerEncryption.ProgressChanged
        progressBar.Value = e.ProgressPercentage
    End Sub

    Private Sub backgroundWorkerEncryption_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles backgroundWorkerEncryption.RunWorkerCompleted
        _AllowClose = True
        Close()
    End Sub

    Private Sub buttonCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonCancel.Click
        buttonCancel.Enabled = False
        backgroundWorkerEncryption.CancelAsync()
    End Sub

    Private Sub ProgressForm_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If Not _AllowClose Then e.Cancel = True
    End Sub
End Class