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

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

public struct Movie : IFlatbufferObject
{
  private Table __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_9_29(); }
  public static Movie GetRootAsMovie(ByteBuffer _bb) { return GetRootAsMovie(_bb, new Movie()); }
  public static Movie GetRootAsMovie(ByteBuffer _bb, Movie obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
  public static bool MovieBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MOVI"); }
  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
  public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public Character MainCharacterType { get { int o = __p.__offset(4); return o != 0 ? (Character)__p.bb.Get(o + __p.bb_pos) : Character.NONE; } }
  public TTable? MainCharacter<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
  public string MainCharacterAsString() { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; }
  public Attacker MainCharacterAsMuLan() { return MainCharacter<Attacker>().Value; }
  public Rapunzel MainCharacterAsRapunzel() { return MainCharacter<Rapunzel>().Value; }
  public BookReader MainCharacterAsBelle() { return MainCharacter<BookReader>().Value; }
  public BookReader MainCharacterAsBookFan() { return MainCharacter<BookReader>().Value; }
  public string MainCharacterAsOther() { return MainCharacterAsString(); }
  public string MainCharacterAsUnused() { return MainCharacterAsString(); }
  public Character CharactersType(int j) { int o = __p.__offset(8); return o != 0 ? (Character)__p.bb.Get(__p.__vector(o) + j * 1) : (Character)0; }
  public int CharactersTypeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<Character> GetCharactersTypeBytes() { return __p.__vector_as_span<Character>(8, 1); }
#else
  public ArraySegment<byte>? GetCharactersTypeBytes() { return __p.__vector_as_arraysegment(8); }
#endif
  public Character[] GetCharactersTypeArray() { int o = __p.__offset(8); if (o == 0) return null; int p = __p.__vector(o); int l = __p.__vector_len(o); Character[] a = new Character[l]; for (int i = 0; i < l; i++) { a[i] = (Character)__p.bb.Get(p + i * 1); } return a; }
  public TTable? Characters<TTable>(int j) where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(__p.__vector(o) + j * 4) : null; }
  public string CharactersAsString(int j) { int o = __p.__offset(10); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
  public int CharactersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }

  public static Offset<Movie> CreateMovie(FlatBufferBuilder builder,
      Character main_character_type = Character.NONE,
      int main_characterOffset = 0,
      VectorOffset characters_typeOffset = default(VectorOffset),
      VectorOffset charactersOffset = default(VectorOffset)) {
    builder.StartTable(4);
    Movie.AddCharacters(builder, charactersOffset);
    Movie.AddCharactersType(builder, characters_typeOffset);
    Movie.AddMainCharacter(builder, main_characterOffset);
    Movie.AddMainCharacterType(builder, main_character_type);
    return Movie.EndMovie(builder);
  }

  public static void StartMovie(FlatBufferBuilder builder) { builder.StartTable(4); }
  public static void AddMainCharacterType(FlatBufferBuilder builder, Character mainCharacterType) { builder.AddByte(0, (byte)mainCharacterType, 0); }
  public static void AddMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.AddOffset(1, mainCharacterOffset, 0); }
  public static void AddCharactersType(FlatBufferBuilder builder, VectorOffset charactersTypeOffset) { builder.AddOffset(2, charactersTypeOffset.Value, 0); }
  public static VectorOffset CreateCharactersTypeVector(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); }
  public static VectorOffset CreateCharactersTypeVectorBlock(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateCharactersTypeVectorBlock(FlatBufferBuilder builder, ArraySegment<Character> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateCharactersTypeVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Character>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartCharactersTypeVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
  public static void AddCharacters(FlatBufferBuilder builder, VectorOffset charactersOffset) { builder.AddOffset(3, charactersOffset.Value, 0); }
  public static VectorOffset CreateCharactersVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateCharactersVectorBlock(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateCharactersVectorBlock(FlatBufferBuilder builder, ArraySegment<int> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateCharactersVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<int>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartCharactersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static Offset<Movie> EndMovie(FlatBufferBuilder builder) {
    int o = builder.EndTable();
    return new Offset<Movie>(o);
  }
  public static void FinishMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.Finish(offset.Value, "MOVI"); }
  public static void FinishSizePrefixedMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.FinishSizePrefixed(offset.Value, "MOVI"); }
  public MovieT UnPack() {
    var _o = new MovieT();
    this.UnPackTo(_o);
    return _o;
  }
  public void UnPackTo(MovieT _o) {
    _o.MainCharacter = new CharacterUnion();
    _o.MainCharacter.Type = this.MainCharacterType;
    switch (this.MainCharacterType) {
      default: break;
      case Character.MuLan:
        _o.MainCharacter.Value = this.MainCharacter<Attacker>().HasValue ? this.MainCharacter<Attacker>().Value.UnPack() : null;
        break;
      case Character.Rapunzel:
        _o.MainCharacter.Value = this.MainCharacter<Rapunzel>().HasValue ? this.MainCharacter<Rapunzel>().Value.UnPack() : null;
        break;
      case Character.Belle:
        _o.MainCharacter.Value = this.MainCharacter<BookReader>().HasValue ? this.MainCharacter<BookReader>().Value.UnPack() : null;
        break;
      case Character.BookFan:
        _o.MainCharacter.Value = this.MainCharacter<BookReader>().HasValue ? this.MainCharacter<BookReader>().Value.UnPack() : null;
        break;
      case Character.Other:
        _o.MainCharacter.Value = this.MainCharacterAsString();
        break;
      case Character.Unused:
        _o.MainCharacter.Value = this.MainCharacterAsString();
        break;
    }
    _o.Characters = new List<CharacterUnion>();
    for (var _j = 0; _j < this.CharactersLength; ++_j) {
      var _o_Characters = new CharacterUnion();
      _o_Characters.Type = this.CharactersType(_j);
      switch (this.CharactersType(_j)) {
        default: break;
        case Character.MuLan:
          _o_Characters.Value = this.Characters<Attacker>(_j).HasValue ? this.Characters<Attacker>(_j).Value.UnPack() : null;
          break;
        case Character.Rapunzel:
          _o_Characters.Value = this.Characters<Rapunzel>(_j).HasValue ? this.Characters<Rapunzel>(_j).Value.UnPack() : null;
          break;
        case Character.Belle:
          _o_Characters.Value = this.Characters<BookReader>(_j).HasValue ? this.Characters<BookReader>(_j).Value.UnPack() : null;
          break;
        case Character.BookFan:
          _o_Characters.Value = this.Characters<BookReader>(_j).HasValue ? this.Characters<BookReader>(_j).Value.UnPack() : null;
          break;
        case Character.Other:
          _o_Characters.Value = this.CharactersAsString(_j);
          break;
        case Character.Unused:
          _o_Characters.Value = this.CharactersAsString(_j);
          break;
      }
      _o.Characters.Add(_o_Characters);
    }
  }
  public static Offset<Movie> Pack(FlatBufferBuilder builder, MovieT _o) {
    if (_o == null) return default(Offset<Movie>);
    var _main_character_type = _o.MainCharacter == null ? Character.NONE : _o.MainCharacter.Type;
    var _main_character = _o.MainCharacter == null ? 0 : CharacterUnion.Pack(builder, _o.MainCharacter);
    var _characters_type = default(VectorOffset);
    if (_o.Characters != null) {
      var __characters_type = new Character[_o.Characters.Count];
      for (var _j = 0; _j < __characters_type.Length; ++_j) { __characters_type[_j] = _o.Characters[_j].Type; }
      _characters_type = CreateCharactersTypeVector(builder, __characters_type);
    }
    var _characters = default(VectorOffset);
    if (_o.Characters != null) {
      var __characters = new int[_o.Characters.Count];
      for (var _j = 0; _j < __characters.Length; ++_j) { __characters[_j] = CharacterUnion.Pack(builder,  _o.Characters[_j]); }
      _characters = CreateCharactersVector(builder, __characters);
    }
    return CreateMovie(
      builder,
      _main_character_type,
      _main_character,
      _characters_type,
      _characters);
  }
}

public class MovieT
{
  [Newtonsoft.Json.JsonProperty("main_character_type")]
  private Character MainCharacterType {
    get {
      return this.MainCharacter != null ? this.MainCharacter.Type : Character.NONE;
    }
    set {
      this.MainCharacter = new CharacterUnion();
      this.MainCharacter.Type = value;
    }
  }
  [Newtonsoft.Json.JsonProperty("main_character")]
  [Newtonsoft.Json.JsonConverter(typeof(CharacterUnion_JsonConverter))]
  public CharacterUnion MainCharacter { get; set; }
  [Newtonsoft.Json.JsonProperty("characters_type")]
  private Character[] CharactersType {
    get {
      if (this.Characters == null) return null;
      var _o = new Character[this.Characters.Count];
      for (var _j = 0; _j < _o.Length; ++_j) { _o[_j] = this.Characters[_j].Type; }
      return _o;
    }
    set {
      this.Characters = new List<CharacterUnion>();
      for (var _j = 0; _j < value.Length; ++_j) {
        var _o = new CharacterUnion();
        _o.Type = value[_j];
        this.Characters.Add(_o);
      }
    }
  }
  [Newtonsoft.Json.JsonProperty("characters")]
  [Newtonsoft.Json.JsonConverter(typeof(CharacterUnion_JsonConverter))]
  public List<CharacterUnion> Characters { get; set; }

  public MovieT() {
    this.MainCharacter = null;
    this.Characters = null;
  }

  public static MovieT DeserializeFromJson(string jsonText) {
    return Newtonsoft.Json.JsonConvert.DeserializeObject<MovieT>(jsonText);
  }
  public string SerializeToJson() {
    return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
  }
  public static MovieT DeserializeFromBinary(byte[] fbBuffer) {
    return Movie.GetRootAsMovie(new ByteBuffer(fbBuffer)).UnPack();
  }
  public byte[] SerializeToBinary() {
    var fbb = new FlatBufferBuilder(0x10000);
    Movie.FinishMovieBuffer(fbb, Movie.Pack(fbb, this));
    return fbb.DataBuffer.ToSizedArray();
  }
}

