using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using FObjBase;

namespace TCPManager
{
    public class TCPListen
    {
        private List<TCPConn> conns = new List<TCPConn>();
        private Socket sock;
        private IPEndPoint ep = new IPEndPoint(IPAddress.Any, 20006);
        public IPEndPoint LocalEP
        {
            get
            {
                return new IPEndPoint(ep.Address, ep.Port);
            }
            set
            {
                ep.Address = value.Address;
                ep.Port = value.Port;
            }
        }
        /// <summary>
        /// 处理接收的数据。 必须有
        /// </summary>
        public ParsePacketHandler ParsePacket = null;
        /// <summary>
        /// 连接状态改变。 可有可无
        /// </summary>
        public Action<TCPConn> ConnectAction;
        /// <summary>
        /// 长时间没发数据，事件。 可有可无
        /// </summary>
        public Action<TCPConn> OutputIsEmptyWithLongTimeAction;


        public TCPListen(IPEndPoint ep, ParsePacketHandler func)
        {
            LocalEP = ep;
            ParsePacket = func;
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sock.Blocking = false;
            PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD, new PollModule.PollHandler(OnPoll), TimeSpan.FromMilliseconds(1));
        }
        /// <summary>
        /// 使能，开始监听
        /// </summary>
        public bool Enable
        {
            set
            {
                if (value)
                    StartListen();
                else
                    StopListen();
            }
        }
        private void StartListen()
        {
            sock.Bind(LocalEP);
            sock.Listen(10);
        }
        private void StopListen()
        {
            sock.Close();
        }
        //DateTime dtlast = DateTime.Now;
        //int pollcnt = 0;
        private void OnPoll()
        {
            //pollcnt++;

            //DateTime dt1 = DateTime.Now;
            //if ((dt1 - dtlast).TotalSeconds >= 1)
            //{
            //    Console.WriteLine("TCPListen OnPoll " + ((dt1 - dtlast).TotalMilliseconds/pollcnt).ToString());
            //    dtlast = dt1;
            //    pollcnt = 0;
            //}
            //查新连接----------------------------------------------------------
            try
            {
                List<Socket> s = new List<Socket>();
                s.Add(sock);
                Socket.Select(s, null, null, 0);
                if (s.Count > 0)
                {
                    Socket socket = sock.Accept();

                    TCPConn sconn = new TCPConn(socket);
                    sconn.ParsePacket = ParsePacket;
                    if(ConnectAction!=null)
                        sconn.ConnectEvent += ConnectAction;
                    if(OutputIsEmptyWithLongTimeAction!=null)
                        sconn.OutputIsEmptyWithLongTimeEvent += OutputIsEmptyWithLongTimeAction;
                    sconn.Enable = true;
                    sconn.IsConnected = true;
                    conns.Add(sconn);
                }
            }
            catch (SocketException e)
            {
            }
            //处理当前连接----------------------------------------------------------
            SConns_Poll();
        }
        private void SConns_Poll()
        {
            int cnt = conns.Count();
            int i = 0;
            while (i < cnt)
            {
                TCPConn conn = conns.ElementAt(i);
                if (conn != null)
                {
                    if (conn.OnPoll() < 0)
                    {
                        conn.Enable = false;
                        conns.RemoveAt(i);
                        cnt--;
                        continue;
                    }
                    i++;
                }
                else
                {
                    cnt--;
                    conns.RemoveAt(i);
                }
            }
        }
    }
}
