package tg

import (
	"context"
	"fmt"
	"strings"

	"github.com/gotd/td/bin"
)

var _ = bin.Buffer{}
var _ = context.Background()
var _ = fmt.Stringer(nil)
var _ = strings.Builder{}

type MessageMediaEmpty struct {
}

const MessageMediaEmptyTypeID = 0x3ded6320

func (m *MessageMediaEmpty) String() string {
	if m == nil {
		return "MessageMediaEmpty(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaEmpty")
	sb.WriteString("{\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaEmpty) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaEmpty#3ded6320 as nil")
	}
	b.PutID(MessageMediaEmptyTypeID)
	return nil
}

func (m *MessageMediaEmpty) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaEmpty#3ded6320 to nil")
	}
	if err := b.ConsumeID(MessageMediaEmptyTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaEmpty#3ded6320: %w", err)
	}
	return nil
}

func (m MessageMediaEmpty) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaEmpty{}
	_ bin.Decoder = &MessageMediaEmpty{}

	_ MessageMediaClass = &MessageMediaEmpty{}
)

type MessageMediaPhoto struct {

	Flags bin.Fields

	Photo PhotoClass

	TTLSeconds int
}

const MessageMediaPhotoTypeID = 0x695150d7

func (m *MessageMediaPhoto) String() string {
	if m == nil {
		return "MessageMediaPhoto(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaPhoto")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tPhoto: ")
		sb.WriteString(fmt.Sprint(m.Photo))
		sb.WriteString(",\n")
	}
	if m.Flags.Has(2) {
		sb.WriteString("\tTTLSeconds: ")
		sb.WriteString(fmt.Sprint(m.TTLSeconds))
		sb.WriteString(",\n")
	}
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaPhoto) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaPhoto#695150d7 as nil")
	}
	b.PutID(MessageMediaPhotoTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaPhoto#695150d7: field flags: %w", err)
	}
	if m.Flags.Has(0) {
		if m.Photo == nil {
			return fmt.Errorf("unable to encode messageMediaPhoto#695150d7: field photo is nil")
		}
		if err := m.Photo.Encode(b); err != nil {
			return fmt.Errorf("unable to encode messageMediaPhoto#695150d7: field photo: %w", err)
		}
	}
	if m.Flags.Has(2) {
		b.PutInt(m.TTLSeconds)
	}
	return nil
}

func (m *MessageMediaPhoto) SetPhoto(value PhotoClass) {
	m.Flags.Set(0)
	m.Photo = value
}

func (m *MessageMediaPhoto) GetPhoto() (value PhotoClass, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Photo, true
}

func (m *MessageMediaPhoto) SetTTLSeconds(value int) {
	m.Flags.Set(2)
	m.TTLSeconds = value
}

func (m *MessageMediaPhoto) GetTTLSeconds() (value int, ok bool) {
	if !m.Flags.Has(2) {
		return value, false
	}
	return m.TTLSeconds, true
}

func (m *MessageMediaPhoto) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaPhoto#695150d7 to nil")
	}
	if err := b.ConsumeID(MessageMediaPhotoTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: field flags: %w", err)
		}
	}
	if m.Flags.Has(0) {
		value, err := DecodePhoto(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: field photo: %w", err)
		}
		m.Photo = value
	}
	if m.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: field ttl_seconds: %w", err)
		}
		m.TTLSeconds = value
	}
	return nil
}

func (m MessageMediaPhoto) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaPhoto{}
	_ bin.Decoder = &MessageMediaPhoto{}

	_ MessageMediaClass = &MessageMediaPhoto{}
)

type MessageMediaGeo struct {

	Geo GeoPointClass
}

const MessageMediaGeoTypeID = 0x56e0d474

func (m *MessageMediaGeo) String() string {
	if m == nil {
		return "MessageMediaGeo(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaGeo")
	sb.WriteString("{\n")
	sb.WriteString("\tGeo: ")
	sb.WriteString(fmt.Sprint(m.Geo))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaGeo) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaGeo#56e0d474 as nil")
	}
	b.PutID(MessageMediaGeoTypeID)
	if m.Geo == nil {
		return fmt.Errorf("unable to encode messageMediaGeo#56e0d474: field geo is nil")
	}
	if err := m.Geo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGeo#56e0d474: field geo: %w", err)
	}
	return nil
}

func (m *MessageMediaGeo) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaGeo#56e0d474 to nil")
	}
	if err := b.ConsumeID(MessageMediaGeoTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaGeo#56e0d474: %w", err)
	}
	{
		value, err := DecodeGeoPoint(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeo#56e0d474: field geo: %w", err)
		}
		m.Geo = value
	}
	return nil
}

func (m MessageMediaGeo) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaGeo{}
	_ bin.Decoder = &MessageMediaGeo{}

	_ MessageMediaClass = &MessageMediaGeo{}
)

type MessageMediaContact struct {

	PhoneNumber string

	FirstName string

	LastName string

	Vcard string

	UserID int
}

const MessageMediaContactTypeID = 0xcbf24940

func (m *MessageMediaContact) String() string {
	if m == nil {
		return "MessageMediaContact(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaContact")
	sb.WriteString("{\n")
	sb.WriteString("\tPhoneNumber: ")
	sb.WriteString(fmt.Sprint(m.PhoneNumber))
	sb.WriteString(",\n")
	sb.WriteString("\tFirstName: ")
	sb.WriteString(fmt.Sprint(m.FirstName))
	sb.WriteString(",\n")
	sb.WriteString("\tLastName: ")
	sb.WriteString(fmt.Sprint(m.LastName))
	sb.WriteString(",\n")
	sb.WriteString("\tVcard: ")
	sb.WriteString(fmt.Sprint(m.Vcard))
	sb.WriteString(",\n")
	sb.WriteString("\tUserID: ")
	sb.WriteString(fmt.Sprint(m.UserID))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaContact) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaContact#cbf24940 as nil")
	}
	b.PutID(MessageMediaContactTypeID)
	b.PutString(m.PhoneNumber)
	b.PutString(m.FirstName)
	b.PutString(m.LastName)
	b.PutString(m.Vcard)
	b.PutInt(m.UserID)
	return nil
}

func (m *MessageMediaContact) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaContact#cbf24940 to nil")
	}
	if err := b.ConsumeID(MessageMediaContactTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaContact#cbf24940: %w", err)
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field phone_number: %w", err)
		}
		m.PhoneNumber = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field first_name: %w", err)
		}
		m.FirstName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field last_name: %w", err)
		}
		m.LastName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field vcard: %w", err)
		}
		m.Vcard = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field user_id: %w", err)
		}
		m.UserID = value
	}
	return nil
}

func (m MessageMediaContact) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaContact{}
	_ bin.Decoder = &MessageMediaContact{}

	_ MessageMediaClass = &MessageMediaContact{}
)

type MessageMediaUnsupported struct {
}

const MessageMediaUnsupportedTypeID = 0x9f84f49e

func (m *MessageMediaUnsupported) String() string {
	if m == nil {
		return "MessageMediaUnsupported(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaUnsupported")
	sb.WriteString("{\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaUnsupported) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaUnsupported#9f84f49e as nil")
	}
	b.PutID(MessageMediaUnsupportedTypeID)
	return nil
}

func (m *MessageMediaUnsupported) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaUnsupported#9f84f49e to nil")
	}
	if err := b.ConsumeID(MessageMediaUnsupportedTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaUnsupported#9f84f49e: %w", err)
	}
	return nil
}

func (m MessageMediaUnsupported) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaUnsupported{}
	_ bin.Decoder = &MessageMediaUnsupported{}

	_ MessageMediaClass = &MessageMediaUnsupported{}
)

type MessageMediaDocument struct {

	Flags bin.Fields

	Document DocumentClass

	TTLSeconds int
}

const MessageMediaDocumentTypeID = 0x9cb070d7

