﻿using System.Collections.Generic;
using System.Linq;
using WhormholeExtreme.BaseClasses;

namespace WhormholeExtreme.Behaviour
{
    public partial class NetworkBehaviour
    {
        #region Connection
        public delegate void EndpointConnectionChangeHandler(NetworkEndPointModule module, bool newState);
        public static event EndpointConnectionChangeHandler OnEndpointConnectionChange;
        private static void RaiseEvent_OnEndpointConnectionChange(NetworkEndPointModule module, bool newState)
        {
            if (OnEndpointConnectionChange == null) return;

            OnEndpointConnectionChange(module, newState);
        }

        private List<NetworkEndPointConnection> _RegisteredConnections;
        private List<NetworkEndPointConnection> RegisteredConnections
        {
            get
            {
                if (this._RegisteredConnections == null) this._RegisteredConnections = new List<NetworkEndPointConnection>();

                return this._RegisteredConnections;
            }
        }
        public static bool TryOpenConnection(NetworkEndPointModule sourceModule, NetworkEndPointModule destinationModule)
        {
            if (NetworkBehaviour.Instance.RegisteredConnections.Where(m => m.Source == sourceModule ||
                                                                        m.Destination == sourceModule ||
                                                                        m.Source == destinationModule ||
                                                                        m.Destination == destinationModule).FirstOrDefault() != null) return false;

            NetworkEndPointConnection connection = new NetworkEndPointConnection(sourceModule, destinationModule);

            NetworkBehaviour.Instance.RegisteredConnections.Add(connection);
            connection.OnNetworkEndPointConnectionTimeout += NetworkBehaviour.OnEndPointConnectionTimeOut;

            NetworkBehaviour.RaiseEvent_OnEndpointConnectionChange(sourceModule, true);
            NetworkBehaviour.RaiseEvent_OnEndpointConnectionChange(destinationModule, true);

            return true;
        }

        public static bool TryCloseConnection(NetworkEndPointModule module)
        {
            return NetworkBehaviour.TryCloseConnection(NetworkBehaviour.GetEndPointConnection(module));
        }

        public static bool TryCloseConnection(NetworkEndPointConnection connection)
        {
            if (!NetworkBehaviour.Instance.RegisteredConnections.Contains(connection)) return false;

            NetworkBehaviour.Instance.RegisteredConnections.Remove(connection);
            connection.OnNetworkEndPointConnectionTimeout -= NetworkBehaviour.OnEndPointConnectionTimeOut;

            NetworkBehaviour.RaiseEvent_OnEndpointConnectionChange(connection.Source, false);
            NetworkBehaviour.RaiseEvent_OnEndpointConnectionChange(connection.Destination, false);

            return true;
        }

        public static bool CheckConnectionRegistration(NetworkEndPointConnection connection)
        {
            return NetworkBehaviour.Instance.RegisteredConnections.Contains(connection);
        }

        public static NetworkEndPointConnection GetEndPointConnection(NetworkEndPointModule module)
        {
            return NetworkBehaviour.Instance.RegisteredConnections.Where(c => c.Source == module || c.Destination == module).FirstOrDefault();
        }

        public static void OnEndPointConnectionTimeOut(NetworkEndPointConnection connection)
        {
            NetworkBehaviour.TryCloseConnection(connection);
        }
        #endregion
    }
}
