// <auto-generated/>
// ReSharper disable All

namespace MyTelegram.Schema;

///<summary>
/// Info about a group call participant
/// See <a href="https://corefork.telegram.org/constructor/groupCallParticipant" />
///</summary>
[TlObject(0xeba636fe)]
public sealed class TGroupCallParticipant : IGroupCallParticipant
{
    public uint ConstructorId => 0xeba636fe;
    ///<summary>
    /// Flags, see <a href="https://corefork.telegram.org/mtproto/TL-combinators#conditional-fields">TL conditional fields</a>
    ///</summary>
    public int Flags { get; set; }

    ///<summary>
    /// Whether the participant is muted
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Muted { get; set; }

    ///<summary>
    /// Whether the participant has left
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Left { get; set; }

    ///<summary>
    /// Whether the participant can unmute themselves
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool CanSelfUnmute { get; set; }

    ///<summary>
    /// Whether the participant has just joined
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool JustJoined { get; set; }

    ///<summary>
    /// If set, and <a href="https://corefork.telegram.org/constructor/updateGroupCallParticipants">updateGroupCallParticipants</a>.version &lt; locally stored call.version, info about this participant should be ignored. If (...), and <a href="https://corefork.telegram.org/constructor/updateGroupCallParticipants">updateGroupCallParticipants</a>.version &gt; call.version+1, the participant list should be refetched using <a href="https://corefork.telegram.org/method/phone.getGroupParticipants">phone.getGroupParticipants</a>.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Versioned { get; set; }

    ///<summary>
    /// If not set, the <code>volume</code> and <code>muted_by_you</code> fields can be safely used to overwrite locally cached information; otherwise, <code>volume</code> will contain valid information only if <code>volume_by_admin</code> is set both in the cache and in the received constructor.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Min { get; set; }

    ///<summary>
    /// Whether this participant was muted by the current user
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool MutedByYou { get; set; }

    ///<summary>
    /// Whether our volume can only changed by an admin
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool VolumeByAdmin { get; set; }

    ///<summary>
    /// Whether this participant is the current user
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Self { get; set; }

    ///<summary>
    /// Whether this participant is currently broadcasting video
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool VideoJoined { get; set; }

    ///<summary>
    /// Peer information
    /// See <a href="https://corefork.telegram.org/type/Peer" />
    ///</summary>
    public MyTelegram.Schema.IPeer Peer { get; set; }

    ///<summary>
    /// When did this participant join the group call
    ///</summary>
    public int Date { get; set; }

    ///<summary>
    /// When was this participant last active in the group call
    ///</summary>
    public int? ActiveDate { get; set; }

    ///<summary>
    /// Source ID
    ///</summary>
    public int Source { get; set; }

    ///<summary>
    /// Volume, if not set the volume is set to 100%.
    ///</summary>
    public int? Volume { get; set; }

    ///<summary>
    /// Info about this participant
    ///</summary>
    public string? About { get; set; }

    ///<summary>
    /// Specifies the UI visualization order of peers with raised hands: peers with a higher rating should be showed first in the list.
    ///</summary>
    public long? RaiseHandRating { get; set; }

    ///<summary>
    /// Info about the video stream the participant is currently broadcasting
    /// See <a href="https://corefork.telegram.org/type/GroupCallParticipantVideo" />
    ///</summary>
    public MyTelegram.Schema.IGroupCallParticipantVideo? Video { get; set; }

    ///<summary>
    /// Info about the screen sharing stream the participant is currently broadcasting
    /// See <a href="https://corefork.telegram.org/type/GroupCallParticipantVideo" />
    ///</summary>
    public MyTelegram.Schema.IGroupCallParticipantVideo? Presentation { get; set; }

    public void ComputeFlag()
    {
        if (Muted) { Flags = Flags.SetBit(0); }
        if (Left) { Flags = Flags.SetBit(1); }
        if (CanSelfUnmute) { Flags = Flags.SetBit(2); }
        if (JustJoined) { Flags = Flags.SetBit(4); }
        if (Versioned) { Flags = Flags.SetBit(5); }
        if (Min) { Flags = Flags.SetBit(8); }
        if (MutedByYou) { Flags = Flags.SetBit(9); }
        if (VolumeByAdmin) { Flags = Flags.SetBit(10); }
        if (Self) { Flags = Flags.SetBit(12); }
        if (VideoJoined) { Flags = Flags.SetBit(15); }
        if (/*ActiveDate != 0 && */ActiveDate.HasValue) { Flags = Flags.SetBit(3); }
        if (/*Volume != 0 && */Volume.HasValue) { Flags = Flags.SetBit(7); }
        if (About != null) { Flags = Flags.SetBit(11); }
        if (/*RaiseHandRating != 0 &&*/ RaiseHandRating.HasValue) { Flags = Flags.SetBit(13); }
        if (Video != null) { Flags = Flags.SetBit(6); }
        if (Presentation != null) { Flags = Flags.SetBit(14); }
    }

    public void Serialize(IBufferWriter<byte> writer)
    {
        ComputeFlag();
        writer.Write(ConstructorId);
        writer.Write(Flags);
        writer.Write(Peer);
        writer.Write(Date);
        if (Flags.IsBitSet(3)) { writer.Write(ActiveDate.Value); }
        writer.Write(Source);
        if (Flags.IsBitSet(7)) { writer.Write(Volume.Value); }
        if (Flags.IsBitSet(11)) { writer.Write(About); }
        if (Flags.IsBitSet(13)) { writer.Write(RaiseHandRating.Value); }
        if (Flags.IsBitSet(6)) { writer.Write(Video); }
        if (Flags.IsBitSet(14)) { writer.Write(Presentation); }
    }

    public void Deserialize(ref ReadOnlyMemory<byte> buffer)
    {
        Flags = buffer.ReadInt32();
        if (Flags.IsBitSet(0)) { Muted = true; }
        if (Flags.IsBitSet(1)) { Left = true; }
        if (Flags.IsBitSet(2)) { CanSelfUnmute = true; }
        if (Flags.IsBitSet(4)) { JustJoined = true; }
        if (Flags.IsBitSet(5)) { Versioned = true; }
        if (Flags.IsBitSet(8)) { Min = true; }
        if (Flags.IsBitSet(9)) { MutedByYou = true; }
        if (Flags.IsBitSet(10)) { VolumeByAdmin = true; }
        if (Flags.IsBitSet(12)) { Self = true; }
        if (Flags.IsBitSet(15)) { VideoJoined = true; }
        Peer = buffer.Read<MyTelegram.Schema.IPeer>();
        Date = buffer.ReadInt32();
        if (Flags.IsBitSet(3)) { ActiveDate = buffer.ReadInt32(); }
        Source = buffer.ReadInt32();
        if (Flags.IsBitSet(7)) { Volume = buffer.ReadInt32(); }
        if (Flags.IsBitSet(11)) { About = buffer.ReadString(); }
        if (Flags.IsBitSet(13)) { RaiseHandRating = buffer.ReadInt64(); }
        if (Flags.IsBitSet(6)) { Video = buffer.Read<MyTelegram.Schema.IGroupCallParticipantVideo>(); }
        if (Flags.IsBitSet(14)) { Presentation = buffer.Read<MyTelegram.Schema.IGroupCallParticipantVideo>(); }
    }
}