func (m *MessageMediaDocument) String() string {
	if m == nil {
		return "MessageMediaDocument(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaDocument")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tDocument: ")
		sb.WriteString(fmt.Sprint(m.Document))
		sb.WriteString(",\n")
	}
	if m.Flags.Has(2) {
		sb.WriteString("\tTTLSeconds: ")
		sb.WriteString(fmt.Sprint(m.TTLSeconds))
		sb.WriteString(",\n")
	}
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaDocument) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaDocument#9cb070d7 as nil")
	}
	b.PutID(MessageMediaDocumentTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaDocument#9cb070d7: field flags: %w", err)
	}
	if m.Flags.Has(0) {
		if m.Document == nil {
			return fmt.Errorf("unable to encode messageMediaDocument#9cb070d7: field document is nil")
		}
		if err := m.Document.Encode(b); err != nil {
			return fmt.Errorf("unable to encode messageMediaDocument#9cb070d7: field document: %w", err)
		}
	}
	if m.Flags.Has(2) {
		b.PutInt(m.TTLSeconds)
	}
	return nil
}

func (m *MessageMediaDocument) SetDocument(value DocumentClass) {
	m.Flags.Set(0)
	m.Document = value
}

func (m *MessageMediaDocument) GetDocument() (value DocumentClass, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Document, true
}

func (m *MessageMediaDocument) SetTTLSeconds(value int) {
	m.Flags.Set(2)
	m.TTLSeconds = value
}

func (m *MessageMediaDocument) GetTTLSeconds() (value int, ok bool) {
	if !m.Flags.Has(2) {
		return value, false
	}
	return m.TTLSeconds, true
}

func (m *MessageMediaDocument) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaDocument#9cb070d7 to nil")
	}
	if err := b.ConsumeID(MessageMediaDocumentTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: field flags: %w", err)
		}
	}
	if m.Flags.Has(0) {
		value, err := DecodeDocument(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: field document: %w", err)
		}
		m.Document = value
	}
	if m.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: field ttl_seconds: %w", err)
		}
		m.TTLSeconds = value
	}
	return nil
}

func (m MessageMediaDocument) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaDocument{}
	_ bin.Decoder = &MessageMediaDocument{}

	_ MessageMediaClass = &MessageMediaDocument{}
)

type MessageMediaWebPage struct {

	Webpage WebPageClass
}

const MessageMediaWebPageTypeID = 0xa32dd600

func (m *MessageMediaWebPage) String() string {
	if m == nil {
		return "MessageMediaWebPage(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaWebPage")
	sb.WriteString("{\n")
	sb.WriteString("\tWebpage: ")
	sb.WriteString(fmt.Sprint(m.Webpage))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaWebPage) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaWebPage#a32dd600 as nil")
	}
	b.PutID(MessageMediaWebPageTypeID)
	if m.Webpage == nil {
		return fmt.Errorf("unable to encode messageMediaWebPage#a32dd600: field webpage is nil")
	}
	if err := m.Webpage.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaWebPage#a32dd600: field webpage: %w", err)
	}
	return nil
}

func (m *MessageMediaWebPage) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaWebPage#a32dd600 to nil")
	}
	if err := b.ConsumeID(MessageMediaWebPageTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaWebPage#a32dd600: %w", err)
	}
	{
		value, err := DecodeWebPage(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaWebPage#a32dd600: field webpage: %w", err)
		}
		m.Webpage = value
	}
	return nil
}

func (m MessageMediaWebPage) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaWebPage{}
	_ bin.Decoder = &MessageMediaWebPage{}

	_ MessageMediaClass = &MessageMediaWebPage{}
)

type MessageMediaVenue struct {

	Geo GeoPointClass

	Title string

	Address string

	Provider string

	VenueID string

	VenueType string
}

const MessageMediaVenueTypeID = 0x2ec0533f

func (m *MessageMediaVenue) String() string {
	if m == nil {
		return "MessageMediaVenue(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaVenue")
	sb.WriteString("{\n")
	sb.WriteString("\tGeo: ")
	sb.WriteString(fmt.Sprint(m.Geo))
	sb.WriteString(",\n")
	sb.WriteString("\tTitle: ")
	sb.WriteString(fmt.Sprint(m.Title))
	sb.WriteString(",\n")
	sb.WriteString("\tAddress: ")
	sb.WriteString(fmt.Sprint(m.Address))
	sb.WriteString(",\n")
	sb.WriteString("\tProvider: ")
	sb.WriteString(fmt.Sprint(m.Provider))
	sb.WriteString(",\n")
	sb.WriteString("\tVenueID: ")
	sb.WriteString(fmt.Sprint(m.VenueID))
	sb.WriteString(",\n")
	sb.WriteString("\tVenueType: ")
	sb.WriteString(fmt.Sprint(m.VenueType))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaVenue) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaVenue#2ec0533f as nil")
	}
	b.PutID(MessageMediaVenueTypeID)
	if m.Geo == nil {
		return fmt.Errorf("unable to encode messageMediaVenue#2ec0533f: field geo is nil")
	}
	if err := m.Geo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaVenue#2ec0533f: field geo: %w", err)
	}
	b.PutString(m.Title)
	b.PutString(m.Address)
	b.PutString(m.Provider)
	b.PutString(m.VenueID)
	b.PutString(m.VenueType)
	return nil
}

func (m *MessageMediaVenue) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaVenue#2ec0533f to nil")
	}
	if err := b.ConsumeID(MessageMediaVenueTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: %w", err)
	}
	{
		value, err := DecodeGeoPoint(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field geo: %w", err)
		}
		m.Geo = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field title: %w", err)
		}
		m.Title = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field address: %w", err)
		}
		m.Address = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field provider: %w", err)
		}
		m.Provider = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field venue_id: %w", err)
		}
		m.VenueID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field venue_type: %w", err)
		}
		m.VenueType = value
	}
	return nil
}

func (m MessageMediaVenue) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaVenue{}
	_ bin.Decoder = &MessageMediaVenue{}

	_ MessageMediaClass = &MessageMediaVenue{}
)

type MessageMediaGame struct {

	Game Game
}

const MessageMediaGameTypeID = 0xfdb19008

func (m *MessageMediaGame) String() string {
	if m == nil {
		return "MessageMediaGame(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaGame")
	sb.WriteString("{\n")
	sb.WriteString("\tGame: ")
	sb.WriteString(fmt.Sprint(m.Game))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaGame) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaGame#fdb19008 as nil")
	}
	b.PutID(MessageMediaGameTypeID)
	if err := m.Game.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGame#fdb19008: field game: %w", err)
	}
	return nil
}

func (m *MessageMediaGame) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaGame#fdb19008 to nil")
	}
	if err := b.ConsumeID(MessageMediaGameTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaGame#fdb19008: %w", err)
	}
	{
		if err := m.Game.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaGame#fdb19008: field game: %w", err)
		}
	}
	return nil
}

func (m MessageMediaGame) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaGame{}
	_ bin.Decoder = &MessageMediaGame{}

	_ MessageMediaClass = &MessageMediaGame{}
)

type MessageMediaInvoice struct {

	Flags bin.Fields

	ShippingAddressRequested bool

	Test bool

	Title string

	Description string

	Photo WebDocumentClass

	ReceiptMsgID int

	Currency string

	TotalAmount int64

	StartParam string
}

const MessageMediaInvoiceTypeID = 0x84551347

func (m *MessageMediaInvoice) String() string {
	if m == nil {
		return "MessageMediaInvoice(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaInvoice")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	sb.WriteString("\tTitle: ")
	sb.WriteString(fmt.Sprint(m.Title))
	sb.WriteString(",\n")
	sb.WriteString("\tDescription: ")
	sb.WriteString(fmt.Sprint(m.Description))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tPhoto: ")
		sb.WriteString(fmt.Sprint(m.Photo))
		sb.WriteString(",\n")
	}
	if m.Flags.Has(2) {
		sb.WriteString("\tReceiptMsgID: ")
		sb.WriteString(fmt.Sprint(m.ReceiptMsgID))
		sb.WriteString(",\n")
	}
	sb.WriteString("\tCurrency: ")
	sb.WriteString(fmt.Sprint(m.Currency))
	sb.WriteString(",\n")
	sb.WriteString("\tTotalAmount: ")
	sb.WriteString(fmt.Sprint(m.TotalAmount))
	sb.WriteString(",\n")
	sb.WriteString("\tStartParam: ")
	sb.WriteString(fmt.Sprint(m.StartParam))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaInvoice) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaInvoice#84551347 as nil")
	}
	b.PutID(MessageMediaInvoiceTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaInvoice#84551347: field flags: %w", err)
	}
	b.PutString(m.Title)
	b.PutString(m.Description)
	if m.Flags.Has(0) {
		if m.Photo == nil {
			return fmt.Errorf("unable to encode messageMediaInvoice#84551347: field photo is nil")
		}
		if err := m.Photo.Encode(b); err != nil {
			return fmt.Errorf("unable to encode messageMediaInvoice#84551347: field photo: %w", err)
		}
	}
	if m.Flags.Has(2) {
		b.PutInt(m.ReceiptMsgID)
	}
	b.PutString(m.Currency)
	b.PutLong(m.TotalAmount)
	b.PutString(m.StartParam)
	return nil
}

