using System;
using System.Net.Sockets;
using System.Collections;
using System.Threading;
using System.Data.Odbc;
using System.Net;

using MySql.Data;
using MySql.Data.MySqlClient;
using System.Diagnostics;

using System.Text;
namespace GameServer
{
    class cWRClient
    {


        public int FuckPacket = 1000;
        public int FuckPacket2 = 165000;
        public int Second=0;
        public struct tItem
        {
            public string itemCode;
            public long expireDate;
            public int SlotCostume;
            public int SlotEngineer;
            public int SlotMedic;
            public int SlotSniper;
            public int SlotAssault;
            public int SlotHeavyTrooper;
         }
        public struct bItem
        {
            
            public string WaffenName;
            public int Level;
            public int Tage3;
            public int Tage7;
            public int Tage15;
            public int Tage30;
            public int Premium;
           
        }


        public string chooseClass = "1";
        public int iExp;
        public int iDinar;
        public int iPoints;
        public int iFlags;
        public int iKills;
        public int iDeaths;
             public string[] Weapons;

             public string slot1E = "DA02";
             public string slot2E = "DB01";
             public string slot3E = "DF01";
             public string slot4E = "DR01";
             public string slot5E = "^";
             public string slot6E = "^";
             public string slot7E = "^";
             public string slot8E = "DI05";

             public string slot1M = "DA02";
             public string slot2M = "DB01";
             public string slot3M = "DF01";
             public string slot4M = "DQ01";
             public string slot5M = "^";
             public string slot6M = "^";
             public string slot7M = "^";
             public string slot8M = "DG24";

             public string slot1S = "DA02";
             public string slot2S = "DB01";
             public string slot3S = "DG05";
             public string slot4S = "DN01";
             public string slot5S = "^";
             public string slot6S = "^";
             public string slot7S = "^";
             public string slot8S = "DC34";

             public string slot1A = "DA02";
             public string slot2A = "DB01";
             public string slot3A = "DC02";
             public string slot4A = "DN01";
             public string slot5A = "^";
             public string slot6A = "^";
             public string slot7A = "^";
             public string slot8A = "DT06";

             public string slot1H = "DA02";
             public string slot2H = "DB01";
             public string slot3H = "DJ01";
             public string slot4H = "DL01";
             public string slot5H = "^";
             public string slot6H = "^";
             public string slot7H = "^";
             public string slot8H = "DI05";
       
        
      
        public cClientPacketHandler pHandler = new cClientPacketHandler();
        public Socket cSocket;
        public long UserID = 0;
        private int SessionID = 0;
        private string Username = "";
        private string Nickname = "";
        public string Password = "";
        private int Accesslevel = 0;
        private int EXP = 0;
        private int Level = 1;
        private int Dinar = 0;
        private int Kills = 0;
        private int Deaths = 0;
        private int Premium = 3;
        private long PremiumTime = 0;
        private long PremiumDate = 0;
        private string Mac = "";
        private int ChannelID = 0;
        private long PremiumLeftTime = 0;
        private int Coupons;
        private int RoomPage = 0;
        private cWRRoom ctRoom = null;
        private int ReadyState = 0;

        public int Team = 0;
        //////////////////////
        public long nIP;
        public long nPort;
        public long lIP;
        public long lPort;
        public int RoomSlot = 0;
        /////////////////////
        private ArrayList Items = new ArrayList();
        public ArrayList PXItems = new ArrayList();
        private ArrayList bItems = new ArrayList();
        ////////////////////////
        private DateTime tLeft;
        private TimeSpan tSpan;
        
        public System.Timers.Timer lTimer = new System.Timers.Timer();
        ////////////////////////
        public bool isLiving = false;
        public int Life;
        public int DoubleKill;
        public int TrippleKill;
        ////////////////////////

        public string[] savedSpawn = new string[1];

        ////////////////////////

        public string CostumeE = "BA01";
        public string CostumeM = "BA02";
        public string CostumeS = "BA03";
        public string CostumeA = "BA04";
        public string CostumeH = "BA05";

        ////////////////////////

        public bool isRegistered = false;
        public bool isLoggedin = false;
        public long ClientPing = 0;
        public int SocketID = 0;
        public bool pingOK = false;

        ////////////////////////
        private byte[] dataBuffer = new byte[1024];
        ////////////////////////

