/
etc/
lib/
src/Abilities/
src/Abilities/Skills/
src/Abilities/Spells/
src/Abilities/Spells/Enums/
src/Affects/
src/ArtheaConsole/
src/ArtheaConsole/Properties/
src/ArtheaGUI/Properties/
src/Clans/Enums/
src/Commands/Communication/
src/Commands/ItemCommands/
src/Connections/
src/Connections/Colors/
src/Connections/Enums/
src/Connections/Players/
src/Connections/Players/Enums/
src/Continents/
src/Continents/Areas/
src/Continents/Areas/Characters/
src/Continents/Areas/Characters/Enums/
src/Continents/Areas/Items/
src/Continents/Areas/Items/Enums/
src/Continents/Areas/Rooms/
src/Continents/Areas/Rooms/Enums/
src/Continents/Areas/Rooms/Exits/
src/Creation/
src/Creation/Attributes/
src/Creation/Interfaces/
src/Database/
src/Database/Interfaces/
src/Environment/
src/Properties/
src/Scripts/Enums/
src/Scripts/Interfaces/
#region Arthea License

/***********************************************************************
*  Arthea MUD by R. Jennings (2007)      http://arthea.googlecode.com/ *
*  By using this code you comply with the Artistic and GPLv2 Licenses. *
***********************************************************************/

#endregion

using Arthea.Abilities.Skills;
using Arthea.Connections.Players;
using Arthea.Environment;

namespace Arthea.Commands
{
    /// <summary>
    /// Implements a command.
    /// </summary>
    public abstract class Command
    {
        #region [rgn] Fields (4)

        private string alias = string.Empty;
        private string description = string.Empty;
        private byte level;
        private string name = string.Empty;

        #endregion [rgn]

        #region [rgn] Constructors (4)

        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="desc">The description.</param>
        /// <param name="level">The level.</param>
        public Command(string name, string desc, byte level)
        {
            this.name = name;
            description = desc;
            this.level = level;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="desc">The description.</param>
        public Command(string name, string desc)
        {
            this.name = name;
            description = desc;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="level">The level.</param>
        public Command(string name, byte level)
        {
            this.name = name;
            this.level = level;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        public Command(string name)
        {
            this.name = name;
            level = 0;
        }

        #endregion [rgn]

        #region [rgn] Properties (4)

        /// <summary>
        /// Gets or sets the alias.
        /// </summary>
        /// <value>The alias.</value>
        public string Alias
        {
            get { return alias; }
            set { alias = value; }
        }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>The description.</value>
        public string Description
        {
            get { return description; }
            set { description = value; }
        }

        /// <summary>
        /// Gets or sets the level.
        /// </summary>
        /// <value>The level.</value>
        public byte Level
        {
            get { return level; }
            set { level = value; }
        }

        /// <summary>
        /// Gets the name.
        /// </summary>
        /// <value>The name.</value>
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        #endregion [rgn]

        #region [rgn] Methods (4)

        // [rgn] Public Methods (4)

        /// <summary>
        /// Interprets an argument from a player to a command.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="argument">The argument.</param>
        public static void Interpret(Player player, String argument)
        {
            if (argument.Empty())
            {
                AutoLookCommand.Look(player);
                return;
            }

            String arg;

            // allow arguments like "'"
            if (!char.IsLetterOrDigit(argument[0]))
            {
                arg = argument[0].ToString();
                argument = argument.Substring(1).Trim();
            }
            else
            {
                arg = argument.FirstArg();
            }

            // check skills
            Skill skill = Lists.Abilities.FindSkill(arg);

            if (skill != null)
            {
                Skill.Execute(skill, player, argument);
                return;
            }

            // check socials
            if (!Lists.Socials.Parse(player, arg, argument))
            {
                // finally its a command
                Lists.Commands.Lookup(arg, player).Process(player, argument);
            }
        }

        /// <summary>
        /// Processes the command for a player.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="argument">The argument.</param>
        public abstract void Process(Player player, String argument);

        /// <summary>
        /// Syntaxes of the command displayed to a player.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="args">The args.</param>
        public void Syntax(Player player, params string[] args)
        {
            player.WriteLine("Syntax:");
            for (int i = 0; i < args.Length; i++)
            {
                player.WriteLine("{0}: {1}", name, args[i]);
            }
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override string ToString()
        {
            return name;
        }

        #endregion [rgn]
    }

    /// <summary>
    /// Implements an unknown command.
    /// </summary>
    public class UnknownCommand : Command
    {
        #region [rgn] Constructors (1)

        /// <summary>
        /// Initializes a new instance of the <see cref="UnknownCommand"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        public UnknownCommand(String name) : base(name.ToString())
        {
        }

        #endregion [rgn]

        #region [rgn] Methods (1)

        // [rgn] Public Methods (1)

        /// <summary>
        /// Processes the command for a player.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="argument">The argument.</param>
        public override void Process(Player player, String argument)
        {
            player.WriteLine("Huh? What does '{0}' mean?", Name);
        }

        #endregion [rgn]
    }

    /// <summary>
    /// Implements a restricted command.
    /// </summary>
    public class RestrictedCommand : Command
    {
        #region [rgn] Constructors (2)

        /// <summary>
        /// Initializes a new instance of the <see cref="RestrictedCommand"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="level">The level.</param>
        public RestrictedCommand(String name, byte level) : base(name.ToString(), level)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RestrictedCommand"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        public RestrictedCommand(String name) : base(name.ToString())
        {
        }

        #endregion [rgn]

        #region [rgn] Methods (1)

        // [rgn] Public Methods (1)

        /// <summary>
        /// Processes the command for a player.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="argument">The argument.</param>
        public override void Process(Player player, String argument)
        {
            if (Level == 0)
            {
                player.WriteLine("You are not allowed to use {0}.", Name);
            }
            else
            {
                player.WriteLine("You must be level {0} to use {1}.", Level, Name);
            }
        }

        #endregion [rgn]
    }
}