func (m *MessageMediaInvoice) SetShippingAddressRequested(value bool) {
	if value {
		m.Flags.Set(1)
		m.ShippingAddressRequested = true
	} else {
		m.Flags.Unset(1)
		m.ShippingAddressRequested = false
	}
}

func (m *MessageMediaInvoice) SetTest(value bool) {
	if value {
		m.Flags.Set(3)
		m.Test = true
	} else {
		m.Flags.Unset(3)
		m.Test = false
	}
}

func (m *MessageMediaInvoice) SetPhoto(value WebDocumentClass) {
	m.Flags.Set(0)
	m.Photo = value
}

func (m *MessageMediaInvoice) GetPhoto() (value WebDocumentClass, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Photo, true
}

func (m *MessageMediaInvoice) SetReceiptMsgID(value int) {
	m.Flags.Set(2)
	m.ReceiptMsgID = value
}

func (m *MessageMediaInvoice) GetReceiptMsgID() (value int, ok bool) {
	if !m.Flags.Has(2) {
		return value, false
	}
	return m.ReceiptMsgID, true
}

func (m *MessageMediaInvoice) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaInvoice#84551347 to nil")
	}
	if err := b.ConsumeID(MessageMediaInvoiceTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaInvoice#84551347: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field flags: %w", err)
		}
	}
	m.ShippingAddressRequested = m.Flags.Has(1)
	m.Test = m.Flags.Has(3)
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field title: %w", err)
		}
		m.Title = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field description: %w", err)
		}
		m.Description = value
	}
	if m.Flags.Has(0) {
		value, err := DecodeWebDocument(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field photo: %w", err)
		}
		m.Photo = value
	}
	if m.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field receipt_msg_id: %w", err)
		}
		m.ReceiptMsgID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field currency: %w", err)
		}
		m.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field total_amount: %w", err)
		}
		m.TotalAmount = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field start_param: %w", err)
		}
		m.StartParam = value
	}
	return nil
}

func (m MessageMediaInvoice) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaInvoice{}
	_ bin.Decoder = &MessageMediaInvoice{}

	_ MessageMediaClass = &MessageMediaInvoice{}
)

type MessageMediaGeoLive struct {

	Flags bin.Fields

	Geo GeoPointClass

	Heading int

	Period int

	ProximityNotificationRadius int
}

const MessageMediaGeoLiveTypeID = 0xb940c666

func (m *MessageMediaGeoLive) String() string {
	if m == nil {
		return "MessageMediaGeoLive(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaGeoLive")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	sb.WriteString("\tGeo: ")
	sb.WriteString(fmt.Sprint(m.Geo))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tHeading: ")
		sb.WriteString(fmt.Sprint(m.Heading))
		sb.WriteString(",\n")
	}
	sb.WriteString("\tPeriod: ")
	sb.WriteString(fmt.Sprint(m.Period))
	sb.WriteString(",\n")
	if m.Flags.Has(1) {
		sb.WriteString("\tProximityNotificationRadius: ")
		sb.WriteString(fmt.Sprint(m.ProximityNotificationRadius))
		sb.WriteString(",\n")
	}
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaGeoLive) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaGeoLive#b940c666 as nil")
	}
	b.PutID(MessageMediaGeoLiveTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGeoLive#b940c666: field flags: %w", err)
	}
	if m.Geo == nil {
		return fmt.Errorf("unable to encode messageMediaGeoLive#b940c666: field geo is nil")
	}
	if err := m.Geo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGeoLive#b940c666: field geo: %w", err)
	}
	if m.Flags.Has(0) {
		b.PutInt(m.Heading)
	}
	b.PutInt(m.Period)
	if m.Flags.Has(1) {
		b.PutInt(m.ProximityNotificationRadius)
	}
	return nil
}

func (m *MessageMediaGeoLive) SetHeading(value int) {
	m.Flags.Set(0)
	m.Heading = value
}

func (m *MessageMediaGeoLive) GetHeading() (value int, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Heading, true
}

func (m *MessageMediaGeoLive) SetProximityNotificationRadius(value int) {
	m.Flags.Set(1)
	m.ProximityNotificationRadius = value
}

func (m *MessageMediaGeoLive) GetProximityNotificationRadius() (value int, ok bool) {
	if !m.Flags.Has(1) {
		return value, false
	}
	return m.ProximityNotificationRadius, true
}

func (m *MessageMediaGeoLive) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaGeoLive#b940c666 to nil")
	}
	if err := b.ConsumeID(MessageMediaGeoLiveTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field flags: %w", err)
		}
	}
	{
		value, err := DecodeGeoPoint(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field geo: %w", err)
		}
		m.Geo = value
	}
	if m.Flags.Has(0) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field heading: %w", err)
		}
		m.Heading = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field period: %w", err)
		}
		m.Period = value
	}
	if m.Flags.Has(1) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field proximity_notification_radius: %w", err)
		}
		m.ProximityNotificationRadius = value
	}
	return nil
}

func (m MessageMediaGeoLive) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaGeoLive{}
	_ bin.Decoder = &MessageMediaGeoLive{}

	_ MessageMediaClass = &MessageMediaGeoLive{}
)

type MessageMediaPoll struct {

	Poll Poll

	Results PollResults
}

const MessageMediaPollTypeID = 0x4bd6e798

func (m *MessageMediaPoll) String() string {
	if m == nil {
		return "MessageMediaPoll(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaPoll")
	sb.WriteString("{\n")
	sb.WriteString("\tPoll: ")
	sb.WriteString(fmt.Sprint(m.Poll))
	sb.WriteString(",\n")
	sb.WriteString("\tResults: ")
	sb.WriteString(fmt.Sprint(m.Results))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaPoll) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaPoll#4bd6e798 as nil")
	}
	b.PutID(MessageMediaPollTypeID)
	if err := m.Poll.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaPoll#4bd6e798: field poll: %w", err)
	}
	if err := m.Results.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaPoll#4bd6e798: field results: %w", err)
	}
	return nil
}

func (m *MessageMediaPoll) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaPoll#4bd6e798 to nil")
	}
	if err := b.ConsumeID(MessageMediaPollTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaPoll#4bd6e798: %w", err)
	}
	{
		if err := m.Poll.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaPoll#4bd6e798: field poll: %w", err)
		}
	}
	{
		if err := m.Results.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaPoll#4bd6e798: field results: %w", err)
		}
	}
	return nil
}

func (m MessageMediaPoll) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaPoll{}
	_ bin.Decoder = &MessageMediaPoll{}

	_ MessageMediaClass = &MessageMediaPoll{}
)

type MessageMediaDice struct {

	Value int

	Emoticon string
}

const MessageMediaDiceTypeID = 0x3f7ee58b

func (m *MessageMediaDice) String() string {
	if m == nil {
		return "MessageMediaDice(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaDice")
	sb.WriteString("{\n")
	sb.WriteString("\tValue: ")
	sb.WriteString(fmt.Sprint(m.Value))
	sb.WriteString(",\n")
	sb.WriteString("\tEmoticon: ")
	sb.WriteString(fmt.Sprint(m.Emoticon))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

func (m *MessageMediaDice) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaDice#3f7ee58b as nil")
	}
	b.PutID(MessageMediaDiceTypeID)
	b.PutInt(m.Value)
	b.PutString(m.Emoticon)
	return nil
}

