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

namespace MailSamples
{
    public partial class MailAttachment : Form
    {
        private readonly bool _exception;

        public MailAttachment()
        {
            try
            {
                InitializeComponent();
            }
            catch (ComponentPro.Licensing.Mail.UltimateLicenseException exc)
            {
                MessageBox.Show(exc.Message, "Error");
                _exception = true;
                return;
            }

            string dataDir;

            // Gets path to the Data folder.
            dataDir = AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Data";
            if (!System.IO.Directory.Exists(dataDir))
                dataDir = AppDomain.CurrentDomain.BaseDirectory + "Data";

            txtEmailFile.Text = dataDir + "\\TestAttachment.eml";
        }

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

        /// <summary>
        /// Writes a message.
        /// </summary>
        /// <param name="msg">Message to write.</param>
        /// <param name="parameters">Parameters.</param>
        private void WriteLine(string msg, params object[] parameters)
        {
            txtResult.Text += string.Format(msg, parameters) + "\r\n";
            System.Windows.Forms.Application.DoEvents();
        }

        /// <summary>
        /// Clears the output.
        /// </summary>
        private void Clear()
        {
            txtResult.Clear();
            System.Windows.Forms.Application.DoEvents();
        }

        /// <summary>
        /// Extracs attachments from a mail file.
        /// </summary>
        /// <param name="fileName">Mail file name.</param>
        /// <returns>A boolean value indicating whether the extraction is successful.</returns>
        private void ExtractAttachments(string fileName)
        {
            try
            {
                // Load the mail message from disk
                MailMessage mail = new MailMessage();
                mail.Load(fileName);

                // DecryptData the message if it is encrypted
                if (mail.IsEncrypted)
                {
                    if (!mail.Decryptable)
                    {
                        WriteLine("Message cannot be decrypted. You do not have the private key.");
                        return;
                    }
                    mail.Decrypt();
                }

                // ValidateRequest the signature if the message is signed
                if (mail.IsSigned)
                {
                    MailSignatureValidationResult result = mail.ValidateSignature();
                    if (result.Valid)
                    {
                        WriteLine("The message is signed and the signature is valid.");
                    }
                    else
                    {
                        WriteLine("The message is signed, but the signature is not valid.");
                        ShowProblems(result);
                    }
                }

                WriteLine("Message contains {0} attachments.", mail.Attachments.Count);

                // If message has no attachments, just exit
                if (mail.Attachments.Count == 0)
                    return;

                foreach (Attachment attachment in mail.Attachments)
                {
                    // Write the file
                    WriteLine("Saving '{0}' ({1}).", attachment.FileName, attachment.MediaType);
                    attachment.Save(attachment.FileName);
                }

                return;
            }
            catch (Exception exc)
            {
                WriteLine("An error occurred: {0}", exc.Message);
            }

            return;
        }

        /// <summary>
        /// Handles the Extract button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
        private void btnExtract_Click(object sender, EventArgs e)
        {
            // Clear logs.
            Clear();
            ExtractAttachments(txtEmailFile.Text);
        }

        /// <summary>
        /// Handles the Browse list file'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 = txtEmailFile.Text;
                dlg.Filter = "Internet Email File (*.eml)|*.eml|Outlook files (*.msg)|*.msg|All files (*.*)|*.*";
                dlg.FilterIndex = 1;
                dlg.Title = "Select Email File";
                // Show Open file dialog.
                if (dlg.ShowDialog() != DialogResult.OK)
                    return;

                txtEmailFile.Text = dlg.FileName;
            }
            catch
            {
                MessageBox.Show(dlg.FileName + " is not a valid email file", "Error");
            }
        }

        /// <summary>
        /// Displays the list of problems of the message that was not validated successfully.
        /// </summary>
        /// <param name="result">Validation result.</param>
        public void ShowProblems(MailSignatureValidationResult result)
        {
            WriteLine("There were following problems:");

            string[] missing = result.MissingSignatureEmails;
            if (missing.Length > 0)
            {
                WriteLine("- The signatures for the following senders are missing:");
                for (int i = 0; i < missing.Length; i++)
                    WriteLine("    {0}", missing[i]);
            }
        }

        /// <summary>
        /// Handles the Close button's Click event.
        /// </summary>
        /// <param name="sender">The button object.</param>
        /// <param name="e">The event arguments.</param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}