using System;
using System.Linq;
using System.Data;
using System.Collections.Generic;

using FilterAPI;
using FilterAPI.Portals;
using FilterAPI.Networking;

using FilterZone.ZoneNetworking;

namespace FilterZone.ZoneHandlers
{
    internal class Zone8Handle
    {
        [ZonePacketHandler(8, 1)]
        public static void HandleNormalMessage(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.ShowPlayers)
            {
                String Message = String.Empty;

                if ((Message = ClientPacket.PacketReader.ReadString()) != String.Empty)
                {
                    if (Message.StartsWith("&"))
                    { // zone something 
                        if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureTVCP"]))
                        {
                            if (ClientSocket.InTrade) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Commands cannot be used during a trade."); }
                            else if (ClientSocket.IsVending) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Commands cannot be used while vending."); }
                            else if (Program.SQL.CanCommandForsMap(ClientSocket.sMap)) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Commands cannot be used in this map."); }
                            else { Command.HandleCommand(ClientSocket, Message); }
                        }
                        else { Command.HandleCommand(ClientSocket, Message); }
                    }
                    else
                    {
                        Message = Message.Replace("?", "?");
						// zone buff on command
                        if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureBONC"]) && Message.ToLower().Contains("buff"))
                        {															// zone buff abstate									zone buff duration												zone buff effect level
                            Command.SetAbstate(ClientSocket, Program.Auth.ConfigValues["ZoneNCBI"], Convert.ToInt32(Program.Auth.ConfigValues["ZoneNCBD"]) * 1000, Convert.ToByte(Program.Auth.ConfigValues["ZoneNCBE"]));

                            GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "A buff has been applied to you! (:");
                        }

                        Boolean SendMessage = true;
						// zone normal chat BAD protection
                        if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureNCBP"]))
                        {
                            Char InvalidSymbol;

                            if (Injection.ContainsInvalidSymbol(Message, out InvalidSymbol))
                            {
                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please do not use \"{0}\" in your message.", InvalidSymbol);

                                SendMessage = false;
                            }
                        }
						// zone normal chat log
                        if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureNCL"])) { Program.SQL.InserttNormal(Program.ZoneID, ClientSocket.sID, Message); }
						// zone normal slander filter
                        if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureNSF"]))
                        {
                            foreach (DataRow Row in Program.SlanderFilter.Table.Rows)
                            {
                                if (Convert.ToBoolean(Row.ItemArray[7]) && Message.ToLower().Contains(Convert.ToString(Row.ItemArray[0])))
                                {
                                    if (Convert.ToBoolean(Row.ItemArray[2])) { Message = Message.Replace(Convert.ToString(Row.ItemArray[0]), Convert.ToString(Row.ItemArray[1])); }
                                    else
                                    {
                                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You are not allowed to say {0} in your message.", Row.ItemArray[0]);

                                        SendMessage = false;
                                    }
                                }
                            }
                        }

                        if (SendMessage) { ClientSocket.SendPacketServer(ClientPacket); }
                    }
                }
            }
            else { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry the normal chat is disabled when you are in hide players mode. Please change map if you want this disabled."); }
        }

        [ZonePacketHandler(8, 10)]
        public static void HandleBeginInteraction(ZoneClient ClientSocket, Packet ClientPacket)
        {
            UInt16 MapObjectID = UInt16.MaxValue;

            if ((MapObjectID = ClientPacket.PacketReader.ReadUInt16()) != UInt16.MaxValue)
            {
                ClientSocket.ClickedMapObjectID = MapObjectID;

                MapObject MO;

                if (ClientSocket.MapObjects == null)
                {
                    ClientSocket.Dispose();

                    return;
                }
                else if ((MO = ClientSocket.MapObjects.ToArray().Where(MOID => MOID.MapObjectID == MapObjectID).FirstOrDefault()) != null)
                {
                    MultiPortal MP;

                    if ((MP = Program.Portals.MultiPortals.Where(MapIndex => MapIndex.MapIndex == ClientSocket.sMap).Where(MobID => MobID.MobID == MO.MobID).FirstOrDefault()) != null)
                    {
                        ClientSocket.MP = MP;

                        GlobalPacket.SendQuestion(ClientSocket, MP.Question, new List<String>() { MP.Map1Text, MP.Map2Text, MP.Map3Text });
                    }
                    else { ClientSocket.SendPacketServer(ClientPacket); }
                }
                else { ClientSocket.SendPacketServer(ClientPacket); }
            }
        }

        [ZonePacketHandler(8, 17)]
        public static void HandleWorldMessage(ZoneClient ClientSocket, Packet ServerPacket)
        {
            String Message = ServerPacket.PacketReader.ReadString();

            if (Message.StartsWith("Mob : ")) { ClientSocket.sMapMobs = Convert.ToUInt16(Message.Replace("Mob : ", "")); }

            if (Message.Contains("ply:") && Message.Contains("mob:"))
            {
                String[] MessageSplit = Message.Split(' ');
                String MapIndex = MessageSplit[0];

                if (MapIndex == ClientSocket.sMap)
                {
                    String[] PMSplit = MessageSplit[1].Split('/');

                    ClientSocket.sMapPlayers = Convert.ToUInt16(PMSplit[0].Replace("ply:", ""));
                    ClientSocket.sMapMobs = Convert.ToUInt16(PMSplit[1].Replace("mob:", ""));
                }

                if (MapIndex == "Total")
                {
                    String[] PMSplit = MessageSplit[1].Split('/');

                    ClientSocket.ZoneTotalPlayers = Convert.ToUInt16(PMSplit[0].Replace("ply:", ""));
                    ClientSocket.ZoneTotalMobs = Convert.ToUInt16(PMSplit[1].Replace("mob:", ""));

                    if (!ClientSocket.SentWarning && ClientSocket.ZoneTotalMobs > 7350)
                    {
                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please note that the zone you are currently on has more than 7350 mobs in it, this could cause problems with instances so please notify an admin if it happens to break! The maximum amount a zone can have is 8000.");

                        ClientSocket.SentWarning = true;
                    }
                    else if (!ClientSocket.SentWarning) { ClientSocket.SentWarning = true; }
                }
            }

            if (Message == "You can not enter because Instance Dungeon is currently full.") { ClientSocket.SendPacketClient(ServerPacket); }
            else if (Message == "You must belong in a party to enter.") { ClientSocket.SendPacketClient(ServerPacket); }

            if (Program.SQL.HasPermission(ClientSocket.nCharNo, "SendWorldMessages")) { ClientSocket.SendPacketClient(ServerPacket); }
        }

        [ZonePacketHandler(8, 18)]
        public static void HandleWalkWithKeyboard(ZoneClient ClientSocket, Packet ClientPacket)
        { // zone walk in trade protection
            if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureWKTP"]))
            {
                if (ClientSocket.TradeWaitAccept)
                {
                    ClientSocket.TradeWaitAccept = false;

                    GlobalPacket.SendRejectTrade(ClientSocket);
                }
                else if (ClientSocket.InTrade)
                {
                    ClientSocket.InTrade = false;

                    GlobalPacket.SendCloseTrade(ClientSocket);
                }
            }

            if (!ClientSocket.CanWalk)
            {
                GlobalPacket.SendCannotWalkHere(ClientSocket, ClientSocket.X, ClientSocket.Y);
                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You are not allowed to walk currently.");

                return;
            }

            Int32 X = -1;
            Int32 Y = -1;

            if ((X = ClientPacket.PacketReader.ReadInt32()) != -1 && (Y = ClientPacket.PacketReader.ReadInt32()) != -1)
            {
                ClientSocket.X = X;
                ClientSocket.Y = Y;
                ClientSocket.SendPacketServer(ClientPacket);
            }
        }

        [ZonePacketHandler(8, 25)]
        public static void HandleAutoWalk(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.MP != null) { ClientSocket.MP = null; }

            if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureAWTP"]) && ClientSocket.TradeWaitAccept)
            {
                ClientSocket.TradeWaitAccept = false;

                GlobalPacket.SendRejectTrade(ClientSocket);
            }
            else if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureAWTP"]) && ClientSocket.InTrade)
            {
                ClientSocket.InTrade = false;

                GlobalPacket.SendCloseTrade(ClientSocket);
            }

            if (!ClientSocket.CanWalk)
            {
                GlobalPacket.SendCannotWalkHere(ClientSocket, ClientSocket.X, ClientSocket.Y);
                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You are not allowed to walk currently.");

                return;
            }

            Int32 FromX = -1;
            Int32 FromY = -1;
            Int32 ToX = -1;
            Int32 ToY = -1;

            if ((FromX = ClientPacket.PacketReader.ReadInt32()) != -1 && (FromY = ClientPacket.PacketReader.ReadInt32()) != -1 && (ToX = ClientPacket.PacketReader.ReadInt32()) != -1 && (ToY = ClientPacket.PacketReader.ReadInt32()) != -1)
            {
                ClientSocket.X = ToX;
                ClientSocket.Y = ToY;
                ClientSocket.SendPacketServer(ClientPacket);
            }
        }

        [ZonePacketHandler(8, 30)]
        public static void HandleShoutMessage(ZoneClient ClientSocket, Packet ClientPacket)
        {
            String Message = String.Empty;

            if ((Message = ClientPacket.PacketReader.ReadString()) != String.Empty)
            {
                Message = Message.Replace("?", "?");

                Boolean SendMessage = true;

                if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureSCBP"]))
                {
                    Char InvalidSymbol;

                    if (Injection.ContainsInvalidSymbol(Message, out InvalidSymbol))
                    {
                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please do not use \"{0}\" in your message.", InvalidSymbol);

                        SendMessage = false;
                    }
                }

                if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureSCL"])) { Program.SQL.InserttShout(Program.ZoneID, ClientSocket.sID, Message); }

                if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureSSF"]))
                {
                    foreach (DataRow Row in Program.SlanderFilter.Table.Rows)
                    {
                        if (Convert.ToBoolean(Row.ItemArray[9]) && Message.ToLower().Contains(Convert.ToString(Row.ItemArray[0])))
                        {
                            if (Convert.ToBoolean(Row.ItemArray[2])) { Message = Message.Replace(Convert.ToString(Row.ItemArray[0]), Convert.ToString(Row.ItemArray[1])); }
                            else
                            {
                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You are not allowed to say {0} in your message.", Row.ItemArray[0]);

                                SendMessage = false;
                            }
                        }
                    }
                }

                if (SendMessage) { ClientSocket.SendPacketServer(ClientPacket); }
            }
        }

        [ZonePacketHandler(8, 63)]
        public static void HandleMounting(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);

            if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureMA"]))
            {
                UInt16 RidingID = UInt16.MaxValue;

                if ((RidingID = ServerPacket.PacketReader.ReadUInt16()) != UInt16.MaxValue)
                {
                    ClientSocket.RidingID = RidingID;
                    ClientSocket.IsMounted = true;
                }
            }
        }

        [ZonePacketHandler(8, 66)]
        public static void HandleUnmounting(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);

            if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureMA"]))
            {
                ClientSocket.RidingID = UInt16.MaxValue;
                ClientSocket.IsMounted = false;
            }
        }

        [ZonePacketHandler(8, 75)]
        public static void HandleRoarMessage(ZoneClient ClientSocket, Packet ClientPacket)
        {
            Int16 SlotID = -1;
            Int16 MessageLenghth = -1;
            String Message = String.Empty;

            if ((SlotID = ClientPacket.PacketReader.ReadByte()) != -1 && (MessageLenghth = ClientPacket.PacketReader.ReadByte()) != -1 && (Message = ClientPacket.ReadString(MessageLenghth - 1)) != String.Empty)
            {
                if (ClientSocket.RoarDateTime > DateTime.Now) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please wait 2 minutes before using the roar again."); }
                else
                {
                    Message = Message.Replace("?", "?");

                    Boolean SendMessage = true;

                    if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureRCBP"]))
                    {
                        Char InvalidSymbol;

                        if (Injection.ContainsInvalidSymbol(Message, true, out InvalidSymbol))
                        {
                            GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please do not use \"{0}\" in your message.", InvalidSymbol);

                            SendMessage = false;
                        }
                    }

                    if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureRCL"])) { Program.SQL.InserttRoar(Program.ZoneID, ClientSocket.sID, Message); }

                    if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureRSF"]))
                    {
                        foreach (DataRow Row in Program.SlanderFilter.Table.Rows)
                        {
                            if (Convert.ToBoolean(Row.ItemArray[8]) && Message.ToLower().Contains(Convert.ToString(Row.ItemArray[0])))
                            {
                                if (Convert.ToBoolean(Row.ItemArray[2])) { Message = Message.Replace(Convert.ToString(Row.ItemArray[0]), Convert.ToString(Row.ItemArray[1])); }
                                else
                                {
                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You are not allowed to say {0} in your message.", Row.ItemArray[0]);

                                    SendMessage = false;
                                }
                            }
                        }
                    }

                    if (SendMessage)
                    {
                        ClientSocket.SendPacketServer(ClientPacket);

                        if (!Program.SQL.HastUnlimitedRoars(ClientSocket.nCharNo)) { ClientSocket.RoarDateTime = DateTime.Now.AddMinutes(2); }
                    }
                }
            }
        }
    }
}