func (m *MessageMediaDice) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaDice#3f7ee58b to nil")
	}
	if err := b.ConsumeID(MessageMediaDiceTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaDice#3f7ee58b: %w", err)
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDice#3f7ee58b: field value: %w", err)
		}
		m.Value = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDice#3f7ee58b: field emoticon: %w", err)
		}
		m.Emoticon = value
	}
	return nil
}

func (m MessageMediaDice) construct() MessageMediaClass { return &m }

var (
	_ bin.Encoder = &MessageMediaDice{}
	_ bin.Decoder = &MessageMediaDice{}

	_ MessageMediaClass = &MessageMediaDice{}
)

type MessageMediaClass interface {
	bin.Encoder
	bin.Decoder
	construct() MessageMediaClass
	fmt.Stringer
}

func DecodeMessageMedia(buf *bin.Buffer) (MessageMediaClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case MessageMediaEmptyTypeID:

		v := MessageMediaEmpty{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaPhotoTypeID:

		v := MessageMediaPhoto{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaGeoTypeID:

		v := MessageMediaGeo{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaContactTypeID:

		v := MessageMediaContact{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaUnsupportedTypeID:

		v := MessageMediaUnsupported{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaDocumentTypeID:

		v := MessageMediaDocument{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaWebPageTypeID:

		v := MessageMediaWebPage{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaVenueTypeID:

		v := MessageMediaVenue{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaGameTypeID:

		v := MessageMediaGame{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaInvoiceTypeID:

		v := MessageMediaInvoice{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaGeoLiveTypeID:

		v := MessageMediaGeoLive{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaPollTypeID:

		v := MessageMediaPoll{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaDiceTypeID:

		v := MessageMediaDice{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", bin.NewUnexpectedID(id))
	}
}

type MessageMediaBox struct {
	MessageMedia MessageMediaClass
}

func (b *MessageMediaBox) Decode(buf *bin.Buffer) error {
	if b == nil {
		return fmt.Errorf("unable to decode MessageMediaBox to nil")
	}
	v, err := DecodeMessageMedia(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.MessageMedia = v
	return nil
}

func (b *MessageMediaBox) Encode(buf *bin.Buffer) error {
	if b == nil || b.MessageMedia == nil {
		return fmt.Errorf("unable to encode MessageMediaClass as nil")
	}
	return b.MessageMedia.Encode(buf)
}
// Code generated by gotdgen, DO NOT EDIT.

package tg

import (
	"context"
	"fmt"
	"strings"

	"github.com/gotd/td/bin"
)

// No-op definition for keeping imports.
var _ = bin.Buffer{}
var _ = context.Background()
var _ = fmt.Stringer(nil)
var _ = strings.Builder{}

// MessageMediaEmpty represents TL type `messageMediaEmpty#3ded6320`.
// Empty constructor.
//
// See https://core.telegram.org/constructor/messageMediaEmpty for reference.
type MessageMediaEmpty struct {
}

// MessageMediaEmptyTypeID is TL type id of MessageMediaEmpty.
const MessageMediaEmptyTypeID = 0x3ded6320

// String implements fmt.Stringer.
func (m *MessageMediaEmpty) String() string {
	if m == nil {
		return "MessageMediaEmpty(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaEmpty")
	sb.WriteString("{\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaEmpty) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaEmpty#3ded6320 as nil")
	}
	b.PutID(MessageMediaEmptyTypeID)
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaEmpty) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaEmpty#3ded6320 to nil")
	}
	if err := b.ConsumeID(MessageMediaEmptyTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaEmpty#3ded6320: %w", err)
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaEmpty) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaEmpty.
var (
	_ bin.Encoder = &MessageMediaEmpty{}
	_ bin.Decoder = &MessageMediaEmpty{}

	_ MessageMediaClass = &MessageMediaEmpty{}
)

// MessageMediaPhoto represents TL type `messageMediaPhoto#695150d7`.
// Attached photo.
//
// See https://core.telegram.org/constructor/messageMediaPhoto for reference.
type MessageMediaPhoto struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Photo
	//
	// Use SetPhoto and GetPhoto helpers.
	Photo PhotoClass
	// Time to live in seconds of self-destructing photo
	//
	// Use SetTTLSeconds and GetTTLSeconds helpers.
	TTLSeconds int
}

// MessageMediaPhotoTypeID is TL type id of MessageMediaPhoto.
const MessageMediaPhotoTypeID = 0x695150d7

// String implements fmt.Stringer.
func (m *MessageMediaPhoto) String() string {
	if m == nil {
		return "MessageMediaPhoto(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaPhoto")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tPhoto: ")
		sb.WriteString(fmt.Sprint(m.Photo))
		sb.WriteString(",\n")
	}
	if m.Flags.Has(2) {
		sb.WriteString("\tTTLSeconds: ")
		sb.WriteString(fmt.Sprint(m.TTLSeconds))
		sb.WriteString(",\n")
	}
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaPhoto) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaPhoto#695150d7 as nil")
	}
	b.PutID(MessageMediaPhotoTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaPhoto#695150d7: field flags: %w", err)
	}
	if m.Flags.Has(0) {
		if m.Photo == nil {
			return fmt.Errorf("unable to encode messageMediaPhoto#695150d7: field photo is nil")
		}
		if err := m.Photo.Encode(b); err != nil {
			return fmt.Errorf("unable to encode messageMediaPhoto#695150d7: field photo: %w", err)
		}
	}
	if m.Flags.Has(2) {
		b.PutInt(m.TTLSeconds)
	}
	return nil
}

// SetPhoto sets value of Photo conditional field.
func (m *MessageMediaPhoto) SetPhoto(value PhotoClass) {
	m.Flags.Set(0)
	m.Photo = value
}

// GetPhoto returns value of Photo conditional field and
// boolean which is true if field was set.
func (m *MessageMediaPhoto) GetPhoto() (value PhotoClass, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Photo, true
}

// SetTTLSeconds sets value of TTLSeconds conditional field.
func (m *MessageMediaPhoto) SetTTLSeconds(value int) {
	m.Flags.Set(2)
	m.TTLSeconds = value
}

// GetTTLSeconds returns value of TTLSeconds conditional field and
// boolean which is true if field was set.
func (m *MessageMediaPhoto) GetTTLSeconds() (value int, ok bool) {
	if !m.Flags.Has(2) {
		return value, false
	}
	return m.TTLSeconds, true
}

// Decode implements bin.Decoder.
func (m *MessageMediaPhoto) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaPhoto#695150d7 to nil")
	}
	if err := b.ConsumeID(MessageMediaPhotoTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: field flags: %w", err)
		}
	}
	if m.Flags.Has(0) {
		value, err := DecodePhoto(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: field photo: %w", err)
		}
		m.Photo = value
	}
	if m.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaPhoto#695150d7: field ttl_seconds: %w", err)
		}
		m.TTLSeconds = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaPhoto) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaPhoto.
var (
	_ bin.Encoder = &MessageMediaPhoto{}
	_ bin.Decoder = &MessageMediaPhoto{}

	_ MessageMediaClass = &MessageMediaPhoto{}
)

// MessageMediaGeo represents TL type `messageMediaGeo#56e0d474`.
// Attached map.
//
// See https://core.telegram.org/constructor/messageMediaGeo for reference.
type MessageMediaGeo struct {
	// GeoPoint
	Geo GeoPointClass
}

// MessageMediaGeoTypeID is TL type id of MessageMediaGeo.
const MessageMediaGeoTypeID = 0x56e0d474

// String implements fmt.Stringer.
func (m *MessageMediaGeo) String() string {
	if m == nil {
		return "MessageMediaGeo(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaGeo")
	sb.WriteString("{\n")
	sb.WriteString("\tGeo: ")
	sb.WriteString(fmt.Sprint(m.Geo))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaGeo) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaGeo#56e0d474 as nil")
	}
	b.PutID(MessageMediaGeoTypeID)
	if m.Geo == nil {
		return fmt.Errorf("unable to encode messageMediaGeo#56e0d474: field geo is nil")
	}
	if err := m.Geo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGeo#56e0d474: field geo: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaGeo) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaGeo#56e0d474 to nil")
	}
	if err := b.ConsumeID(MessageMediaGeoTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaGeo#56e0d474: %w", err)
	}
	{
		value, err := DecodeGeoPoint(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeo#56e0d474: field geo: %w", err)
		}
		m.Geo = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaGeo) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaGeo.
var (
	_ bin.Encoder = &MessageMediaGeo{}
	_ bin.Decoder = &MessageMediaGeo{}

	_ MessageMediaClass = &MessageMediaGeo{}
)

// MessageMediaContact represents TL type `messageMediaContact#cbf24940`.
// Attached contact.
//
// See https://core.telegram.org/constructor/messageMediaContact for reference.
type MessageMediaContact struct {
	// Phone number
	PhoneNumber string
	// Contact's first name
	FirstName string
	// Contact's last name
	LastName string
	// VCARD of contact
	Vcard string
	// User identifier or 0, if the user with the given phone number is not registered
	UserID int
}

// MessageMediaContactTypeID is TL type id of MessageMediaContact.
const MessageMediaContactTypeID = 0xcbf24940

// String implements fmt.Stringer.
func (m *MessageMediaContact) String() string {
	if m == nil {
		return "MessageMediaContact(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaContact")
	sb.WriteString("{\n")
	sb.WriteString("\tPhoneNumber: ")
	sb.WriteString(fmt.Sprint(m.PhoneNumber))
	sb.WriteString(",\n")
	sb.WriteString("\tFirstName: ")
	sb.WriteString(fmt.Sprint(m.FirstName))
	sb.WriteString(",\n")
	sb.WriteString("\tLastName: ")
	sb.WriteString(fmt.Sprint(m.LastName))
	sb.WriteString(",\n")
	sb.WriteString("\tVcard: ")
	sb.WriteString(fmt.Sprint(m.Vcard))
	sb.WriteString(",\n")
	sb.WriteString("\tUserID: ")
	sb.WriteString(fmt.Sprint(m.UserID))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaContact) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaContact#cbf24940 as nil")
	}
	b.PutID(MessageMediaContactTypeID)
	b.PutString(m.PhoneNumber)
	b.PutString(m.FirstName)
	b.PutString(m.LastName)
	b.PutString(m.Vcard)
	b.PutInt(m.UserID)
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaContact) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaContact#cbf24940 to nil")
	}
	if err := b.ConsumeID(MessageMediaContactTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaContact#cbf24940: %w", err)
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field phone_number: %w", err)
		}
		m.PhoneNumber = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field first_name: %w", err)
		}
		m.FirstName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field last_name: %w", err)
		}
		m.LastName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field vcard: %w", err)
		}
		m.Vcard = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaContact#cbf24940: field user_id: %w", err)
		}
		m.UserID = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaContact) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaContact.
