/*
Package Name: AFKChecker
Author: CEO
Version: 1.2
Public Release: 04/21/06
Modified by Vinz Clortho (http://auberon.stranky.org/)
*/
using System;
using System.Text;
using Server;
using Server.Accounting;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Network;

namespace Server.Gumps
{
    public class AFKCPassPhraseGump : Gump
    {
        private const int MaxDistractors = 4;

        public AFKCPassPhraseGump(string passphrase)
            : base(265, 190)
        {
            Closable = false;
            Disposable = true;
            Dragable = false;
            Resizable = false;
            string color = Utility.RandomBool() ? (Utility.Random(4) == 0 ? null : "White") : GetRandomColor(null); // All one color vs. multiple
            string m_passphrase = Utility.RandomBool() ? passphrase : passphrase.ToUpper(); // change to Upper it all
            bool altCharSet = Utility.Random(5) == 0 ? true : false;
            int background = Utility.RandomList(5120, 9200, 9250, 9260, 9300, 9350); //, 9400, 9450, 9500, 9550);
            AddBackground(0, 0, 265, 90, background);
            //AddLabel(0,0, 0, string.Format("{0}", background));
            int AlphaSizeX = 10 + Utility.Random(130);
            int AlphaSizeY = 10 + Utility.Random(40);
            if (Utility.RandomBool())
                AddAlphaRegion(AlphaSizeX, AlphaSizeY, Utility.Random(250 - AlphaSizeX), Utility.Random(90 - AlphaSizeY));
            for (int i = 0; i < 5; i++)
            {
                if (altCharSet)
                    AddHtml(10 + (i * 45) + Utility.Random(40), 40 + (Utility.RandomBool() ? Utility.Random(25) : -Utility.Random(25)), 60, 60, Color(getchar(m_passphrase.Substring(i, 1)), color), false, false);
                else
                    AddHtml(10 + (i * 45) + Utility.Random(40), 40 + (Utility.RandomBool() ? Utility.Random(25) : -Utility.Random(25)), 60, 60, Color(m_passphrase.Substring(i, 1), color), false, false);
                for (int h = 0; h < Utility.Random(MaxDistractors); h++)
                {
                    AddLabel(10 + (i * 45) + Utility.Random(41), 15 + Utility.Random(50), Utility.Random(1200), ".");
                }
            }
        }

        private string Color(string text, string color)
        {
            return String.Format("<BASEFONT size=\"7\" COLOR={0}>{1}</BASEFONT", GetRandomColor(color), text);
        }

        private string GetRandomColor(string color)
        {
            if (color != null)
                return color;
            switch (Utility.Random(7))
            {
                case 0: return "DarkRed";
                case 1: return "Yellow";
                case 2: return "Blue";
                case 3: return "White";
                case 4: return "Brown";
                case 5: return "Gold";
                default: return "Black";
            }
        }

//         public override void OnResponse(NetState state, RelayInfo info)
//         {
//             Mobile from = state.Mobile;
//             if (from == null)
//                 return;
//             from.SendMessage("Spatna odpoved. Vypni Razor macro behem AFK kontroly!");
//         }

        private string getchar(string passchar)
        {
            switch (passchar)
            {                   
                case "a":
                    {
                        switch (Utility.Random(4))
                        {
                            case 0:
                                return "\u0101";
                            case 1:
                                return "\u0103";
                            case 2:
                                return "\u0105";
                        }
                        break;
                    }

                case "A":
                    {
                        switch (Utility.Random(6))
                        {
                            case 0:
                                return "\u0100";
                            case 1:
                                return "\u0102";
                            case 2:
                                return "\u0104";
                            case 3:
                                return "\u00C4";
                            case 4:
                                return "\u00C5";
                        }
                        break;
                    }

                case "b":
                    {
                        switch (Utility.Random(2))
                        {
                            case 0:
                                return "\u00FE";
                        }
                        break;
                    }

                case "B":
                    {
                        switch (Utility.Random(3))
                        {
                            case 0:
                                return "\u00DF";
                            case 1:
                                return "\u03B2";
                        }
                        break;
                    }

                case "c":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u0107";
                            case 1:
                                return "\u0109";
                            case 2:
                                return "\u010B";
                            case 3:
                                return "\u010D";
                        }
                        break;
                    }

