using System;
using System.Text;
using System.Web.UI.WebControls;
using ComponentPro.Net;
using ComponentPro.Net.Mail;

public partial class _Default : System.Web.UI.Page
{
    void PopulateEnum()
    {
        ImapAuthenticationMethod[] arr = (ImapAuthenticationMethod[])Enum.GetValues(typeof(ImapAuthenticationMethod));

        for (int i = 0; i < arr.Length; i++)
        {
            ddlAuthentication.Items.Add(new ListItem(arr[i].ToString(), ((int)arr[i]).ToString()));
        }

        int index;
        if (int.TryParse(Request.Form["ddlAuthentication"], out index))
            ddlAuthentication.SelectedIndex = index;
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        PopulateEnum();
    }

    /// <summary>
    /// Handles the Download button's Click event.
    /// </summary>
    /// <param name="sender">The button object.</param>
    /// <param name="e">The event arguments.</param>
    protected void btnDownload_Click(object sender, EventArgs e)
    {
        Imap client = new Imap();

        try
        {
            string mailsPath = AppDomain.CurrentDomain.BaseDirectory + "Mails\\";

            // Create the directory that stores downloaded messages if it is not present.
            if (!System.IO.Directory.Exists(mailsPath))
                System.IO.Directory.CreateDirectory(mailsPath);

            StringBuilder sb = new StringBuilder();
            // Parse the port num.
            int port = int.Parse(txtPort.Text);

            // Connect to the server.
            client.Connect(txtServer.Text, port, (SecurityMode)ddlSecurityMode.SelectedIndex);

            // Login to the server.
            ImapAuthenticationMethod ia = (ImapAuthenticationMethod)int.Parse(ddlAuthentication.SelectedValue);

            // Login.
            client.Authenticate(txtUser.Text, txtPassword.Text, ia);

            // Select working folder.
            client.Select(txtFolder.Text);

            // Retrieve a list of messages.
            ImapMessageCollection list = client.ListMessages(ImapEnvelopeParts.UniqueId | ImapEnvelopeParts.MessageInboxIndex);
            int messages = int.Parse(txtMessages.Text);
            if (list.Count < messages)
                messages = list.Count;

            ImapMessage message;
            for (int i = 0; i < messages; i++)
            {
                message = list[i];

                // Get file name.
                string filename = mailsPath + GetFilename(message.UniqueId) + ".eml";

                // Get new message only.
                if (!System.IO.File.Exists(filename))
                {
                    client.DownloadMessage(message.MessageInboxIndex, filename);
                    sb.AppendFormat("Message {0} downloaded<br>", message.UniqueId);
                }
            }

            sb.AppendFormat("{0} message(s) have been downloaded successfully!", messages);
            lblResult.Text = sb.ToString();
        }
        catch (Exception exc)
        {
            lblResult.Text = string.Format(null, "Exception: {0}", exc.Message);
        }
        finally
        {
            // Disconnect.
            client.Disconnect();            
        }
    }

    /// <summary>
    /// Returns a uniquely correct file name from the specified unique message ID.
    /// </summary>
    /// <param name="uniqueId">The unique id.</param>
    /// <returns>The corrected file name.</returns>
    private static string GetFilename(string uniqueId)
    {
        // Characters allowed in the filename
        //string allowed = " .-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";            
        const string allowed = " .-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        // Replace invalid charactes with its hex representation
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < uniqueId.Length; i++)
        {
            if (allowed.IndexOf(uniqueId[i]) < 0)
                sb.AppendFormat("_{0:X2}", (int)uniqueId[i]);
            else
                sb.Append(uniqueId[i]);
        }
        return sb.ToString();
    }
}