using Godot;
using System.Collections.Generic;


namespace Rokojori
{  
  public abstract class NetClassDefinition
  {
    protected NetMember[] _members = new NetMember[ 0 ];

    public void SetMembers( params NetMember[] members )
    {
      _members = members;
    }
    
    public void ReadMembers( BitView view )
    {
      System.Array.ForEach( _members, m => m.ReadMember( view ) );
    }

    public void WriteMembers( BitView view )
    {
      System.Array.ForEach( _members, m => m.WriteMember( view ) );
    }
  }

  public class NetClassDataType<T> where T:NetClassDefinition, new()
  {
    public T ReadData( BitView view )
    {
      var n = new T();
      n.ReadMembers( view );
      return n;
    }

    public void WriteData( BitView view, T t )
    {
      t.WriteMembers( view );
    }
  } 

  public class NetClass<T>:NetMember where T:NetClassDefinition, new()
  {
    public T value;

    public NetClass( T value )
    {
      this.value = value;
    }

    public NetClassDataType<T> dataType => Singleton<NetClassDataType<T>>.Get();

    public override void ReadMember( BitView view )
    {
      var isNull = ! view.ReadBit();

      if ( isNull )
      {
        value = null;
        return;
      }

      value = dataType.ReadData( view );
    }

    public override void WriteMember( BitView view )
    {
      view.WriteBit( value != null );

      if ( value == null )
      {
        return;
      }

      dataType.WriteData( view, value );
    } 
  }
}