using System;

namespace Volpe.Cafe.Model
{
    /// <summary>
    /// Provides the title, description, and version information of a <see cref="ICompliance"/> modeling implementation.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
    public class ModelDescriptionAttribute : Attribute
    {

        #region /*** Nested Types ***/

        /// <summary>
        /// Specifies the version type of the <see cref="ICompliance"/>, whether the version information is alpha, beta, or neither.
        /// </summary>
        public enum VersionType : int
        {
            /// <summary>Specifies that the verison information of the <see cref="ICompliance"/> is neither alpha nor beta version.</summary>
            None = 0,
            /// <summary>Specifies that the verison information of the <see cref="ICompliance"/> is the alpha version.</summary>
            Alpha = 1,
            /// <summary>Specifies that the verison information of the <see cref="ICompliance"/> is the beta version.</summary>
            Beta = 2
        }

        #endregion


        #region /*** Constructors ***/

        /// <summary>
        /// Initializes a new instance of the ModelDescriptionAttribute using default values.
        /// </summary>
        public ModelDescriptionAttribute() : this(null, null, 0.0F) {}
        /// <summary>
        /// Initializes a new instance of the ModelDescriptionAttribute with the specified title, description, and version
        /// information, and using the default <see cref="VersionType"/>.
        /// </summary>
        /// <param name="title">The title information of the <see cref="ICompliance"/>.</param>
        /// <param name="description">The description information of the <see cref="ICompliance"/>.</param>
        /// <param name="version">The version information of the <see cref="ICompliance"/>.</param>
        public ModelDescriptionAttribute(string title, string description, float version) : this(title, description, version, VersionType.None) {}
        /// <summary>
        /// Initializes a new instance of the ModelDescriptionAttribute with the specified title, description, version,
        /// information, and version type.
        /// </summary>
        /// <param name="title">The title information of the <see cref="ICompliance"/>.</param>
        /// <param name="description">The description information of the <see cref="ICompliance"/>.</param>
        /// <param name="version">The version information of the <see cref="ICompliance"/>.</param>
        /// <param name="verType">The version type of the <see cref="ICompliance"/>, whether the version information is alpha, beta, or neither.</param>
        public ModelDescriptionAttribute(string title, string description, float version, VersionType verType)
        {
            this._title = title;
            this._description = description;
            this._version = version;
            this._verType = verType;
        }

        #endregion


        #region /*** Methods ***/

        /// <summary>
        /// Returns the string representation of this ModelDescriptionAttribute instance.
        /// </summary>
        /// <returns>The string representation of the ModelDescriptionAttribute instance.</returns>
        public override string ToString()
        {
            return this.FullTitle;
        }
        /// <summary>
        /// Returns the string representation of this ModelDescriptionAttribute instance, optionally including the description
        /// field in the output string.
        /// </summary>
        /// <param name="omitDescription">true, to omit the descripton field from the output string; false, otherwise.</param>
        /// <returns>The string representation of the ModelDescriptionAttribute instance.</returns>
        public string ToString(bool omitDescription)
        {
            return (this.FullTitle + ((omitDescription) ? " - " + this._description : ""));
        }

        /// <summary>
        /// Returns an indication whether the value of this instance is the default value.
        /// </summary>
        /// <returns>true, if this instance does not contain any information (such that its title and description are null or
        ///   empty, and its version is equals to 0); false, otherwise.</returns>
        public override bool IsDefaultAttribute()
        {
            return (this._verType == ModelDescriptionAttribute.VersionType.None && this._version == 0.0F &&
                (this._description == null || this._description == "") && (this._title == null || this._title == ""));
        }

        #endregion


        #region /*** Properties ***/

        /// <summary>Gets the title information of the <see cref="ICompliance"/>.</summary>
        public string Title { get { return this._title; } }
        /// <summary>Gets the full title information of the <see cref="ICompliance"/>, including the tile, version, and version type (if applicable).</summary>
        public string FullTitle { get { return this._title + " (v." + this.VersionString + ")"; } }
        /// <summary>Gets the description information of the <see cref="ICompliance"/>.</summary>
        public string Description { get { return this._description; } }
        /// <summary>Gets the version information of the <see cref="ICompliance"/>, including the version number and type (if applicable).</summary>
        public string VersionString
        {
            get
            {
                return this._version.ToString("0.0#") +
                    ((this._verType == ModelDescriptionAttribute.VersionType.Alpha) ? "a" :
                    (this._verType == ModelDescriptionAttribute.VersionType.Beta) ? "b" : "");
            }
        }
        /// <summary>Gets the version information of the <see cref="ICompliance"/>.</summary>
        public float Version { get { return this._version; } }
        /// <summary>Gets the version type of the <see cref="ICompliance"/>, whether the version information is alpha, beta, or neither.</summary>
        public ModelDescriptionAttribute.VersionType VerType { get { return this._verType; } }

        #endregion


        #region /*** Variables ***/

        string _title;
        string _description;
        float  _version;
        ModelDescriptionAttribute.VersionType _verType;

        #endregion

    }
}
