using System;
using System.ComponentModel;
using System.Windows.Forms;
using ComponentPro.Net;
using System.Text;
using ComponentPro;
using ComponentPro.Net.Mail;

namespace EmailValidatorDemo
{
    public partial class Main : Form
    {
        private readonly bool _exception;
        string _blackListFile;
        string _whiteListFile;
        
        int _selectedTabIndex;

        string _dataDir;
        public string DataDir
        {
            get
            {
                if (_dataDir == null)
                {
                    // Set default data dir.
                    _dataDir = AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Data";
                    if (!System.IO.Directory.Exists(_dataDir))
                        _dataDir = AppDomain.CurrentDomain.BaseDirectory + "Data";
                }
                return _dataDir;
            }
        }

        public Main()
        {
            string emailListFile;

            // This licensing exception handling code segment is not needed if you have a production license.
            try
            {
                InitializeComponent();
            }
            catch (ComponentPro.Licensing.EmailValidator.UltimateLicenseException exc)
            {
                MessageBox.Show(exc.Message);
                _exception = true;
                return;
            }

            emailListFile = DataDir + "\\EmailList.txt";
            txtEmailListFile.Text = emailListFile;
            txtEmailListThread.Text = emailListFile;

#if !Framework4_5 && !SYNC
            this.emailValidator.ValidateCompleted += this.sfbEmailValidator_ValidateCompleted;
            this.emailValidator.ValidateEmailsCompleted += this.sfbEmailValidator_ValidateTextFileCompleted;
            this.emailValidator.GetMailExchangeRecordsCompleted += this.sfbEmailValidator_GetMailExchangeRecordsCompleted;
#endif
        }

        /// <summary>
        /// Handles the form Load's event.
        /// </summary>
        /// <param name="e">The event arguments.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (_exception)
                this.Close();

            LoadConfig();
        }

        /// <summary>
        /// Handles the form Closing's event.
        /// </summary>
        /// <param name="e">The event arguments.</param>
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            SaveConfig();

