// <auto-generated>
//  automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>

namespace MyGame.Example
{

using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;

public struct LargeArrayStruct : IFlatbufferObject
{
  private Struct __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
  public LargeArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public byte D(int j) { return __p.bb.Get(__p.bb_pos + 0 + j * 1); }
  public const int DLength = 64;
#if ENABLE_SPAN_T
  public Span<byte> GetDBytes() { return __p.bb.ToSpan(__p.bb_pos + 0, 64); }
#else
  public ArraySegment<byte>? GetDBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 0, 64);}
#endif
  public void MutateD(int j, byte d) { __p.bb.Put(__p.bb_pos + 0 + j * 1, d); }
  public float E(int j) { return __p.bb.GetFloat(__p.bb_pos + 64 + j * 4); }
  public const int ELength = 64;
#if ENABLE_SPAN_T
  public Span<float> GetEBytes() { return System.Runtime.InteropServices.MemoryMarshal.Cast<byte, float>(__p.bb.ToSpan(__p.bb_pos + 64, 256)); }
#else
  public ArraySegment<byte>? GetEBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 64, 256);}
#endif
  public void MutateE(int j, float e) { __p.bb.PutFloat(__p.bb_pos + 64 + j * 4, e); }
  public bool F(int j) { return 0!=__p.bb.Get(__p.bb_pos + 320 + j * 1); }
  public const int FLength = 64;
#if ENABLE_SPAN_T
  public Span<bool> GetFBytes() { return System.Runtime.InteropServices.MemoryMarshal.Cast<byte, bool>(__p.bb.ToSpan(__p.bb_pos + 320, 64)); }
#else
  public ArraySegment<byte>? GetFBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 320, 64);}
#endif
  public void MutateF(int j, bool f) { __p.bb.Put(__p.bb_pos + 320 + j * 1, (byte)(f ? 1 : 0)); }
  public MyGame.Example.NestedStruct G(int j) { return (new MyGame.Example.NestedStruct()).__assign(__p.bb_pos + 384 + j * 32, __p.bb); }
  public MyGame.Example.TestEnum H(int j) { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 2432 + j * 1); }
  public const int HLength = 64;
#if ENABLE_SPAN_T
  public Span<MyGame.Example.TestEnum> GetHBytes() { return System.Runtime.InteropServices.MemoryMarshal.Cast<byte, MyGame.Example.TestEnum>(__p.bb.ToSpan(__p.bb_pos + 2432, 64)); }
#else
  public ArraySegment<byte>? GetHBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 2432, 64);}
#endif
  public void MutateH(int j, MyGame.Example.TestEnum h) { __p.bb.PutSbyte(__p.bb_pos + 2432 + j * 1, (sbyte)h); }

  public static Offset<MyGame.Example.LargeArrayStruct> CreateLargeArrayStruct(FlatBufferBuilder builder, byte[] D, float[] E, bool[] F, int[,] g_A, MyGame.Example.TestEnum[] g_B, MyGame.Example.TestEnum[,] g_C, long[,] g_D, MyGame.Example.TestEnum[] H) {
    builder.Prep(8, 2496);
    for (int _idx0 = 64; _idx0 > 0; _idx0--) {
      builder.PutSbyte((sbyte)H[_idx0-1]);
    }
    for (int _idx0 = 64; _idx0 > 0; _idx0--) {
      builder.Prep(8, 32);
      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
        builder.PutLong(g_D[_idx0-1,_idx1-1]);
      }
      builder.Pad(5);
      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
        builder.PutSbyte((sbyte)g_C[_idx0-1,_idx1-1]);
      }
      builder.PutSbyte((sbyte)g_B[_idx0-1]);
      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
        builder.PutInt(g_A[_idx0-1,_idx1-1]);
      }
    }
    for (int _idx0 = 64; _idx0 > 0; _idx0--) {
      builder.PutBool(F[_idx0-1]);
    }
    for (int _idx0 = 64; _idx0 > 0; _idx0--) {
      builder.PutFloat(E[_idx0-1]);
    }
    for (int _idx0 = 64; _idx0 > 0; _idx0--) {
      builder.PutByte(D[_idx0-1]);
    }
    return new Offset<MyGame.Example.LargeArrayStruct>(builder.Offset);
  }
  public LargeArrayStructT UnPack() {
    var _o = new LargeArrayStructT();
    this.UnPackTo(_o);
    return _o;
  }
  public void UnPackTo(LargeArrayStructT _o) {
    _o.D = new byte[64];
    for (var _j = 0; _j < 64; ++_j) { _o.D[_j] = this.D(_j); }
    _o.E = new float[64];
    for (var _j = 0; _j < 64; ++_j) { _o.E[_j] = this.E(_j); }
    _o.F = new bool[64];
    for (var _j = 0; _j < 64; ++_j) { _o.F[_j] = this.F(_j); }
    _o.G = new MyGame.Example.NestedStructT[64];
    for (var _j = 0; _j < 64; ++_j) { _o.G[_j] = this.G(_j).UnPack(); }
    _o.H = new MyGame.Example.TestEnum[64];
    for (var _j = 0; _j < 64; ++_j) { _o.H[_j] = this.H(_j); }
  }
  public static Offset<MyGame.Example.LargeArrayStruct> Pack(FlatBufferBuilder builder, LargeArrayStructT _o) {
    if (_o == null) return default(Offset<MyGame.Example.LargeArrayStruct>);
    var _d = _o.D;
    var _e = _o.E;
    var _f = _o.F;
    var _g_a = new int[64,2];
    for (var idx0 = 0; idx0 < 64; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_g_a[idx0,idx1] = _o.G[idx0].A[idx1];}}
    var _g_b = new MyGame.Example.TestEnum[64];
    for (var idx0 = 0; idx0 < 64; ++idx0) {_g_b[idx0] = _o.G[idx0].B;}
    var _g_c = new MyGame.Example.TestEnum[64,2];
    for (var idx0 = 0; idx0 < 64; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_g_c[idx0,idx1] = _o.G[idx0].C[idx1];}}
    var _g_d = new long[64,2];
    for (var idx0 = 0; idx0 < 64; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_g_d[idx0,idx1] = _o.G[idx0].D[idx1];}}
    var _h = _o.H;
    return CreateLargeArrayStruct(
      builder,
      _d,
      _e,
      _f,
      _g_a,
      _g_b,
      _g_c,
      _g_d,
      _h);
  }
}

public class LargeArrayStructT
{
  [Newtonsoft.Json.JsonProperty("d")]
  public byte[] D { get; set; }
  [Newtonsoft.Json.JsonProperty("e")]
  public float[] E { get; set; }
  [Newtonsoft.Json.JsonProperty("f")]
  public bool[] F { get; set; }
  [Newtonsoft.Json.JsonProperty("g")]
  public MyGame.Example.NestedStructT[] G { get; set; }
  [Newtonsoft.Json.JsonProperty("h")]
  public MyGame.Example.TestEnum[] H { get; set; }

  public LargeArrayStructT() {
    this.D = new byte[64];
    this.E = new float[64];
    this.F = new bool[64];
    this.G = new MyGame.Example.NestedStructT[64];
    this.H = new MyGame.Example.TestEnum[64];
  }
}


}
