// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any,
 * @typescript-eslint/no-non-null-assertion */
import * as flatbuffers from 'flatbuffers';

import {Character, unionListToCharacter, unionToCharacter} from './character.js';

export class Movie {
  constructor() {
    this.bb = null;
    this.bb_pos = 0;
  }
  __init(i, bb) {
    this.bb_pos = i;
    this.bb = bb;
    return this;
  }
  static getRootAsMovie(bb, obj) {
    return (obj || new Movie())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static getSizePrefixedRootAsMovie(bb, obj) {
    bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
    return (obj || new Movie())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static bufferHasIdentifier(bb) {
    return bb.__has_identifier('MOVI');
  }
  mainCharacterType() {
    const offset = this.bb.__offset(this.bb_pos, 4);
    return offset ? this.bb.readUint8(this.bb_pos + offset) : Character.NONE;
  }
  mainCharacter(obj) {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ? this.bb.__union_with_string(obj, this.bb_pos + offset) :
                    null;
  }
  charactersType(index) {
    const offset = this.bb.__offset(this.bb_pos, 8);
    return offset ?
        this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) :
        null;
  }
  charactersTypeLength() {
    const offset = this.bb.__offset(this.bb_pos, 8);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  charactersTypeArray() {
    const offset = this.bb.__offset(this.bb_pos, 8);
    return offset ?
        new Uint8Array(
            this.bb.bytes().buffer,
            this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset),
            this.bb.__vector_len(this.bb_pos + offset)) :
        null;
  }
  characters(index, obj) {
    const offset = this.bb.__offset(this.bb_pos, 10);
    return offset ?
        this.bb.__union_with_string(
            obj, this.bb.__vector(this.bb_pos + offset) + index * 4) :
        null;
  }
  charactersLength() {
    const offset = this.bb.__offset(this.bb_pos, 10);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  static getFullyQualifiedName() {
    return 'Movie';
  }
  static startMovie(builder) {
    builder.startObject(4);
  }
  static addMainCharacterType(builder, mainCharacterType) {
    builder.addFieldInt8(0, mainCharacterType, Character.NONE);
  }
  static addMainCharacter(builder, mainCharacterOffset) {
    builder.addFieldOffset(1, mainCharacterOffset, 0);
  }
  static addCharactersType(builder, charactersTypeOffset) {
    builder.addFieldOffset(2, charactersTypeOffset, 0);
  }
  static createCharactersTypeVector(builder, data) {
    builder.startVector(1, data.length, 1);
    for (let i = data.length - 1; i >= 0; i--) {
      builder.addInt8(data[i]);
    }
    return builder.endVector();
  }
  static startCharactersTypeVector(builder, numElems) {
    builder.startVector(1, numElems, 1);
  }
  static addCharacters(builder, charactersOffset) {
    builder.addFieldOffset(3, charactersOffset, 0);
  }
  static createCharactersVector(builder, data) {
    builder.startVector(4, data.length, 4);
    for (let i = data.length - 1; i >= 0; i--) {
      builder.addOffset(data[i]);
    }
    return builder.endVector();
  }
  static startCharactersVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static endMovie(builder) {
    const offset = builder.endObject();
    return offset;
  }
  static finishMovieBuffer(builder, offset) {
    builder.finish(offset, 'MOVI');
  }
  static finishSizePrefixedMovieBuffer(builder, offset) {
    builder.finish(offset, 'MOVI', true);
  }
  static createMovie(
      builder, mainCharacterType, mainCharacterOffset, charactersTypeOffset,
      charactersOffset) {
    Movie.startMovie(builder);
    Movie.addMainCharacterType(builder, mainCharacterType);
    Movie.addMainCharacter(builder, mainCharacterOffset);
    Movie.addCharactersType(builder, charactersTypeOffset);
    Movie.addCharacters(builder, charactersOffset);
    return Movie.endMovie(builder);
  }
  unpack() {
    return new MovieT(
        this.mainCharacterType(), (() => {
          const temp = unionToCharacter(
              this.mainCharacterType(), this.mainCharacter.bind(this));
          if (temp === null) {
            return null;
          }
          if (typeof temp === 'string') {
            return temp;
          }
          return temp.unpack();
        })(),
        this.bb.createScalarList(
            this.charactersType.bind(this), this.charactersTypeLength()),
        (() => {
          const ret = [];
          for (let targetEnumIndex = 0;
               targetEnumIndex < this.charactersTypeLength();
               ++targetEnumIndex) {
            const targetEnum = this.charactersType(targetEnumIndex);
            if (targetEnum === null || Character[targetEnum] === 'NONE') {
              continue;
            }
            const temp = unionListToCharacter(
                targetEnum, this.characters.bind(this), targetEnumIndex);
            if (temp === null) {
              continue;
            }
            if (typeof temp === 'string') {
              ret.push(temp);
              continue;
            }
            ret.push(temp.unpack());
          }
          return ret;
        })());
  }
  unpackTo(_o) {
    _o.mainCharacterType = this.mainCharacterType();
    _o.mainCharacter = (() => {
      const temp = unionToCharacter(
          this.mainCharacterType(), this.mainCharacter.bind(this));
      if (temp === null) {
        return null;
      }
      if (typeof temp === 'string') {
        return temp;
      }
      return temp.unpack();
    })();
    _o.charactersType = this.bb.createScalarList(
        this.charactersType.bind(this), this.charactersTypeLength());
    _o.characters = (() => {
      const ret = [];
      for (let targetEnumIndex = 0;
           targetEnumIndex < this.charactersTypeLength(); ++targetEnumIndex) {
        const targetEnum = this.charactersType(targetEnumIndex);
        if (targetEnum === null || Character[targetEnum] === 'NONE') {
          continue;
        }
        const temp = unionListToCharacter(
            targetEnum, this.characters.bind(this), targetEnumIndex);
        if (temp === null) {
          continue;
        }
        if (typeof temp === 'string') {
          ret.push(temp);
          continue;
        }
        ret.push(temp.unpack());
      }
      return ret;
    })();
  }
}
export class MovieT {
  constructor(
      mainCharacterType = Character.NONE, mainCharacter = null,
      charactersType = [], characters = []) {
    this.mainCharacterType = mainCharacterType;
    this.mainCharacter = mainCharacter;
    this.charactersType = charactersType;
    this.characters = characters;
  }
  pack(builder) {
    const mainCharacter = builder.createObjectOffset(this.mainCharacter);
    const charactersType =
        Movie.createCharactersTypeVector(builder, this.charactersType);
    const characters = Movie.createCharactersVector(
        builder, builder.createObjectOffsetList(this.characters));
    return Movie.createMovie(
        builder, this.mainCharacterType, mainCharacter, charactersType,
        characters);
  }
}