            base.OnClosing(e);
        }

        #region Configuration

        /// <summary>
        /// Loads settings from the Registry.
        /// </summary>
        void LoadConfig()
        {
            _blackListFile = (string)Util.GetProperty("BlackList", DataDir + "\\BlackList.txt");
            _whiteListFile = (string)Util.GetProperty("WhiteList", DataDir + "\\WhiteList.txt");

            // General
            emailValidator.SmtpFromEmail = (string)Util.GetProperty("From", "someone@microsoft.com");
            emailValidator.SmtpHeloDomain = (string)Util.GetProperty("FromDomain", "microsoft.com");
            emailValidator.SmtpPort = Util.GetIntProperty("SmtpPort", 25);
            emailValidator.SmtpTimeout = Util.GetIntProperty("Timeout", 15000);
            emailValidator.DnsTimeout = Util.GetIntProperty("DnsTimeout", 15000);
            //emailValidator.UseRandomDnsServer = Util.GetIntProperty("UseRandomDnsServer", 1) == 1;
            emailValidator.ValidationLevel = (ValidationLevel)Util.GetIntProperty("Level", (int)ValidationLevel.Mailbox);
            emailValidator.UseMailExchangeRecordCache = Util.GetIntProperty("UseMailExchangeRecordCache", 1) == 1;
            emailValidator.EmailSyntaxPattern = (string)Util.GetProperty("Pattern", @"^[\w-\.]{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]{2,3}$");
            emailValidator.MailExchangeRecordCacheTimeout = Util.GetIntProperty("MailExchangeRecordCacheTimeout", 30);

            // Proxy
            emailValidator.ProxyHost = (string)Util.GetProperty("ProxyHost", string.Empty);
            emailValidator.ProxyPort = Util.GetIntProperty("ProxyPort", 1080);
            emailValidator.ProxyUserName = (string)Util.GetProperty("ProxyUser", string.Empty);
            emailValidator.ProxyPassword = (string)Util.GetProperty("ProxyPass", string.Empty);
            emailValidator.ProxyDomain = (string)Util.GetProperty("ProxyDomain", string.Empty);
            emailValidator.ProxyHttpConnectAuthMethodMethod = (ProxyHttpConnectAuthMethod)Util.GetIntProperty("ProxyAuth", (int)ProxyHttpConnectAuthMethod.Basic);
            emailValidator.ProxyType = (ProxyType)Util.GetIntProperty("ProxyType", (int)ProxyType.None);
        }

        /// <summary>
        /// Saves settings to the registry.
        /// </summary>
        void SaveConfig()
        {
            Util.SaveProperty("BlackList", _blackListFile);
            Util.SaveProperty("WhiteList", _whiteListFile);

            // General
            Util.SaveProperty("From", emailValidator.SmtpFromEmail);
            Util.SaveProperty("FromDomain", emailValidator.SmtpHeloDomain);
            Util.SaveProperty("SmtpPort", emailValidator.SmtpPort);
            Util.SaveProperty("Timeout", emailValidator.SmtpTimeout);
            Util.SaveProperty("DnsTimeout", emailValidator.DnsTimeout);
            //Util.SaveProperty("UseRandomDnsServer", emailValidator.UseRandomDnsServer ? 1 : 0);
            Util.SaveProperty("Level", (int)emailValidator.ValidationLevel);
            Util.SaveProperty("UseMailExchangeRecordCache", emailValidator.UseMailExchangeRecordCache ? 1 : 0);
            Util.SaveProperty("Pattern", emailValidator.EmailSyntaxPattern);
            Util.SaveProperty("MailExchangeRecordCacheTimeout", emailValidator.MailExchangeRecordCacheTimeout);

            // Proxy
            Util.SaveProperty("ProxyHost", emailValidator.ProxyHost);
            Util.SaveProperty("ProxyPort", emailValidator.ProxyPort);
            Util.SaveProperty("ProxyUser", emailValidator.ProxyUserName);
            Util.SaveProperty("ProxyPass", emailValidator.ProxyPassword);
            Util.SaveProperty("ProxyDomain", emailValidator.ProxyDomain);
            Util.SaveProperty("ProxyAuth", (int)emailValidator.ProxyHttpConnectAuthMethodMethod);
            Util.SaveProperty("ProxyType", (int)emailValidator.ProxyType);
        }

        #endregion

        #region Message Logging

        /// <summary>
        /// Handles the emailvalidator's MessageLogging event.
        /// </summary>
        /// <param name="sender">The emailvalidator object.</param>
        /// <param name="e">The event arguments.</param>
        private void sfbEmailValidator_MessageLogging(object sender, ComponentPro.Net.EmailValidatorLogEventArgs e)
        {
            if (!IsDisposed)
                Invoke(new EventHandler<EmailValidatorLogEventArgs>(MessageLogging), sender, e);
        }

        void MessageLogging(object sender, ComponentPro.Net.EmailValidatorLogEventArgs e)
        {
            string msg = e.SmtpTranscript.Replace("\r\n", string.Empty);

            AdvancedLog(msg, e.ThreadId);
        }

        void AdvancedLog(string msg, int threadId)
        {
            switch (_selectedTabIndex)
            {
                case 0: // Single Email
                    lst1AdvancedLog.Items.Add(msg);
                    break;

                case 1: // Validate Email Addresses loaded from a file with a single thread
                    lst2AdvancedLog.Items.Add(msg);
                    break;

                case 2: // Validate Email Addresses loaded from a file with two threads                    
                    ListBox lb = threadId == 0 ? lst3AdvancedLog : lst4AdvancedLog;
                    lb.Items.Add(msg);
                    lb.Invalidate();
                    break;
            }
        }

        void Log(string msg, int threadId)
        {
            switch (_selectedTabIndex)
            {
                case 0: // Single Email
                    lst1Log.Items.Add(msg);
                    break;

                case 1: // Validate Email Addresses loaded from a file with a single thread
                    lst2Log.Items.Add(msg);
                    break;

                case 2: // Validate Email Addresses loaded from a file with two threads                    
                    ListBox lb = threadId == 0 ? lst3Log : lst4Log;
                    lb.Items.Add(msg);
                    lb.Invalidate();
                    break;
            }
        }

        #endregion

        int _processed;
        int _passed;

        private void sfbEmailValidator_EmailValidated(object sender, EmailValidatedEventArgs e)
        {
            if (!IsDisposed)
                Invoke(new EventHandler<EmailValidatedEventArgs>(EmailValidated), sender, e);
        }

        private void EmailValidated(object sender, EmailValidatedEventArgs e)
        {
            if (e.Error != null)
            {
                AdvancedLog(string.Format("Email '{0}' validated at level {1} with error: {2}.", e.EmailAddress, e.ValidatedLevel, e.Error.Message), e.ThreadId);
                Log(string.Format("    Mailbox '{0}' is invalid - completed with error: {1}", e.EmailAddress, e.Error.Message), e.ThreadId);
            }
            else
            {
                AdvancedLog(string.Format("Email '{0}' validated at level {1}.", e.EmailAddress, e.ValidatedLevel), e.ThreadId);

                if (e.ValidatedLevel == ValidationLevel.Success)
                {
                    Log(string.Format("    Completed successfully - Mailbox {0} is valid", e.EmailAddress), e.ThreadId);
                    _passed++;
                }
                else
                {
                    Log(string.Format("    Mailbox '{0}' is invalid - completed at level: {1}", e.EmailAddress, e.ValidatedLevel), e.ThreadId);
                }
            }
            AdvancedLog("------------------------------------", e.ThreadId);
            Log("----------------", e.ThreadId);
            _processed++;
        }

        /// <summary>
        /// Loads black and white lists from files.
        /// </summary>
        private void LoadBlackAndWhiteListFiles()
        {
            if (!string.IsNullOrEmpty(_blackListFile))
            {
                try
                {
                    emailValidator.BlackList.LoadFromFile(_blackListFile);
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Unable to load: " + _blackListFile + "\r\n" + exc.Message);
                }
            }

            if (!string.IsNullOrEmpty(_whiteListFile))
            {
                try
                {
                    emailValidator.WhiteList.LoadFromFile(_whiteListFile);
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Unable to load: " + _whiteListFile + "\r\n" + exc.Message);
                }
            }
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Show the Settings form.
            SettingsDialog form = new SettingsDialog(emailValidator, _whiteListFile, _blackListFile);
            form.ShowDialog();
            _blackListFile = form.BlackListFile;
            _whiteListFile = form.WhiteListFile;
            // Clear the DNS cache.
            EmailValidator.ClearDnsCache();
        }

        private void lblSettings_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            settingsToolStripMenuItem_Click(null, null);
        }

        void EnableDialog(bool enable)
        {
            toolbarMain.Enabled = enable;
            Util.EnableCloseButton(this, enable);
        }

        #region MailXChange Rec

        void EnableMailXChangeRecord(bool enable)
        {
            EnableDialog(enable);

            lblSettings.Enabled = enable;

            tpValidateSingleEmail.Enabled = enable;
            tpEmails.Enabled = enable;
            tpMultipleThreads.Enabled = enable;
            btnGet.Enabled = enable;
            txtMXServerAddress.Enabled = enable;
        }

        /// <summary>
        /// Handles the Get mail xchange records button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
