/
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.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Arthea.Connections.Colors;
using Arthea.Connections.Players;
using Arthea.Continents.Areas.Characters;
using Arthea.Continents.Areas.Items;
using Arthea.Environment;
using Arthea.Scripts.Enums;

namespace Arthea
{
    /// <summary>
    /// Miscellaneous code
    /// </summary>
    public struct Util
    {
        /// <summary>
        /// Simulates rolling of dice
        /// </summary>
        /// <param name="rolls">the number of die to roll</param>
        /// <param name="dieSize">the number of faces on a die</param>
        /// <returns>the sum of die rolls</returns>
        public static int Dice(int rolls, int dieSize)
        {
            int idice;
            int sum;

            switch (dieSize)
            {
                case 0:
                    return 0;
                case 1:
                    return rolls;
            }

            for (idice = 0, sum = 0; idice < rolls; idice++)
                sum += Randomizer.Next(1, dieSize);

            return sum;
        }


        /// <summary>
        /// Encrypts a string
        /// </summary>
        /// <param name="inp">the string to encrypt</param>
        /// <returns>an encrypted version of input</returns>
        public static string Encrypt(string inp)
        {
            MD5CryptoServiceProvider hasher = new MD5CryptoServiceProvider();

            byte[] tBytes = Globals.Encoding.GetBytes(inp);

            byte[] hBytes = hasher.ComputeHash(tBytes);

            return Convert.ToBase64String(hBytes);
        }
    }

    /// <summary>
    /// Handles serialization
    /// </summary>
    public struct Persistance
    {
        /// <summary>
        /// formats a string into a would-be file name
        /// </summary>
        /// <param name="words">the words to format</param>
        /// <returns>a possible file name</returns>
        public static string MakeFileName(string words)
        {
            return words.Replace(' ', '_').ToLower();
        }

        /// <summary>
        /// Makes sure there is a .xml extension on a filename
        /// </summary>
        /// <param name="filename">the filename to check</param>
        /// <returns>a filename that ends in .xml</returns>
        public static string XmlFileName(string filename)
        {
            if (!filename.EndsWith(".xml"))
                filename += ".xml";

            return filename;
        }

        /// <summary>
        /// Checks if an xml file of given name exits.
        /// </summary>
        /// <param name="file">the file name to check</param>
        /// <returns>true if the file exists</returns>
        public static bool XmlFileExists(string file)
        {
            return File.Exists(XmlFileName(file));
        }

        /// <summary>
        /// Deserializes (Loads) a type from a given reader
        /// </summary>
        /// <typeparam name="T">The type of object</typeparam>
        /// <param name="reader">the xml reader</param>
        /// <returns>and instance of T</returns>
        public static T Load<T>(XmlReader reader)
        {
            XmlSerializer s = new XmlSerializer(typeof (T));
            return (T) s.Deserialize(reader);
        }

        /// <summary>
        /// Deserializes an object in a file
        /// </summary>
        /// <typeparam name="T">The type of object</typeparam>
        /// <param name="filename">The filename to load</param>
        /// <returns>an instance of T</returns>
        public static T Load<T>(string filename)
        {
            XmlSerializer s = new XmlSerializer(typeof (T));
            TextReader r = new StreamReader(XmlFileName(filename));
            T data = (T) s.Deserialize(r);
            r.Close();
            return data;
        }

        /// <summary>
        /// Loads if file exists.
        /// </summary>
        /// <typeparam name="T">the type of object to load</typeparam>
        /// <param name="filename">The filename.</param>
        /// <returns>an instance of T</returns>
        public static T LoadIfExists<T>(string filename) where T : new()
        {
            if (!XmlFileExists(filename))
                return new T();

            return Load<T>(filename);
        }

        /// <summary>
        /// Saves an object to a given xml writer
        /// </summary>
        /// <param name="writer">the xml writer</param>
        /// <param name="obj">the object to save</param>
        public static void Save(XmlWriter writer, object obj)
        {
            XmlSerializer x = new XmlSerializer(obj.GetType());
            x.Serialize(writer, obj);
        }

        /// <summary>
        /// Saves an object to a file.
        /// </summary>
        /// <param name="filename">The file name</param>
        /// <param name="obj">The object to save.</param>
        public static void Save(string filename, object obj)
        {
            XmlSerializer x = new XmlSerializer(obj.GetType());
            string tempFile = Path.GetTempFileName();
            string xmlFile = XmlFileName(filename);
            TextWriter w = new StreamWriter(tempFile);
            x.Serialize(w, obj);
            w.Close();
            if (File.Exists(xmlFile))
                File.Delete(xmlFile);
            File.Move(tempFile, xmlFile);
        }