var (
	_ bin.Encoder = &MessageMediaContact{}
	_ bin.Decoder = &MessageMediaContact{}

	_ MessageMediaClass = &MessageMediaContact{}
)

// MessageMediaUnsupported represents TL type `messageMediaUnsupported#9f84f49e`.
// Current version of the client does not support this media type.
//
// See https://core.telegram.org/constructor/messageMediaUnsupported for reference.
type MessageMediaUnsupported struct {
}

// MessageMediaUnsupportedTypeID is TL type id of MessageMediaUnsupported.
const MessageMediaUnsupportedTypeID = 0x9f84f49e

// String implements fmt.Stringer.
func (m *MessageMediaUnsupported) String() string {
	if m == nil {
		return "MessageMediaUnsupported(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaUnsupported")
	sb.WriteString("{\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaUnsupported) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaUnsupported#9f84f49e as nil")
	}
	b.PutID(MessageMediaUnsupportedTypeID)
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaUnsupported) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaUnsupported#9f84f49e to nil")
	}
	if err := b.ConsumeID(MessageMediaUnsupportedTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaUnsupported#9f84f49e: %w", err)
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaUnsupported) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaUnsupported.
var (
	_ bin.Encoder = &MessageMediaUnsupported{}
	_ bin.Decoder = &MessageMediaUnsupported{}

	_ MessageMediaClass = &MessageMediaUnsupported{}
)

// MessageMediaDocument represents TL type `messageMediaDocument#9cb070d7`.
// Document (video, audio, voice, sticker, any media type except photo)
//
// See https://core.telegram.org/constructor/messageMediaDocument for reference.
type MessageMediaDocument struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Attached document
	//
	// Use SetDocument and GetDocument helpers.
	Document DocumentClass
	// Time to live of self-destructing document
	//
	// Use SetTTLSeconds and GetTTLSeconds helpers.
	TTLSeconds int
}

// MessageMediaDocumentTypeID is TL type id of MessageMediaDocument.
const MessageMediaDocumentTypeID = 0x9cb070d7

// String implements fmt.Stringer.
func (m *MessageMediaDocument) String() string {
	if m == nil {
		return "MessageMediaDocument(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaDocument")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tDocument: ")
		sb.WriteString(fmt.Sprint(m.Document))
		sb.WriteString(",\n")
	}
	if m.Flags.Has(2) {
		sb.WriteString("\tTTLSeconds: ")
		sb.WriteString(fmt.Sprint(m.TTLSeconds))
		sb.WriteString(",\n")
	}
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaDocument) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaDocument#9cb070d7 as nil")
	}
	b.PutID(MessageMediaDocumentTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaDocument#9cb070d7: field flags: %w", err)
	}
	if m.Flags.Has(0) {
		if m.Document == nil {
			return fmt.Errorf("unable to encode messageMediaDocument#9cb070d7: field document is nil")
		}
		if err := m.Document.Encode(b); err != nil {
			return fmt.Errorf("unable to encode messageMediaDocument#9cb070d7: field document: %w", err)
		}
	}
	if m.Flags.Has(2) {
		b.PutInt(m.TTLSeconds)
	}
	return nil
}

// SetDocument sets value of Document conditional field.
func (m *MessageMediaDocument) SetDocument(value DocumentClass) {
	m.Flags.Set(0)
	m.Document = value
}

// GetDocument returns value of Document conditional field and
// boolean which is true if field was set.
func (m *MessageMediaDocument) GetDocument() (value DocumentClass, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Document, true
}

// SetTTLSeconds sets value of TTLSeconds conditional field.
func (m *MessageMediaDocument) SetTTLSeconds(value int) {
	m.Flags.Set(2)
	m.TTLSeconds = value
}

// GetTTLSeconds returns value of TTLSeconds conditional field and
// boolean which is true if field was set.
func (m *MessageMediaDocument) GetTTLSeconds() (value int, ok bool) {
	if !m.Flags.Has(2) {
		return value, false
	}
	return m.TTLSeconds, true
}

// Decode implements bin.Decoder.
func (m *MessageMediaDocument) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaDocument#9cb070d7 to nil")
	}
	if err := b.ConsumeID(MessageMediaDocumentTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: field flags: %w", err)
		}
	}
	if m.Flags.Has(0) {
		value, err := DecodeDocument(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: field document: %w", err)
		}
		m.Document = value
	}
	if m.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDocument#9cb070d7: field ttl_seconds: %w", err)
		}
		m.TTLSeconds = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaDocument) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaDocument.
var (
	_ bin.Encoder = &MessageMediaDocument{}
	_ bin.Decoder = &MessageMediaDocument{}

	_ MessageMediaClass = &MessageMediaDocument{}
)

// MessageMediaWebPage represents TL type `messageMediaWebPage#a32dd600`.
// Preview of webpage
//
// See https://core.telegram.org/constructor/messageMediaWebPage for reference.
type MessageMediaWebPage struct {
	// Webpage preview
	Webpage WebPageClass
}

// MessageMediaWebPageTypeID is TL type id of MessageMediaWebPage.
const MessageMediaWebPageTypeID = 0xa32dd600

