Imports ComponentPro
Imports ComponentPro.Net.Mail

Namespace ScanMessagesSample
	Partial Public Class ScanMessages
		Inherits Form
		Private ReadOnly _exception As Boolean
		Private _dataDir As String
		Private ReadOnly _customSignatures As New List(Of SignatureInfo)()

		Public Sub New()
			Try
				InitializeComponent()

			Catch exc As ComponentPro.Licensing.BounceInspector.UltimateLicenseException
				MessageBox.Show(exc.Message, "Error")
				_exception = True
			End Try

			LoadFormSettings()

#If Not Framework4_5 Then
			AddHandler Me.bounceFilter.ProcessMessagesCompleted, AddressOf bounceFilter_ProcessMessagesCompleted
#End If
		End Sub

		''' <summary>
		''' Handles the form Load event.
		''' </summary>
		''' <param name="e">The event arguments.</param>
		Protected Overrides Sub OnLoad(ByVal e As EventArgs)
			MyBase.OnLoad(e)
			If _exception Then
				Me.Close()
			End If
		End Sub

		''' <summary>
		''' Loads settings from the Registry.
		''' </summary>
		Private Sub LoadFormSettings()
			txtPath.Text = CStr(Util.GetProperty("DataDir", DataDir))
			chkDelete.Checked = Util.GetIntProperty("Delete", 0) = 1
		End Sub

		''' <summary>
		''' Saves settings to the registry.
		''' </summary>
		Private Sub SaveFormSettings()
			Util.SaveProperty("DataDir", txtPath.Text)
			If chkDelete.Checked Then
				Util.SaveProperty("Delete",1)
			Else
				Util.SaveProperty("Delete",0)
			End If
		End Sub

		''' <summary>
		''' Handles the form's Closed event.
		''' </summary>
		''' <param name="e"></param>
		Protected Overrides Sub OnClosed(ByVal e As EventArgs)
			MyBase.OnClosed(e)

			SaveFormSettings()
		End Sub

		''' <summary>
		''' Gets the default data folder that stores Messages.
		''' </summary>
		Public ReadOnly Property DataDir() As String
			Get
				_dataDir = System.IO.Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory & "..\..\Data")
				If Not System.IO.Directory.Exists(_dataDir) Then
					_dataDir = AppDomain.CurrentDomain.BaseDirectory & "Data"
				End If

				Return _dataDir
			End Get
		End Property

		''' <summary>
		''' Enables/disables form's controls.
		''' </summary>
		''' <param name="enable">Enable or disable the form.</param>
		Private Sub EnableProgress(ByVal enable As Boolean)
			progressBar.Enabled = enable
			progressBar.Value = 0
			btnAbort.Enabled = enable
			btnCustomSignature.Enabled = Not enable
			btnScan.Enabled = Not enable
			lblName.Enabled = Not enable
			txtPath.Enabled = Not enable
			btnBrowse.Enabled = Not enable
			chkDelete.Enabled = Not enable
			'ltvResult.Enabled = !enable;

			Util.EnableCloseButton(Me, (Not enable))
		End Sub

		''' <summary>
		''' Handles the CustomSignature button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub btnCustomSignature_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCustomSignature.Click
			Dim dlg As New CustomSignatures(bounceFilter, _customSignatures)
			dlg.ShowDialog()
		End Sub

		''' <summary>
		''' Handles the Scan button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
#If Framework4_5 Then
		Private Async Sub btnScan_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnScan.Click
#Else
		Private Sub btnScan_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnScan.Click
#End If
			If txtPath.Text.Length = 0 Then
				MessageBox.Show("Please enter path to messages to scan", "BounceInspector", MessageBoxButtons.OK)
				Return
			End If

			EnableProgress(True)

			ltvResult.Items.Clear()
			tsbOpen.Enabled = False

			' Allow delete bounced emails?
			bounceFilter.AllowDelete = chkDelete.Checked

#If Framework4_5 Then
			Dim result As BounceResultCollection

			Try
				' Scan messages.
				result = Await bounceFilter.ProcessMessagesAsync(txtPath.Text)
			Catch ex As Exception
				Util.ShowError(ex)
				Return
			End Try

			PostProcessMessages(result)
#Else
			' Scan messages.
			bounceFilter.ProcessMessagesAsync(txtPath.Text)
#End If
		End Sub

		Private Sub PostProcessMessages(ByVal result As BounceResultCollection)
			EnableProgress(False)

			If result IsNot Nothing Then
				If result.HasErrors Then
					Dim dlg As New Errors()
					dlg.SetErrors(result)
					dlg.ShowDialog()
				End If

				Dim found As String = String.Format("{0}/{1} bounced e-mails found.", result.BounceCount, result.Count)

				If result.CancelledIndex <> -1 Then
					MessageBox.Show("Operation has been cancelled by user. " & found, "BounceInspector", MessageBoxButtons.OK)
				Else
					MessageBox.Show(found, "BounceInspector", MessageBoxButtons.OK)
				End If
			End If
		End Sub

		''' <summary>
		''' Handles the Browse button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub btnBrowse_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnBrowse.Click
			' Open Folder Browser Dialog.
			Dim dlg As New FolderBrowserDialog()
			dlg.SelectedPath = txtPath.Text
			If dlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
				txtPath.Text = dlg.SelectedPath
			End If
		End Sub

		''' <summary>
		''' Handles the Abort button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub btnAbort_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAbort.Click
			' Abort scanning.
			bounceFilter.Cancel()
		End Sub

		Private Sub bounceFilter_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs) Handles bounceFilter.Processed
			' Handle the bounce Processed event here.
		End Sub

#If Not Framework4_5 Then
		''' <summary>
		''' Handles the bounce ProcessMessagesCompleted event.
		''' </summary>
		''' <param name="sender">The BounceInspector object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub bounceFilter_ProcessMessagesCompleted(ByVal sender As Object, ByVal e As ExtendedAsyncCompletedEventArgs(Of BounceResultCollection))
			If e.Error IsNot Nothing Then
				Util.ShowError(e.Error)
				Return
			End If

			PostProcessMessages(e.Result)
		End Sub
#End If

		''' <summary>
		''' Handles the BounceInspector's Progress event.
		''' </summary>
		''' <param name="sender">The BounceInspector object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub bounceFilter_Progress(ByVal sender As Object, ByVal e As ProgressEventArgs) Handles bounceFilter.Progress
			Try
				Dim r As BounceResult = e.Result

				If r.MailMessage Is Nothing Then
					Return
				End If

				progressBar.Value = e.Current * 100 / e.Total

				If r.Identified Then
					' Add to the result list view.
					Dim item As New ListViewItem(New String() { System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted.ToString(), r.Dsn.Action.ToString(), r.Dsn.DiagnosticCode })

					item.Tag = r.FilePath

					ltvResult.Items.Add(item)
				End If
			Catch exc As Exception
				MessageBox.Show(exc.Message)
			End Try
		End Sub

		Private Sub tsbOpen_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbOpen.Click
			Dim form As New MessageViewer(CStr(ltvResult.SelectedItems(0).Tag))
			form.ShowDialog(Me)
		End Sub

		Private Sub ltvResult_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ltvResult.SelectedIndexChanged
			tsbOpen.Enabled = ltvResult.SelectedItems.Count > 0 AndAlso ltvResult.SelectedItems(0).Tag IsNot Nothing
		End Sub

		Private Sub ltvResult_DoubleClick(ByVal sender As Object, ByVal e As EventArgs) Handles ltvResult.DoubleClick
			If tsbOpen.Enabled Then
				tsbOpen_Click(sender, e)
			End If
		End Sub
	End Class

	''' <summary>
	''' Contains signature information for local uses.
	''' </summary>
	Public Class SignatureInfo
		Public Index As Integer
		Public RegexPattern As String
		Public CategoryCode As Integer
		Public TypeCode As Integer
		Public Delete As Boolean
		Public SignaturePart As BounceSignaturePart
	End Class
End Namespace