        /// <summary>
        /// Gets a list of xml files in a specified directory
        /// </summary>
        /// <param name="path">The directory to explore</param>
        /// <returns>an array of files</returns>
        public static FileInfo[] GetDirectoryXmlFiles(string path)
        {
            DirectoryInfo di = new DirectoryInfo(path);
            return di.GetFiles("*.xml");
        }
    }

    /// <summary>
    /// Handles action messages
    /// </summary>
    public class Act : Flag
    {
        #region [rgn] Fields (5)

        /// <summary>
        /// Display to room not include the victim
        /// </summary>
        public const ulong ToNotVict = (1UL << 3);

        /// <summary>
        /// Display to the player
        /// </summary>
        public const ulong ToPlayer = (1UL << 0);

        /// <summary>
        /// Display to the room
        /// </summary>
        public const ulong ToRoom = (1UL << 2);

        /// <summary>
        /// Display to the victim
        /// </summary>
        public const ulong ToVictim = (1UL << 1);

        /// <summary>
        /// Display to all players
        /// </summary>
        public const ulong ToWorld = (1UL << 4);

        #endregion [rgn]

        #region [rgn] Constructors (1)

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

        #endregion [rgn]

        #region [rgn] Methods (1)

        // [rgn] Public Methods (1)

        /// <summary>
        /// Displayes an action message
        /// </summary>
        /// <param name="player">the player causing the action</param>
        /// <param name="arg1">arg1 in the formating</param>
        /// <param name="arg2">arg2 in the formating</param>
        /// <param name="to">the player recieving the action message</param>
        /// <param name="text">the action message</param>
        public static void Show(Character player, object arg1, object arg2, Character to, string text)
        {
            Character victim = arg2 as Character;
            Item item1 = arg1 as Item;
            Item item2 = arg2 as Item;

            CharEnumerator ch = text.GetEnumerator();
            StringBuilder buf = new StringBuilder();

            while (ch.MoveNext())
            {
                if (ch.Current != '$')
                {
                    buf.Append(ch.Current);
                    continue;
                }

                if (!ch.MoveNext())
                    break;

                if (ch.Current == '$')
                {
                    buf.Append('$');
                    continue;
                }

                if (arg2 == null && char.IsUpper(ch.Current))
                {
                    Log.Bug("Act.Show: missing argument for {0}", ch.Current);
                }
                else
                {
                    switch (ch.Current)
                    {
                        default:
                            Log.Bug("Act.Show: bad code {0}", ch.Current);
                            break;

                        case 't':
                            if (arg1 != null)
                                buf.Append(arg1 as string);
                            break;

                        case 'T':
                            if (arg2 != null)
                                buf.Append(arg2 as string);
                            break;

                        case 'n':
                            if (player != null)
                                buf.Append(player.ToString(to));
                            else
                                Log.Bug("Bad act code $n");
                            break;

                        case 'N':
                            if (victim != null)
                                buf.Append(victim.ToString(to));
                            else
                                Log.Bug("Bad act code $N");
                            break;

                        case 'o':
                            if (item1 != null)
                                buf.Append(item1.ToString(to));
                            break;

                        case 'O':
                            if (item2 != null)
                                buf.Append(item2.ToString(to));
                            break;
                    }
                }
            }
            to.WriteLine(buf.ToString());

            if (to.Index != null)
            {
                to.Index.Scripts.HandleTrigger(TriggerType.Act, to, buf.ToString(), player, arg1, arg2);
            }
            if (to.Room != null)
            {
                to.Room.Scripts.HandleTrigger(TriggerType.Act, to.Room, buf.ToString(), player, arg1, arg2);

                foreach (Item item in to.Room.Items)
                {
                    if (item.Index != null)
                        item.Index.Scripts.HandleTrigger(TriggerType.Act, item, buf.ToString(), player, arg1, arg2);
                }
            }
        }

        #endregion [rgn]
    }

    /// <summary>
    /// Handles displaying text in columns
    /// </summary>
    public struct Columns
    {
        /// <summary>
        /// Displays a list of objects in columns
        /// </summary>
        /// <param name="player">the player viewing the columns</param>
        /// <param name="columns">the number of columns</param>
        /// <param name="width">the width of a column</param>
        /// <param name="objects">the list of objects to display in the columns as an array</param>
        public static void Show(Player player, ushort columns, ushort width, object[] objects)
        {
            string format = string.Format("{{0,-{0}}}", width);

            for (int i = 0; i < objects.Length; i++)
            {
                player.Write(format, Color.Convert(objects[i].ToString(), player));

                if ((i + 1)%columns == 0 || (i + 1) == objects.Length)
                {
                    player.WriteLine();
                }
            }
        }
    }
}