// String implements fmt.Stringer.
func (m *MessageMediaWebPage) String() string {
	if m == nil {
		return "MessageMediaWebPage(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaWebPage")
	sb.WriteString("{\n")
	sb.WriteString("\tWebpage: ")
	sb.WriteString(fmt.Sprint(m.Webpage))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaWebPage) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaWebPage#a32dd600 as nil")
	}
	b.PutID(MessageMediaWebPageTypeID)
	if m.Webpage == nil {
		return fmt.Errorf("unable to encode messageMediaWebPage#a32dd600: field webpage is nil")
	}
	if err := m.Webpage.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaWebPage#a32dd600: field webpage: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaWebPage) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaWebPage#a32dd600 to nil")
	}
	if err := b.ConsumeID(MessageMediaWebPageTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaWebPage#a32dd600: %w", err)
	}
	{
		value, err := DecodeWebPage(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaWebPage#a32dd600: field webpage: %w", err)
		}
		m.Webpage = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaWebPage) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaWebPage.
var (
	_ bin.Encoder = &MessageMediaWebPage{}
	_ bin.Decoder = &MessageMediaWebPage{}

	_ MessageMediaClass = &MessageMediaWebPage{}
)

// MessageMediaVenue represents TL type `messageMediaVenue#2ec0533f`.
// Venue
//
// See https://core.telegram.org/constructor/messageMediaVenue for reference.
type MessageMediaVenue struct {
	// Geolocation of venue
	Geo GeoPointClass
	// Venue name
	Title string
	// Address
	Address string
	// Venue provider: currently only "foursquare" needs to be supported
	Provider string
	// Venue ID in the provider's database
	VenueID string
	// Venue type in the provider's database
	VenueType string
}

// MessageMediaVenueTypeID is TL type id of MessageMediaVenue.
const MessageMediaVenueTypeID = 0x2ec0533f

// String implements fmt.Stringer.
func (m *MessageMediaVenue) String() string {
	if m == nil {
		return "MessageMediaVenue(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaVenue")
	sb.WriteString("{\n")
	sb.WriteString("\tGeo: ")
	sb.WriteString(fmt.Sprint(m.Geo))
	sb.WriteString(",\n")
	sb.WriteString("\tTitle: ")
	sb.WriteString(fmt.Sprint(m.Title))
	sb.WriteString(",\n")
	sb.WriteString("\tAddress: ")
	sb.WriteString(fmt.Sprint(m.Address))
	sb.WriteString(",\n")
	sb.WriteString("\tProvider: ")
	sb.WriteString(fmt.Sprint(m.Provider))
	sb.WriteString(",\n")
	sb.WriteString("\tVenueID: ")
	sb.WriteString(fmt.Sprint(m.VenueID))
	sb.WriteString(",\n")
	sb.WriteString("\tVenueType: ")
	sb.WriteString(fmt.Sprint(m.VenueType))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaVenue) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaVenue#2ec0533f as nil")
	}
	b.PutID(MessageMediaVenueTypeID)
	if m.Geo == nil {
		return fmt.Errorf("unable to encode messageMediaVenue#2ec0533f: field geo is nil")
	}
	if err := m.Geo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaVenue#2ec0533f: field geo: %w", err)
	}
	b.PutString(m.Title)
	b.PutString(m.Address)
	b.PutString(m.Provider)
	b.PutString(m.VenueID)
	b.PutString(m.VenueType)
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaVenue) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaVenue#2ec0533f to nil")
	}
	if err := b.ConsumeID(MessageMediaVenueTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: %w", err)
	}
	{
		value, err := DecodeGeoPoint(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field geo: %w", err)
		}
		m.Geo = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field title: %w", err)
		}
		m.Title = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field address: %w", err)
		}
		m.Address = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field provider: %w", err)
		}
		m.Provider = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field venue_id: %w", err)
		}
		m.VenueID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaVenue#2ec0533f: field venue_type: %w", err)
		}
		m.VenueType = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaVenue) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaVenue.
var (
	_ bin.Encoder = &MessageMediaVenue{}
	_ bin.Decoder = &MessageMediaVenue{}

	_ MessageMediaClass = &MessageMediaVenue{}
)

// MessageMediaGame represents TL type `messageMediaGame#fdb19008`.
// Telegram game
//
// See https://core.telegram.org/constructor/messageMediaGame for reference.
type MessageMediaGame struct {
	// Game
	Game Game
}

// MessageMediaGameTypeID is TL type id of MessageMediaGame.
const MessageMediaGameTypeID = 0xfdb19008

// String implements fmt.Stringer.
func (m *MessageMediaGame) String() string {
	if m == nil {
		return "MessageMediaGame(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaGame")
	sb.WriteString("{\n")
	sb.WriteString("\tGame: ")
	sb.WriteString(fmt.Sprint(m.Game))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaGame) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaGame#fdb19008 as nil")
	}
	b.PutID(MessageMediaGameTypeID)
	if err := m.Game.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGame#fdb19008: field game: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaGame) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaGame#fdb19008 to nil")
	}
	if err := b.ConsumeID(MessageMediaGameTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaGame#fdb19008: %w", err)
	}
	{
		if err := m.Game.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaGame#fdb19008: field game: %w", err)
		}
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaGame) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaGame.
var (
	_ bin.Encoder = &MessageMediaGame{}
	_ bin.Decoder = &MessageMediaGame{}

	_ MessageMediaClass = &MessageMediaGame{}
)

// MessageMediaInvoice represents TL type `messageMediaInvoice#84551347`.
// Invoice
//
// See https://core.telegram.org/constructor/messageMediaInvoice for reference.
type MessageMediaInvoice struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Whether the shipping address was requested
	ShippingAddressRequested bool
	// Whether this is an example invoice
	Test bool
	// Product name, 1-32 characters
	Title string
	// Product description, 1-255 characters
	Description string
	// URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for.
	//
	// Use SetPhoto and GetPhoto helpers.
	Photo WebDocumentClass
	// Message ID of receipt: if set, clients should change the text of the first keyboardButtonBuy¹ button always attached to the message² to a localized version of the word Receipt
	//
	// Links:
	//  1) https://core.telegram.org/constructor/keyboardButtonBuy
	//  2) https://core.telegram.org/constructor/message
	//
	// Use SetReceiptMsgID and GetReceiptMsgID helpers.
	ReceiptMsgID int
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Total price in the smallest units of the currency (integer, not float/double). For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in currencies.json¹, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	TotalAmount int64
	// Unique bot deep-linking parameter that can be used to generate this invoice
	StartParam string
}

// MessageMediaInvoiceTypeID is TL type id of MessageMediaInvoice.
const MessageMediaInvoiceTypeID = 0x84551347

// String implements fmt.Stringer.
func (m *MessageMediaInvoice) String() string {
	if m == nil {
		return "MessageMediaInvoice(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaInvoice")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	sb.WriteString("\tTitle: ")
	sb.WriteString(fmt.Sprint(m.Title))
	sb.WriteString(",\n")
	sb.WriteString("\tDescription: ")
	sb.WriteString(fmt.Sprint(m.Description))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tPhoto: ")
		sb.WriteString(fmt.Sprint(m.Photo))
		sb.WriteString(",\n")
	}
	if m.Flags.Has(2) {
		sb.WriteString("\tReceiptMsgID: ")
		sb.WriteString(fmt.Sprint(m.ReceiptMsgID))
		sb.WriteString(",\n")
	}
	sb.WriteString("\tCurrency: ")
	sb.WriteString(fmt.Sprint(m.Currency))
	sb.WriteString(",\n")
	sb.WriteString("\tTotalAmount: ")
	sb.WriteString(fmt.Sprint(m.TotalAmount))
	sb.WriteString(",\n")
	sb.WriteString("\tStartParam: ")
	sb.WriteString(fmt.Sprint(m.StartParam))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaInvoice) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaInvoice#84551347 as nil")
	}
	b.PutID(MessageMediaInvoiceTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaInvoice#84551347: field flags: %w", err)
	}
	b.PutString(m.Title)
	b.PutString(m.Description)
	if m.Flags.Has(0) {
		if m.Photo == nil {
			return fmt.Errorf("unable to encode messageMediaInvoice#84551347: field photo is nil")
		}
		if err := m.Photo.Encode(b); err != nil {
			return fmt.Errorf("unable to encode messageMediaInvoice#84551347: field photo: %w", err)
		}
	}
	if m.Flags.Has(2) {
		b.PutInt(m.ReceiptMsgID)
	}
	b.PutString(m.Currency)
	b.PutLong(m.TotalAmount)
	b.PutString(m.StartParam)
	return nil
}