                case "C":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u0106";
                            case 1:
                                return "\u0108";
                            case 2:
                                return "\u010A";
                            case 3:
                                return "\u010C";
                        }
                        break;
                    }

                case "d":
                    {
                        switch (Utility.Random(3))
                        {
                            case 0:
                                return "\u010F";
                            case 1:
                                return "\u0111";
                        }
                        break;
                    }

                case "D":
                    {
                        switch (Utility.Random(3))
                        {
                            case 0:
                                return "\u010E";
                            case 1:
                                return "\u0110";
                        }
                        break;
                    }

                case "e":
                    {
                        switch (Utility.Random(6))
                        {
                            case 0:
                                return "\u0113";
                            case 1:
                                return "\u0115";
                            case 2:
                                return "\u0117";
                            case 3:
                                return "\u0119";
                            case 4:
                                return "\u011B";
                        }
                        break;
                    }

                case "E":
                    {
                        switch (Utility.Random(8))
                        {
                            case 0:
                                return "\u0112";
                            case 1:
                                return "\u0114";
                            case 2:
                                return "\u0116";
                            case 3:
                                return "\u0118";
                            case 4:
                                return "\u011A";
                            case 5:
                                return "\u00CB";
                            case 6:
                                return "\u0404";
                        }
                        break;
                    }

                case "g":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u011D";
                            case 1:
                                return "\u011F";
                            case 2:
                                return "\u0121";
                            case 3:
                                return "\u0123";
                        }
                        break;
                    }

                case "G":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u011C";
                            case 1:
                                return "\u011E";
                            case 2:
                                return "\u0120";
                            case 3:
                                return "\u0122";
                        }
                        break;
                    }

                case "h":
                    {
                        switch (Utility.Random(3))
                        {
                            case 0:
                                return "\u0125";
                            case 1:
                                return "\u0127";
                        }
                        break;
                    }

                case "H":
                    {
                        switch (Utility.Random(3))
                        {
                            case 0:
                                return "\u0124";
                            case 1:
                                return "\u0126";
                        }
                        break;
                    }

                case "j":
                    {
                        switch (Utility.Random(2))
                        {
                            case 0:
                                return "\u0135";
                        }
                        break;
                    }

                case "J":
                    {
                        switch (Utility.Random(2))
                        {
                            case 0:
                                return "\u0134";
                        }
                        break;
                    }

                case "k":
                case "K":
                    {
                        switch (Utility.Random(4))
                        {
                            case 0:
                                return "\u0136";
                            case 1:
                                return "\u0137";
                            case 2:
                                return "\u0138";
                        }
                        break;
                    }

                case "n":
                    {
                        switch (Utility.Random(6))
                        {
                            case 0:
                                return "\u0144";
                            case 1:
                                return "\u0146";
                            case 2:
                                return "\u0148";
                            case 3:
                                return "\u0149";
                            case 4:
                                return "\u014B";
                        }
                        break;
                    }

                case "N":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u0143";
                            case 1:
                                return "\u0145";
                            case 2:
                                return "\u0147";
                            case 3:
                                return "\u014A";
                        }
                        break;
                    }

                case "r":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u0155";
                            case 1:
                                return "\u0157";
                            case 2:
                                return "\u0159";
                            case 3:
                                return "\u044F";
                        }
                        break;
                    }

                case "R":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u0154";
                            case 1:
                                return "\u0156";
                            case 2:
                                return "\u0158";
                            case 3:
                                return "\u042F";
                        }
                        break;
                    }

                case "s":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u015B";
                            case 1:
                                return "\u015D";
                            case 2:
                                return "\u015F";
                            case 3:
                                return "\u0161";
                        }
                        break;
                    }

                case "S":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u015A";
                            case 1:
                                return "\u015C";
                            case 2:
                                return "\u015E";
                            case 3:
                                return "\u0160";
                        }
                        break;
                    }


                case "t":
                    {
                        switch (Utility.Random(5))
                        {
                            case 0:
                                return "\u0163";
                            case 1:
                                return "\u0165";
                            case 2:
                                return "\u0167";
                            case 3:
                                return "\u03C4";
                        }
                        break;
                    }
                case "T":
                    {
                        switch (Utility.Random(4))
                        {
                            case 0:
                                return "\u0162";
                            case 1:
                                return "\u0164";
                            case 2:
                                return "\u0166";
                        }
                        break;
                    }

                case "u":
                    {
                        switch (Utility.Random(7))
                        {
                            case 0:
                                return "\u0169";
                            case 1:
                                return "\u016B";
                            case 2:
                                return "\u016D";
                            case 3:
                                return "\u016F";
                            case 4:
                                return "\u0171";
                            case 5:
                                return "\u0173";
                        }
                        break;
                    }

                case "U":
                    {
                        switch (Utility.Random(8))
                        {
                            case 0:
                                return "\u0168";
                            case 1:
                                return "\u016A";
                            case 2:
                                return "\u016C";
                            case 3:
                                return "\u016E";
                            case 4:
                                return "\u0170";
                            case 5:
                                return "\u0172";
                            case 6:
                                return "\u00DC";
                        }
                        break;
                    }

                case "w":
                    {
                        switch (Utility.Random(3))
                        {
                            case 0:
                                return "\u0175";
                            case 1:
                                return "\u03C9";
                        }
                        break;
                    }

                case "W":
                    {
                        switch (Utility.Random(2))
                        {
                            case 0:
                                return "\u0174";
                        }
                        break;
                    }

                case "X":
                    {
                        switch (Utility.Random(2))
                        {
                            case 0:
                                return "\u03C7";
                        }
                        break;
                    }

                case "y":
                case "Y":

                    {
                        switch (Utility.Random(4))
                        {
                            case 0:
                                return "\u0176";
                            case 1:
                                return "\u0177";
                            case 2:
                                return "\u0178";
                        }
                        break;
                    }

                case "z":
                    {
                        switch (Utility.Random(4))
                        {
                            case 0:
                                return "\u017A";
                            case 1:
                                return "\u017C";
                            case 2:
                                return "\u017E";
                        }
                        break;
                    }

                case "Z":
                    {
                        switch (Utility.Random(4))
                        {
                            case 0:
                                return "\u0179";
                            case 1:
                                return "\u017B";
                            case 2:
                                return "\u017D";
                        }
                        break;
                    }

                default:
                    return passchar;
            }
            return passchar;
        }
    }

    public class AFKCheckGump : Gump
    {
        public Mobile m_From;
        private string m_userphrase;
        private byte m_RetryCount;
        private byte m_MaxRetries;
        private int m_TotalSeconds;
        private int m_MaxSeconds;
        private bool m_Kick;
        private Point3D m_MoveTo;
        private Map m_MoveToMap;
        private string m_passphrase;
        private int m_textID;
        private byte m_seconds;
        private GumpTimer m_GumpTimer;
        private KickTimer m_KickTimer;

        public AFKCheckGump(Mobile From, byte RetryCount, byte MaxRetries, int TotalSeconds, int MaxSeconds, string userphrase, bool Kick, Point3D MoveTo, Map MoveToMap, string passphrase)
            : base((RetryCount >= MaxRetries || TotalSeconds > MaxSeconds) ? 300 : 290, (RetryCount >= MaxRetries || TotalSeconds > MaxSeconds) ? 145 : 280)
        {
            m_From = From;
            m_RetryCount = RetryCount;
            m_MaxRetries = MaxRetries;
            m_TotalSeconds = TotalSeconds;
            m_MaxSeconds = MaxSeconds;
            m_Kick = Kick;
            m_MoveTo = MoveTo;
            m_MoveToMap = MoveToMap;
            m_userphrase = userphrase;
            m_passphrase = passphrase;
            Closable = RetryCount >= MaxRetries || TotalSeconds > MaxSeconds ? true : false;
            Disposable = true;
            Dragable = false;
            Resizable = false;

            if (m_RetryCount >= m_MaxRetries || m_TotalSeconds > m_MaxSeconds)
            {
                AddBackground(0, 0, 200, 60, 9200);
                AddLabel(45, 20, 1150, "Pristizen/a AFK!");
                UserAFK(m_From);
            }
            else
            {
                string keytext = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
                string[] keychar = new string[5];
                m_textID = 100 + Utility.Random(1000);
                AddBackground(0, 0, 220, 57, 9260);
                for (int i = 0; i < 5; i++)
                {
                    keychar[i] = keytext.Substring(Utility.Random(keytext.Length), 1);
                    m_passphrase = m_passphrase + keychar[i];
                }
                AddImageTiled(17, 16, 190, 25, 2624);
                AddLabel(20, 18, 1150, "Opis kod:");
                AddImageTiled(92, 19, 60, 19, 0xBBC);
                AddTextEntry(92, 18, 60, 19, 1150, m_textID, userphrase);
                AddButton(157, 18, 2450, 2451, m_textID, GumpButtonType.Reply, 0);
                Effects.PlaySound(new Point3D(m_From.X, m_From.Y, m_From.Z), m_From.Map, 0x3D);
                m_From.SendMessage(36, "**** AFK kontrola! ****");
                m_seconds = 0;
                ActivatePassphraseTimer(m_From, m_passphrase, false);
                m_From.CloseGump(typeof(AFKCPassPhraseGump));
                m_From.SendGump(new AFKCPassPhraseGump(m_passphrase));
            }
        }

        public void ActivatePassphraseTimer(Mobile m_From, string m_passphrase, bool incseconds)
        {
            if (incseconds)
            {
                m_TotalSeconds++;
                m_seconds++;
                if ((m_MaxSeconds - m_TotalSeconds) < 10 && m_seconds > 10 && m_From != null)
                    m_From.PlaySound(0x3D);
            }
            m_GumpTimer = new GumpTimer( m_From, m_RetryCount, m_MaxRetries, m_TotalSeconds, m_MaxSeconds, m_userphrase, m_Kick, m_MoveTo, m_MoveToMap, m_passphrase, this, m_seconds, TimeSpan.FromSeconds(1));
            m_GumpTimer.Start();
        }

        private void UserThere(Mobile m)
        {
            if (m == null)
                return;
            //m.Say("Jsem zde!");
            m.SendMessage(71, "Kontrola AFK probehla v poradku!");
        }

        private void UserAFK(Mobile m)
        {
            if (m == null)
                return;
            m.CloseGump(typeof(AFKCPassPhraseGump));
            m.Say("Jsem AFK!");
            
            if (m_MoveToMap != null && m_MoveTo != Point3D.Zero)
            {
                m.MoveToWorld(m_MoveTo, m_MoveToMap);
                Effects.SendBoltEffect(m, true, 0);
                Effects.PlaySound(new Point3D(m.X, m.Y, m.Z), m.Map, 0x307);
            }
            if (m_Kick)
            {
                m_KickTimer = new KickTimer(m, TimeSpan.FromSeconds(5));
                m_KickTimer.Start();
            }
        }

        public override void OnResponse(NetState state, RelayInfo info)
        {
            Mobile from = state.Mobile;
            if (m_GumpTimer != null)
                m_GumpTimer.Stop();
            if (from == null)
                return;
            from.CloseGump(typeof(AFKCPassPhraseGump));
            if ((Closable && info.ButtonID == 0))
            {
                from.CloseGump(typeof(AFKCheckGump));
                return;
            }
            else if (info.ButtonID == m_textID)
            {
                if (m_RetryCount < m_MaxRetries)
                {
                    TextRelay tr = info.GetTextEntry(m_textID);
                    if (tr != null && tr.Text.ToUpper() == m_passphrase.ToUpper())
                    {
                        UserThere(from);
                        from.CloseGump(typeof(AFKCPassPhraseGump));
                        return;
                    }
                    else
                    {
                        m_passphrase = null;
                        from.SendMessage(34, "Spatne, zkus znovu.");
                    }
                    m_RetryCount++;
                    from.SendGump(new AFKCheckGump( m_From, m_RetryCount, m_MaxRetries, m_TotalSeconds, m_MaxSeconds, m_userphrase, m_Kick, m_MoveTo, m_MoveToMap, m_passphrase));
                }
            }
            else
            {
                if (m_RetryCount < m_MaxRetries)
                {
                    if (Utility.RandomDouble() < .035) // Give a random retry count to prevent an endless passphrase loop
                    {
                        m_RetryCount++;
                    }
                    //from.SendMessage("Spatna odpoved. Vypni Razor macro behem AFK kontroly!");
                    from.SendGump(new AFKCheckGump(m_From, m_RetryCount, m_MaxRetries, m_TotalSeconds, m_MaxSeconds, m_userphrase, m_Kick, m_MoveTo, m_MoveToMap, m_passphrase));
                }
            }
        }

        private class KickTimer : Timer
        {
            private Mobile m;
           
            public KickTimer(Mobile mobile, TimeSpan delay)
                : base(delay)
            {
                Priority = TimerPriority.OneSecond;
                m = mobile;
            }

            protected override void OnTick()
            {
                if (m.Map != Map.Internal)
                {
                    NetState ns = m.NetState;
                    if (ns != null)
                    {
                        Account mAccount = ns.Account as Account;
                        if (mAccount != null)
                        {
//                             CommandLogging.WriteLine(m, "{0} {1} {2} ", m.AccessLevel, CommandLogging.Format(m), "Kicked.");
                            m.Say("Odpojen(a) kvuli AFK makru!");
                            ns.Dispose();
                        }
                    }
                }
            }
        }

        private class GumpTimer : Timer
        {
            private Mobile m_From;
            private Gump m_afkgump;
            private string m_userphrase;
            private byte m_RetryCount;
            private byte m_MaxRetries;
            private int m_TotalSeconds;
            private int m_MaxSeconds;
            private bool m_Kick;
            private Point3D m_MoveTo;
            private Map m_MoveToMap;
            private string m_passphrase;
            private byte m_seconds;

            public GumpTimer(Mobile From, byte RetryCount, byte MaxRetries, int TotalSeconds, int MaxSeconds, string userphrase, bool Kick, Point3D MoveTo, Map MoveToMap, string passphrase, Gump afkgump, byte seconds, TimeSpan delay)
                : base(delay)
            {
                Priority = TimerPriority.OneSecond;
                m_From = From;
                m_afkgump = afkgump;
                m_RetryCount = RetryCount;
                m_MaxRetries = MaxRetries;
                m_TotalSeconds = TotalSeconds;
                m_MaxSeconds = MaxSeconds;
                m_Kick = Kick;
                m_MoveTo = MoveTo;
                m_MoveToMap = MoveToMap;
                m_passphrase = passphrase;
                m_seconds = seconds;
            }

            protected override void OnTick()
            {
                if (m_seconds < 20)
                {
                    m_From.CloseGump(typeof(AFKCPassPhraseGump));
                    m_From.SendGump(new AFKCPassPhraseGump(m_passphrase));
                    ((AFKCheckGump)m_afkgump).ActivatePassphraseTimer(m_From, m_passphrase, true);
                }
                else
                {
                    m_From.CloseGump(typeof(AFKCPassPhraseGump));
                    m_From.CloseGump(typeof(AFKCheckGump));
                    m_From.SendGump(new AFKCheckGump(m_From, m_RetryCount, m_MaxRetries, m_TotalSeconds, m_MaxSeconds, m_userphrase, m_Kick, m_MoveTo, m_MoveToMap, null));
                }
            }
        }
    }
}