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

namespace ScanImapSample
{
    public partial class MessageViewer : Form
    {
        MailMessage _msg;
        private readonly string _fileName;

        public MessageViewer()
        {
            InitializeComponent();
        }

        public MessageViewer(string fileName)
        {
            InitializeComponent();

            _fileName = fileName;
        }

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

            // Disable the X button.
            Util.EnableCloseButton(this, false);
        }

        /// <summary>
        /// Handles the form's Shown event.
        /// </summary>
        /// <param name="e">The even arguments.</param>
        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            try
            {
                _msg = new MailMessage(_fileName);

                // Fill from, to, cc.
                txtFrom.Text = _msg.From.ToString();
                txtTo.Text = _msg.To.ToString();
                txtCc.Text = _msg.Cc.ToString();

                // Fill subject.
                txtSubject.Text = _msg.Subject;

                saveAsToolStripMenuItem.Enabled = true;
                copyToolStripMenuItem.Enabled = true;
                selectAllToolStripMenuItem.Enabled = true;
                Util.EnableCloseButton(this, true);

                // Fill the attachment list.
                if (_msg.Attachments.Count > 0)
                    foreach (Attachment at in _msg.Attachments)
                    {
                        cbxAttachment.Items.Add(at.FileName);
                    }

                if (cbxAttachment.Items.Count > 0)
                {
                    cbxAttachment.SelectedIndex = 0;
                    saveAttachmentsToolStripMenuItem.Enabled = true;
                }
                else
                {
                    cbxAttachment.Enabled = false;
                    saveAttachmentsToolStripMenuItem.Enabled = false;
                }

                // Fill body plain text version.
                txtBody.Text = _msg.BodyText.Replace("\n", "\r\n");
                // Fill body HTML version.
                txtHtml.Text = _msg.BodyHtml.Replace("\n", "\r\n");

                HeaderCollection headers = _msg.Headers;

                // Show all message header
                for (int i = 0; i < headers.Count; i++)
                {
                    Header header = headers[i];

                    // add name column
                    ListViewItem item = new ListViewItem(header.Name);

                    // add header raw content column
                    item.SubItems.Add(header.Raw);

                    // show unparsed (corrupted) headers in red				
                    if (header.Unparsable)
                        item.ForeColor = System.Drawing.Color.Red;

                    // add row to the ListView				
                    lvwHeaders.Items.Add(item);
                }

                byte[] rawData;
                using (FileStream reader = new FileStream(_fileName, FileMode.Open))
                {
                    rawData = new byte[reader.Length];
                    reader.Read(rawData, 0, rawData.Length);
                }

                // Fill raw message.
                string rawtext = System.Text.Encoding.Default.GetString(rawData, 0, Math.Min(rawData.Length, 500000));
                txtRawText.Text = rawtext;
            }
            catch (Exception exc)
            {                
                Util.ShowError(exc);

                this.Close();
            }         
        }

        /// <summary>
        /// Shows Save as dialog and save the message to the specified file.
        /// </summary>
        private void SaveMessageAs()
        {
            SaveFileDialog dlg = new SaveFileDialog();
            try
            {
                dlg.OverwritePrompt = true;
                dlg.Filter = "Email files (*.eml)|*.eml|All files (*.*)|*.*";
                dlg.FilterIndex = 1;
                dlg.Title = "Save the mail as";
                // Show the Save File As dialog.
                if (dlg.ShowDialog() != DialogResult.OK)
                    return;                
            }
            catch
            {
                MessageBox.Show(dlg.FileName + " is not an email file", "Error");
            }

            SaveMessageAs(dlg.FileName);
        }

        /// <summary>
        /// Saves the current message as a file.
        /// </summary>
        /// <param name="fileName"></param>
        private void SaveMessageAs(string fileName)
        {
            try
            {
                _msg.Save(fileName);
            }
            catch (Exception exc)
            {
                Util.ShowError(exc);
            }
        }

        /// <summary>
        /// Saves attachments to a specific folder.
        /// </summary>
        private void SaveAttachmentAs(string folder)
        {
            try
            {
                foreach (Attachment att in _msg.Attachments)
                {
                    att.Save(Path.Combine(folder, att.FileName));
                }
            }
            catch (Exception exc)
            {
                Util.ShowError(exc);
            }
        }

        /// <summary>
        /// Saves attachments to a specific folder. A browing folder dialog will be shown.
        /// </summary>
        private void SaveAttachmentAs()
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
                return;

            string path = folderBrowserDialog.SelectedPath;
            SaveAttachmentAs(path);
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtBody.SelectAll();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveMessageAs();
        }

        private void saveAttachmentsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveAttachmentAs();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtBody.Copy();
        }
    }
}