using Godot;

using System.Collections.Generic;

namespace Rokojori
{  

  public class NetworkNodeMember
  {
    protected int _networkID = -1; 
    public int networkID => _networkID;
    public bool hasNetworkID => _networkID != -1;

    public void _SetNetworkID ( int netID )
    {
      _networkID = netID;
    }
    
    protected INetworkNode _networkNode;
    public INetworkNode networkNode => _networkNode;


    protected NetworkTransportType customNetworkType = NetworkTransportType.Never_Networked;
    protected bool hasCustomNetworkType = false;
    public NetworkTransportType networkType => hasCustomNetworkType ? customNetworkType : networkNode.GetNetworkType();

    public bool hasOwnedTransportType => NetworkTransportType.Owned_By_One == networkType;
    
    public bool IsOwnedBy( int sessionMember )
    {
      return hasOwnedTransportType && networkNode.GetNetworkOwner() == sessionMember;
    }

    public bool isOwnedLocally
    {
      get 
      {
        return IsOwnedBy( NetworkManager.ownSessionMemberIndex );
      }
    }
    
    public bool CanReceive()
    {
      return NetworkTransportSettings.CanReceive( networkType, networkNode.GetNetworkOwner() );
    }

    public bool CanSend()
    {
      return NetworkTransportSettings.CanSend( networkType, networkNode.GetNetworkOwner() );
    }

    public void _SetNode( NetworkNode node )
    {
      _networkNode = node;
    }

    public void ReceiveNetworkMessage( NetworkMessageEvent messageEvent )
    {
      if ( ! CanReceive() )
      {
        return;
      }    

      OnNetworkMessageReceived( messageEvent );
    }

    protected virtual void OnNetworkMessageReceived( NetworkMessageEvent messageEvent )
    {

    }

    public void Send( BitView view, List<int> targets = null, bool reliable = true )
    {
      if ( ! CanSend() )
      {
        return;
      }

      var nm = Unique<NetworkManager>.Get();
      var viewWithID = BitView.PrependID( networkID, view );      
      nm.transport.SendMessage( viewWithID, targets, reliable );
    }

    public void SendWithID( BitView viewWithID, List<int> targets = null, bool reliable = true )
    {
      if ( ! CanSend() )
      {
        return;
      }

      var nm = Unique<NetworkManager>.Get();   
      nm.transport.SendMessage( viewWithID, targets, reliable );
    }
  }
}