using System;
using System.Collections;
using System.Text;

namespace GameServer
{
    class cWRRoom
    {
        public int ID;
        public String Name = "WarRock";
        public int EnablePassword = 0;
        public String Password = "";
        public int MapID = 0;
        public int PremiumOnly = 0;
        public int VoteKick = 0;
        public int RoomStatus = 1; // 1 Waiting - 0 & 2 Playing
        public int RoomMode = 0; // Mode : 0 = Explosive, 1 = FFA, 2 = Deathmatch, 3 = Conquest
        public int RoomType = 0;
        public int LevelLimit = 0;
        public int Ping = 0;
        public int Rounds = 0;
        public bool isSpawned = false;
        public int LastTick = 0;

        public int BombTimeLeft = 45000;
        public int RoundTimeLeft = 180000;
        public int RoundTimeSpent = 10000;

        public int cNIUPoints = 0;
        public int cDeberanPoints = 0;

        public int[] Flag = new int[32];
        public ArrayList Flags = new ArrayList();
        public int[] Kills = new int[32];

        public int RoomTimeLeft = 165000 * 10;
        public int FuckPacket = 0;
        public long Second = 0;

        public int Channel = 1;

        public int Plants = 1;

        private Hashtable Users = new Hashtable();
        public int RoomMaster = 0;
        private int MaxUsers = 0;

        private bool ZombieShit = false;

        public int PlantedBomb = -1;
        public bool BombAPlanted = false;
        public bool BombBPlanted = false;

        public ArrayList NIUPlayers = new ArrayList();
        public ArrayList DeberanPlayers = new ArrayList();

        public cWRRoom()
        {
        }

         
        enum FFARounds
        {
            Kills10,
            Kills15,
            Kills20,
            Kills25,
            Kills30
        }

        enum PingLimits
        {
            Green,
            Yellow,
            Red,
        }
        public int getRealRounds()
        {
            int Rounds = 0;
            if (RoomMode == 1)
            {
                switch ( Rounds )
                {
                    case 0:
                        Rounds = 10;
                        break;
                    case 1:
                        Rounds = 15;
                        break;
                    case 2:
                        Rounds = 20;
                        break;
                    case 3:
                        Rounds = 25;
                        break;
                    case 4:
                        Rounds = 30;
                        break;
                }
            }
            else if (RoomMode == 0)
            {
                switch (Rounds)
                {
                    case 0:
                        Rounds = 1;
                        break;
                    case 1:
                        Rounds = 3;
                        break;
                    case 2:
                        Rounds = 5;
                        break;
                    case 3:
                        Rounds = 7;
                        break;
                    case 4:
                        Rounds = 9;
                        break;
                }
            }
            else if (RoomMode == 2)
            {
                switch (Rounds)
                {
                    case 0:
                        Rounds = 30;
                        break;
                    case 1:
                        Rounds = 50;
                        break;
                    case 2:
                        Rounds = 100;
                        break;
                    case 3:
                        Rounds = 150;
                        break;
                    case 4:
                        Rounds = 200;
                        break;
                }
            }
            return Rounds;
        }
        public int switchSide(cWRClient Client)
        {
            if (Client != null)
            {
                int OldSlot = Client.RoomSlot;
                if (OldSlot < (Users.Count / 2))
                {
                    for (byte I = Convert.ToByte(Users.Count / 2); I < Convert.ToByte(Users.Count); I++)
                    {
                        if (Users[I] == null)
                        {
                            Users[I] = Client;
                            Client.RoomSlot = I;
                            Users[OldSlot] = null;
                            return I;
                        }
                    }
                }
                else
                {
                    for (byte I = 0; I < Convert.ToByte(Users.Count / 2); I++)
                    {
                        if (Users[I] == null)
                        {
                            Users[I] = Client;
                            Client.RoomSlot = I;
                            Users[OldSlot] = null;
                            
                            return I;
                        }
                    }
                }
            }
            return -1;
        }

