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

[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Gadget : byte
{
  NONE = 0,
  FallingTub = 1,
  HandFan = 2,
};

public class GadgetUnion {
  public Gadget Type { get; set; }
  public object Value { get; set; }

  public GadgetUnion() {
    this.Type = Gadget.NONE;
    this.Value = null;
  }

  public T As<T>() where T : class { return this.Value as T; }
  public FallingTubT AsFallingTub() { return this.As<FallingTubT>(); }
  public static GadgetUnion FromFallingTub(FallingTubT _fallingtub) { return new GadgetUnion{ Type = Gadget.FallingTub, Value = _fallingtub }; }
  public HandFanT AsHandFan() { return this.As<HandFanT>(); }
  public static GadgetUnion FromHandFan(HandFanT _handfan) { return new GadgetUnion{ Type = Gadget.HandFan, Value = _handfan }; }

  public static int Pack(Google.FlatBuffers.FlatBufferBuilder builder, GadgetUnion _o) {
    switch (_o.Type) {
      default: return 0;
      case Gadget.FallingTub: return FallingTub.Pack(builder, _o.AsFallingTub()).Value;
      case Gadget.HandFan: return HandFan.Pack(builder, _o.AsHandFan()).Value;
    }
  }
}

public class GadgetUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
  public override bool CanConvert(System.Type objectType) {
    return objectType == typeof(GadgetUnion) || objectType == typeof(System.Collections.Generic.List<GadgetUnion>);
  }
  public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) {
    var _olist = value as System.Collections.Generic.List<GadgetUnion>;
    if (_olist != null) {
      writer.WriteStartArray();
      foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); }
      writer.WriteEndArray();
    } else {
      this.WriteJson(writer, value as GadgetUnion, serializer);
    }
  }
  public void WriteJson(Newtonsoft.Json.JsonWriter writer, GadgetUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
    if (_o == null) return;
    serializer.Serialize(writer, _o.Value);
  }
  public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) {
    var _olist = existingValue as System.Collections.Generic.List<GadgetUnion>;
    if (_olist != null) {
      for (var _j = 0; _j < _olist.Count; ++_j) {
        reader.Read();
        _olist[_j] = this.ReadJson(reader, _olist[_j], serializer);
      }
      reader.Read();
      return _olist;
    } else {
      return this.ReadJson(reader, existingValue as GadgetUnion, serializer);
    }
  }
  public GadgetUnion ReadJson(Newtonsoft.Json.JsonReader reader, GadgetUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
    if (_o == null) return null;
    switch (_o.Type) {
      default: break;
      case Gadget.FallingTub: _o.Value = serializer.Deserialize<FallingTubT>(reader); break;
      case Gadget.HandFan: _o.Value = serializer.Deserialize<HandFanT>(reader); break;
    }
    return _o;
  }
}

