/
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 System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Arthea
{
    /// <summary>
    /// Wrapper for string objects
    /// </summary>
    public class String : IXmlSerializable
    {
        #region [rgn] Fields (1)

        private string mString;

        #endregion [rgn]

        #region [rgn] Constructors (3)

        /// <summary>
        /// Initializes a new instance of the <see cref="String"/> class.
        /// </summary>
        /// <param name="str">The STR.</param>
        public String(string str)
        {
            mString = str;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="String"/> class.
        /// </summary>
        /// <param name="str">The STR.</param>
        public String(String str)
        {
            mString = str.mString;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="String"/> class.
        /// </summary>
        public String()
        {
        }

        #endregion [rgn]

        #region [rgn] Properties (2)

        /// <summary>
        /// Gets the length.
        /// </summary>
        /// <value>The length.</value>
        public int Length
        {
            get { return mString.Length; }
        }

        /// <summary>
        /// Gets the <see cref="System.Char"/> at the specified index.
        /// </summary>
        /// <value></value>
        public char this[int index]
        {
            get { return mString[index]; }
        }

        #endregion [rgn]

        #region [rgn] Methods (28)

        // [rgn] Public Methods (28)

        /// <summary>
        /// Checks if a string is empty
        /// </summary>
        /// <param name="str">the string to check</param>
        /// <returns>true if string is empty</returns>
        public static bool operator !(String str)
        {
            return str.Empty();
        }

        /// <summary>
        /// Checks if a string is NOT empty.
        /// </summary>
        /// <param name="str">the string being operated on</param>
        /// <returns>true if a string is not empty</returns>
        public static bool operator +(String str)
        {
            return !str.Empty();
        }

        /// <summary>
        /// Implements the operator +.
        /// </summary>
        /// <param name="lStr">The left side STR.</param>
        /// <param name="rStr">The right side STR.</param>
        /// <returns>The result of the operator.</returns>
        public static String operator +(String lStr, String rStr)
        {
            return lStr.mString + rStr.mString;
        }

        /// <summary>
        /// Puts the first letter in upper case and the rest in lower case
        /// </summary>
        /// <returns>a captialized string</returns>
        public String Capitalize(bool tolower)
        {
            if (Empty())
            {
                return this;
            }

            char firstLetter;

            if (!char.IsUpper(mString[0]))
            {
                firstLetter = char.ToUpper(mString[0]);
            }
            else
            {
                firstLetter = mString[0];
            }

            if (tolower)
                return firstLetter + mString.Substring(1).ToLower();
            else
                return firstLetter + mString.Substring(1);
        }

        /// <summary>
        /// Capitalizes this instance.
        /// </summary>
        /// <returns></returns>
        public String Capitalize()
        {
            return Capitalize(true);
        }

        /// <summary>
        /// Checks if a string is empty
        /// </summary>
        /// <returns>true if the string is empty</returns>
        public bool Empty()
        {
            return string.IsNullOrEmpty(mString);
        }

        /// <summary>
        /// Compares the end of the string.
        /// </summary>
        /// <param name="end">The end part.</param>
        /// <returns>true if the string ends with specified end part.</returns>
        public bool EndsWith(string end)
        {
            return mString.EndsWith(end, StringComparison.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// Checks if two strings are equal (cast insensitive)
        /// </summary>
        /// <param name="str">the other string</param>
        /// <returns>true if strings are equal</returns>
        public bool Equals(string str)
        {
            return mString.Equals(str, StringComparison.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// Overriden equals equation
        /// </summary>
        /// <param name="obj">the object to compare with</param>
        /// <returns>true if objects are equal</returns>
        public override bool Equals(object obj)
        {
            if (mString == null)
                return base.Equals(obj);

            return mString.Equals(obj);
        }

        /// <summary>
        /// Gets the first argument in a string
        /// Delimited by a space, '', "", or ()
        /// </summary>
        /// <param name="update">true if this string should be updated</param>
        /// <returns>the rest of the string</returns>
        public String FirstArg(bool update)
        {
            string arg;

            if (Empty())
            {
                return this;
            }

            char cEnd = ' ';
            int pos, begin = 0;


            if (mString[0] == '\'' || mString[0] == '"' || mString[0] == '(')
            {
                if (mString[0] == '(')
                {
                    cEnd = ')';
                }
                else
                {
                    cEnd = mString[0];
                }
                begin = 1;
            }

            if ((pos = mString.IndexOf(cEnd, begin)) == -1)
            {
                if (begin != 0)
                {
                    arg = mString[0].ToString();
                    if (update)
                    {
                        mString = mString.Substring(begin).Trim();
                    }
                }
                else
                {
                    arg = mString;
                    if (update)
                    {
                        mString = string.Empty;
                    }
                }
            }
            else
            {
                arg = mString.Substring(begin, pos).Trim();

                if (update)
                {
                    mString = mString.Substring(pos + 1).Trim();
                }
            }
            return arg;
        }

        /// <summary>
        /// Gets the first arg of this string.
        /// Will reassign this string.
        /// </summary>
        /// <returns>a string</returns>
        public String FirstArg()
        {
            return FirstArg(true);
        }

        /// <summary>
        /// Gets an array of args in this instance.
        /// </summary>
        /// <returns>a string array</returns>
        public String[] GetArgs()
        {
            List<String> args = new List<String>();
            String temp = new String(this);

            while (!temp.Empty())
            {
                args.Add(temp.FirstArg());
            }

            return args.ToArray();
        }

        /// <summary>
        /// Retrieves an object that can iterate through individual characters in the string.
        /// </summary>
        /// <returns>a character enumurator</returns>
        public CharEnumerator GetEnumerator()
        {
            return mString.GetEnumerator();
        }

        /// <summary>
        /// Overriden for equality operator
        /// </summary>
        /// <returns>this string hash code</returns>
        public override int GetHashCode()
        {
            if (mString == null)
                return base.GetHashCode();

            return mString.GetHashCode();
        }

        /// <summary>
        /// Gets a line from the string.
        /// </summary>
        /// <returns>a line of text from the string</returns>
        public String GetLine()
        {
            if (Empty())
                return this;

            int pos = mString.IndexOf(System.Environment.NewLine);
            String line;

            if (pos >= 0)
            {
                line = mString.Substring(0, pos);

                if (pos + System.Environment.NewLine.Length <= mString.Length)
                    mString = mString.Substring(pos + System.Environment.NewLine.Length);
                else
                    mString = string.Empty;

                return line;
            }
            else
            {
                line = mString;
                mString = string.Empty;

                return line;
            }
        }

        /// <summary>
        /// Gets the lines.
        /// </summary>
        /// <returns></returns>
        public string[] GetLines()
        {
            return mString.Split(new string[] {System.Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        /// Determines whether this instance has a line.
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance has a line; otherwise, <c>false</c>.
        /// </returns>
        public bool HasLine()
        {
            return HasLine(mString);
        }

        /// <summary>
        /// Determines whether the specified STR has a line.
        /// </summary>
        /// <param name="str">The STR.</param>
        /// <returns>
        /// 	<c>true</c> if the specified STR has a line; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasLine(string str)
        {
            return str.Length > 0 && str.EndsWith(System.Environment.NewLine);
        }

        /// <summary>
        /// Checks if a string is a number
        /// </summary>
        /// <returns>true if the string is a number</returns>
        public bool IsNumber()
        {
            if (Empty())
                return false;

            for (CharEnumerator ch = mString.GetEnumerator(); ch.MoveNext();)
            {
                if (!char.IsDigit(ch.Current))
                    return false;
            }
            return true;
        }

        /// <summary>
        /// Checks if this string is a prefix of another string (case insensitive)
        /// </summary>
        /// <param name="str">the string to check</param>
        /// <returns>true if this string is a prefix of the paramter</returns>
        public bool IsPrefixOf(string str)
        {
            return str.StartsWith(mString, StringComparison.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// Replaces the specified find.
        /// </summary>
        /// <param name="find">The string to find.</param>
        /// <param name="replace">The replace value.</param>
        /// <returns></returns>
        public String Replace(String find, String replace)
        {
            return mString.Replace(find, replace);
        }

        /// <summary>
        /// Checks is this string starts with another string (case insensitive)
        /// </summary>
        /// <param name="str">the prefix to check</param>
        /// <returns>true if this string starts with parameter</returns>
        public bool StartsWith(string str)
        {
            return mString.StartsWith(str, StringComparison.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// Performs an explicit conversion from <see cref="Arthea.String"/> to <see cref="System.String"/>.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator string(String x)
        {
            return x.mString;
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.String"/> to <see cref="Arthea.String"/>.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator String(string x)
        {
            return new String(x);
        }

        /// <summary>
        /// Returns a substring of this string
        /// </summary>
        /// <param name="startPos">the position to start at</param>
        /// <returns>a substring</returns>
        public String Substring(int startPos)
        {
            return mString.Substring(startPos);
        }

        /// <summary>
        /// Gets a substring of this string
        /// </summary>
        /// <param name="start">the index to start at</param>
        /// <param name="length">the length of substring to return</param>
        /// <returns>a substring</returns>
        public String Substring(int start, int length)
        {
            return mString.Substring(start, length);
        }

        /// <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 mString; // return the internal string
        }

        /// <summary>
        /// Removes whitespace from the string
        /// </summary>
        /// <returns>formated string</returns>
        public String Trim()
        {
            return mString.Trim();
        }

        #endregion [rgn]

        #region operators

        /// <summary>
        /// Checks if two strings are equal (case insensitive)
        /// </summary>
        /// <param name="orig">first string</param>
        /// <param name="str">second string</param>
        /// <returns>true if strings are equal</returns>
        public static bool operator ==(String orig, string str)
        {
            return orig.Equals(str);
        }

        /// <summary>
        /// Check if two string are not equal (case insensitive)
        /// </summary>
        /// <param name="orig">first string</param>
        /// <param name="str">second string</param>
        /// <returns>true if strings are not equal</returns>
        public static bool operator !=(String orig, string str)
        {
            return !orig.Equals(str);
        }

        #endregion

        #region IXmlSerializable Members

        /// <summary>
        /// Converts an object into its XML representation.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Xml.XmlWriter"></see> stream to which the object is serialized.</param>
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("value", mString);
        }

        /// <summary>
        /// Generates an object from its XML representation.
        /// </summary>
        /// <param name="reader">The <see cref="T:System.Xml.XmlReader"></see> stream from which the object is deserialized.</param>
        public void ReadXml(XmlReader reader)
        {
            mString = reader.GetAttribute("value");
            reader.ReadEndElement();
        }

        /// <summary>
        /// This property is reserved, apply the <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"></see> to the class instead.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Xml.Schema.XmlSchema"></see> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"></see> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"></see> method.
        /// </returns>
        public XmlSchema GetSchema()
        {
            return (null);
        }

        #endregion
    }
}