        public ArrayList PlayersInTeam(int Team)
        {
            ArrayList ar = new ArrayList();
            foreach (cWRClient c in Players)
            {
                if (getSide(c) == Team)
                {
                    ar.Add(c);
                }
            }
            return ar;
        }

        public int MaxPlayers
        {

            get
            {
                return MaxUsers;
            }

            set
            {
                MaxUsers = value;
            }

        }

        public ArrayList Players
        {
            get { return new ArrayList(Users.Values); }
        }

        public int PlayerCount { get { return Users.Count; } }
        public int RoomMasterSlot { get { return RoomMaster; } }

        public void send(cServerPacketHandler p)
        {
            foreach (cWRClient RoomUser in ((Hashtable)Users.Clone()).Values)
            {
                RoomUser.Send(p);
                
            }
        }

        public int getHighestKillsFFA()
        {
            int largestNum = Kills[0];
            for (int i = 1; i < Kills.Length; i++)
            {
                if (Kills[i] > largestNum)
                {
                    largestNum = Kills[i];
                }
            }

            return largestNum;
        }

        public void update()
        {
            /* Update Room Info Etc.. */
            if (Users.Count > 0 && this.isSpawned == true)
            {
                if (LastTick != DateTime.Now.Second)
                {
                    if (RoundTimeLeft > 0)
                    {
                        RoundTimeLeft -= 1000;
                    }
                    else
                    {
                        if (RoomMode == 0)
                        {
                            foreach (cWRClient _C in DeberanPlayers)
                            {
                                _C.Send(new SP_CHANGE_ROOM_DATA(_C, 2));
                                cDeberanPoints++;
                            }
                            foreach (cWRClient _C in NIUPlayers)
                            {
                                _C.Send(new SP_CHANGE_ROOM_DATA(_C, 1));
                            }
                            System.Threading.Thread.Sleep(1500);
                        }
                    }


                    RoundTimeSpent += 1000;

                    LastTick = DateTime.Now.Second;
                    if (RoomMode == 1)
                    {
                        foreach (cWRClient c in Players)
                        {
                            if (c.isLiving)
                            {
                                Kills[c.RoomSlot] = c.iKills;
                            }
                            c.Send(new SP_SpawnCount(c, this));
                        }
                    }
                    else
                    {
                        if (RoomMode != 7)
                        {
                            this.send(new SP_SpawnCount(this));
                        }
                        else
                        {
                            foreach (cWRClient c in Players)
                            {
                                c.Send(new SP_SpawnCount(c));
                            }
                        }
                    }
                }
                /* Update Other Information */
            }
        }

        public ArrayList getLivingTeamPlayer(int Team)
        {
            ArrayList ar = new ArrayList();
            foreach (cWRClient c in Players)
            {
                if (getSide(c) == Team)
                {
                    if (c.isLiving)
                    {
                        ar.Add(c);
                    }
                }
            }

            return ar;
        }

        public ArrayList getTeamPlayer(int Team)
        {
            ArrayList ar = new ArrayList();
            foreach (cWRClient c in Players)
            {
                if (getSide(c) == Team)
                {
                    ar.Add(c);
                }
            }

            return ar;
        }

        public ArrayList getNotTeamPlayer(int Team)
        {
            ArrayList ar = new ArrayList();
            foreach (cWRClient c in Players)
            {
                if (getSide(c) != Team)
                {
                    ar.Add(c);
                }
            }

            return ar;
        }

