using System;

namespace LumiSoft.Net.Mime
{
	/// <summary>
	/// RFC 2822 3.4. (Address Specification) Mailbox address. 
	/// <p/>
	/// Syntax: ["display-name"&lt;SP&gt;]&lt;local-part@domain&gt;.
	/// </summary>
	public class MailboxAddress :  Address
	{
		private string m_DisplayName  = "";
		private string m_EmailAddress = "";

		/// <summary>
		/// Default constructor.
		/// </summary>
		public MailboxAddress() : base(false)
		{
		}

		/// <summary>
		/// Creates new mailbox from specified email address.
		/// </summary>
		/// <param name="emailAddress">Email address.</param>
		public MailboxAddress(string emailAddress) : base(false)
		{
			m_EmailAddress = emailAddress;
		}

		/// <summary>
		/// Creates new mailbox from specified name and email address.
		/// </summary>
		/// <param name="displayName">Display name.</param>
		/// <param name="emailAddress">Email address.</param>
		public MailboxAddress(string displayName,string emailAddress) : base(false)
		{
			m_DisplayName = displayName;
			m_EmailAddress = emailAddress;
		}


		#region method Parse

		/// <summary>
		/// Parses mailbox from mailbox address string.
		/// </summary>
		/// <param name="mailbox">Mailbox string. Format: ["diplay-name"&lt;SP&gt;]&lt;local-part@domain&gt;.</param>
		/// <returns></returns>
		public static MailboxAddress Parse(string mailbox)
		{
			mailbox = mailbox.Trim();

			/* We must parse following situations:
				"Ivar Lumi" <ivar@lumisoft.ee>
				"Ivar Lumi" ivar@lumisoft.ee
				<ivar@lumisoft.ee>
				ivar@lumisoft.ee				
				Ivar Lumi <ivar@lumisoft.ee>
			*/
			
			string name = "";
			string emailAddress = mailbox;

			// Email address is between <> and remaining left part is display name
			if(mailbox.IndexOf("<") > -1 && mailbox.IndexOf(">") > -1){
				name = TextUtils.RemoveQuotes(mailbox.Substring(0,mailbox.IndexOf("<")));
				emailAddress = mailbox.Substring(mailbox.IndexOf("<") + 1,mailbox.Length - mailbox.IndexOf("<") - 2);
			}
			else{
				// There is name included, parse it
				if(mailbox.StartsWith("\"")){
					int startIndex = mailbox.IndexOf("\"");
					if(startIndex > -1 && mailbox.LastIndexOf("\"") > startIndex){
						name = mailbox.Substring(startIndex + 1,mailbox.LastIndexOf("\"") - startIndex - 1).Trim();
					}

					emailAddress = mailbox.Substring(mailbox.LastIndexOf("\"") + 1).Trim();
				}

				// Left part must be email address
				emailAddress = emailAddress.Replace("<","").Replace(">","").Trim();
			}
			
			return new MailboxAddress(name,emailAddress);
		}

		#endregion


		#region internal method OnChanged

		/// <summary>
		/// This called when mailox address has changed.
		/// </summary>
		internal void OnChanged()
		{
			if(this.Owner != null){
				if(this.Owner is AddressList){
					((AddressList)this.Owner).OnCollectionChanged();
				}
				else if(this.Owner is MailboxAddressCollection){
					((MailboxAddressCollection)this.Owner).OnCollectionChanged();
				}
			}
		}

		#endregion


		#region Properties Implementation

		/// <summary>
		/// Gets Mailbox as RFC 2822(3.4. Address Specification) string. Format: ["display-name"&lt;SP&gt;]&lt;local-part@domain&gt;.
		/// For example, "Ivar Lumi" &lt;ivar@lumisoft.ee&gt;.
		/// </summary>
		public string MailboxString
		{
			get{ 
				string retVal = "";
				if(this.DisplayName != ""){
					retVal += TextUtils.QuoteString(this.DisplayName) + " ";
				}
                retVal += "<" + this.EmailAddress + ">";

				return retVal;
			}
		}

		/// <summary>
		/// Gets or sets display name. 
		/// </summary>
		public string DisplayName
		{
			get{ return m_DisplayName; }

			set{ 
				m_DisplayName = value; 

				OnChanged();
			}
		}

		/// <summary>
		/// Gets or sets email address. For example ivar@lumisoft.ee.
		/// </summary>
		public string EmailAddress
		{
			get{ return m_EmailAddress; }

			set{
				// Email address can contain only ASCII chars.
				if(!Core.IsAscii(value)){
					throw new Exception("Email address can contain ASCII chars only !");
				}

				m_EmailAddress = value; 

				OnChanged();
			}
		}
		
		/// <summary>
		/// Gets local-part from email address. For example mailbox is "ivar" from "ivar@lumisoft.ee".
		/// </summary>
		public string LocalPart
		{
			get{ 
				if(this.EmailAddress.IndexOf("@") > -1){
					return this.EmailAddress.Substring(0,this.EmailAddress.IndexOf("@"));
				}
				else{
					return this.EmailAddress;
				}
			}
		}

		/// <summary>
		/// Gets domain from email address. For example domain is "lumisoft.ee" from "ivar@lumisoft.ee".
		/// </summary>
		public string Domain
		{
			get{ 
				if(this.EmailAddress.IndexOf("@") != -1){
					return this.EmailAddress.Substring(this.EmailAddress.IndexOf("@") + 1);
				}
				else{
					return "";
				}
			}
		}

		#endregion

     }
}
