//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//
//       bebopc version:
//           2.3.1
//
//
//       bebopc source:
//           https://github.com/RainwayApp/bebop
//
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
import { BebopView, BebopRuntimeError } from "bebop";

export interface IWordId {
  clientId: bigint;
  counter: bigint;
}

export const WordId = {
  encode(message: IWordId): Uint8Array {
    const view = BebopView.getInstance();
    view.startWriting();
    this.encodeInto(message, view);
    return view.toArray();
  },

  encodeInto(message: IWordId, view: BebopView): number {
    const before = view.length;
      view.writeUint64(message.clientId);
      view.writeUint64(message.counter);
    const after = view.length;
    return after - before;
  },

  decode(buffer: Uint8Array): IWordId {
    const view = BebopView.getInstance();
    view.startReading(buffer);
    return this.readFrom(view);
  },

  readFrom(view: BebopView): IWordId {
    let field0: bigint;
    field0 = view.readUint64();
    let field1: bigint;
    field1 = view.readUint64();
    let message: IWordId = {
      clientId: field0,
      counter: field1,
    };
    return message;
  },
};

export interface IVersion {
  counter: bigint;
  clientId: bigint;
}

export const Version = {
  encode(message: IVersion): Uint8Array {
    const view = BebopView.getInstance();
    view.startWriting();
    this.encodeInto(message, view);
    return view.toArray();
  },

  encodeInto(message: IVersion, view: BebopView): number {
    const before = view.length;
      view.writeUint64(message.counter);
      view.writeUint64(message.clientId);
    const after = view.length;
    return after - before;
  },

  decode(buffer: Uint8Array): IVersion {
    const view = BebopView.getInstance();
    view.startReading(buffer);
    return this.readFrom(view);
  },

  readFrom(view: BebopView): IVersion {
    let field0: bigint;
    field0 = view.readUint64();
    let field1: bigint;
    field1 = view.readUint64();
    let message: IVersion = {
      counter: field0,
      clientId: field1,
    };
    return message;
  },
};

export interface IWord {
  wordId: IWordId;
  version: IVersion;
  letters: string;
  links: ILinks;
}

export const Word = {
  encode(message: IWord): Uint8Array {
    const view = BebopView.getInstance();
    view.startWriting();
    this.encodeInto(message, view);
    return view.toArray();
  },

  encodeInto(message: IWord, view: BebopView): number {
    const before = view.length;
      WordId.encodeInto(message.wordId, view)
      Version.encodeInto(message.version, view)
      view.writeString(message.letters);
      Links.encodeInto(message.links, view)
    const after = view.length;
    return after - before;
  },

  decode(buffer: Uint8Array): IWord {
    const view = BebopView.getInstance();
    view.startReading(buffer);
    return this.readFrom(view);
  },

  readFrom(view: BebopView): IWord {
    let field0: IWordId;
    field0 = WordId.readFrom(view);
    let field1: IVersion;
    field1 = Version.readFrom(view);
    let field2: string;
    field2 = view.readString();
    let field3: ILinks;
    field3 = Links.readFrom(view);
    let message: IWord = {
      wordId: field0,
      version: field1,
      letters: field2,
      links: field3,
    };
    return message;
  },
};

export interface ILinks {
  previous?: IWordId;
  next?: IWordId;
}

export const Links = {
  encode(message: ILinks): Uint8Array {
    const view = BebopView.getInstance();
    view.startWriting();
    this.encodeInto(message, view);
    return view.toArray();
  },

  encodeInto(message: ILinks, view: BebopView): number {
    const before = view.length;
      const pos = view.reserveMessageLength();
      const start = view.length;
      if (message.previous != null) {
        view.writeByte(1);
        WordId.encodeInto(message.previous, view)
      }
      if (message.next != null) {
        view.writeByte(2);
        WordId.encodeInto(message.next, view)
      }
      view.writeByte(0);
      const end = view.length;
      view.fillMessageLength(pos, end - start);
    const after = view.length;
    return after - before;
  },

  decode(buffer: Uint8Array): ILinks {
    const view = BebopView.getInstance();
    view.startReading(buffer);
    return this.readFrom(view);
  },

  readFrom(view: BebopView): ILinks {
    let message: ILinks = {};
    const length = view.readMessageLength();
    const end = view.index + length;
    while (true) {
      switch (view.readByte()) {
        case 0:
          return message;

        case 1:
          message.previous = WordId.readFrom(view);
          break;

        case 2:
          message.next = WordId.readFrom(view);
          break;

        default:
          view.index = end;
          return message;
      }
    }
  },
};

export interface IMessage {
  updates?: Array<IWord>;
  undo?: boolean;
  redo?: boolean;
}

export const Message = {
  encode(message: IMessage): Uint8Array {
    const view = BebopView.getInstance();
    view.startWriting();
    this.encodeInto(message, view);
    return view.toArray();
  },

  encodeInto(message: IMessage, view: BebopView): number {
    const before = view.length;
      const pos = view.reserveMessageLength();
      const start = view.length;
      if (message.updates != null) {
        view.writeByte(1);
        {
        const length0 = message.updates.length;
        view.writeUint32(length0);
        for (let i0 = 0; i0 < length0; i0++) {
          Word.encodeInto(message.updates[i0], view)
        }
      }
      }
      if (message.undo != null) {
        view.writeByte(2);
        view.writeByte(Number(message.undo));
      }
      if (message.redo != null) {
        view.writeByte(3);
        view.writeByte(Number(message.redo));
      }
      view.writeByte(0);
      const end = view.length;
      view.fillMessageLength(pos, end - start);
    const after = view.length;
    return after - before;
  },

  decode(buffer: Uint8Array): IMessage {
    const view = BebopView.getInstance();
    view.startReading(buffer);
    return this.readFrom(view);
  },

  readFrom(view: BebopView): IMessage {
    let message: IMessage = {};
    const length = view.readMessageLength();
    const end = view.index + length;
    while (true) {
      switch (view.readByte()) {
        case 0:
          return message;

        case 1:
          {
        let length0 = view.readUint32();
        message.updates = new Array<IWord>(length0);
        for (let i0 = 0; i0 < length0; i0++) {
          let x0: IWord;
          x0 = Word.readFrom(view);
          message.updates[i0] = x0;
        }
      }
          break;

        case 2:
          message.undo = !!view.readByte();
          break;

        case 3:
          message.redo = !!view.readByte();
          break;

        default:
          view.index = end;
          return message;
      }
    }
  },
};