        public void EndGame(int WinningTeam)
        {
            foreach (cWRClient c in Players)
            {
                c.Send(new SP_GAME_END(this,c));
            }
        }
        public void newRound(int WinningTeam)
        {
            if (cNIUPoints == 7 || cDeberanPoints == 7)
            {
                EndGame(WinningTeam);
            }
            else
            {
                System.Threading.Thread.Sleep(3500);
                foreach (cWRClient c in getTeamPlayer(WinningTeam))
                {
                    c.Send(new SP_CHANGE_ROOM_DATA(c, 2));
                }

                foreach (cWRClient c in getNotTeamPlayer(WinningTeam))
                {
                    c.Send(new SP_CHANGE_ROOM_DATA(c, 1));
                }
               
            }
        }
        public void remove()
        {
            if (Users.Count > 0)
            {
                foreach (cWRClient RoomUser in ((Hashtable)Users.Clone()).Values)
                {


                }
            }
            Program.rCollector.RemoveRoom(this, Channel);
        }

        public int getSide(cWRClient Client)
        {
            if (Client.RoomSlot < (this.MaxPlayers / 2))
                return 0;
            else
                return 1;
        }

        public bool joinUser(cWRClient User)
        {
            User.chooseClass = "1";
            User.setReadyState(0);
            User.Life = 1000;
            User.iKills = User.iDeaths = User.iPoints = 0;

            if (Users.Count <= 0)
            {
                User.setRoom(this);
                User.RoomSlot = 0;
                Users.Add(0, User);
                RoomMaster = 0;
                return true;
            }
            else
            {
                if (Users.Count < MaxUsers)
                {
                    int Incr = 0;
                    for (int I = 0; I < MaxUsers; I++)
                    {
                        if (I % 2 == 0)
                        {
                            if (Users.ContainsKey(I / 2) == false)
                            {
                                User.RoomSlot = I / 2;
                                User.setRoom(this);
                                Users.Add(I / 2, User);
                                User.Send(new SP_JOIN_ROOM(User, this));
                                Program.WriteLine("cWRRoom",User.getNickname() + " Positive [" + I + "]");
                                DeberanPlayers.Add(User);
                                User.Team = getSide(User);
                                return true;
                            }
                        }
                        else
                        {
                            if (Users.ContainsKey((MaxUsers / 2) + Incr) == false)
                            {
                                User.RoomSlot = (MaxUsers / 2) + Incr;
                              User.setRoom(this);
                                Users.Add((MaxUsers / 2) + Incr, User);
                                User.Send(new SP_JOIN_ROOM(User, this));
                                 Program.WriteLine("cWRRoom",User.getNickname() + " User Joined Side Negative [" + I + "]");
                                NIUPlayers.Add(User);
                                User.Team = getSide(User);
                                return true;
                            }
                            Incr++;
                        }
                    }
                }
            }
            return false;
        }

        public cWRClient getPlayer(int SlotID)
        {
            if (Users.ContainsKey(SlotID))
            {
                return (cWRClient)Users[SlotID];
            }
            return null;
        }

        public bool removeUser(int SlotID)
        {
            if (SlotID >= 0 && Users.ContainsKey(SlotID))
            {
                cWRClient uObj = (cWRClient)Users[SlotID];

                uObj.setRoom(null);
                uObj.RoomSlot = -1;

                Users.Remove(SlotID);

                if (SlotID == RoomMaster && Users.Count > 0)
                {
                    /* Select New Master First */
                    for (int I = 0; I < MaxPlayers; I++)
                    {
                        if (Users.ContainsKey(I))
                        {
                            RoomMaster = I;
                            break;
                        }
                    }

                    send(new SP_LEAVE_ROOM(uObj, this, SlotID, RoomMaster));
                }
                else if (Users.Count <= 0)
                {
                    Program.cCollector.RemoveRoom(this,this.Channel);
                }

                uObj.Send(new SP_LEAVE_ROOM(uObj, this, SlotID, RoomMaster));

                foreach (cWRClient LobbyUser in Program.cCollector.getPlayerInChannel(this.Channel))
                {
                    if (LobbyUser.getRoomPage() == Math.Floor(Convert.ToDecimal(this.ID / 8)))
                    {
                        LobbyUser.Send(new SP_ROOM_LIST(LobbyUser, LobbyUser.getRoomPage()));
                    }
                }


                return true;
            }

            return false;
        }
    }
}
