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

using FilterAPI.Networking;

namespace FilterTimers.Timers
{
    internal class LUSkillsTimer
    {
        private Boolean IsDone = true;

        public LUSkillsTimer()
        {
            Thread NewThread = new Thread(delegate ()
            {
                while (true)
                {
                    if (IsDone) { Run(); }

                    Thread.Sleep(60000);
                }
            });

            NewThread.Start();
        }

        private void Run()
        {
            IsDone = false;

            try
            {
                Dictionary<Int32, List<UInt16>> nSkillNos = Program.SQL.GetnSkillNos();

                foreach (String sID in Program.SQL.GetOnlinesIDs())
                {
                    Int32 nCharNo = Program.SQL.GetnCharNoFromsID(sID);
                    
                    Byte Level = Program.SQL.GetnLevelFromsID(sID);
                    Byte PlayerClass = Program.SQL.GetnClassFromnCharNo(nCharNo);

                    List<List<Object[]>> SkillsToLearn = new List<List<Object[]>>();
                    List<List<Object[]>> PassivesToLearn = new List<List<Object[]>>();

                    switch (PlayerClass)
                    {
                        case 1:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[1].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[1].ToList());

                                break;
                            }
                        case 2:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[1].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[2].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[1].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[2].ToList());

                                break;
                            }
                        case 3:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[1].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[2].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[3].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[1].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[2].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[3].ToList());

                                break;
                            }
                        case 4:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[1].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[2].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[3].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[4].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[1].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[2].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[3].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[4].ToList());

                                break;
                            }
                        case 5:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[1].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[2].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[3].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[5].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[1].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[2].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[3].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[5].ToList());

                                break;
                            }
                        case 6:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[6].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[6].ToList());

                                break;
                            }
                        case 7:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[6].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[7].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[6].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[7].ToList());

                                break;
                            }
                        case 8:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[6].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[7].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[8].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[6].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[7].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[8].ToList());

                                break;
                            }
                        case 9:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[6].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[7].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[8].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[9].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[6].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[7].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[8].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[9].ToList());

                                break;
                            }
                        case 10:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[6].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[7].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[8].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[10].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[6].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[7].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[8].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[10].ToList());

                                break;
                            }
                        case 11:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[11].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[11].ToList());

                                break;
                            }
                        case 12:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[11].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[12].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[11].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[12].ToList());

                                break;
                            }
                        case 13:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[11].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[12].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[13].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[11].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[12].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[13].ToList());

                                break;
                            }
                        case 14:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[11].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[12].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[13].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[14].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[11].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[12].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[13].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[14].ToList());

                                break;
                            }
                        case 15:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[11].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[12].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[13].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[15].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[11].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[12].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[13].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[15].ToList());

                                break;
                            }
                        case 16:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[16].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[16].ToList());

                                break;
                            }
                        case 17:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[16].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[17].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[16].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[17].ToList());

                                break;
                            }
                        case 18:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[16].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[17].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[18].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[16].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[17].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[18].ToList());

                                break;
                            }
                        case 19:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[16].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[17].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[18].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[19].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[16].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[17].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[18].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[19].ToList());

                                break;
                            }
                        case 20:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[16].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[17].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[18].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[20].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[16].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[17].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[18].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[20].ToList());

                                break;
                            }
                        case 21:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[21].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[21].ToList());

                                break;
                            }
                        case 22:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[21].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[22].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[21].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[22].ToList());

                                break;
                            }
                        case 23:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[21].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[22].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[23].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[21].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[22].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[23].ToList());

                                break;
                            }
                        case 24:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[21].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[22].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[23].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[24].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[21].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[22].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[23].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[24].ToList());

                                break;
                            }
                        case 25:
                            {
                                SkillsToLearn.Add(Program.ClassSkills[21].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[22].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[23].ToList());
                                SkillsToLearn.Add(Program.ClassSkills[25].ToList());

                                PassivesToLearn.Add(Program.ClassPassives[21].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[22].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[23].ToList());
                                PassivesToLearn.Add(Program.ClassPassives[25].ToList());

                                break;
                            }
                    }
					bool addedSkills = false;
                    foreach (UInt16 nSkillNo in Program.SQL.GettSkilllearnerFornCharNo(nCharNo))
                    {
                        if (!nSkillNos.ContainsKey(nCharNo) || !nSkillNos[nCharNo].Contains(nSkillNo))
                        {
                            using (var LocalPacket = new Packet(5, 15))
                            {
                                LocalPacket.PacketWriter.Write(sID);
                                LocalPacket.PacketWriter.Write(nSkillNo);

                                Program.LocalClient.SendPacket(LocalPacket);
								addedSkills = true;
							}
                        }
                    }

                    Program.SQL.DeletetSkillLearner(nCharNo);

                    foreach (List<Object[]> ClassSkills in SkillsToLearn)
                    {
                        foreach (Object[] SkillInfo in ClassSkills)
                        {
                            if ((!nSkillNos.ContainsKey(nCharNo) || !nSkillNos[nCharNo].Contains(Convert.ToUInt16(SkillInfo[1]))) && Level >= Convert.ToByte(SkillInfo[0]))
                            {
                                using (var LocalPacket = new Packet(5, 15))
                                {
                                    LocalPacket.PacketWriter.Write(sID);
                                    LocalPacket.PacketWriter.Write(Convert.ToInt32(SkillInfo[1]));

                                    Program.LocalClient.SendPacket(LocalPacket);
									addedSkills = true;
								}
                            }
                        }
                    }

                    foreach (List<Object[]> ClassPassives in PassivesToLearn)
                    {
                        foreach (Object[] PassiveInfo in ClassPassives)
                        {
                            if ((!nSkillNos.ContainsKey(nCharNo) || !nSkillNos[nCharNo].Contains(Convert.ToUInt16(Convert.ToUInt16(PassiveInfo[1]) + 30000))) && Level >= Convert.ToByte(PassiveInfo[0]))
                            {
                                using (var LocalPacket = new Packet(5, 16))
                                {
                                    LocalPacket.PacketWriter.Write(sID);
                                    LocalPacket.PacketWriter.Write(Convert.ToInt32(PassiveInfo[1]));

                                    Program.LocalClient.SendPacket(LocalPacket);
									addedSkills = true;
								}
                            }
                        }
                    }

					if (addedSkills)
					{
						Program.SendConsoleText(ConsoleColor.Gray, "Added skills for {0}", sID);
					}

                    SkillsToLearn.Clear();
                    PassivesToLearn.Clear();
                }

                nSkillNos.Clear();
            }
            catch (Exception Error) { Program.SendConsoleText(ConsoleColor.Red, "Timers error - Levelup skill giver\n{0}", Error.ToString()); }

            IsDone = true;
        }
    }
}