// SetShippingAddressRequested sets value of ShippingAddressRequested conditional field.
func (m *MessageMediaInvoice) SetShippingAddressRequested(value bool) {
	if value {
		m.Flags.Set(1)
		m.ShippingAddressRequested = true
	} else {
		m.Flags.Unset(1)
		m.ShippingAddressRequested = false
	}
}

// SetTest sets value of Test conditional field.
func (m *MessageMediaInvoice) SetTest(value bool) {
	if value {
		m.Flags.Set(3)
		m.Test = true
	} else {
		m.Flags.Unset(3)
		m.Test = false
	}
}

// SetPhoto sets value of Photo conditional field.
func (m *MessageMediaInvoice) SetPhoto(value WebDocumentClass) {
	m.Flags.Set(0)
	m.Photo = value
}

// GetPhoto returns value of Photo conditional field and
// boolean which is true if field was set.
func (m *MessageMediaInvoice) GetPhoto() (value WebDocumentClass, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Photo, true
}

// SetReceiptMsgID sets value of ReceiptMsgID conditional field.
func (m *MessageMediaInvoice) SetReceiptMsgID(value int) {
	m.Flags.Set(2)
	m.ReceiptMsgID = value
}

// GetReceiptMsgID returns value of ReceiptMsgID conditional field and
// boolean which is true if field was set.
func (m *MessageMediaInvoice) GetReceiptMsgID() (value int, ok bool) {
	if !m.Flags.Has(2) {
		return value, false
	}
	return m.ReceiptMsgID, true
}

// Decode implements bin.Decoder.
func (m *MessageMediaInvoice) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaInvoice#84551347 to nil")
	}
	if err := b.ConsumeID(MessageMediaInvoiceTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaInvoice#84551347: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field flags: %w", err)
		}
	}
	m.ShippingAddressRequested = m.Flags.Has(1)
	m.Test = m.Flags.Has(3)
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field title: %w", err)
		}
		m.Title = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field description: %w", err)
		}
		m.Description = value
	}
	if m.Flags.Has(0) {
		value, err := DecodeWebDocument(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field photo: %w", err)
		}
		m.Photo = value
	}
	if m.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field receipt_msg_id: %w", err)
		}
		m.ReceiptMsgID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field currency: %w", err)
		}
		m.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field total_amount: %w", err)
		}
		m.TotalAmount = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaInvoice#84551347: field start_param: %w", err)
		}
		m.StartParam = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaInvoice) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaInvoice.
var (
	_ bin.Encoder = &MessageMediaInvoice{}
	_ bin.Decoder = &MessageMediaInvoice{}

	_ MessageMediaClass = &MessageMediaInvoice{}
)

// MessageMediaGeoLive represents TL type `messageMediaGeoLive#b940c666`.
// Indicates a live geolocation¹
//
// Links:
//  1) https://core.telegram.org/api/live-location
//
// See https://core.telegram.org/constructor/messageMediaGeoLive for reference.
type MessageMediaGeoLive struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Geolocation
	Geo GeoPointClass
	// For live locations¹, a direction in which the location moves, in degrees; 1-360
	//
	// Links:
	//  1) https://core.telegram.org/api/live-location
	//
	// Use SetHeading and GetHeading helpers.
	Heading int
	// Validity period of provided geolocation
	Period int
	// For live locations¹, a maximum distance to another chat member for proximity alerts, in meters (0-100000).
	//
	// Links:
	//  1) https://core.telegram.org/api/live-location
	//
	// Use SetProximityNotificationRadius and GetProximityNotificationRadius helpers.
	ProximityNotificationRadius int
}

// MessageMediaGeoLiveTypeID is TL type id of MessageMediaGeoLive.
const MessageMediaGeoLiveTypeID = 0xb940c666

// String implements fmt.Stringer.
func (m *MessageMediaGeoLive) String() string {
	if m == nil {
		return "MessageMediaGeoLive(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaGeoLive")
	sb.WriteString("{\n")
	sb.WriteString("\tFlags: ")
	sb.WriteString(fmt.Sprint(m.Flags))
	sb.WriteString(",\n")
	sb.WriteString("\tGeo: ")
	sb.WriteString(fmt.Sprint(m.Geo))
	sb.WriteString(",\n")
	if m.Flags.Has(0) {
		sb.WriteString("\tHeading: ")
		sb.WriteString(fmt.Sprint(m.Heading))
		sb.WriteString(",\n")
	}
	sb.WriteString("\tPeriod: ")
	sb.WriteString(fmt.Sprint(m.Period))
	sb.WriteString(",\n")
	if m.Flags.Has(1) {
		sb.WriteString("\tProximityNotificationRadius: ")
		sb.WriteString(fmt.Sprint(m.ProximityNotificationRadius))
		sb.WriteString(",\n")
	}
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaGeoLive) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaGeoLive#b940c666 as nil")
	}
	b.PutID(MessageMediaGeoLiveTypeID)
	if err := m.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGeoLive#b940c666: field flags: %w", err)
	}
	if m.Geo == nil {
		return fmt.Errorf("unable to encode messageMediaGeoLive#b940c666: field geo is nil")
	}
	if err := m.Geo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaGeoLive#b940c666: field geo: %w", err)
	}
	if m.Flags.Has(0) {
		b.PutInt(m.Heading)
	}
	b.PutInt(m.Period)
	if m.Flags.Has(1) {
		b.PutInt(m.ProximityNotificationRadius)
	}
	return nil
}

// SetHeading sets value of Heading conditional field.
func (m *MessageMediaGeoLive) SetHeading(value int) {
	m.Flags.Set(0)
	m.Heading = value
}

// GetHeading returns value of Heading conditional field and
// boolean which is true if field was set.
func (m *MessageMediaGeoLive) GetHeading() (value int, ok bool) {
	if !m.Flags.Has(0) {
		return value, false
	}
	return m.Heading, true
}

// SetProximityNotificationRadius sets value of ProximityNotificationRadius conditional field.
func (m *MessageMediaGeoLive) SetProximityNotificationRadius(value int) {
	m.Flags.Set(1)
	m.ProximityNotificationRadius = value
}

// GetProximityNotificationRadius returns value of ProximityNotificationRadius conditional field and
// boolean which is true if field was set.
func (m *MessageMediaGeoLive) GetProximityNotificationRadius() (value int, ok bool) {
	if !m.Flags.Has(1) {
		return value, false
	}
	return m.ProximityNotificationRadius, true
}

// Decode implements bin.Decoder.
func (m *MessageMediaGeoLive) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaGeoLive#b940c666 to nil")
	}
	if err := b.ConsumeID(MessageMediaGeoLiveTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: %w", err)
	}
	{
		if err := m.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field flags: %w", err)
		}
	}
	{
		value, err := DecodeGeoPoint(b)
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field geo: %w", err)
		}
		m.Geo = value
	}
	if m.Flags.Has(0) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field heading: %w", err)
		}
		m.Heading = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field period: %w", err)
		}
		m.Period = value
	}
	if m.Flags.Has(1) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaGeoLive#b940c666: field proximity_notification_radius: %w", err)
		}
		m.ProximityNotificationRadius = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaGeoLive) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaGeoLive.
var (
	_ bin.Encoder = &MessageMediaGeoLive{}
	_ bin.Decoder = &MessageMediaGeoLive{}

	_ MessageMediaClass = &MessageMediaGeoLive{}
)

// MessageMediaPoll represents TL type `messageMediaPoll#4bd6e798`.
// Poll
//
// See https://core.telegram.org/constructor/messageMediaPoll for reference.
type MessageMediaPoll struct {
	// The poll
	Poll Poll
	// The results of the poll
	Results PollResults
}

