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

using FilterAPI;
using FilterAPI.Networking;
using FilterAPI.ItemExchange;
using FilterAPI.CustomCurrency;

using FilterZone.ZoneNetworking;

namespace FilterZone.ZoneHandlers
{
    internal class Zone12Handle
    {
        [ZonePacketHandler(12, 1)]
        public static void HandleInventoryChange(ZoneServer ServerSocket, Packet ServerPacket)
        {
            if (ServerSocket.IsConnected == 0)
            {
                if (ServerPacket.Remaining >= 6)
                {
                    Int16 FromSlotID = ServerPacket.PacketReader.ReadByte();
                    Int16 Unk00 = ServerPacket.PacketReader.ReadByte();
                    Int16 ToSlotID = ServerPacket.PacketReader.ReadByte();
                    Int16 Unk01 = ServerPacket.PacketReader.ReadByte();
                    Int32 ItemID = ServerPacket.PacketReader.ReadUInt16();

                    Boolean IsVault = false;

                    if (Program.VaultReplacer.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[0]) == ItemID).Count() >= 1 && Program.SQL.HasItemInSlot(ServerSocket.Client.nCharNo, ToSlotID))
                    {
                        ServerSocket.Client.SendPacket(ServerPacket);

                        GlobalPacket.SendUseItem(ServerSocket.Client, Convert.ToByte(ToSlotID));

                        foreach (DataRow Row in Program.VaultReplacer.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[0]) == ItemID))
                        {
                            Random RandomGenerator = new Random();

                            Byte RatioOutput = Convert.ToByte(RandomGenerator.Next(0, Convert.ToByte(Row[3])));

                            if (RatioOutput < Convert.ToByte(Row[2])) { Command.Makeitem(ServerSocket.Client, Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[0]) == Convert.ToUInt16(Row.ItemArray[1])).FirstOrDefault().ItemArray[1])); }
                        }

                        IsVault = true;

                        Program.SQL.DeleteItem(Program.SQL.GetnItemKeyFromnOwnerAndnStorage(ServerSocket.Client.nCharNo, ToSlotID));
                    }

                    if (!IsVault && ItemID != 65535 && ServerPacket.Remaining >= 1)
                    {
                        Int16 Amount = -1;

                        if (((Amount = ServerPacket.PacketReader.ReadByte()) != -1))
                        {
                            Int64 ItemKey = Program.SQL.GetnItemKeyFromnOwnerAndnStorage(ServerSocket.Client.nCharNo, ToSlotID);

                            if (ServerSocket.Client.ItemAmounts.ContainsKey(ItemKey)) { ServerSocket.Client.ItemAmounts[ItemKey] = Amount; }

                            ServerSocket.Client.SendPacket(ServerPacket);
                        }
                    }
                    else if (!IsVault) { ServerSocket.Client.SendPacket(ServerPacket); }
                }
                else { ServerSocket.Client.SendPacket(ServerPacket); }
            }
        }

        [ZonePacketHandler(12, 3)]
        public static void HandleBuyItem(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                if (ClientSocket.TradeWaitAccept)
                {
                    ClientSocket.TradeWaitAccept = false;

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

                    GlobalPacket.SendCloseTrade(ClientSocket);
                }
                else if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureAWVP"]) && ClientSocket.IsVending)
                {
                    ClientSocket.Disconnect();
                    ClientSocket.Server.BanAndWipe(String.Format("Buying an item from NPC while vending on character {0}.", ClientSocket.sID));

                    return;
                }

                UInt16 ItemID = UInt16.MaxValue;
                Byte Amount = 0;

                if (((ItemID = ClientPacket.PacketReader.ReadUInt16()) != UInt16.MaxValue) && ((Amount = ClientPacket.PacketReader.ReadByte()) != 0))
                {
                    DataRow ItemRow = Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault();

                    List<CurrencyItem> CurrencyItems = null;
                    List<TokenItem> TokenItems = null;

                    if (Convert.ToInt32(ItemRow.ItemArray[30]) == 0) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "The item \"{0}\" cannot be bought from the NPC.", ItemRow[2]); }
                    else if ((CurrencyItems = Program.Currencies.CurrencyItemIDs.Where(CItemID => CItemID.ItemID == ItemID).ToList()).Count == 0 && (TokenItems = Program.Tokens.TokenItemIDs.Where(TItemID => TItemID.ItemID == ItemID).ToList()).Count == 0) { ClientSocket.Server.SendPacket(ClientPacket); }
                    else
                    {
                        List<String> Messages = new List<String>();

                        Boolean HasEnough = true;

                        if (ClientSocket.BuyItemID != ItemID)
                        {
                            ClientSocket.BuyItemID = ItemID;
                            ClientSocket.BuyNeedsConfirm = true;
                        }
                        else
                        {
                            ClientSocket.BuyItemID = UInt32.MaxValue;
                            ClientSocket.BuyNeedsConfirm = false;
                        }

                        if (TokenItems != null && TokenItems.Count != 0)
                        {
                            foreach (TokenItem TI in TokenItems)
                            {
                                Token T = Program.Tokens.TokenInfo.Where(TokenID => TokenID.TokenID == TI.TokenID).FirstOrDefault();

                                String Type = T.IsCharacter ? "nCharNo" : "nUserNo";
                                Int32 Value = T.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;

                                Int64 TokenAmount = Program.SQL.GetAmountForCC(T.TableName, Type, Value);

                                if (TokenAmount == -1)
                                {
                                    TokenAmount = 0;

                                    HasEnough = false;
                                }
                                else if (TI.TokenCost * Amount > TokenAmount) { HasEnough = false; }

                                if (ClientSocket.BuyNeedsConfirm) { Messages.Add(String.Format("{0}: ({1}/{2}) [HaveEnough: {3}]", T.TokenName, TokenAmount, TI.TokenCost * Amount, HasEnough ? "Yes" : "No")); }
                                else { Messages.Add(String.Format("{0}: ({1}/{2}) [Need: {3}]", T.TokenName, TokenAmount, TI.TokenCost * Amount, (TI.TokenCost * Amount) - TokenAmount)); }
                            }

                            if (ClientSocket.BuyNeedsConfirm)
                            {
                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Before purchasing this item please check you have enough space to accept it in your inventory.");
                                GlobalPacket.SendShoutMessageServer(ClientSocket, ".", "Here are you current token amounts for the tokens needed to buy this item:");

                                foreach (String Message in Messages) { GlobalPacket.SendShoutMessageServer(ClientSocket, ".", Message); }
                            }
                            else if (!HasEnough)
                            {
                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You do not have enough to buy this item you have:");

                                foreach (String Message in Messages) { GlobalPacket.SendShoutMessageServer(ClientSocket, ".", Message); }
                            }
                            else
                            {
                                Messages.Clear();

                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Some of your tokens have been changed:");

                                foreach (TokenItem TI in TokenItems)
                                {
                                    Token T = Program.Tokens.TokenInfo.Where(TokenID => TokenID.TokenID == TI.TokenID).FirstOrDefault();

                                    String Type = T.IsCharacter ? "nCharNo" : "nUserNo";
                                    Int32 Value = T.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;

                                    Int64 TokenAmount = Program.SQL.GetAmountForCC(T.TableName, Type, Value);

                                    Program.SQL.MinusAmountForCC(T.TableName, TI.TokenCost * Amount, Type, Value);

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, ".", "{0} has been taken from the token \"{1}\". You are left with {2}.", TI.TokenCost * Amount, T.TokenName, TokenAmount - (TI.TokenCost * Amount));
                                }

                                TokenItem TIMain = TokenItems.Where(IsMainHandle => IsMainHandle.IsMainHandle).FirstOrDefault();

                                if (TIMain.IsCharacterCreated)
                                {
                                    String ItemIndex = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[1]);

                                    if (TIMain.HasUpgrade) { Command.Makeitem(ClientSocket, ItemIndex, true, TIMain.Upgrade); }
                                    else { Command.Makeitem(ClientSocket, ItemIndex, Amount); }
                                }
                                else { ClientSocket.Server.SendPacket(ClientPacket); }

                                String ItemName = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[2]);

                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You have bought {0}x\"{1}\".", Amount, ItemName);
                            }
                        }

                        if (TokenItems == null && Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureCCB"]))
                        {
                            foreach (CurrencyItem CI in CurrencyItems)
                            {
                                Currency C = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == CI.CurrencyID).FirstOrDefault();

                                if (C.IsDateSpecific)
                                {
                                    String[] StartDateSplit = C.StartDate.Split('/');
                                    String[] EndDateSplit = C.EndDate.Split('/');

                                    DateTime StartDate = new DateTime(Convert.ToInt32(StartDateSplit[2]), Convert.ToInt32(StartDateSplit[1]), Convert.ToInt32(StartDateSplit[0]), 0, 0, 0);
                                    DateTime EndDate = new DateTime(Convert.ToInt32(EndDateSplit[2]), Convert.ToInt32(EndDateSplit[1]), Convert.ToInt32(EndDateSplit[0]), 23, 59, 59);

                                    if (StartDate > DateTime.Now)
                                    {
                                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "The currency {0} is not useable yet. It can be used starting from: {1}, and ending on {2}.", C.CurrencyName, C.StartDate, C.EndDate);

                                        return;
                                    }
                                    else if (DateTime.Now > EndDate)
                                    {
                                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "The currency {0} is no longer useable. It was useable from: {1} to {2}.", C.CurrencyName, C.StartDate, C.EndDate);

                                        return;
                                    }
                                }

                                if (C.IsTimeSpecific)
                                {
                                    String[] StartTimeSplit = C.StartTime.Split(':');
                                    String[] EndTimeSplit = C.EndTime.Split(':');

                                    DateTime StartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, Convert.ToInt32(StartTimeSplit[0]), Convert.ToInt32(StartTimeSplit[1]), 0);
                                    DateTime EndTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, Convert.ToInt32(EndTimeSplit[0]), Convert.ToInt32(EndTimeSplit[1]), 59);

                                    if (StartTime > DateTime.Now)
                                    {
                                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "The currency {0} is only useable between: {1} - {2}. Time now: {3}:{4}.", C.CurrencyName, C.StartTime, C.EndTime, DateTime.Now.Hour.ToString("00"), DateTime.Now.Minute.ToString("00"));

                                        return;
                                    }
                                    else if (DateTime.Now > EndTime)
                                    {
                                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "The currency {0} is only useable between: {1} - {2}. Time now: {3}:{4}.", C.CurrencyName, C.StartTime, C.EndTime, DateTime.Now.Hour.ToString("00"), DateTime.Now.Minute.ToString("00"));

                                        return;
                                    }
                                }

                                if (C.IsQuestSpecific && !Program.SQL.IsQuestComplete(ClientSocket.nCharNo, C.QuestID))
                                {
                                    Int32 QuestNameID = Convert.ToInt32(Program.QuestData.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == C.QuestID).FirstOrDefault().ItemArray[1]);
                                    String QuestName = Convert.ToString(Program.QuestDialog.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == QuestNameID).FirstOrDefault().ItemArray[1]);

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You need to complete the quest \"{0}\" before you can use the currency {1}.", QuestName, C.CurrencyName);

                                    return;
                                }

                                Int64 CurrencyCost = CI.CurrencyWorth * Amount;
                                String Type = C.IsCharacter ? "nCharNo" : "nUserNo";
                                Int32 Value = C.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;
                                Int64 CurrencyAmount = Program.SQL.GetAmountForCC(C.TableName, Type, Value);

                                if (C.HasDiscount) { CurrencyCost = Convert.ToInt32(Math.Round(Convert.ToDouble(CurrencyCost / C.Discount), 0)); }

                                Int64 CurrencyTake = CurrencyCost - CurrencyAmount;

                                if (0 > CurrencyTake) { CurrencyTake = 0; }

                                if (CurrencyAmount == -1)
                                {
                                    CurrencyAmount = 0;

                                    HasEnough = false;
                                }
                                else if (CurrencyCost > CurrencyAmount) { HasEnough = false; }

                                if (ClientSocket.BuyNeedsConfirm) { Messages.Add(String.Format("{0}: ({1}/{2}) [HaveEnough: {3}]", C.CurrencyName, CurrencyAmount, CurrencyCost, HasEnough ? "Yes" : "No")); }
                                else { Messages.Add(String.Format("{0}: ({1}/{2}) [Need: {3}]", C.CurrencyName, CurrencyAmount, CurrencyCost, CurrencyTake)); }
                            }

                            if (ClientSocket.BuyNeedsConfirm)
                            {
                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Before purchasing this item please check you have enough space to accept it in your inventory.");
                                GlobalPacket.SendShoutMessageServer(ClientSocket, ".", "Here are you current currency amounts for the currencies needed to buy this item:");

                                foreach (String Message in Messages) { GlobalPacket.SendShoutMessageServer(ClientSocket, ".", Message); }
                            }
                            else if (!HasEnough)
                            {
                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You do not have enough to buy this item you have:");

                                foreach (String Message in Messages) { GlobalPacket.SendShoutMessageServer(ClientSocket, ".", Message); }
                            }
                            else
                            {
                                Messages.Clear();

                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Some of your currencies have been changed:");

                                foreach (CurrencyItem CI in CurrencyItems)
                                {
                                    Currency C = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == CI.CurrencyID).FirstOrDefault();

                                    Int64 CurrencyCost = CI.CurrencyWorth * Amount;
                                    String Type = C.IsCharacter ? "nCharNo" : "nUserNo";
                                    Int32 Value = C.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;
                                    Int64 CurrencyAmount = Program.SQL.GetAmountForCC(C.TableName, Type, Value);

                                    if (C.HasDiscount) { CurrencyCost = Convert.ToInt32(Math.Round(Convert.ToDouble(CurrencyCost / C.Discount), 0)); }

                                    Program.SQL.MinusAmountForCC(C.TableName, CurrencyCost, Type, Value);

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, ".", "{0} has been taken from the currency \"{1}\". You are left with {2}.", CurrencyCost, C.CurrencyName, CurrencyAmount - CurrencyCost);
                                }

                                CurrencyItem CIMain = CurrencyItems.Where(IsMainHandle => IsMainHandle.IsMainHandle).FirstOrDefault();

                                if (CIMain.IsMob)
                                {
                                    String MobName = Convert.ToString(Program.MobInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => ItemArray.ItemArray[1].ToString() == CIMain.MobIndex).FirstOrDefault().ItemArray[2]);

                                    for (Byte Counter = 0; Counter < CIMain.MobAmount; Counter++) { Command.Mobbreed(ClientSocket, CIMain.MobIndex, Amount, 0, false, 1); }

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "{0}x\"{1}\" have been spawned at your current location.", Amount, MobName);
                                }
                                else if (CIMain.IsAbstate)
                                {
                                    String AbstateName = Convert.ToString(Program.AbStateView.Table.Rows.Cast<DataRow>().Where(ItemArray => ItemArray.ItemArray[0].ToString() == CIMain.AbstateIndex).FirstOrDefault().ItemArray[4]);

                                    Command.SetAbstate(ClientSocket, CIMain.AbstateIndex, CIMain.AbstateDuration, CIMain.AbstateEffect);

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You have bought {0} seconds of \"{1}\".", CIMain.AbstateDuration / 1000, AbstateName);
                                }
                                else if (CIMain.IsTrigger)
                                {
                                    Boolean Refund = false;

                                    switch (CIMain.TriggerID)
                                    {
                                        case 0:
                                            {
                                                if (Program.SQL.HastUnlimitedRoars(ClientSocket.nCharNo))
                                                {
                                                    Refund = true;

                                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You already have unlimited raors. Your currencies have been refunded");
                                                }
                                                else
                                                {
                                                    Program.SQL.InserttUnlimitedRoars(ClientSocket.nCharNo);

                                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You have bought unlimited roars.");
                                                }

                                                break;
                                            }
                                        case 1:
                                            {
                                                Program.SQL.AddtStatRerollFornCharNo(ClientSocket.nCharNo, Amount);

                                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You have bought {0}x\"Stat reroll\".", Amount);

                                                break;
                                            }
                                    }

                                    if (Refund)
                                    {
                                        foreach (CurrencyItem CI in CurrencyItems)
                                        {
                                            Currency C = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == CI.CurrencyID).FirstOrDefault();

                                            Int64 CurrencyCost = CI.CurrencyWorth * Amount;
                                            String Type = C.IsCharacter ? "nCharNo" : "nUserNo";
                                            Int32 Value = C.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;
                                            Int64 CurrencyAmount = Program.SQL.GetAmountForCC(C.TableName, Type, Value);

                                            if (C.HasDiscount) { CurrencyCost = Convert.ToInt32(Math.Round(Convert.ToDouble(CurrencyCost / C.Discount), 0)); }

                                            Program.SQL.AddAmountForCC(C.TableName, CurrencyCost, Type, Value);
                                        }
                                    }
                                }
                                else
                                {
                                    if (CIMain.IsCharacterCreated)
                                    {
                                        String ItemIndex = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[1]);

                                        if (CIMain.HasUpgrade) { Command.Makeitem(ClientSocket, ItemIndex, CIMain.Upgrade, Amount); }
                                        else { Command.Makeitem(ClientSocket, ItemIndex, Amount); }
                                    }
                                    else { ClientSocket.Server.SendPacket(ClientPacket); }

                                    String ItemName = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[2]);

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You have bought {0}x\"{1}\".", Amount, ItemName);
                                }
                            }
                        }
                        else if (TokenItems == null) { ClientSocket.Server.SendPacket(ClientPacket); }
                    }
                }
            }
        }

        [ZonePacketHandler(12, 6)]
        public static void HandleSellItem(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                if (ClientSocket.TradeWaitAccept)
                {
                    ClientSocket.TradeWaitAccept = false;

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

                    GlobalPacket.SendCloseTrade(ClientSocket);
                }
                else if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureAWVP"]) && ClientSocket.IsVending)
                {
                    ClientSocket.Disconnect();
                    ClientSocket.Server.BanAndWipe(String.Format("Selling an item to NPC while vending on character {0}.", ClientSocket.sID));

                    return;
                }

                Int16 SlotID = -1;
                Byte Amount;

                if (ClientSocket.SellDateTime > DateTime.Now)
                {
                    //TimeSpan SellSpan = ClientSocket.SellDateTime - DateTime.Now;

                    //if (SellSpan.TotalSeconds > 35)
                    //{
                    //    ClientSocket.Disconnect();
                    //    ClientSocket.Server.BanAndWipe(String.Format("Selling too quickly to an NPC using character {0}.", ClientSocket.sID));

                    //    return;
                    //}

                    //ClientSocket.SellDateTime = ClientSocket.SellDateTime.AddSeconds(1);

                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please wait 1 second between each sale to the NPC.");
                }
                else if (((SlotID = ClientPacket.PacketReader.ReadByte()) != -1) && ((Amount = ClientPacket.PacketReader.ReadByte()) != 0))
                {
                    if (Program.SQL.HasItemInSlot(ClientSocket.nCharNo, SlotID))
                    {
                        ClientSocket.SellDateTime = DateTime.Now.AddSeconds(1);

                        UInt32 ItemID = Program.SQL.GetnItemIDFromnOwnerAndnStorage(ClientSocket.nCharNo, Convert.ToByte(SlotID));
                        Int64 ItemKey = Program.SQL.GetnItemKeyFromnOwnerAndnStorage(ClientSocket.nCharNo, SlotID);

                        DataRow ItemRow = Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault();

                        if (ItemKey == -1) { ClientSocket.Disconnect(); }
                        else if (Convert.ToBoolean(ItemRow.ItemArray[52]) || Convert.ToInt32(ItemRow.ItemArray[31]) == 0) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "The item \"{0}\" cannot be sold to the NPC.", ItemRow[2]); }
                        else
                        {
                            //DataRow StatRerollRow = Program.StatReroll.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[1]) == ItemID).FirstOrDefault();

                            //Boolean IsStatReroll = false;

                            //if (StatRerollRow != null && Convert.ToString(Program.StatReroll.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToString(ItemArray.ItemArray[0]) == "NpcMapIndex").FirstOrDefault().ItemArray[1]) != ClientSocket.sMap || Convert.ToInt32(Program.StatReroll.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToString(ItemArray.ItemArray[0]) == "NpcX").FirstOrDefault().ItemArray[1]) != ClientSocket.MapObjectIDsX[ClientSocket.ClickedMapObjectID] || Convert.ToInt32(Program.StatReroll.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToString(ItemArray.ItemArray[0]) == "NpcY").FirstOrDefault().ItemArray[1]) != ClientSocket.MapObjectIDsY[ClientSocket.ClickedMapObjectID]) { IsStatReroll = true; }

                            if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureSP"]))
                            {
                                Int16 ItemAmount = Program.SQL.GetAmountForItem(ItemKey);

                                if (!ClientSocket.ItemAmounts.ContainsKey(ItemKey)) { ClientSocket.ItemAmounts.Add(ItemKey, ItemAmount); }

                                Int16 DictionaryAmount = ClientSocket.ItemAmounts[ItemKey];

                                if (DictionaryAmount <= -1 || Amount > DictionaryAmount)
                                {
                                    ClientSocket.Disconnect();

                                    Program.SQL.DeleteItem(ItemKey);

                                    return;
                                }
                                else
                                {
                                    //if (!IsStatReroll) { ClientSocket.Server.SendPacket(ClientPacket); }

                                    ClientSocket.Server.SendPacket(ClientPacket);

                                    Thread.Sleep(100);

                                    ClientSocket.ItemAmounts[ItemKey] = (Int16)(ClientSocket.ItemAmounts[ItemKey] - Amount);

                                    if (ClientSocket.ItemAmounts[ItemKey] <= 0) { Program.SQL.DeleteItem(ItemKey); }
                                }
                            }
                            //else if (!IsStatReroll) { ClientSocket.Server.SendPacket(ClientPacket); }
                            else { ClientSocket.Server.SendPacket(ClientPacket); }

                            //if (IsStatReroll)
                            //{
                            //    if (!Program.SQL.CanRerollItemStats(ClientSocket.nCharNo)) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You need atleast 1x \"stat reroll\" in order to make the stats on this item be rerolled."); }
                            //    else
                            //    {
                            //        ClientSocket.Server.SendPacket(ClientPacket);

                            //        Program.SQL.MinustStatReroll(ClientSocket.nCharNo, 1);

                            //        Byte Upgrade = Convert.ToByte(Program.SQL.GetnOptionDataFornOptionType(ClientSocket.nCharNo, SlotID, 418) + Program.SQL.GetnOptionDataFornOptionType(ClientSocket.nCharNo, SlotID, 500) + Program.SQL.GetnOptionDataFornOptionType(ClientSocket.nCharNo, SlotID, 700) + Program.SQL.GetnOptionDataFornOptionType(ClientSocket.nCharNo, SlotID, 800));

                            //        if (Upgrade >= 12) { Upgrade = 0; }

                            //        String ItemIndex = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[1]);

                            //        if (Upgrade == 0) { Command.Makeitem(ClientSocket, ItemIndex); }
                            //        else { Command.Makeitem(ClientSocket, ItemIndex, true, Upgrade); }
                            //    }
                            //}

                            if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureTS"]))
                            {
                                Int64 Tax = Convert.ToInt64(Math.Round(Convert.ToDouble(((Convert.ToInt64(ItemRow.ItemArray[31]) * Amount) / 100) * 5), 0));

                                if (Tax != 0)
                                {
                                    Program.SQL.SetnMoneyFortTaxLottery(Tax);

                                    GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "{0} has been added to the tax lottery. Due to you selling \"{1}\".", Money.ConvertMoney(Tax), ItemRow.ItemArray[2]);
                                }
                            }

                            List<TokenItem> TokenItems;

                            if ((TokenItems = Program.Tokens.TokenItemIDs.Where(TItemID => TItemID.ItemID == ItemID).ToList()).Count != 0)
                            {
                                foreach (TokenItem TI in TokenItems)
                                {
                                    if (TI.TokenWorth > 0)
                                    {
                                        Token T = Program.Tokens.TokenInfo.Where(TokenID => TokenID.TokenID == TI.TokenID).FirstOrDefault();

                                        String Type = T.IsCharacter ? "nCharNo" : "nUserNo";
                                        Int32 Value = T.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;

                                        Program.SQL.AddAmountForCC(T.TableName, TI.TokenWorth * Amount, Type, Value);

                                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You obtained {0}x\"{1}\".", TI.TokenWorth * Amount, T.TokenName);
                                    }
                                }
                            }

                            if (TokenItems.Count == 0 && Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureCCS"]))
                            {
                                List<CurrencyItem> CurrencyItems;

                                if ((CurrencyItems = Program.Currencies.CurrencyItemIDs.Where(CItemID => CItemID.ItemID == ItemID).Where(CIsCoin => CIsCoin.IsCoin == true).ToList()).Count != 0)
                                {
                                    foreach (CurrencyItem CI in CurrencyItems.Where(IsAutoAdd => !IsAutoAdd.IsAutoAdd).ToList())
                                    {
                                        Currency C = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == CI.CurrencyID).FirstOrDefault();

                                        Int64 CurrencyWorth = CI.CurrencyWorth * Amount;
                                        String Type = C.IsCharacter ? "nCharNo" : "nUserNo";
                                        Int32 Value = C.IsCharacter ? ClientSocket.nCharNo : ClientSocket.nUserNo;

                                        if (C.HasMaximum)
                                        {
                                            Int32 CurrencyObtained = Program.SQL.GetObtainedForCC(C.TableName, Type, Value);

                                            if (CurrencyObtained == -1)
                                            {
                                                Program.SQL.AddObtainedForCC(C.TableName, 0, Type, Value);

                                                CurrencyObtained = 0;
                                            }

                                            if ((CurrencyObtained + CurrencyWorth) > C.Maximum)
                                            {
                                                Int32 AddObtained = Convert.ToInt32(C.Maximum - CurrencyObtained);

                                                Program.SQL.AddAmountForCC(C.TableName, AddObtained, Type, Value);
                                                Program.SQL.AddObtainedForCC(C.TableName, Convert.ToInt16(AddObtained), Type, Value);

                                                String TypeName = C.IsCharacter ? "character" : "account";

                                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You cannot obtain anymore of \"{0}\" on this {1}, as you have obtained the maximum, which is {2}.", C.CurrencyName, TypeName, C.Maximum);
                                            }
                                            else
                                            {
                                                Int32 AddObtained = Convert.ToInt32(CurrencyObtained + CurrencyWorth);

                                                Program.SQL.AddAmountForCC(C.TableName, AddObtained, Type, Value);
                                                Program.SQL.AddObtainedForCC(C.TableName, Convert.ToInt16(AddObtained), Type, Value);

                                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You obtained {0}x\"{1}\".", CurrencyWorth, C.CurrencyName);
                                            }
                                        }
                                        else
                                        {
                                            Program.SQL.AddAmountForCC(C.TableName, CurrencyWorth, Type, Value);

                                            GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You obtained {0}x\"{1}\".", CurrencyWorth, C.CurrencyName);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else { ClientSocket.Disconnect(); }
                }
            }
        }

        [ZonePacketHandler(12, 7)]
        public static void HandleDropItem(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                if (!Program.SQL.HasPermission(ClientSocket.nCharNo, "CanDrop")) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry \"{0}\", you are not allowed to drop items.", ClientSocket.sID); }
                else if (Program.AntiDropMapIndexs.Keys.Contains(ClientSocket.sMap)) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You cannot drop items in \"{0}\".", Program.AntiDropMapIndexs[ClientSocket.sMap]); }
                else
                {
                    if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureCCDI"]))
                    {
                        Int16 SlotID = -1;

                        if ((SlotID = ClientPacket.PacketReader.ReadByte()) != -1)
                        {
                            UInt32 ItemID = Program.SQL.GetnItemIDFromnOwnerAndnStorage(ClientSocket.nCharNo, Convert.ToByte(SlotID));

                            List<CurrencyItem> CurrencyItems;

                            if ((CurrencyItems = Program.Currencies.CurrencyItemIDs.Where(CItemID => CItemID.ItemID == ItemID).Where(CIsMainhandle => CIsMainhandle.IsMainHandle == true).Where(CIsCoin => CIsCoin.IsCoin == true).ToList()).Count == 0) { ClientSocket.Server.SendPacket(ClientPacket); }
                            else if (CurrencyItems[0].IsAutoAdd)
                            {
                                String ItemName = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[2]);

                                GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "You cannot drop \"{0}\" as this is a coin that adds currency to you on pick up. Please sell it to an NPC.", ItemName);
                            }
                            else { ClientSocket.Server.SendPacket(ClientPacket); }
                        }
                    }
                    else { ClientSocket.Server.SendPacket(ClientPacket); }
                }
            }
        }

        [ZonePacketHandler(12, 9)]
        public static void HandlePickupItem(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                if (!Program.SQL.HasPermission(ClientSocket.nCharNo, "CanPickUp")) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Sorry \"{0}\", you are not allowed to pickup items.", ClientSocket.sID); }
                else
                {
                    if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeaturePUCP"]))
                    {
                        UInt16 MapObjectID;

                        if ((MapObjectID = ClientPacket.PacketReader.ReadUInt16()) != UInt16.MaxValue)
                        {
                            if (ClientSocket.MapObjectIDsItem.ContainsKey(MapObjectID) && ClientSocket.MapObjectIDsItem[MapObjectID] == Convert.ToUInt16(Program.Auth.ConfigValues["ZoneCenItemID"]))
                            {
                                Random RandomGenerator = new Random();

                                Int32 nMinimum;
                                Int32 nMaximum;

                                Program.SQL.GetnMinimumAndnMaximum(out nMinimum, out nMaximum);

                                Int64 AddMoney = RandomGenerator.Next(nMinimum, nMaximum);

                                Program.SQL.PutMoneyInStorage(ClientSocket.sID, AddMoney);

                                if (Program.SQL.ShowCenMessage()) { GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "{0} has been added to your storage for picking up {1}!", Money.ConvertMoney(AddMoney), Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[0]) == ClientSocket.MapObjectIDsItem[MapObjectID]).FirstOrDefault().ItemArray[2]); }

                                ClientSocket.MapObjectIDsItem.Remove(MapObjectID);
                                ClientSocket.Server.SendPacket(ClientPacket);
                            }
                            else { ClientSocket.Server.SendPacket(ClientPacket); }
                        }
                    }
                    else { ClientSocket.Server.SendPacket(ClientPacket); }
                }
            }
        }

        [ZonePacketHandler(12, 10)]
        public static void HandleItemPickedUp(ZoneServer ServerSocket, Packet ServerPacket)
        {
            if (ServerSocket.IsConnected == 0)
            {
                UInt16 ItemID = ServerPacket.PacketReader.ReadUInt16();
                Byte ItemAmount = ServerPacket.PacketReader.ReadByte();

                //if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureIPUA"]))
                //{
                //    DataRow PickupAnnouncementsRow;

                //    if ((PickupAnnouncementsRow = Program.PickupAnnouncements.Table.Rows.Cast<DataRow>().Where(ItemArrary => Convert.ToUInt16(ItemArrary.ItemArray[0]) == ItemID).FirstOrDefault()) != null)
                //    {
                //        Int64 nItemKey = Program.SQL.GetLastPickupForCharacter(ServerSocket.Client.nCharNo, ItemID);
                //        Int32 PickupCount = Program.SQL.GetPickupCountFornItemkey(nItemKey);

                //        if (PickupCount == 1)
                //        {
                //            Packet LocalPacket = new Packet(4, 8);
                //            LocalPacket.PacketWriter.Write((Byte)1);
                //            LocalPacket.PacketWriter.Write("");
                //            LocalPacket.PacketWriter.Write(Convert.ToString(PickupAnnouncementsRow.ItemArray[1]).Replace("PLAYER_NAME", ServerSocket.Client.sID));

                //            Program.LocalClient.SendPacket(LocalPacket);

                //            String ItemName = Convert.ToString(Program.ItemInfo.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToInt32(ItemArray.ItemArray[0]) == ItemID).FirstOrDefault().ItemArray[2]);

                //            LocalPacket = new Packet(4, 8);
                //            LocalPacket.PacketWriter.Write((Byte)1);
                //            LocalPacket.PacketWriter.Write("");
                //            LocalPacket.PacketWriter.Write(ItemName);

                //            Program.LocalClient.SendPacket(LocalPacket);
                //        }
                //    }
                //}

                if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureCCPUI"]))
                {
                    List<CurrencyItem> CurrencyItems;

                    if ((CurrencyItems = Program.Currencies.CurrencyItemIDs.Where(CItemID => CItemID.ItemID == ItemID).Where(CIsCoin => CIsCoin.IsCoin == true).ToList()).Count != 0)
                    {
                        foreach (CurrencyItem CI in CurrencyItems)
                        {
                            if (CI.IsAutoAdd)
                            {
                                Currency C = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == CI.CurrencyID).FirstOrDefault();

                                Int64 CurrencyWorth = CI.CurrencyWorth * ItemAmount;
                                String Type = C.IsCharacter ? "nCharNo" : "nUserNo";
                                Int32 Value = C.IsCharacter ? ServerSocket.Client.nCharNo : ServerSocket.Client.nUserNo;

                                if (C.HasMaximum)
                                {
                                    Int32 CurrencyObtained = Program.SQL.GetObtainedForCC(C.TableName, Type, Value);

                                    if (CurrencyObtained == -1)
                                    {
                                        Program.SQL.AddObtainedForCC(C.TableName, 0, Type, Value);

                                        CurrencyObtained = 0;
                                    }

                                    if ((CurrencyObtained + CurrencyWorth) > C.Maximum)
                                    {
                                        Int32 AddObtained = Convert.ToInt32(C.Maximum - CurrencyObtained);

                                        Program.SQL.AddAmountForCC(C.TableName, AddObtained, Type, Value);
                                        Program.SQL.AddObtainedForCC(C.TableName, Convert.ToInt16(AddObtained), Type, Value);

                                        String TypeName = C.IsCharacter ? "character" : "account";

                                        GlobalPacket.SendShoutMessageServer(ServerSocket.Client, "Server", "You cannot obtain anymore of \"{0}\" on this {1}, as you have obtained the maximum, which is {2}.", C.CurrencyName, TypeName, C.Maximum);
                                    }
                                    else
                                    {
                                        Int32 AddObtained = Convert.ToInt32(CurrencyObtained + CurrencyWorth);

                                        Program.SQL.AddAmountForCC(C.TableName, AddObtained, Type, Value);
                                        Program.SQL.AddObtainedForCC(C.TableName, Convert.ToInt16(AddObtained), Type, Value);

                                        GlobalPacket.SendShoutMessageServer(ServerSocket.Client, "Server", "You obtained {0}x\"{1}\".", AddObtained, C.CurrencyName);
                                    }
                                }
                                else
                                {
                                    Program.SQL.AddAmountForCC(C.TableName, CurrencyWorth, Type, Value);

                                    GlobalPacket.SendShoutMessageServer(ServerSocket.Client, "Server", "You obtained {0}x\"{1}\".", CurrencyWorth, C.CurrencyName);
                                }
                            }
                        }
                    }
                }

                ServerSocket.Client.SendPacket(ServerPacket);
            }
        }


        [ZonePacketHandler(12, 15)]
        public static void HandleEquip(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                Byte SlotID = ClientPacket.PacketReader.ReadByte();

                ClientSocket.Server.SendPacket(ClientPacket);
            }
        }

        [ZonePacketHandler(12, 18)]
        public static void HandleUnequip(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                Byte FromSlotID = ClientPacket.PacketReader.ReadByte();
                Byte ToSlotID = ClientPacket.PacketReader.ReadByte();

                ClientSocket.Server.SendPacket(ClientPacket);
            }
        }

        [ZonePacketHandler(12, 21)]
        public static void HandleUseItem(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeatureUITP"]))
                {
                    Int16 SlotID = -1;

                    if ((SlotID = ClientPacket.PacketReader.ReadByte()) != -1)
                    {
                        if (ClientSocket.TradeWaitAccept)
                        {
                            ClientSocket.TradeWaitAccept = false;

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

                            GlobalPacket.SendCloseTrade(ClientSocket);
                        }

                        ClientSocket.Server.SendPacket(ClientPacket);
                    }
                }
                else { ClientSocket.Server.SendPacket(ClientPacket); }
            }
        }

        [ZonePacketHandler(12, 32)]
        public static void HandlePremiumInventory(ZoneClient ClientSocket, Packet ClientPacket)
        {
            if (ClientSocket.IsConnected == 0)
            {
                if (Convert.ToBoolean(Program.Auth.ConfigValues["ZoneFeaturePISP"]))
                {
                    if (ClientSocket.PremiumDateTime > DateTime.Now)
                    {
                        TimeSpan PremiumSpan = ClientSocket.PremiumDateTime - DateTime.Now;

                        if (PremiumSpan.TotalSeconds > 60)
                        {
                            ClientSocket.Disconnect();
                            ClientSocket.Server.BanAndWipe(String.Format("Spamming the premium inventory, this could of crashed the server using character {0}.", ClientSocket.sID));

                            return;
                        }

                        ClientSocket.PremiumDateTime = ClientSocket.PremiumDateTime.AddSeconds(5);

                        GlobalPacket.SendShoutMessageServer(ClientSocket, "Server", "Please wait 5 seconds before pressing the premium inventory button agian, or you will banned!");
                    }
                    else
                    {
                        ClientSocket.PremiumDateTime = DateTime.Now.AddSeconds(5);

                        ClientSocket.Server.SendPacket(ClientPacket);
                    }
                }
                else { ClientSocket.Server.SendPacket(ClientPacket); }
            }
        }
    }
}