        public int CurrentWeapon = 0;
        public int Cash = 0;

        ////////////////////////

        public cWRClient(Socket tSocket, int sID , int sSocketID ,bool isISC)
        {
            cSocket = tSocket;
            SessionID = sID;
            SocketID = sSocketID;

            Program.cCollector.AddClient(this);
            cSocket.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(arrivedData), null);
        }

        #region Arrival

        private void arrivedData(IAsyncResult iAr)
        {
            try
            {
                int DataLength = cSocket.EndReceive(iAr);

                if (DataLength > 1)
                {
                    byte[] packetBuffer = new byte[DataLength];
                    Array.Copy(dataBuffer, 0, packetBuffer, 0, DataLength);

                    pHandler.Handle(packetBuffer, this, false);
                }

                cSocket.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(arrivedData), null);
            }
            catch {  }
        }

        #endregion

        #region Send
        
        public void Send(cServerPacketHandler p)
        {
            byte[] sendBuffer = p.getPacket(false);
            try { cSocket.BeginSend(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, new AsyncCallback(sendCallBack), null); }
            catch { Disconnect(); }
        }

        private void sendCallBack(IAsyncResult iAr)
        {
            try { cSocket.EndSend(iAr); }
            catch { Disconnect(); }
        }

        #endregion

        public string generateTimeStamp(int Days)
        {
            string Date = (DateTime.Now.Year - 2000).ToString() + DateTime.Now.Month.ToString() + (DateTime.Now.Day + Days).ToString() + DateTime.Now.Hour.ToString();
            return Date;
        }

        public void SetupPremiumTime()
        {
            lTimer.Interval = 1000;
            lTimer.Elapsed += new System.Timers.ElapsedEventHandler(PremiumLeft);
            lTimer.Start();
        }
        private void PremiumLeft(Object myObject, EventArgs myEventArgs)
        {
            if (Premium > 0)
            {
                tSpan = DateTime.Now - tLeft;
                PremiumLeftTime = PremiumTime - tSpan.Minutes;
                if (PremiumLeftTime <= 0) { PremiumLeftTime = -1; }
            }
            else { PremiumLeftTime = -1; }

            Send(new SP_PREMIUM_LEFT(this));
        }

        public int uniqID = 0;
        public int uniqID2 = 0;
        public int uniqIDisCRC = 910;

        public bool sDisconnected = false;

        public bool hasPX(string ID)
        {
            try
            {
                foreach (tItem pItem in PXItems)
                {
                    if (pItem.itemCode.Contains(ID))
                    {
                        return true;
                    }
                }
            }
            catch { }
            return false;
        }
        public string generateInventoryString()
        {

            string Items = "";

            foreach (cWRClient.tItem pItem in this.getItems())
            {
                Items += pItem.itemCode + "-1-3-" + pItem.expireDate.ToString() + "-0-0-0-0-0-9999-9999,";//-9999-9999
            }

            for (int i = 0; i < (31 - this.getItems().Count); i++)
            {
                Items += "^,";
            }

            Items = Items.Substring(0, Items.Length - 1);

            return Items; // Inventory (Weapons/PX-Items)


        }
        public string getOpenSlots()
        {
            StringBuilder SB = new StringBuilder();
            if (hasPX("CA01"))
            {
                SB.Append("T,");
            }
            else
            {
                SB.Append("F,");
            }
            if (slot6E == "^" && slot6M == "^" && slot6S == "^" && slot6A == "^" && slot6H == "^")
            {
                SB.Append("F,F,");
            }
            else
            {
                SB.Append("T,F,");
            }
            if (hasPX("CA04"))
            {
                SB.Append("T");
            }
            else
            {
                SB.Append("F");
            }
            return SB.ToString();
        }
        public int getID(string sNickName)
        {
             if (Program.SQL.conn.mySqlConnection.State != System.Data.ConnectionState.Open)
                {
                    Program.SQL.conn.OpenConnection();
                }
            int UserID = 0; // only if you use int you need return it.
            MySqlDataReader SQLReader;
            MySqlCommand SQLCommand = new MySqlCommand("SELECT userID FROM account WHERE nickname = '" + sNickName + "'", Program.SQL.conn.mySqlConnection);
            SQLReader = SQLCommand.ExecuteReader();
            while (SQLReader.Read())
            {
                UserID = SQLReader.GetInt32(0);
            } SQLReader.Close();
            Program.SQL.conn.CloseConnection();
            return UserID;
        }
        public void loadItems()
        {
            try
            {
                Program.SQL.conn.CloseConnection();
                if (Program.SQL.conn.mySqlConnection.State != System.Data.ConnectionState.Open)
                {
                    Program.SQL.conn.OpenConnection();
                }
                tItem pItem = new tItem();
                Items.Clear();
                MySqlDataReader SQLReader;
                MySqlCommand SQLCommand = new MySqlCommand("SELECT itemCode, expireDate,isCostume, class_0, class_1, class_2, class_3, class_4 FROM INVENTORY_TBL WHERE userID = '" + UserID + "'", Program.SQL.conn.mySqlConnection);
                SQLReader = SQLCommand.ExecuteReader();
                while (SQLReader.Read())
                {
                    pItem.itemCode = SQLReader.GetString(0);
                    pItem.expireDate = SQLReader.GetInt64(1);
                    pItem.SlotCostume = SQLReader.GetInt32(2);
                    pItem.SlotEngineer = SQLReader.GetInt32(3);
                    pItem.SlotMedic = SQLReader.GetInt32(4);
                    pItem.SlotSniper = SQLReader.GetInt32(5);
                    pItem.SlotAssault = SQLReader.GetInt32(6);
                    pItem.SlotHeavyTrooper = SQLReader.GetInt32(7);
                    if (pItem.SlotCostume == 0)
                    {
                        if (pItem.itemCode.Remove(0,1) == "C" || pItem.itemCode =="D101")
                        {
                            PXItems.Add(pItem);
                        }
                        Items.Add(pItem);
                    }
                }
                SQLReader.Close();
                Program.SQL.conn.CloseConnection();
            }
            catch (MySqlException ex)
            {
                new cLog(C.MSG_ERROR, "MySQL Error: " + ex.Message);
                Disconnect();
            }
        }

        public void GetAllCostumes()
        {
            try
            {
                Program.SQL.conn.CloseConnection();
                if (Program.SQL.conn.mySqlConnection.State != System.Data.ConnectionState.Open)
                {
                    Program.SQL.conn.OpenConnection();
                }
                MySqlDataReader SQLReader;
                MySqlCommand SQLCommand = new MySqlCommand("SELECT class_0,class_1,class_2,class_3,class_4 FROM costumes WHERE userID = '" + UserID + "'", Program.SQL.conn.mySqlConnection);
               SQLReader = SQLCommand.ExecuteReader();

                while (SQLReader.Read())
                {
                    CostumeE = SQLReader.GetString(0);
                    CostumeM = SQLReader.GetString(1);
                    CostumeS = SQLReader.GetString(2);
                    CostumeA = SQLReader.GetString(3);
                    CostumeH = SQLReader.GetString(4);
                }
                SQLReader.Close();
                Program.SQL.conn.CloseConnection();
            }
            catch (MySqlException ex)
            {
                new cLog(C.MSG_ERROR, "MySQL Error: " + ex.Message);
                Disconnect();
            }

        }
        public void getUserData()
        {
            try
            {
              if (Program.SQL.conn.mySqlConnection.State != System.Data.ConnectionState.Open)
                {
                    Program.SQL.conn.OpenConnection();
                }

                MySqlDataReader SQLReader;
                MySqlCommand SQLCommand = new MySqlCommand("SELECT username, nickname, password, accesslevel FROM account WHERE userID = '" + UserID + "'", Program.SQL.conn.mySqlConnection);
                SQLReader = SQLCommand.ExecuteReader();
                while (SQLReader.Read())
                {
                    Username = SQLReader.GetString(0);
                    Nickname = SQLReader.GetString(1);
                    Password = SQLReader.GetString(2);
                    Accesslevel = SQLReader.GetInt32(3);

                    isRegistered = true;
                } SQLReader.Close();
                Program.SQL.conn.CloseConnection();

                if (Program.SQL.conn.mySqlConnection.State != System.Data.ConnectionState.Open)
                {
                    Program.SQL.conn.OpenConnection();
                }
                SQLCommand = new MySqlCommand("SELECT exp, level, dinar, kills, deaths, premium, premiumTime, premiumDate,Coupons,iscash FROM account_detail WHERE userID = '" + UserID + "'", Program.SQL.conn.mySqlConnection);
                SQLReader = SQLCommand.ExecuteReader();
                while (SQLReader.Read())
                {
                    EXP = SQLReader.GetInt32(0);
                    Level = SQLReader.GetInt32(1);
                    Dinar = SQLReader.GetInt32(2);
                    Kills = SQLReader.GetInt32(3);
                    Deaths = SQLReader.GetInt32(4);
                    Premium = SQLReader.GetInt32(5);
                    PremiumTime = SQLReader.GetInt64(6);
                    PremiumDate = SQLReader.GetInt64(7);
                    Coupons = SQLReader.GetInt32(8);
                    Cash = SQLReader.GetInt32(9);
                } SQLReader.Close();
                Program.SQL.conn.CloseConnection();

                uniqID = Convert.ToInt16(UserID + 1);
                uniqID2 = Convert.ToInt16(UserID);
            }
            catch (Exception ex)
            {
                Disconnect();
            }
        }

        public void Disconnect()
        {
          if(sDisconnected) return;

          sDisconnected = true;

          if (ctRoom != null)
              ctRoom.removeUser(this.RoomSlot);

          Program.cCollector.RemoveClient(this);

            try { cSocket.Close(); }
            catch { }

            Program.ServerClass.freeSlot(SocketID);

        }


        public void SendISC(cServerPacketHandler fPacket)
        {
             byte[] bPacket = fPacket.getPacket(true);
             cSocket.Send(bPacket);
        }

        public IPEndPoint RemoteNetwork = null;

        public void setSessionID(int sID) { SessionID = sID; }
        public int getSessionID() { return SessionID; }

        public void setUserID(long sID) { UserID = sID; }
        public long getUserID() { return UserID; }

        public string getNickname() { return Nickname; }
        public void setNickname(string NN) { Nickname = NN; }
        public int getExp() { return EXP; }
        public void setExp(int EXPs) { EXP = EXPs; }
        public int getLevel() { return Level; }
        public void setLevel(int Lvl) { Level = Lvl; }
        public int getDinar() { return Dinar; }
        public void setDinar(int Dnar) { Dinar = Dnar; }
        public int getKills() { return Kills; }
        public void setKills(int tKills) { Kills = tKills; }
        public void setDeaths(int tKills) { Deaths = tKills; }
        public int getCoupons() { return Coupons; }
        public void setCoupons(int cpns) { Coupons = cpns; }
        public int getDeaths() { return Deaths; }
        public long getPremium() { return Premium; }
        public void setPremium(int Prem1) { Premium = Prem1; }
        public ArrayList getItemList() { return bItems; }
        public void setMac(string sMac) { Mac = sMac; }
        public string getMac() { return Mac; }
        
        public int getChannelID() { return ChannelID; }
        public void setChannelID(int cID) { ChannelID = cID; }

        public long getPremiumLeftTime() { return PremiumLeftTime; }
        public ArrayList getItems() { return Items; }

        public void setRoom(cWRRoom Room) { ctRoom = Room; }
        public cWRRoom getRoom() { return ctRoom; }

        public void setRoomPage(int Page) { RoomPage = Page; }
        public int getRoomPage() { return RoomPage; }

        public int getAccesslevel() { return Accesslevel; }


        public void setNetwork(IPEndPoint IPeo)
        {
            nIP = Program.WRServer.IPToInt(IPeo.Address.ToString());
            nPort = Program.WRServer.PortToInt(IPeo.Port);

            if (Program.bannedips.Contains(nIP.ToString()))
            {
                this.Send(new SP_GET_CHECKSUM());
                this.Disconnect();
            }

        }

        public void setUPLocalNetwork(IPEndPoint IPeo)
        {
            lIP = Program.WRServer.IPToInt(IPeo.Address.ToString()); 
            lPort = Program.WRServer.PortToInt(IPeo.Port);
        }


        public long getNetworkIP() { return nIP; }
        public long getNetworkPort() { return nPort; }
        public long getLocalIP() { return lIP; }
        public long getLocalPort() { return lPort; }

        public void setReadyState(int State) { ReadyState = State; }
        public int getReadyState() { return ReadyState; }


    }
}