// MessageMediaPollTypeID is TL type id of MessageMediaPoll.
const MessageMediaPollTypeID = 0x4bd6e798

// String implements fmt.Stringer.
func (m *MessageMediaPoll) String() string {
	if m == nil {
		return "MessageMediaPoll(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaPoll")
	sb.WriteString("{\n")
	sb.WriteString("\tPoll: ")
	sb.WriteString(fmt.Sprint(m.Poll))
	sb.WriteString(",\n")
	sb.WriteString("\tResults: ")
	sb.WriteString(fmt.Sprint(m.Results))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaPoll) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaPoll#4bd6e798 as nil")
	}
	b.PutID(MessageMediaPollTypeID)
	if err := m.Poll.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaPoll#4bd6e798: field poll: %w", err)
	}
	if err := m.Results.Encode(b); err != nil {
		return fmt.Errorf("unable to encode messageMediaPoll#4bd6e798: field results: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaPoll) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaPoll#4bd6e798 to nil")
	}
	if err := b.ConsumeID(MessageMediaPollTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaPoll#4bd6e798: %w", err)
	}
	{
		if err := m.Poll.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaPoll#4bd6e798: field poll: %w", err)
		}
	}
	{
		if err := m.Results.Decode(b); err != nil {
			return fmt.Errorf("unable to decode messageMediaPoll#4bd6e798: field results: %w", err)
		}
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaPoll) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaPoll.
var (
	_ bin.Encoder = &MessageMediaPoll{}
	_ bin.Decoder = &MessageMediaPoll{}

	_ MessageMediaClass = &MessageMediaPoll{}
)

// MessageMediaDice represents TL type `messageMediaDice#3f7ee58b`.
// Dice-based animated sticker¹
//
// Links:
//  1) https://core.telegram.org/api/dice
//
// See https://core.telegram.org/constructor/messageMediaDice for reference.
type MessageMediaDice struct {
	// Dice value¹
	//
	// Links:
	//  1) https://core.telegram.org/api/dice
	Value int
	// The emoji, for now ,  and  are supported
	Emoticon string
}

// MessageMediaDiceTypeID is TL type id of MessageMediaDice.
const MessageMediaDiceTypeID = 0x3f7ee58b

// String implements fmt.Stringer.
func (m *MessageMediaDice) String() string {
	if m == nil {
		return "MessageMediaDice(nil)"
	}
	var sb strings.Builder
	sb.WriteString("MessageMediaDice")
	sb.WriteString("{\n")
	sb.WriteString("\tValue: ")
	sb.WriteString(fmt.Sprint(m.Value))
	sb.WriteString(",\n")
	sb.WriteString("\tEmoticon: ")
	sb.WriteString(fmt.Sprint(m.Emoticon))
	sb.WriteString(",\n")
	sb.WriteString("}")
	return sb.String()
}

// Encode implements bin.Encoder.
func (m *MessageMediaDice) Encode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't encode messageMediaDice#3f7ee58b as nil")
	}
	b.PutID(MessageMediaDiceTypeID)
	b.PutInt(m.Value)
	b.PutString(m.Emoticon)
	return nil
}

// Decode implements bin.Decoder.
func (m *MessageMediaDice) Decode(b *bin.Buffer) error {
	if m == nil {
		return fmt.Errorf("can't decode messageMediaDice#3f7ee58b to nil")
	}
	if err := b.ConsumeID(MessageMediaDiceTypeID); err != nil {
		return fmt.Errorf("unable to decode messageMediaDice#3f7ee58b: %w", err)
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDice#3f7ee58b: field value: %w", err)
		}
		m.Value = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode messageMediaDice#3f7ee58b: field emoticon: %w", err)
		}
		m.Emoticon = value
	}
	return nil
}

// construct implements constructor of MessageMediaClass.
func (m MessageMediaDice) construct() MessageMediaClass { return &m }

// Ensuring interfaces in compile-time for MessageMediaDice.
var (
	_ bin.Encoder = &MessageMediaDice{}
	_ bin.Decoder = &MessageMediaDice{}

	_ MessageMediaClass = &MessageMediaDice{}
)

// MessageMediaClass represents MessageMedia generic type.
//
// See https://core.telegram.org/type/MessageMedia for reference.
//
// Example:
//  g, err := DecodeMessageMedia(buf)
//  if err != nil {
//      panic(err)
//  }
//  switch v := g.(type) {
//  case *MessageMediaEmpty: // messageMediaEmpty#3ded6320
//  case *MessageMediaPhoto: // messageMediaPhoto#695150d7
//  case *MessageMediaGeo: // messageMediaGeo#56e0d474
//  case *MessageMediaContact: // messageMediaContact#cbf24940
//  case *MessageMediaUnsupported: // messageMediaUnsupported#9f84f49e
//  case *MessageMediaDocument: // messageMediaDocument#9cb070d7
//  case *MessageMediaWebPage: // messageMediaWebPage#a32dd600
//  case *MessageMediaVenue: // messageMediaVenue#2ec0533f
//  case *MessageMediaGame: // messageMediaGame#fdb19008
//  case *MessageMediaInvoice: // messageMediaInvoice#84551347
//  case *MessageMediaGeoLive: // messageMediaGeoLive#b940c666
//  case *MessageMediaPoll: // messageMediaPoll#4bd6e798
//  case *MessageMediaDice: // messageMediaDice#3f7ee58b
//  default: panic(v)
//  }
type MessageMediaClass interface {
	bin.Encoder
	bin.Decoder
	construct() MessageMediaClass
	fmt.Stringer
}

// DecodeMessageMedia implements binary de-serialization for MessageMediaClass.
func DecodeMessageMedia(buf *bin.Buffer) (MessageMediaClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case MessageMediaEmptyTypeID:
		// Decoding messageMediaEmpty#3ded6320.
		v := MessageMediaEmpty{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaPhotoTypeID:
		// Decoding messageMediaPhoto#695150d7.
		v := MessageMediaPhoto{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaGeoTypeID:
		// Decoding messageMediaGeo#56e0d474.
		v := MessageMediaGeo{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaContactTypeID:
		// Decoding messageMediaContact#cbf24940.
		v := MessageMediaContact{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaUnsupportedTypeID:
		// Decoding messageMediaUnsupported#9f84f49e.
		v := MessageMediaUnsupported{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaDocumentTypeID:
		// Decoding messageMediaDocument#9cb070d7.
		v := MessageMediaDocument{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaWebPageTypeID:
		// Decoding messageMediaWebPage#a32dd600.
		v := MessageMediaWebPage{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaVenueTypeID:
		// Decoding messageMediaVenue#2ec0533f.
		v := MessageMediaVenue{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaGameTypeID:
		// Decoding messageMediaGame#fdb19008.
		v := MessageMediaGame{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaInvoiceTypeID:
		// Decoding messageMediaInvoice#84551347.
		v := MessageMediaInvoice{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaGeoLiveTypeID:
		// Decoding messageMediaGeoLive#b940c666.
		v := MessageMediaGeoLive{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaPollTypeID:
		// Decoding messageMediaPoll#4bd6e798.
		v := MessageMediaPoll{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	case MessageMediaDiceTypeID:
		// Decoding messageMediaDice#3f7ee58b.
		v := MessageMediaDice{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode MessageMediaClass: %w", bin.NewUnexpectedID(id))
	}
}

// MessageMedia boxes the MessageMediaClass providing a helper.
type MessageMediaBox struct {
	MessageMedia MessageMediaClass
}

// Decode implements bin.Decoder for MessageMediaBox.
func (b *MessageMediaBox) Decode(buf *bin.Buffer) error {
	if b == nil {
		return fmt.Errorf("unable to decode MessageMediaBox to nil")
	}
	v, err := DecodeMessageMedia(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.MessageMedia = v
	return nil
}

// Encode implements bin.Encode for MessageMediaBox.
func (b *MessageMediaBox) Encode(buf *bin.Buffer) error {
	if b == nil || b.MessageMedia == nil {
		return fmt.Errorf("unable to encode MessageMediaClass as nil")
	}
	return b.MessageMedia.Encode(buf)
}
