using System;
using System.Data;
using System.Linq;

using FilterAPI.Networking;

using FilterZone.ZoneNetworking;

namespace FilterZone.ZoneHandlers
{
    internal class Zone19Handle
    {
        [ZonePacketHandler(19, 1)]
        public static void HandleSendTrade(ZoneClient ClientSocket, Packet ClientPacket)
        {
            UInt16 MapObjectID = UInt16.MaxValue;

            MapObject MO = null;

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

                return;
            }
            else if ((MapObjectID = ClientPacket.PacketReader.ReadUInt16()) != UInt16.MaxValue && !Program.SQL.HasPermission(ClientSocket.nCharNo, "CanTrade"))
            {
                using (var ServerPacket = new Packet(19, 4))
                {
                    ServerPacket.PacketWriter.Write(MapObjectID);

                    ClientSocket.SendPacketClient(ServerPacket);
                }

                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry \"{0}\", you are not allowed to trade.", ClientSocket.sID);
            }
            else if (ClientSocket.MapObjects != null && (MO = ClientSocket.MapObjects.ToArray().Where(MOID => MOID.MapObjectID == MapObjectID).FirstOrDefault()) != null && !Program.SQL.HasPermission(Program.SQL.GetnCharNoFromsID(MO.sID), "CanTrade")) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry, \"{0}\" is not allowed to trade.", MO.sID); }
            else if (MO == null) { ClientSocket.Dispose(); }
            else
            {
                ZoneClient TradeReceiver;

                if ((TradeReceiver = Program.ZoneClients.Where(MOID => MOID.Value.MapObjectID == MapObjectID).FirstOrDefault().Value) != null)
                {
                    Boolean CanTradeSender = true;
                    Boolean CanTradeReceiver = true;
					// zone (?) trade area system???
                    if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureATAS"]))
                    {
                        foreach (DataRow Row in Program.CustomTradeAreas.Table.Rows.Cast<DataRow>().Where(ItemArray => ItemArray.ItemArray[0].ToString() == ClientSocket.sMap))
                        {
                            if (!(ClientSocket.X >= Convert.ToInt32(Row.ItemArray[1])) && ClientSocket.X >= Convert.ToInt32(Row.ItemArray[3]) && !(ClientSocket.Y >= Convert.ToInt32(Row.ItemArray[2])) && ClientSocket.Y >= Convert.ToInt32(Row.ItemArray[4]))
                            {
                                CanTradeSender = true;

                                break;
                            }
                            else { CanTradeSender = false; }
                        }

                        foreach (DataRow Row in Program.CustomTradeAreas.Table.Rows.Cast<DataRow>().Where(ItemArray => ItemArray.ItemArray[0].ToString() == ClientSocket.sMap))
                        {
                            if (!(TradeReceiver.X >= Convert.ToInt32(Row.ItemArray[1])) && TradeReceiver.X >= Convert.ToInt32(Row.ItemArray[3]) && !(TradeReceiver.Y >= Convert.ToInt32(Row.ItemArray[2])) && TradeReceiver.Y >= Convert.ToInt32(Row.ItemArray[4]))
                            {
                                CanTradeReceiver = true;

                                break;
                            }
                            else { CanTradeReceiver = false; }
                        }
                    }

                    if (CanTradeSender && CanTradeReceiver)
                    {
                        ClientSocket.TradeWaitAccept = true;
                        ClientSocket.SendPacketServer(ClientPacket);
                    }
                    else if (!CanTradeSender) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry you cannot open a trade at your current location, please go to a tradeable location."); }
                    else if (!CanTradeReceiver) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry \"{0}\" is not within a tradeable location, please tell them to get closer to you.", TradeReceiver.sID); }
                }
                else { ClientSocket.Dispose(); }
            }
        }

        [ZonePacketHandler(19, 2)]
        public static void HandleReceiveTrade(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);
            ClientSocket.TradeMapObjectID = ServerPacket.PacketReader.ReadUInt16();
            ClientSocket.TradeWaitAccept = true;
        }

        [ZonePacketHandler(19, 3)]
        public static void HandleRejectTrade(ZoneClient ClientSocket, Packet ClientPacket)
        {
            ClientSocket.SendPacketServer(ClientPacket);
            ClientSocket.TradeMapObjectID = UInt16.MaxValue;
            ClientSocket.TradeWaitAccept = false;
        }

        [ZonePacketHandler(19, 4)]
        public static void HandleTradeRejected(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);
            ClientSocket.TradeMapObjectID = UInt16.MaxValue;
            ClientSocket.TradeWaitAccept = false;
        }

        [ZonePacketHandler(19, 9)]
        public static void HandleTradeOpened(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);
            ClientSocket.TradeWaitAccept = false;
            ClientSocket.InTrade = true;
            ClientSocket.TradeMapObjectID = ServerPacket.PacketReader.ReadUInt16();
        }

        [ZonePacketHandler(19, 11)]
        public static void HandleTradeClosedSender(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);
            ClientSocket.InTrade = false;
            ClientSocket.TradeMapObjectID = UInt16.MaxValue;
        }

        [ZonePacketHandler(19, 12)]
        public static void HandleTradeClosedReceiver(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);
            ClientSocket.InTrade = false;
            ClientSocket.TradeMapObjectID = UInt16.MaxValue;
        }

        [ZonePacketHandler(19, 15)]
        public static void HandleItemPutInTradeServer(ZoneClient ClientSocket, Packet ServerPacket)
        {
            Byte SlotID = ServerPacket.PacketReader.ReadByte();

            Boolean HasItem = Program.SQL.HasItemInSlot(ClientSocket.nCharNo, SlotID);

            if (!HasItem) { ClientSocket.Dispose(); }
            else { ClientSocket.SendPacketClient(ServerPacket); }
        }

        [ZonePacketHandler(19, 36)]
        public static void HandleTradeComplete(ZoneClient ClientSocket, Packet ServerPacket)
        {
            ClientSocket.SendPacketClient(ServerPacket);
            ClientSocket.InTrade = false;
            ClientSocket.TradeMapObjectID = UInt16.MaxValue;
        }
    }
}