#if Framework4_5
        async
#endif
        void btnGet_Click(object sender, EventArgs e)
        {
            _selectedTabIndex = 3;
            lstMXRecords.Items.Clear();
            
            // Disable some controls.
            EnableMailXChangeRecord(false);

#if Framework4_5 || SYNC
            try
            {
#if SYNC
                ShowResult(emailValidator.GetMailExchangeRecords(txtMXServerAddress.Text));
#else
                // Asynchronously get mail exchange records.
                ShowResult(await emailValidator.GetMailExchangeRecordsAsync(txtMXServerAddress.Text));
#endif
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            finally
            {
                EnableMailXChangeRecord(true);
            }
#else
            // Asynchronously get mail exchange records.
            emailValidator.GetMailExchangeRecordsAsync(txtMXServerAddress.Text);
#endif
        }

        void ShowResult(MailExchangeRecord[] result)
        {
            // Get Mail Exchange records.
            foreach (MailExchangeRecord m in result)
            {
                // Add to the list control.
                lstMXRecords.Items.Add(m.ToString());
            }

            if (lstMXRecords.Items.Count == 0)
                MessageBox.Show("No MX Records found", "ComponentPro Email Validator", MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
        }

#if !Framework4_5
        /// <summary>
        /// Handles the emailvalidator's GetMailExchangeRecordsCompleted event.
        /// </summary>
        /// <param name="sender">The emailvalidator object.</param>
        /// <param name="e">The event arguments.</param>
        private void sfbEmailValidator_GetMailExchangeRecordsCompleted(object sender, ExtendedAsyncCompletedEventArgs<MailExchangeRecord[]> e)
        {
            if (e.Error != null)
            {
                Util.ShowError(e.Error);
            }
            else
            {
                ShowResult(e.Result);
            }

            // Enable controls.
            EnableMailXChangeRecord(true);
        }
#endif

        #endregion

        #region Single Mail Validation

        void EnableSingleMode(bool enable)
        {
            EnableDialog(enable);

            lnkSettingsSingle.Enabled = enable;

            tpEmails.Enabled = enable;
            tpGetMxRecords.Enabled = enable;
            tpMultipleThreads.Enabled = enable;
            txtEmailSingle.Enabled = enable;
            btnValidateSingle.Text = enable ? "Validate" : "Stop";
            if (enable)
                btnValidateSingle.Enabled = true;
        }

        /// <summary>
        /// Handles the validate single email button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
#if Framework4_5
        async
#endif
        void btnValidateSingle_Click(object sender, EventArgs e)
        {
            // Is not validating?
            if (btnValidateSingle.Text == "Validate")
            {
                // Clear logs.
                _selectedTabIndex = 0;
                lst1AdvancedLog.Items.Clear();
                lst1Log.Items.Clear();
                
                EnableSingleMode(false);

                // Load black and white lists.
                LoadBlackAndWhiteListFiles();

#if Framework4_5 || SYNC
                try
                {
#if SYNC
                    ShowSingleEmailResult(emailValidator.Validate(txtEmailSingle.Text));
#else
                    // Asynchronously validate a single email.
                    ShowSingleEmailResult(await emailValidator.ValidateAsync(txtEmailSingle.Text));
#endif
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    EnableSingleMode(true);
                }
#else
                // Asynchronously validate a single email.
                emailValidator.ValidateAsync(txtEmailSingle.Text);
#endif
            }
            else
            {
                // Abort the validation.
                btnValidateSingle.Enabled = false;
                emailValidator.Cancel();
            }
        }

        void ShowSingleEmailResult(ValidationLevel level)
        {
            MessageBox.Show("E-mail address validation completed at level: " + level.ToString(), "Email Validator Demo", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

#if !Framework4_5
        /// <summary>
        /// Handles the email validator's ValidateCompleted event.
        /// </summary>
        /// <param name="sender">The email validator object.</param>
        /// <param name="e">The event arguments.</param>
        private void sfbEmailValidator_ValidateCompleted(object sender, ExtendedAsyncCompletedEventArgs<ValidationLevel> e)
        {
            if (e.Error != null)
            {
                Util.ShowError(e.Error);
            }
            else
                ShowSingleEmailResult(e.Result);

            EnableSingleMode(true);
        }
#endif

        #endregion

        #region Validate Text File

        void EnableValidateFile(bool enable)
        {
            EnableDialog(enable);

            lnkSettingsEmailList.Enabled = enable;

            tpGetMxRecords.Enabled = enable;
            tpMultipleThreads.Enabled = enable;
            tpValidateSingleEmail.Enabled = enable;
            txtEmailListFile.Enabled = enable;
            btnBrowseListFile.Enabled = enable;
            btnValidateFile.Text = enable ? "Validate" : "Stop";
            if (enable)
                btnValidateFile.Enabled = true;
        }

        /// <summary>
        /// Handles the validate a single file button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
#if Framework4_5
        async
#endif
        void btnValidateFile_Click(object sender, EventArgs e)
        {
            // Validating?
            if (btnValidateFile.Text == "Validate")
            {
                // Clear logs.
                _selectedTabIndex = 1;
                lst2AdvancedLog.Items.Clear();
                lst2Log.Items.Clear();
                EnableValidateFile(false);

                // Load email list from a file and validate it easily with ValidateTextFile method.
                LoadBlackAndWhiteListFiles();

                // Reset counters.
                _processed = 0;
                _passed = 0;

#if Framework4_5 || SYNC
                try
                {
#if SYNC
                    emailValidator.ValidateTextFile(txtEmailListFile.Text);
#else
                    await emailValidator.ValidateTextFileAsync(txtEmailListFile.Text);
#endif
                    
                    ShowSummary();
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    EnableValidateFile(true);
                }
#else
                emailValidator.ValidateTextFileAsync(txtEmailListFile.Text);
#endif
            }
            else
            {
                // Abort the validation.
                btnValidateFile.Enabled = false;
                emailValidator.Cancel();
            }
        }

        void ShowSummary()
        {
            MessageBox.Show(string.Format("E-mail addresses validation has completed. {0} email(s) processed, {1} passed.", _processed, _passed), "Email Validator Demo", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

#if !Framework4_5 && !SYNC
        /// <summary>
        /// Handles the email validator's ValidateTextFileCompleted event.
        /// </summary>
        /// <param name="sender">The email validator object.</param>
        /// <param name="e">The event arguments.</param>
        private void sfbEmailValidator_ValidateTextFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Util.ShowError(e.Error);
            }
            else
            {
                ShowSummary();
            }

            // Enable controls.
            EnableValidateFile(true);
        }
#endif

        #endregion

        #region Validate with multiple threads

        void EnableValidateWithThreads(bool enable)
        {
            EnableDialog(enable);

            lnkMultiThreadsSettings.Enabled = enable;

            tpEmails.Enabled = enable;
            tpGetMxRecords.Enabled = enable;
            tpValidateSingleEmail.Enabled = enable;
            txtEmailListThread.Enabled = enable;
            btnBrowseThread.Enabled = enable;
            btnValidateThreads.Text = enable ? "Validate" : "Stop";
            if (enable)
                btnValidateThreads.Enabled = true;
        }

        /// <summary>
        /// Handles the validate with threads button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
        private void btnValidateThreads_Click(object sender, EventArgs e)
        {
            // Validating?
            if (btnValidateThreads.Text == "Validate")
            {
                // Clear logs.
                _selectedTabIndex = 2;
                lst3AdvancedLog.Items.Clear();
                lst4AdvancedLog.Items.Clear();
                lst3Log.Items.Clear();
                lst4Log.Items.Clear();

                try
                {
                    // Disable controls.
                    EnableValidateWithThreads(false);

                    // Load black and white list files.
                    LoadBlackAndWhiteListFiles();
                    // Start validate file with multi-threads.
                    emailValidator.MultiThreadsValidateTextFile(txtEmailListThread.Text, 2, true);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    EnableValidateWithThreads(true);
                }
            }
            else
            {
                // Abort operation.
                btnValidateThreads.Enabled = false;
                emailValidator.Cancel();
            }
        }

        /// <summary>
        /// Handles the emailvalidator's ThreadCompleted event.
        /// </summary>
        /// <param name="sender">The emailvalidator object.</param>
        /// <param name="e">The event arguments.</param>
        private void sfbEmailValidator_ThreadsCompleted(object sender, EmailValidatorThreadsCompletedEventArgs e)
        {
            if (!IsDisposed)
                Invoke(new EventHandler<EmailValidatorThreadsCompletedEventArgs>(ThreadsCompleted), sender, e);
        }

        void ThreadsCompleted(object sender, EmailValidatorThreadsCompletedEventArgs e)
        {
            // Enable controls.
            EnableValidateWithThreads(true);

            StringBuilder sb = new StringBuilder();

            foreach (EmailValidatorThreadInfo info in e.Result)
            {
                if (info.LastException != null)
                    sb.AppendFormat("\r\nThread {0} error: {1}", info.ThreadId, info.LastException.Message); 
            }

            MessageBox.Show("Multi-threads validation completed!" + sb.ToString() + string.Format("\r\n{0} email(s) processed, {1} passed", e.EmailsProcessed, e.EmailsPassed), "Email Validator Demo", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /// <summary>
        /// Handles the emailvalidator's ThreadCompleted event.
        /// </summary>
        /// <param name="sender">The emailverifer object.</param>
        /// <param name="e">The event arguments.</param>
        private void sfbEmailValidator_ThreadCompleted(object sender, EmailValidatorThreadCompletedEventArgs e)
        {
            if (!IsDisposed)
                Invoke(new EventHandler<EmailValidatorThreadCompletedEventArgs>(ThreadCompleted), sender, e);
        }

        void ThreadCompleted(object sender, EmailValidatorThreadCompletedEventArgs e)
        {
            Log(string.Format("Validation completed. {0} email(s) processed, {1} passed", e.EmailsProcessed, e.EmailsPassed), e.ThreadId);
            if (e.LastException != null)
                Log("Last error: " + e.LastException.Message, e.ThreadId);
        }

        #endregion

        private void lnkSettingsSingle_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // Show settings dialog.
            settingsToolStripMenuItem_Click(null, null);
        }

        private void lnkMultiThreadsSettings_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // Show settings dialog.
            settingsToolStripMenuItem_Click(null, null);
        }

        /// <summary>
        /// Handles the BrowseListFile button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
        private void btnBrowseListFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            try
            {
                dlg.FileName = txtEmailListFile.Text;
                dlg.Filter = "List File (*.txt)|*.txt|All files (*.*)|*.*";
                dlg.FilterIndex = 1;
                dlg.Title = "Select Email List File";
                // Show select file dialog.
                if (dlg.ShowDialog() != DialogResult.OK)
                    return;

                txtEmailListFile.Text = dlg.FileName;
            }
            catch
            {
                MessageBox.Show(dlg.FileName + " is not a valid address list", "Error");
            }
        }

        /// <summary>
        /// Handles the Browse list file button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
        private void btnBrowseThread_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            try
            {
                dlg.FileName = txtEmailListThread.Text;
                dlg.Filter = "List File (*.txt)|*.txt|All files (*.*)|*.*";
                dlg.FilterIndex = 1;
                dlg.Title = "Select Email List File";
                // Show select file dialog.
                if (dlg.ShowDialog() != DialogResult.OK)
                    return;

                txtEmailListThread.Text = dlg.FileName;
            }
            catch
            {
                MessageBox.Show(dlg.FileName + " is not a valid address list", "Error");
            }
        }

        private void lnkSettingsEmailList_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // Show settings dialog.
            settingsToolStripMenuItem_Click(null, null);
        }

        /// <summary>
        /// Handles the proxy setting menu item's Click event.
        /// </summary>
        /// <param name="sender">The menu item object.</param>
        /// <param name="e">The event arguments.</param>
        private void proxySettingsToolStripMenuItem_Click(object sender, EventArgs e)
        {            
            ProxySettings dlg = new ProxySettings();
            
            dlg.ProxyServer = emailValidator.ProxyHost;
            dlg.UserName = emailValidator.ProxyUserName;
            dlg.Password = emailValidator.ProxyPassword;
            dlg.Domain = emailValidator.ProxyDomain;
            dlg.Port = emailValidator.ProxyPort;
            dlg.AuthenticationMethod = emailValidator.ProxyHttpConnectAuthMethodMethod;
            dlg.Type = emailValidator.ProxyType;
            
            // Show the proxy setting dialog.
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                emailValidator.ProxyHost = dlg.ProxyServer;
                emailValidator.ProxyUserName = dlg.UserName;
                emailValidator.ProxyPassword = dlg.Password;
                emailValidator.ProxyDomain = dlg.Domain;
                emailValidator.ProxyPort = dlg.Port;
                emailValidator.ProxyHttpConnectAuthMethodMethod = dlg.AuthenticationMethod;
                emailValidator.ProxyType = dlg.Type;
            }
        }

        private void sfbEmailValidator_EmailValidating(object sender, EmailValidatingEventArgs e)
        {
            if (!IsDisposed)
                Invoke(new EventHandler<EmailValidatingEventArgs>(EmailValidating), sender, e);
        }

        private void EmailValidating(object sender, EmailValidatingEventArgs e)
        {
            Log(string.Format("Start validating e-mail address: '{0}'", e.EmailAddress), e.ThreadId);
        }

        private void sfbEmailValidator_Progress(object sender, EmailValidatorProgressEventArgs e)
        {
            if (!IsDisposed)
                Invoke(new EventHandler<EmailValidatorProgressEventArgs>(Progress), sender, e);
        }

        private void Progress(object sender, EmailValidatorProgressEventArgs e)
        {
            if (e.EmailAddress != null)
                if (e.Passed)
                    Log("    Passed: " + e.Level.ToString(), e.ThreadId);
                else
                    Log("    Failed: " + e.Level.ToString(), e.ThreadId);

            if (_selectedTabIndex == 0)
                return; // Progress bar is not available in single email validation.

            if (_selectedTabIndex == 1)
                progressBar.Value = e.ProgressPercentage;
            else
                progressBarThreads.Value = e.ProgressPercentage;
        }
    }
}