/*
 * This is the source code of Telegram for Android v. 5.x.x.
 * It is licensed under GNU GPL v. 2 or later.
 * You should have received a copy of the license in this archive (see LICENSE).
 *
 * Copyright Nikolai Kudashov, 2013-2018.
 */

package org.telegram.ui.Cells;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.Property;
import android.util.SparseArray;
import android.util.StateSet;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewStructure;
import android.view.Window;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;

import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.DownloadController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.FlagSecureReason;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LiteMode;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.WebFile;
import org.telegram.messenger.browser.Browser;
import org.telegram.messenger.video.VideoPlayerRewinder;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AnimatedNumberLayout;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.AudioVisualizerDrawable;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.CheckBoxBase;
import org.telegram.ui.Components.ClipRoundedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EmptyStubSpan;
import org.telegram.ui.Components.FloatSeekBarAccessibilityDelegate;
import org.telegram.ui.Components.Forum.MessageTopicButton;
import org.telegram.ui.Components.InfiniteProgress;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.LoadingDrawable;
import org.telegram.ui.Components.MediaActionDrawable;
import org.telegram.ui.Components.MessageBackgroundDrawable;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.MsgClockDrawable;
import org.telegram.ui.Components.Point;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RadialProgress2;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.RoundVideoPlayingDrawable;
import org.telegram.ui.Components.SeekBar;
import org.telegram.ui.Components.SeekBarAccessibilityDelegate;
import org.telegram.ui.Components.SeekBarWaveform;
import org.telegram.ui.Components.SlotsDrawable;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.TimerParticles;
import org.telegram.ui.Components.TranscribeButton;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanBotCommand;
import org.telegram.ui.Components.URLSpanBrowser;
import org.telegram.ui.Components.URLSpanMono;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import org.telegram.ui.Components.VideoForwardDrawable;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.PinchToZoomHelper;
import org.telegram.ui.SecretMediaViewer;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicReference;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;

public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate, ImageReceiver.ImageReceiverDelegate, DownloadController.FileDownloadProgressListener, TextSelectionHelper.SelectableView, NotificationCenter.NotificationCenterDelegate {
    private final static int TIME_APPEAR_MS = 200;

    public boolean clipToGroupBounds;
    public boolean drawForBlur;
    private boolean flipImage;
    private boolean visibleOnScreen;
    public boolean shouldCheckVisibleOnScreen;
    float parentBoundsTop;
    int parentBoundsBottom;

    public RadialProgress2 getRadialProgress() {
        return radialProgress;
    }

    boolean enterTransitionInProgress;

    public void setEnterTransitionInProgress(boolean b) {
        enterTransitionInProgress = b;
        invalidate();
    }

    public ReactionsLayoutInBubble.ReactionButton getReactionButton(ReactionsLayoutInBubble.VisibleReaction visibleReaction) {
        return reactionsLayoutInBubble.getReactionButton(visibleReaction);
    }

    // primary message for group
    // contains caption, reactions etc for all group
    public MessageObject getPrimaryMessageObject() {
        MessageObject messageObject = null;
        if (currentMessageObject != null && currentMessagesGroup != null && currentMessageObject.hasValidGroupId()) {
            messageObject = currentMessagesGroup.findPrimaryMessageObject();
        }
        if (messageObject != null) {
            return messageObject;
        }
        return currentMessageObject;
    }

    @Override
    public void didReceivedNotification(int id, int account, Object... args) {
        if (id == NotificationCenter.startSpoilers) {
            setSpoilersSuppressed(false);
        } else if (id == NotificationCenter.stopSpoilers) {
            setSpoilersSuppressed(true);
        } else if (id == NotificationCenter.userInfoDidLoad) {
            if (currentUser != null) {
                Long uid = (Long) args[0];
                if (currentUser.id == uid) {
                    setAvatar(currentMessageObject);
                }
            }
        } else if (id == NotificationCenter.emojiLoaded) {
            invalidate();
        }
    }

    private void setAvatar(MessageObject messageObject) {
        if (messageObject == null) {
            return;
        }
        if (isAvatarVisible) {
            if (messageObject.customAvatarDrawable != null) {
                avatarImage.setImageBitmap(messageObject.customAvatarDrawable);
            } else if (currentUser != null) {
                if (currentUser.photo != null) {
                    currentPhoto = currentUser.photo.photo_small;
                } else {
                    currentPhoto = null;
                }
                post(() -> {
                    avatarDrawable.setInfo(currentUser);
                    avatarImage.setForUserOrChat(currentUser, avatarDrawable, null, LiteMode.isEnabled(LiteMode.FLAGS_CHAT), VectorAvatarThumbDrawable.TYPE_SMALL);
                });
            } else if (currentChat != null) {
                if (currentChat.photo != null) {
                    currentPhoto = currentChat.photo.photo_small;
                } else {
                    currentPhoto = null;
                }
                post(() -> {
                    avatarDrawable.setInfo(currentChat);
                    avatarImage.setForUserOrChat(currentChat, avatarDrawable);
                });
            } else if (messageObject != null && messageObject.isSponsored()) {
                if (messageObject.sponsoredChatInvite != null && messageObject.sponsoredChatInvite.chat != null) {
                    post(() -> {
                        avatarDrawable.setInfo(messageObject.sponsoredChatInvite.chat);
                        avatarImage.setForUserOrChat(messageObject.sponsoredChatInvite.chat, avatarDrawable);
                    });
                } else {
                    avatarDrawable.setInfo(messageObject.sponsoredChatInvite);
                    if (messageObject.sponsoredChatInvite != null) {
                        TLRPC.Photo photo = messageObject.sponsoredChatInvite.photo;
                        if (photo != null) {
                            avatarImage.setImage(ImageLocation.getForPhoto(photo.sizes.get(0), photo), "50_50", avatarDrawable, null, null, 0);
                        }
                    }
                }
            } else {
                currentPhoto = null;
                avatarDrawable.setInfo(messageObject.getFromChatId(), null, null);
                avatarImage.setImage(null, null, avatarDrawable, null, null, 0);
            }
        } else {
            currentPhoto = null;
        }
    }

    public void setSpoilersSuppressed(boolean s) {
        for (int i = 0; i < captionSpoilers.size(); i++) {
            SpoilerEffect eff = captionSpoilers.get(i);
            eff.setSuppressUpdates(s);
        }
        for (int i = 0; i < replySpoilers.size(); i++) {
            SpoilerEffect eff = replySpoilers.get(i);
            eff.setSuppressUpdates(s);
        }
        if (getMessageObject() != null && getMessageObject().textLayoutBlocks != null) {
            for (int k = 0; k < getMessageObject().textLayoutBlocks.size(); k++) {
                MessageObject.TextLayoutBlock bl = getMessageObject().textLayoutBlocks.get(k);
                for (int i = 0; i < bl.spoilers.size(); i++) {
                    SpoilerEffect eff = bl.spoilers.get(i);
                    eff.setSuppressUpdates(s);
                }
            }
        }
    }

    public boolean hasSpoilers() {
        if (hasCaptionLayout() && !captionSpoilers.isEmpty() || replyTextLayout != null && !replySpoilers.isEmpty()) {
            return true;
        }
        if (getMessageObject() != null && getMessageObject().textLayoutBlocks != null) {
            for (MessageObject.TextLayoutBlock bl : getMessageObject().textLayoutBlocks) {
                if (!bl.spoilers.isEmpty()) {
                    return true;
                }
            }
        }
        return false;
    }

    private void updateSpoilersVisiblePart(int top, int bottom) {
        if (hasCaptionLayout()) {
            float off = -captionY;
            for (SpoilerEffect eff : captionSpoilers) {
                eff.setVisibleBounds(0, top + off, getWidth(), bottom + off);
            }
        }
        if (replyTextLayout != null) {
            float off = -replyStartY - replyTextLayout.getHeight();
            for (SpoilerEffect eff : replySpoilers) {
                eff.setVisibleBounds(0, top + off, getWidth(), bottom + off);
            }
        }
        if (getMessageObject() != null && getMessageObject().textLayoutBlocks != null) {
            for (MessageObject.TextLayoutBlock bl : getMessageObject().textLayoutBlocks) {
                for (SpoilerEffect eff : bl.spoilers) {
                    eff.setVisibleBounds(0, top - bl.textYOffset - textY, getWidth(), bottom - bl.textYOffset - textY);
                }
            }
        }
    }

    public void setScrimReaction(String scrimViewReaction) {
        reactionsLayoutInBubble.setScrimReaction(scrimViewReaction);
    }

    public void drawScrimReaction(Canvas canvas, String scrimViewReaction) {
        if ((currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) {
            reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, scrimViewReaction);
        }
    }

    public boolean checkUnreadReactions(float clipTop, int clipBottom) {
        if (!reactionsLayoutInBubble.hasUnreadReactions) {
            return false;
        }
        float y = getY() + reactionsLayoutInBubble.y;
        if (y > clipTop && y + reactionsLayoutInBubble.height - AndroidUtilities.dp(16) < clipBottom) {
            return true;
        }
        return false;
    }

    public void markReactionsAsRead() {
        reactionsLayoutInBubble.hasUnreadReactions = false;
        if (currentMessageObject == null) {
            return;
        }
        currentMessageObject.markReactionsAsRead();
    }

    public void setVisibleOnScreen(boolean visibleOnScreen) {
        if (this.visibleOnScreen != visibleOnScreen) {
            this.visibleOnScreen = visibleOnScreen;
            checkImageReceiversAttachState();
        }
    }

    public void setParentBounds(float chatListViewPaddingTop, int blurredViewBottomOffset) {
        parentBoundsTop = chatListViewPaddingTop;
        parentBoundsBottom = blurredViewBottomOffset;
        if (photoImageOutOfBounds) {
            float top = getY() + photoImage.getImageY();
            float bottom = top + photoImage.getImageHeight();
            if (bottom >= parentBoundsTop && top <= parentBoundsBottom) {
                invalidate();
            }
        }
    }

    //点击事件回调
    public interface ChatMessageCellDelegate {
        default boolean isReplyOrSelf() {
            return false;
        }

        default void didPressExtendedMediaPreview(ChatMessageCell cell, TLRPC.KeyboardButton button) {
        }

        default void didPressUserAvatar(ChatMessageCell cell, TLRPC.User user, float touchX, float touchY) {
        }

        default boolean didLongPressUserAvatar(ChatMessageCell cell, TLRPC.User user, float touchX, float touchY) {
            return false;
        }

        default void didPressHiddenForward(ChatMessageCell cell) {
        }

        default void didPressViaBotNotInline(ChatMessageCell cell, long botId) {
        }

        default void didPressViaBot(ChatMessageCell cell, String username) {
        }

        default void didPressChannelAvatar(ChatMessageCell cell, TLRPC.Chat chat, int postId, float touchX, float touchY) {
        }

        default boolean didLongPressChannelAvatar(ChatMessageCell cell, TLRPC.Chat chat, int postId, float touchX, float touchY) {
            return false;
        }

        default void didPressCancelSendButton(ChatMessageCell cell) {
        }

        default void didLongPress(ChatMessageCell cell, float x, float y) {
        }

        default void didPressReplyMessage(ChatMessageCell cell, int id) {
        }

        default boolean isProgressLoading(ChatMessageCell cell, int type) {
            return false;
        }

        default String getProgressLoadingBotButtonUrl(ChatMessageCell cell) {
            return null;
        }

        default CharacterStyle getProgressLoadingLink(ChatMessageCell cell) {
            return null;
        }

        default void didPressUrl(ChatMessageCell cell, CharacterStyle url, boolean longPress) {
        }

        default void needOpenWebView(MessageObject message, String url, String title, String description, String originalUrl, int w, int h) {
        }

        default void didPressImage(ChatMessageCell cell, float x, float y) {
        }

        default void didPressSideButton(ChatMessageCell cell) {
        }

        default void didPressOther(ChatMessageCell cell, float otherX, float otherY) {
        }

        default void didPressTime(ChatMessageCell cell) {
        }

        default void didPressBotButton(ChatMessageCell cell, TLRPC.KeyboardButton button) {
        }

        default void didLongPressBotButton(ChatMessageCell cell, TLRPC.KeyboardButton button) {
        }

        default void didPressReaction(ChatMessageCell cell, TLRPC.ReactionCount reaction, boolean longpress) {
        }

        default void didPressVoteButtons(ChatMessageCell cell, ArrayList<TLRPC.TL_pollAnswer> buttons, int showCount, int x, int y) {
        }

        default void didPressInstantButton(ChatMessageCell cell, int type) {
        }

        default void didPressCommentButton(ChatMessageCell cell) {
        }

        default void didPressHint(ChatMessageCell cell, int type) {
        }

        default void needShowPremiumFeatures(String source) {
        }

        default void needShowPremiumBulletin(int type) {
        }

        default String getAdminRank(long uid) {
            return null;
        }

        default boolean needPlayMessage(MessageObject messageObject, boolean muted) {
            return false;
        }

        default boolean drawingVideoPlayerContainer() {
            return false;
        }

        default boolean canPerformActions() {
            return false;
        }

        default boolean onAccessibilityAction(int action, Bundle arguments) {
            return false;
        }

        default void videoTimerReached() {
        }

        default void didStartVideoStream(MessageObject message) {
        }

        default boolean shouldRepeatSticker(MessageObject message) {
            return true;
        }

        default void setShouldNotRepeatSticker(MessageObject message) {
        }

        default TextSelectionHelper.ChatListTextSelectionHelper getTextSelectionHelper() {
            return null;
        }

        default boolean hasSelectedMessages() {
            return false;
        }

        default void needReloadPolls() {

        }

        default void onDiceFinished() {

        }

        default boolean shouldDrawThreadProgress(ChatMessageCell cell) {
            return false;
        }

        default PinchToZoomHelper getPinchToZoomHelper() {
            return null;
        }

        default boolean keyboardIsOpened() {
            return false;
        }

        default boolean isLandscape() {
            return false;
        }

        default void invalidateBlur() {
        }

        default boolean canDrawOutboundsContent() {
            return true;
        }

        default boolean didPressAnimatedEmoji(ChatMessageCell cell, AnimatedEmojiSpan span) {
            return false;
        }

        default void didPressTopicButton(ChatMessageCell cell) {}

        default boolean shouldShowTopicButton() {
            return false;
        }
    }

    private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
    private final static int DOCUMENT_ATTACH_TYPE_DOCUMENT = 1;
    private final static int DOCUMENT_ATTACH_TYPE_GIF = 2;
    private final static int DOCUMENT_ATTACH_TYPE_AUDIO = 3;
    private final static int DOCUMENT_ATTACH_TYPE_VIDEO = 4;
    private final static int DOCUMENT_ATTACH_TYPE_MUSIC = 5;
    private final static int DOCUMENT_ATTACH_TYPE_STICKER = 6;
    private final static int DOCUMENT_ATTACH_TYPE_ROUND = 7;
    private final static int DOCUMENT_ATTACH_TYPE_WALLPAPER = 8;
    private final static int DOCUMENT_ATTACH_TYPE_THEME = 9;

    private class BotButton {
        private int x;
        private int y;
        private int width;
        private int height;
        private StaticLayout title;
        private TLRPC.KeyboardButton button;
        private TLRPC.TL_reactionCount reaction;
        private int angle;
        private float progressAlpha;
        private long lastUpdateTime;
        private boolean isInviteButton;

        private LoadingDrawable loadingDrawable;
        private Drawable selectorDrawable;

        private boolean pressed;
        private float pressT;
        private ValueAnimator pressAnimator;
        private void setPressed(boolean pressed) {
            if (this.pressed != pressed) {
                this.pressed = pressed;
                invalidateOutbounds();
                if (pressed) {
                    if (pressAnimator != null) {
                        pressAnimator.removeAllListeners();
                        pressAnimator.cancel();
                    }
                }
                if (!pressed && pressT != 0) {
                    pressAnimator = ValueAnimator.ofFloat(pressT, 0);
                    pressAnimator.addUpdateListener(animation -> {
                        pressT = (float) animation.getAnimatedValue();
                        invalidateOutbounds();
                    });
                    pressAnimator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            super.onAnimationEnd(animation);
                            pressAnimator = null;
                        }
                    });
                    pressAnimator.setInterpolator(new OvershootInterpolator(2.0f));
                    pressAnimator.setDuration(350);
                    pressAnimator.start();
                }
            }
        }

        private float getPressScale() {
            if (pressed && pressT != 1f) {
                pressT += (float) Math.min(40, 1000f / AndroidUtilities.screenRefreshRate) / 100f;
                pressT = Utilities.clamp(pressT, 1f, 0);
                invalidateOutbounds();
            }
            return 0.96f + 0.04f * (1f - pressT);
        }
    }

    public static class PollButton {
        public int x;
        public int y;
        public int height;
        private int percent;
        private float decimal;
        private int prevPercent;
        private float percentProgress;
        private float prevPercentProgress;
        private boolean chosen;
        private int count;
        private boolean prevChosen;
        private boolean correct;
        private StaticLayout title;
        private TLRPC.TL_pollAnswer answer;
    }

    public boolean pinnedTop;
    public boolean pinnedBottom;
    private boolean drawPinnedTop;
    public boolean drawPinnedBottom;
    private MessageObject.GroupedMessages currentMessagesGroup;
    private MessageObject.GroupedMessagePosition currentPosition;
    private boolean groupPhotoInvisible;
    public final ReactionsLayoutInBubble reactionsLayoutInBubble = new ReactionsLayoutInBubble(this);

    private boolean invalidateSpoilersParent;

    private int textX;//文字起始位置
    private int unmovedTextX;
    private int textY;//文字起始位置
    private int totalHeight;
    private int additionalTimeOffsetY;
    private int keyboardHeight;
    private int linkBlockNum;
    private int linkSelectionBlockNum;

    private boolean inLayout;

    private int currentMapProvider;

    private Rect scrollRect = new Rect();

    private int lastVisibleBlockNum;
    private int firstVisibleBlockNum;
    private int totalVisibleBlocksCount;
    private boolean needNewVisiblePart;
    private boolean fullyDraw;

    private int parentWidth;
    private int parentHeight;
    public float parentViewTopOffset;

    private boolean attachedToWindow;

    private boolean isUpdating;

    private RadialProgress2 radialProgress;
    private RadialProgress2 videoRadialProgress;
    private boolean drawRadialCheckBackground;
    private ImageReceiver photoImage;
    private ImageReceiver blurredPhotoImage;
    private AvatarDrawable contactAvatarDrawable;
    private Drawable locationLoadingThumb;

    private boolean disallowLongPress;
    private float lastTouchX;
    private float lastTouchY;

    private boolean drawMediaCheckBox;
    private boolean drawSelectionBackground;
    private CheckBoxBase mediaCheckBox;
    private CheckBoxBase checkBox;
    private boolean checkBoxVisible;
    private boolean checkBoxAnimationInProgress;
    private float checkBoxAnimationProgress;
    private long lastCheckBoxAnimationTime;
    private int checkBoxTranslation;

    private boolean isSmallImage;
    private boolean drawImageButton;
    private boolean drawVideoImageButton;
    private long lastLoadingSizeTotal;
    private boolean drawVideoSize;
    private boolean canStreamVideo;
    private int animatingDrawVideoImageButton;
    private float animatingDrawVideoImageButtonProgress;
    private boolean animatingNoSoundPlaying;
    private int animatingNoSound;
    private float animatingNoSoundProgress;
    private int noSoundCenterX;
    private int forwardNameCenterX;
    private long lastAnimationTime;
    private long lastNamesAnimationTime;
    private int documentAttachType;
    private TLRPC.Document documentAttach;
    private boolean drawPhotoImage;
    private boolean hasLinkPreview;
    private boolean hasOldCaptionPreview;
    private boolean hasGamePreview;
    private boolean hasInvoicePreview;
    private int linkPreviewHeight;
    private int mediaOffsetY;
    private int descriptionY;
    private int durationWidth;
    private int photosCountWidth;
    private int descriptionX;
    private int titleX;
    private int authorX;
    private boolean siteNameRtl;
    private int siteNameWidth;
    private StaticLayout siteNameLayout;
    private StaticLayout titleLayout;
    private StaticLayout descriptionLayout;
    private StaticLayout videoInfoLayout;
    private StaticLayout photosCountLayout;
    private StaticLayout authorLayout;
    private StaticLayout instantViewLayout;
    private boolean drawInstantView;
    private boolean pollInstantViewTouchesBottom;
    private int drawInstantViewType;
    private int imageBackgroundColor;
    private float imageBackgroundIntensity;
    private int imageBackgroundGradientColor1;
    private int imageBackgroundGradientColor2;
    private int imageBackgroundGradientColor3;
    private int imageBackgroundGradientRotation = 45;
    private LinearGradient gradientShader;
    private MotionBackgroundDrawable motionBackgroundDrawable;
    private int imageBackgroundSideColor;
    private int imageBackgroundSideWidth;
    private boolean drawJoinGroupView;
    private boolean drawJoinChannelView;
    private int instantTextX;
    private int instantTextLeftX;
    private int instantWidth;
    private boolean instantTextNewLine;
    private boolean instantPressed;
    private boolean instantButtonPressed;
    private float instantButtonPressProgress;
    private Drawable[] selectorDrawable = new Drawable[2];
    private int[] selectorDrawableMaskType = new int[2];
    private RectF instantButtonRect = new RectF();
    private LoadingDrawable instantButtonLoading;
    private ValueAnimator instantButtonPressAnimator;
    private int[] pressedState = new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed};
    private float animatingLoadingProgressProgress;
    CharSequence accessibilityText;
    private boolean accessibilityTextUnread, accessibilityTextContentUnread;
    private long accessibilityTextFileSize;
    private boolean wasTranscriptionOpen;

    private RoundVideoPlayingDrawable roundVideoPlayingDrawable;

    private StaticLayout docTitleLayout;
    private int docTitleWidth;
    private int docTitleOffsetX;
    private boolean locationExpired;

    private StaticLayout captionLayout;
    private CharSequence currentCaption;
    private int captionOffsetX;
    private float captionX;
    private float captionY;
    private int captionHeight;
    private int captionWidth;
    private int addedCaptionHeight;

    private StaticLayout infoLayout;
    private StaticLayout loadingProgressLayout;
    private int infoX;
    private int infoWidth;

    private String currentUrl;
    private WebFile currentWebFile;
    private WebFile lastWebFile;
    private boolean addedForTest;

    private boolean hasEmbed;

    private boolean wasSending;
    private boolean checkOnlyButtonPressed;
    private int buttonX;
    private int buttonY;
    private int videoButtonX;
    private int videoButtonY;
    private int buttonState;
    private int buttonPressed;
    private int videoButtonPressed;
    private int miniButtonPressed;
    private int otherX;
    private int otherY;
    private int lastWidth;
    private int lastHeight;
    private int hasMiniProgress;
    private int miniButtonState;
    private boolean imagePressed;
    private boolean otherPressed;
    private boolean photoNotSet;
    private RectF deleteProgressRect = new RectF();
    private RectF rect = new RectF();
    private TLObject photoParentObject;
    private TLRPC.PhotoSize currentPhotoObject;
    private TLRPC.PhotoSize currentPhotoObjectThumb;
    private BitmapDrawable currentPhotoObjectThumbStripped;
    private String currentPhotoFilter;
    private String currentPhotoFilterThumb;

    private boolean timePressed;

    private float timeAlpha = 1.0f;
    private float controlsAlpha = 1.0f;
    private long lastControlsAlphaChangeTime;
    private long totalChangeTime;
    private boolean mediaWasInvisible;
    private boolean timeWasInvisible;

    private AnimatedEmojiSpan pressedEmoji;
    private LinkSpanDrawable pressedLink;
    private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this);
    private int pressedLinkType;
    private boolean linkPreviewPressed;
    private boolean gamePreviewPressed;
    private ArrayList<LinkPath> urlPathCache = new ArrayList<>();
    private ArrayList<LinkPath> urlPathSelection = new ArrayList<>();
    private CharacterStyle highlightPathSpan;
    private LinkPath highlightPath;
    private long highlightPathStart;

    private LoadingDrawable progressLoadingLinkCurrentDrawable;
    class LoadingDrawableLocation {
        LoadingDrawable drawable;
        int blockNum;
    };
    private ArrayList<LoadingDrawableLocation> progressLoadingLinkDrawables;
    private CharacterStyle progressLoadingLink;

    private Path rectPath = new Path();
    private static float[] radii = new float[8];

    private boolean useSeekBarWaveform;
    private SeekBar seekBar;
    private SeekBarWaveform seekBarWaveform;
    private SeekBarAccessibilityDelegate seekBarAccessibilityDelegate;
    private int seekBarX;
    private int seekBarY;

    private boolean useTranscribeButton;
    private TranscribeButton transcribeButton;
    private float transcribeX, transcribeY;

    private StaticLayout durationLayout;
    private int lastTime;
    private int timeWidthAudio;
    private int timeAudioX;

    private StaticLayout songLayout;
    private int songX;

    private StaticLayout performerLayout;
    private int performerX;

    private ArrayList<PollButton> pollButtons = new ArrayList<>();
    private float pollAnimationProgress;
    private float pollAnimationProgressTime;
    private boolean pollVoted;
    private boolean pollClosed;
    private long lastPollCloseTime;
    private String closeTimeText;
    private int closeTimeWidth;
    private boolean pollVoteInProgress;
    private boolean vibrateOnPollVote;
    private boolean pollUnvoteInProgress;
    private boolean animatePollAnswer;
    private boolean animatePollAvatars;
    private boolean animatePollAnswerAlpha;
    private int pollVoteInProgressNum;
    private long voteLastUpdateTime;
    private float voteRadOffset;
    private float voteCurrentCircleLength;
    private boolean firstCircleLength;
    private boolean voteRisingCircleLength;
    private float voteCurrentProgressTime;
    private int pressedVoteButton;
    private TLRPC.Poll lastPoll;
    private float timerTransitionProgress;
    private ArrayList<TLRPC.TL_pollAnswerVoters> lastPollResults;
    private int lastPollResultsVoters;
    private TimerParticles timerParticles;
    private int pollHintX;
    private int pollHintY;
    private boolean pollHintPressed;
    private boolean hintButtonVisible;
    private float hintButtonProgress;

    private String lastPostAuthor;
    private TLRPC.Message lastReplyMessage;

    private boolean hasPsaHint;
    private int psaHelpX;
    private int psaHelpY;
    private boolean psaHintPressed;
    private boolean psaButtonVisible;
    private float psaButtonProgress;

    private TLRPC.TL_messageReactions lastReactions;

    private boolean autoPlayingMedia;

    private ArrayList<BotButton> botButtons = new ArrayList<>();
    private HashMap<String, BotButton> botButtonsByData = new HashMap<>();
    private HashMap<String, BotButton> botButtonsByPosition = new HashMap<>();
    private String botButtonsLayout;
    private int widthForButtons;
    private int pressedBotButton;

    private SpoilerEffect spoilerPressed;
    private boolean isCaptionSpoilerPressed;
    private boolean isSpoilerRevealing;

    private MessageObject currentMessageObject;
    private MessageObject messageObjectToSet;
    private MessageObject.GroupedMessages groupedMessagesToSet;
    private boolean topNearToSet;
    private boolean bottomNearToSet;

    private AnimatorSet shakeAnimation;

    //
    private int TAG;
    private int currentAccount = UserConfig.selectedAccount;

    private boolean invalidatesParent;

    public boolean isChat;//save messages中isChat为true
    public boolean isBot;
    public boolean isMegagroup;
    public boolean isForum;
    public boolean isForumGeneral;
    public boolean isThreadChat;
    public boolean hasDiscussion;
    public boolean isPinned;
    private boolean wasPinned;
    public long linkedChatId;
    public boolean isRepliesChat;
    public boolean isPinnedChat;
    private boolean isPressed;
    private boolean forwardName;
    private boolean isHighlighted;
    private boolean isHighlightedAnimated;
    private int highlightProgress;
    private float currentSelectedBackgroundAlpha;
    private long lastHighlightProgressTime;
    private boolean mediaBackground;
    private boolean isMedia;
    private boolean isCheckPressed = true;
    private boolean wasLayout;
    private boolean isAvatarVisible;
    private boolean isThreadPost;
    private boolean drawBackground = true;
    private int substractBackgroundHeight;
    private boolean allowAssistant;
    private Theme.MessageDrawable currentBackgroundDrawable;
    private Theme.MessageDrawable currentBackgroundSelectedDrawable;
    private int backgroundDrawableLeft;
    private int backgroundDrawableRight;
    private int backgroundDrawableTop;
    private int backgroundDrawableBottom;
    private int viaWidth;
    private int viaNameWidth;
    private TypefaceSpan viaSpan1;
    private TypefaceSpan viaSpan2;
    private int availableTimeWidth;
    private int widthBeforeNewTimeLine;

    private int backgroundWidth = 100;
    private boolean hasNewLineForTime;

    private int layoutWidth;
    private int layoutHeight;

    private ImageReceiver[] pollAvatarImages;
    private AvatarDrawable[] pollAvatarDrawables;
    private boolean[] pollAvatarImagesVisible;
    private CheckBoxBase[] pollCheckBox;

    private InfiniteProgress commentProgress;
    private float commentProgressAlpha;
    private long commentProgressLastUpadteTime;
    private ImageReceiver[] commentAvatarImages;
    private AvatarDrawable[] commentAvatarDrawables;
    private boolean[] commentAvatarImagesVisible;
    private StaticLayout commentLayout;
    private AnimatedNumberLayout commentNumberLayout;
    private boolean drawCommentNumber;
    private int commentArrowX;
    private int commentUnreadX;
    private boolean commentDrawUnread;
    private int commentWidth;
    private int commentX;
    private int totalCommentWidth;
    private int commentNumberWidth;
    private boolean drawCommentButton;
    private Rect commentButtonRect = new Rect();
    private boolean commentButtonPressed;

    private ImageReceiver avatarImage;
    private AvatarDrawable avatarDrawable;
    private boolean avatarPressed;
    private boolean forwardNamePressed;
    private boolean forwardBotPressed;

    private ImageReceiver locationImageReceiver;

    public StaticLayout replyNameLayout;
    public StaticLayout replyTextLayout;
    private AtomicReference<Layout> spoilersPatchedReplyTextLayout = new AtomicReference<>();
    public ImageReceiver replyImageReceiver;
    public int replyStartX;
    public int replyStartY;
    public float replyHeight;
    private int replyNameWidth;
    private int replyNameOffset;
    private int replyTextWidth;
    private int replyTextOffset;
    public boolean needReplyImage;
    private boolean replyPressed;
    private boolean replySelectorPressed, replySelectorCanBePressed;
    private AnimatedFloat replyPressedFloat;
    private float replyTouchX, replyTouchY;
    private TLRPC.PhotoSize currentReplyPhoto;

    private AnimatedFloat translationLoadingFloat;
    private LinkPath translationLoadingPath;
    private LoadingDrawable translationLoadingDrawable;
    private ArrayList<MessageObject.TextLayoutBlock> translationLoadingDrawableText;
    private StaticLayout translationLoadingDrawableLayout;

    private boolean drawTopic;
    private MessageTopicButton topicButton;

    private int drawSideButton;
    private boolean sideButtonPressed;
    private float sideStartX;
    private float sideStartY;

    private StaticLayout nameLayout;
    private int nameLayoutWidth;
    private StaticLayout adminLayout;
    private int nameWidth;
    private float nameOffsetX;
    private float nameX;
    private float nameY;
    private boolean drawName;
    private boolean drawNameLayout;

    private StaticLayout[] forwardedNameLayout = new StaticLayout[2];
    private int forwardedNameWidth;
    private boolean drawForwardedName;
    private float forwardNameX;
    private int forwardNameY;
    private int forwardHeight;
    private float[] forwardNameOffsetX = new float[2];

    private float drawTimeX;
    private float drawTimeY;
    private StaticLayout timeLayout;
    private int timeWidth;
    private int timeTextWidth;
    private int timeX;
    private CharSequence currentTimeString;
    private boolean drawTime = true;
    private boolean forceNotDrawTime;
    private Paint drillHolePaint;
    private Path drillHolePath;

    private Path mediaSpoilerPath = new Path();
    private float[] mediaSpoilerRadii = new float[8];
    private SpoilerEffect mediaSpoilerEffect = new SpoilerEffect();
    private float mediaSpoilerRevealProgress;
    private float mediaSpoilerRevealX;
    private float mediaSpoilerRevealY;
    private float mediaSpoilerRevealMaxRadius;

    private float unlockAlpha = 1f;
    private float unlockX;
    private float unlockY;
    private StaticLayout unlockLayout;
    private int unlockTextWidth;
    private String currentUnlockString;
    private SpoilerEffect unlockSpoilerEffect = new SpoilerEffect();
    private Path unlockSpoilerPath = new Path();
    private float[] unlockSpoilerRadii = new float[8];

    private StaticLayout viewsLayout;
    private int viewsTextWidth;
    private String currentViewsString;

    private StaticLayout repliesLayout;
    private int repliesTextWidth;
    private String currentRepliesString;

    private TLRPC.User currentUser;
    private TLRPC.Chat currentChat;
    private TLRPC.FileLocation currentPhoto;
    private String currentNameString;
    private Object currentNameStatus;
    private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable currentNameStatusDrawable;

    private TLRPC.User currentForwardUser;
    private TLRPC.User currentViaBotUser;
    private long currentReplyUserId;
    private TLRPC.Chat currentForwardChannel;
    private String currentForwardName;
    private String currentForwardNameString;
    private boolean replyPanelIsForward;
    private boolean animationRunning;
    private boolean willRemoved;
    public AnimatedEmojiSpan.EmojiGroupedSpans animatedEmojiStack;
    public AnimatedEmojiSpan.EmojiGroupedSpans animatedEmojiReplyStack;
    public AnimatedEmojiSpan.EmojiGroupedSpans animatedEmojiDescriptionStack;
    public Drawable replySelector;
    public LoadingDrawable replyLoadingDrawable;
    private float replyLoadingT;
    private float[] replyLoadingSegment;
    private float[] replyRoundRectRadii;
    private Path replyRoundRectPath;
    public Rect replySelectorRect = new Rect();
    public int replySelectorColor;
    public float replySelectorRadLeft, replySelectorRadRight;

    private ChatMessageCellDelegate delegate;

    private MessageBackgroundDrawable backgroundDrawable;

    private int namesOffset;

    private int lastSendState;
    private int lastDeleteDate;
    private int lastViewsCount;
    private int lastRepliesCount;
    private float selectedBackgroundProgress;
    private boolean lastTranslated;

    private float viewTop;
    private int backgroundHeight;
    private int blurredViewTopOffset;
    private int blurredViewBottomOffset;

    private boolean scheduledInvalidate;

    private final boolean ALPHA_PROPERTY_WORKAROUND = Build.VERSION.SDK_INT == 28;
    private float alphaInternal = 1f;

    private final TransitionParams transitionParams = new TransitionParams();
    private boolean edited;
    private boolean imageDrawn;
    private boolean photoImageOutOfBounds;

    private boolean wouldBeInPip;
    private AnimatedFloat roundVideoPlayPipFloat = new AnimatedFloat(this, 200, CubicBezierInterpolator.EASE_OUT);
    private Paint roundVideoPipPaint;

    private FlagSecureReason flagSecure;

    private Runnable diceFinishCallback = new Runnable() {
        @Override
        public void run() {
            if (delegate != null) {
                delegate.onDiceFinished();
            }
        }
    };

    private int animateToStatusDrawableParams;
    private int animateFromStatusDrawableParams;
    private float statusDrawableProgress;
    private boolean statusDrawableAnimationInProgress;
    private ValueAnimator statusDrawableAnimator;

    private int overideShouldDrawTimeOnMedia;
    private float toSeekBarProgress;

    private Runnable invalidateRunnable = new Runnable() {
        @Override
        public void run() {
            checkLocationExpired();
            if (locationExpired) {
                invalidate();
                scheduledInvalidate = false;
            } else {
                invalidate((int) rect.left - 5, (int) rect.top - 5, (int) rect.right + 5, (int) rect.bottom + 5);
                if (scheduledInvalidate) {
                    AndroidUtilities.runOnUIThread(invalidateRunnable, 1000);
                }
            }
        }
    };
    private SparseArray<Rect> accessibilityVirtualViewBounds = new SparseArray<>();
    private boolean isRoundVideo;
    private boolean isPlayingRound;
    private float roundProgressAlpha;
    private float roundToPauseProgress;
    private float roundToPauseProgress2;
    private float roundPlayingDrawableProgress;
    private long lastSeekUpdateTime;

    float seekbarRoundX;
    float seekbarRoundY;
    float lastDrawingPlayPauseAlpha;
    int roundSeekbarTouched;
    float roundSeekbarOutProgress;
    float roundSeekbarOutAlpha;

    private float lastDrawingAudioProgress;
    private int currentFocusedVirtualView = -1;
    public boolean drawFromPinchToZoom;

    private Theme.MessageDrawable.PathDrawParams backgroundCacheParams = new Theme.MessageDrawable.PathDrawParams();

    VideoForwardDrawable videoForwardDrawable;
    VideoPlayerRewinder videoPlayerRewinder;

    private Theme.ResourcesProvider resourcesProvider;
    private final boolean canDrawBackgroundInParent;

    // Public for enter transition
    public List<SpoilerEffect> replySpoilers = new ArrayList<>();
    private Stack<SpoilerEffect> replySpoilersPool = new Stack<>();
    private List<SpoilerEffect> captionSpoilers = new ArrayList<>();
    private Stack<SpoilerEffect> captionSpoilersPool = new Stack<>();
    private AtomicReference<Layout> captionPatchedSpoilersLayout = new AtomicReference<>();
    private Path sPath = new Path();
    public boolean isBlurred;

    public ChatMessageCell(Context context) {
        this(context, false, null);
    }

    public ChatMessageCell(Context context, boolean canDrawBackgroundInParent, Theme.ResourcesProvider resourcesProvider) {
        super(context);
        this.resourcesProvider = resourcesProvider;
        this.canDrawBackgroundInParent = canDrawBackgroundInParent;

        backgroundDrawable = new MessageBackgroundDrawable(this);
        avatarImage = new ImageReceiver();
        avatarImage.setAllowLoadingOnAttachedOnly(true);
        avatarImage.setRoundRadius(AndroidUtilities.dp(21));
        avatarDrawable = new AvatarDrawable();
        replyImageReceiver = new ImageReceiver(this);
        replyImageReceiver.setAllowLoadingOnAttachedOnly(true);
        replyImageReceiver.setRoundRadius(AndroidUtilities.dp(4));
        locationImageReceiver = new ImageReceiver(this);
        locationImageReceiver.setAllowLoadingOnAttachedOnly(true);
        locationImageReceiver.setRoundRadius(AndroidUtilities.dp(26.1f));
        TAG = DownloadController.getInstance(currentAccount).generateObserverTag();

        contactAvatarDrawable = new AvatarDrawable();
        photoImage = new ImageReceiver(this);
        photoImage.setAllowLoadingOnAttachedOnly(true);
        photoImage.setUseRoundForThumbDrawable(true);
        photoImage.setDelegate(this);
        blurredPhotoImage = new ImageReceiver(this);
        blurredPhotoImage.setAllowLoadingOnAttachedOnly(true);
        blurredPhotoImage.setUseRoundForThumbDrawable(true);
        radialProgress = new RadialProgress2(this, resourcesProvider);
        videoRadialProgress = new RadialProgress2(this, resourcesProvider);
        videoRadialProgress.setDrawBackground(false);
        videoRadialProgress.setCircleRadius(AndroidUtilities.dp(15));
        seekBar = new SeekBar(this) {
            @Override
            protected void onTimestampUpdate(URLSpanNoUnderline link) {
                highlightCaptionLink(link);
            }
        };
        seekBar.setDelegate(this);
        seekBarWaveform = new SeekBarWaveform(context);
        seekBarWaveform.setDelegate(this);
        seekBarWaveform.setParentView(this);
        seekBarAccessibilityDelegate = new FloatSeekBarAccessibilityDelegate() {
            @Override
            public float getProgress() {
                if (currentMessageObject.isMusic()) {
                    return seekBar.getProgress();
                } else if (currentMessageObject.isVoice()) {
                    if (useSeekBarWaveform) {
                        return seekBarWaveform.getProgress();
                    } else {
                        return seekBar.getProgress();
                    }
                } else if (currentMessageObject.isRoundVideo()) {
                    return currentMessageObject.audioProgress;
                } else {
                    return 0f;
                }
            }

            @Override
            public void setProgress(float progress) {
                if (currentMessageObject.isMusic()) {
                    seekBar.setProgress(progress);
                } else if (currentMessageObject.isVoice()) {
                    if (useSeekBarWaveform) {
                        seekBarWaveform.setProgress(progress);
                    } else {
                        seekBar.setProgress(progress);
                    }
                } else if (currentMessageObject.isRoundVideo()) {
                    if (useSeekBarWaveform) {
                        if (seekBarWaveform != null) {
                            seekBarWaveform.setProgress(progress);
                        }
                    } else {
                        if (seekBar != null) {
                            seekBar.setProgress(progress);
                        }
                    }
                    currentMessageObject.audioProgress = progress;
                } else {
                    return;
                }
                onSeekBarDrag(progress);
                invalidate();
            }
        };
        roundVideoPlayingDrawable = new RoundVideoPlayingDrawable(this, resourcesProvider);
        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
    }

    public void setResourcesProvider(Theme.ResourcesProvider resourcesProvider) {
        this.resourcesProvider = resourcesProvider;
        if (radialProgress != null) {
            radialProgress.setResourcesProvider(resourcesProvider);
        }
        if (videoRadialProgress != null) {
            videoRadialProgress.setResourcesProvider(resourcesProvider);
        }
        if (roundVideoPlayingDrawable != null) {
            roundVideoPlayingDrawable.setResourcesProvider(resourcesProvider);
        }
    }

    private void createPollUI() {
        if (pollAvatarImages != null) {
            return;
        }
        pollAvatarImages = new ImageReceiver[3];
        pollAvatarDrawables = new AvatarDrawable[3];
        pollAvatarImagesVisible = new boolean[3];
        for (int a = 0; a < pollAvatarImages.length; a++) {
            pollAvatarImages[a] = new ImageReceiver(this);
            pollAvatarImages[a].setRoundRadius(AndroidUtilities.dp(8));
            pollAvatarDrawables[a] = new AvatarDrawable();
            pollAvatarDrawables[a].setTextSize(AndroidUtilities.dp(22));
        }
        pollCheckBox = new CheckBoxBase[10];
        for (int a = 0; a < pollCheckBox.length; a++) {
            pollCheckBox[a] = new CheckBoxBase(this, 20, resourcesProvider);
            pollCheckBox[a].setDrawUnchecked(false);
            pollCheckBox[a].setBackgroundType(9);
        }
    }

    private void createCommentUI() {
        if (commentAvatarImages != null) {
            return;
        }
        commentAvatarImages = new ImageReceiver[3];
        commentAvatarDrawables = new AvatarDrawable[3];
        commentAvatarImagesVisible = new boolean[3];
        for (int a = 0; a < commentAvatarImages.length; a++) {
            commentAvatarImages[a] = new ImageReceiver(this);
            commentAvatarImages[a].setRoundRadius(AndroidUtilities.dp(12));
            commentAvatarDrawables[a] = new AvatarDrawable();
            commentAvatarDrawables[a].setTextSize(AndroidUtilities.dp(18));
        }
    }

    public void resetPressedLink(int type) {
        if (type != -1) {
            links.removeLinks(type);
        } else {
            links.clear();
        }
        pressedEmoji = null;
        if (pressedLink == null || pressedLinkType != type && type != -1) {
            return;
        }
        pressedLink = null;
        pressedLinkType = -1;
        invalidate();
    }

    private void resetUrlPaths() {
        if (urlPathSelection.isEmpty()) {
            return;
        }
        urlPathCache.addAll(urlPathSelection);
        urlPathSelection.clear();
    }

    private LinkPath obtainNewUrlPath() {
        LinkPath linkPath;
        if (!urlPathCache.isEmpty()) {
            linkPath = urlPathCache.get(0);
            urlPathCache.remove(0);
        } else {
            linkPath = new LinkPath(true);
        }
        linkPath.reset();
        urlPathSelection.add(linkPath);
        return linkPath;
    }

    private int[] getRealSpanStartAndEnd(Spannable buffer, CharacterStyle link) {
        int start = 0;
        int end = 0;
        boolean ok = false;
        if (link instanceof URLSpanBrowser) {
            URLSpanBrowser span = (URLSpanBrowser) link;
            TextStyleSpan.TextStyleRun style = span.getStyle();
            if (style != null && style.urlEntity != null) {
                start = style.urlEntity.offset;
                end = style.urlEntity.offset + style.urlEntity.length;
                ok = true;
            }
        }
        if (!ok) {
            start = buffer.getSpanStart(link);
            end = buffer.getSpanEnd(link);
        }
        return new int[]{start, end};
    }

    private boolean checkTextBlockMotionEvent(MotionEvent event) {
        if (!(currentMessageObject.type == MessageObject.TYPE_TEXT || currentMessageObject.type == MessageObject.TYPE_EMOJIS) || currentMessageObject.textLayoutBlocks == null || currentMessageObject.textLayoutBlocks.isEmpty() || !(currentMessageObject.messageText instanceof Spannable)) {
            return false;
        }
        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP && pressedLinkType == 1) {
            int x = (int) event.getX();
            int y = (int) event.getY();
            if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
                y -= textY;
                int blockNum = 0;
                for (int a = 0; a < currentMessageObject.textLayoutBlocks.size(); a++) {
                    if (currentMessageObject.textLayoutBlocks.get(a).textYOffset > y) {
                        break;
                    }
                    blockNum = a;
                }
                try {
                    MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
                    x -= textX - (block.isRtl() ? currentMessageObject.textXOffset : 0);
                    y -= block.textYOffset;
                    final int line = block.textLayout.getLineForVertical(y);
                    final int off = block.charactersOffset + block.textLayout.getOffsetForHorizontal(line, x);

                    final float left = block.textLayout.getLineLeft(line);
                    if (left <= x && left + block.textLayout.getLineWidth(line) >= x) {
                        Spannable buffer = (Spannable) currentMessageObject.messageText;
                        CharacterStyle[] link = buffer.getSpans(off, off, ClickableSpan.class);
                        boolean isMono = false;
                        if (link == null || link.length == 0) {
                            link = buffer.getSpans(off, off, URLSpanMono.class);
                            isMono = true;
                        }
                        if (link == null || link.length == 0) {
                            link = buffer.getSpans(off, off, AnimatedEmojiSpan.class);
                            isMono = false;
                        }
                        boolean ignore = false;
                        if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
                            ignore = true;
                        }
                        if (!ignore && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
                            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                                if (link[0] instanceof AnimatedEmojiSpan) {
                                    if (pressedEmoji == null || pressedEmoji != link[0]) {
                                        resetPressedLink(1);
                                        pressedEmoji = (AnimatedEmojiSpan) link[0];
                                        pressedLinkType = 1;
                                    }
                                } else if (pressedLink == null || pressedLink.getSpan() != link[0]) {
                                    links.removeLink(pressedLink);
                                    pressedLink = new LinkSpanDrawable(link[0], resourcesProvider, x, y, spanSupportsLongPress(link[0]));
                                    pressedLink.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLinkSelectBackground : Theme.key_chat_linkSelectBackground));
                                    linkBlockNum = blockNum;
                                    pressedLinkType = 1;
                                    try {
                                        LinkPath path = pressedLink.obtainNewPath();
                                        int[] pos = getRealSpanStartAndEnd(buffer, pressedLink.getSpan());
                                        pos[0] -= block.charactersOffset;
                                        pos[1] -= block.charactersOffset;
                                        path.setCurrentLayout(block.textLayout, pos[0], 0);
                                        block.textLayout.getSelectionPath(pos[0], pos[1], path);
                                        if (pos[1] >= block.charactersEnd) {
                                            for (int a = blockNum + 1; a < currentMessageObject.textLayoutBlocks.size(); a++) {
                                                MessageObject.TextLayoutBlock nextBlock = currentMessageObject.textLayoutBlocks.get(a);
                                                CharacterStyle[] nextLink;
                                                if (isMono) {
                                                    nextLink = buffer.getSpans(nextBlock.charactersOffset, nextBlock.charactersOffset, URLSpanMono.class);
                                                } else {
                                                    nextLink = buffer.getSpans(nextBlock.charactersOffset, nextBlock.charactersOffset, ClickableSpan.class);
                                                }
                                                if (nextLink == null || nextLink.length == 0 || nextLink[0] != pressedLink.getSpan()) {
                                                    break;
                                                }
                                                path = pressedLink.obtainNewPath();
                                                path.setCurrentLayout(nextBlock.textLayout, 0, nextBlock.textYOffset - block.textYOffset);
                                                int p1 = pos[1] + block.charactersOffset - nextBlock.charactersOffset;
                                                nextBlock.textLayout.getSelectionPath(0, p1, path);
                                                if (p1 < nextBlock.charactersEnd - 1) {
                                                    break;
                                                }
                                            }
                                        }
                                        if (pos[0] <= block.charactersOffset) {
                                            int offsetY = 0;
                                            for (int a = blockNum - 1; a >= 0; a--) {
                                                MessageObject.TextLayoutBlock nextBlock = currentMessageObject.textLayoutBlocks.get(a);
                                                CharacterStyle[] nextLink;
                                                if (isMono) {
                                                    nextLink = buffer.getSpans(nextBlock.charactersEnd - 1, nextBlock.charactersEnd - 1, URLSpanMono.class);
                                                } else {
                                                    nextLink = buffer.getSpans(nextBlock.charactersEnd - 1, nextBlock.charactersEnd - 1, ClickableSpan.class);
                                                }
                                                if (nextLink == null || nextLink.length == 0 || nextLink[0] != pressedLink.getSpan()) {
                                                    break;
                                                }
                                                path = pressedLink.obtainNewPath();
                                                offsetY -= nextBlock.height;
                                                int p0 = pos[0] + block.charactersOffset - nextBlock.charactersOffset;
                                                int p1 = pos[1] + block.charactersOffset - nextBlock.charactersOffset;
                                                path.setCurrentLayout(nextBlock.textLayout, p0, offsetY);
                                                nextBlock.textLayout.getSelectionPath(p0, p1, path);
                                                if (p0 > nextBlock.charactersOffset) {
                                                    break;
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        FileLog.e(e);
                                    }
                                    links.addLink(pressedLink, 1);
                                }
                                invalidate();
                                return true;
                            } else {
                                if (link[0] instanceof AnimatedEmojiSpan && pressedEmoji == link[0]) {
                                    if (delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
                                        resetPressedLink(1);
                                        pressedEmoji = null;
                                        return true;
                                    }
                                    resetPressedLink(1);
                                    pressedEmoji = null;
                                } else if (pressedLink != null && link[0] == pressedLink.getSpan()) {
                                    delegate.didPressUrl(this, pressedLink.getSpan(), false);
                                    resetPressedLink(1);
                                    return true;
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            } else {
                resetPressedLink(1);
            }
        }
        return false;
    }

    private boolean checkCaptionMotionEvent(MotionEvent event) {
        if (!(currentCaption instanceof Spannable) || captionLayout == null) {
            return false;
        }
        if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null || pressedEmoji != null) && event.getAction() == MotionEvent.ACTION_UP) {
            int x = (int) event.getX();
            int y = (int) event.getY();
            if (x >= captionX && x <= captionX + captionWidth && y >= captionY && y <= captionY + captionHeight) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    try {
                        x -= captionX;
                        y -= captionY;
                        final int line = captionLayout.getLineForVertical(y);
                        final int off = captionLayout.getOffsetForHorizontal(line, x);

                        final float left = captionLayout.getLineLeft(line);
                        if (left <= x && left + captionLayout.getLineWidth(line) >= x) {
                            Spannable buffer = (Spannable) currentCaption;
                            CharacterStyle[] link = buffer.getSpans(off, off, ClickableSpan.class);
                            if (link == null || link.length == 0) {
                                link = buffer.getSpans(off, off, URLSpanMono.class);
                            }
                            if (link == null || link.length == 0) {
                                link = buffer.getSpans(off, off, AnimatedEmojiSpan.class);
                            }
                            boolean ignore = false;
                            if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
                                ignore = true;
                            }
                            if (!ignore && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
                                if (link[0] instanceof AnimatedEmojiSpan) {
                                    resetPressedLink(3);
                                    pressedLinkType = 3;
                                    pressedEmoji = (AnimatedEmojiSpan) link[0];
                                } else if (pressedLink == null || pressedLink.getSpan() != link[0]) {
                                    links.removeLink(pressedLink);
                                    pressedLink = new LinkSpanDrawable(link[0], resourcesProvider, x, y, spanSupportsLongPress(link[0]));
                                    pressedLink.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLinkSelectBackground : Theme.key_chat_linkSelectBackground));
                                    pressedLinkType = 3;
                                    try {
                                        LinkPath path = pressedLink.obtainNewPath();
                                        int[] pos = getRealSpanStartAndEnd(buffer, pressedLink.getSpan());
                                        path.setCurrentLayout(captionLayout, pos[0], 0);
                                        captionLayout.getSelectionPath(pos[0], pos[1], path);
                                    } catch (Exception e) {
                                        FileLog.e(e);
                                    }
                                    links.addLink(pressedLink, 3);
                                }
                                invalidateWithParent();
                                return true;
                            }
                        }
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                } else if (pressedLinkType == 3) {
                    if (pressedEmoji != null) {
                        if (delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
                            resetPressedLink(3);
                            pressedEmoji = null;
                            return true;
                        }
                        resetPressedLink(3);
                        pressedEmoji = null;
                        return false;
                    } else {
                        delegate.didPressUrl(this, pressedLink.getSpan(), false);
                        resetPressedLink(3);
                        return true;
                    }
                }
            } else {
                resetPressedLink(3);
            }
        }
        return false;
    }

    private boolean checkGameMotionEvent(MotionEvent event) {
        if (!hasGamePreview) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (drawPhotoImage && drawImageButton && buttonState != -1 && x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE) {
                buttonPressed = 1;
                invalidate();
                return true;
            } else if (drawPhotoImage && photoImage.isInsideImage(x, y)) {
                gamePreviewPressed = true;
                return true;
            } else if (descriptionLayout != null && y >= descriptionY) {
                try {
                    x -= unmovedTextX + AndroidUtilities.dp(10) + descriptionX;
                    y -= descriptionY;
                    final int line = descriptionLayout.getLineForVertical(y);
                    final int off = descriptionLayout.getOffsetForHorizontal(line, x);

                    final float left = descriptionLayout.getLineLeft(line);
                    if (left <= x && left + descriptionLayout.getLineWidth(line) >= x) {
                        Spannable buffer = (Spannable) currentMessageObject.linkDescription;
                        ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
                        boolean ignore = false;
                        if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
                            ignore = true;
                        }
                        if (!ignore && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
                            if (pressedLink == null || pressedLink.getSpan() != link[0]) {
                                links.removeLink(pressedLink);
                                pressedLink = new LinkSpanDrawable(link[0], resourcesProvider, x, y, spanSupportsLongPress(link[0]));
                                pressedLink.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLinkSelectBackground : Theme.key_chat_linkSelectBackground));
                                linkBlockNum = -10;
                                pressedLinkType = 2;
                                try {
                                    LinkPath path = pressedLink.obtainNewPath();
                                    int[] pos = getRealSpanStartAndEnd(buffer, pressedLink.getSpan());
                                    path.setCurrentLayout(descriptionLayout, pos[0], 0);
                                    descriptionLayout.getSelectionPath(pos[0], pos[1], path);
                                } catch (Exception e) {
                                    FileLog.e(e);
                                }
                                links.addLink(pressedLink, 2);
                            }
                            invalidate();
                            return true;
                        }
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (pressedLinkType == 2 || gamePreviewPressed || buttonPressed != 0) {
                if (buttonPressed != 0) {
                    buttonPressed = 0;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    didPressButton(true, false);
                    invalidate();
                } else if (pressedLink != null) {
                    if (pressedLink.getSpan() instanceof URLSpan) {
                        Browser.openUrl(getContext(), ((URLSpan) pressedLink.getSpan()).getURL());
                    } else if (pressedLink.getSpan() instanceof ClickableSpan) {
                        ((ClickableSpan) pressedLink.getSpan()).onClick(this);
                    }
                    resetPressedLink(2);
                } else {
                    gamePreviewPressed = false;
                    for (int a = 0; a < botButtons.size(); a++) {
                        BotButton button = botButtons.get(a);
                        if (button.button instanceof TLRPC.TL_keyboardButtonGame) {
                            playSoundEffect(SoundEffectConstants.CLICK);
                            delegate.didPressBotButton(this, button.button);
                            invalidate();
                            break;
                        }
                    }
                    resetPressedLink(2);
                    return true;
                }
            } else {
                resetPressedLink(2);
            }
        }
        return false;
    }

    private boolean checkTranscribeButtonMotionEvent(MotionEvent event) {
        return useTranscribeButton && (!isPlayingRound || getVideoTranscriptionProgress() > 0 || wasTranscriptionOpen) && transcribeButton != null && transcribeButton.onTouch(event.getAction(), event.getX(), event.getY());
    }

    private boolean checkLinkPreviewMotionEvent(MotionEvent event) {
        if (currentMessageObject.type != MessageObject.TYPE_TEXT || !hasLinkPreview) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();

        if (x >= unmovedTextX && x <= unmovedTextX + backgroundWidth && y >= textY + currentMessageObject.textHeight && y <= textY + currentMessageObject.textHeight + linkPreviewHeight + AndroidUtilities.dp(8 + (drawInstantView ? 46 : 0))) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (descriptionLayout != null && y >= descriptionY) {
                    try {
                        int checkX = x - (unmovedTextX + AndroidUtilities.dp(10) + descriptionX);
                        int checkY = y - descriptionY;
                        if (checkY <= descriptionLayout.getHeight()) {
                            final int line = descriptionLayout.getLineForVertical(checkY);
                            final int off = descriptionLayout.getOffsetForHorizontal(line, checkX);

                            final float left = descriptionLayout.getLineLeft(line);
                            if (left <= checkX && left + descriptionLayout.getLineWidth(line) >= checkX) {
                                Spannable buffer = (Spannable) currentMessageObject.linkDescription;
                                ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
                                boolean ignore = false;
                                if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
                                    ignore = true;
                                }
                                if (!ignore && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
                                    if (pressedLink == null || pressedLink.getSpan() != link[0]) {
                                        links.removeLink(pressedLink);
                                        pressedLink = new LinkSpanDrawable(link[0], resourcesProvider, x, y, spanSupportsLongPress(link[0]));
                                        pressedLink.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLinkSelectBackground : Theme.key_chat_linkSelectBackground));
                                        linkBlockNum = -10;
                                        pressedLinkType = 2;
                                        startCheckLongPress();
                                        try {
                                            LinkPath path = pressedLink.obtainNewPath();
                                            int[] pos = getRealSpanStartAndEnd(buffer, pressedLink.getSpan());
                                            path.setCurrentLayout(descriptionLayout, pos[0], 0);
                                            descriptionLayout.getSelectionPath(pos[0], pos[1], path);
                                        } catch (Exception e) {
                                            FileLog.e(e);
                                        }
                                        links.addLink(pressedLink, 2);
                                    }
                                    invalidate();
                                    return true;
                                }
                            }
                        }
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                }
                if (pressedLink == null) {
                    int side = AndroidUtilities.dp(48);
                    boolean area2 = false;
                    if (miniButtonState >= 0) {
                        int offset = AndroidUtilities.dp(27);
                        area2 = x >= buttonX + offset && x <= buttonX + offset + side && y >= buttonY + offset && y <= buttonY + offset + side;
                    }
                    if (area2) {
                        miniButtonPressed = 1;
                        invalidate();
                        return true;
                    } else if (drawVideoImageButton && buttonState != -1 && x >= videoButtonX && x <= videoButtonX + AndroidUtilities.dp(26 + 8) + Math.max(infoWidth, docTitleWidth) && y >= videoButtonY && y <= videoButtonY + AndroidUtilities.dp(30)) {
                        videoButtonPressed = 1;
                        invalidate();
                        return true;
                    } else if (drawPhotoImage && drawImageButton && buttonState != -1 && (!checkOnlyButtonPressed && photoImage.isInsideImage(x, y) || x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE)) {
                        buttonPressed = 1;
                        invalidate();
                        return true;
                    } else if (drawInstantView) {
                        instantPressed = true;
                        selectorDrawableMaskType[0] = 0;
                        if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                            if (selectorDrawable[0].getBounds().contains(x, y)) {
                                selectorDrawable[0].setHotspot(x, y);
                                selectorDrawable[0].setState(pressedState);
                                setInstantButtonPressed(true);
                            }
                        }
                        invalidate();
                        return true;
                    } else if (documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT && drawPhotoImage && photoImage.isInsideImage(x, y)) {
                        linkPreviewPressed = true;
                        TLRPC.WebPage webPage = MessageObject.getMedia(currentMessageObject.messageOwner).webpage;
                        if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && buttonState == -1 && SharedConfig.isAutoplayGifs() && (photoImage.getAnimation() == null || !TextUtils.isEmpty(webPage.embed_url))) {
                            linkPreviewPressed = false;
                            return false;
                        }
                        return true;
                    }
                }
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                if (instantPressed) {
                    if (delegate != null) {
                        delegate.didPressInstantButton(this, drawInstantViewType);
                    }
                    playSoundEffect(SoundEffectConstants.CLICK);
                    if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                        selectorDrawable[0].setState(StateSet.NOTHING);
                    }
                    setInstantButtonPressed(instantPressed = false);
                    invalidate();
                } else if (pressedLinkType == 2 || buttonPressed != 0 || miniButtonPressed != 0 || videoButtonPressed != 0 || linkPreviewPressed) {
                    if (videoButtonPressed == 1) {
                        videoButtonPressed = 0;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        didPressButton(true, true);
                        invalidate();
                    } else if (buttonPressed != 0) {
                        buttonPressed = 0;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        if (drawVideoImageButton) {
                            didClickedImage();
                        } else {
                            didPressButton(true, false);
                        }
                        invalidate();
                    } else if (miniButtonPressed != 0) {
                        miniButtonPressed = 0;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        didPressMiniButton(true);
                        invalidate();
                    } else if (pressedLink != null) {
                        if (pressedLink.getSpan() instanceof URLSpan) {
                            delegate.didPressUrl(this, pressedLink.getSpan(), false);
                        } else if (pressedLink.getSpan() instanceof ClickableSpan) {
                            ((ClickableSpan) pressedLink.getSpan()).onClick(this);
                        }
                        resetPressedLink(2);
                    } else if (pressedEmoji != null && delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
                        pressedEmoji = null;
                        resetPressedLink(2);
                    } else {
                        if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                            if (!MediaController.getInstance().isPlayingMessage(currentMessageObject) || MediaController.getInstance().isMessagePaused()) {
                                delegate.needPlayMessage(currentMessageObject, false);
                            } else {
                                MediaController.getInstance().pauseMessage(currentMessageObject);
                            }
                        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && drawImageButton) {
                            if (buttonState == -1) {
                                if (SharedConfig.isAutoplayGifs()) {
                                    delegate.didPressImage(this, lastTouchX, lastTouchY);
                                } else {
                                    buttonState = 2;
                                    currentMessageObject.gifState = 1;
                                    photoImage.setAllowStartAnimation(false);
                                    photoImage.stopAnimation();
                                    radialProgress.setIcon(getIconForCurrentState(), false, true);
                                    invalidate();
                                    playSoundEffect(SoundEffectConstants.CLICK);
                                }
                            } else if (buttonState == 2 || buttonState == 0) {
                                didPressButton(true, false);
                                playSoundEffect(SoundEffectConstants.CLICK);
                            }
                        } else {
                            TLRPC.WebPage webPage = MessageObject.getMedia(currentMessageObject.messageOwner).webpage;
                            if (webPage != null && !TextUtils.isEmpty(webPage.embed_url)) {
                                delegate.needOpenWebView(currentMessageObject, webPage.embed_url, webPage.site_name, webPage.title, webPage.url, webPage.embed_width, webPage.embed_height);
                            } else if (buttonState == -1 || buttonState == 3) {
                                delegate.didPressImage(this, lastTouchX, lastTouchY);
                                playSoundEffect(SoundEffectConstants.CLICK);
                            } else if (webPage != null) {
                                Browser.openUrl(getContext(), webPage.url);
                            }
                        }
                        resetPressedLink(2);
                        return true;
                    }
                } else if (!hadLongPress) {
                    hadLongPress = false;
                    resetPressedLink(2);
                }
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                if (instantButtonPressed && Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                    selectorDrawable[0].setHotspot(x, y);
                }
            }
        }
        return false;
    }

    private boolean checkPollButtonMotionEvent(MotionEvent event) {
        if (currentMessageObject.eventId != 0 || pollVoteInProgress || pollUnvoteInProgress || pollButtons.isEmpty() || currentMessageObject.type != MessageObject.TYPE_POLL || !currentMessageObject.isSent()) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();

        boolean result = false;
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            pressedVoteButton = -1;
            pollHintPressed = false;
            if (hintButtonVisible && pollHintX != -1 && x >= pollHintX && x <= pollHintX + AndroidUtilities.dp(40) && y >= pollHintY && y <= pollHintY + AndroidUtilities.dp(40)) {
                pollHintPressed = true;
                result = true;
                selectorDrawableMaskType[0] = 3;
                if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                    selectorDrawable[0].setBounds(pollHintX - AndroidUtilities.dp(8), pollHintY - AndroidUtilities.dp(8), pollHintX + AndroidUtilities.dp(32), pollHintY + AndroidUtilities.dp(32));
                    selectorDrawable[0].setHotspot(x, y);
                    selectorDrawable[0].setState(pressedState);
                }
                invalidate();
            } else {
                for (int a = 0; a < pollButtons.size(); a++) {
                    PollButton button = pollButtons.get(a);
                    int y2 = button.y + namesOffset - AndroidUtilities.dp(13);
                    if (x >= button.x && x <= button.x + backgroundWidth - AndroidUtilities.dp(31) && y >= y2 && y <= y2 + button.height + AndroidUtilities.dp(26)) {
                        pressedVoteButton = a;
                        if (!pollVoted && !pollClosed) {
                            selectorDrawableMaskType[0] = 1;
                            if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                                selectorDrawable[0].setBounds(button.x - AndroidUtilities.dp(9), y2, button.x + backgroundWidth - AndroidUtilities.dp(22), y2 + button.height + AndroidUtilities.dp(26));
                                selectorDrawable[0].setHotspot(x, y);
                                selectorDrawable[0].setState(pressedState);
                            }
                            invalidate();
                        }
                        result = true;
                        break;
                    }
                }
            }
        } else {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                if (pollHintPressed) {
                    playSoundEffect(SoundEffectConstants.CLICK);
                    delegate.didPressHint(this, 0);
                    pollHintPressed = false;
                    if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                        selectorDrawable[0].setState(StateSet.NOTHING);
                    }
                } else if (pressedVoteButton != -1) {
                    playSoundEffect(SoundEffectConstants.CLICK);
                    if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                        selectorDrawable[0].setState(StateSet.NOTHING);
                    }
                    if (currentMessageObject.scheduled) {
                        Toast.makeText(getContext(), LocaleController.getString("MessageScheduledVote", R.string.MessageScheduledVote), Toast.LENGTH_LONG).show();
                    } else {
                        PollButton button = pollButtons.get(pressedVoteButton);
                        TLRPC.TL_pollAnswer answer = button.answer;
                        if (pollVoted || pollClosed) {
                            ArrayList<TLRPC.TL_pollAnswer> answers = new ArrayList<>();
                            answers.add(answer);
                            delegate.didPressVoteButtons(this, answers, button.count, button.x + AndroidUtilities.dp(50), button.y + namesOffset);
                        } else {
                            if (lastPoll.multiple_choice) {
                                if (currentMessageObject.checkedVotes.contains(answer)) {
                                    currentMessageObject.checkedVotes.remove(answer);
                                    pollCheckBox[pressedVoteButton].setChecked(false, true);
                                } else {
                                    currentMessageObject.checkedVotes.add(answer);
                                    pollCheckBox[pressedVoteButton].setChecked(true, true);
                                }
                            } else {
                                pollVoteInProgressNum = pressedVoteButton;
                                pollVoteInProgress = true;
                                vibrateOnPollVote = true;
                                voteCurrentProgressTime = 0.0f;
                                firstCircleLength = true;
                                voteCurrentCircleLength = 360;
                                voteRisingCircleLength = false;
                                ArrayList<TLRPC.TL_pollAnswer> answers = new ArrayList<>();
                                answers.add(answer);
                                delegate.didPressVoteButtons(this, answers, -1, 0, 0);
                            }
                        }
                    }
                    pressedVoteButton = -1;
                    invalidate();
                }
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                if ((pressedVoteButton != -1 || pollHintPressed) && Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                    selectorDrawable[0].setHotspot(x, y);
                }
            }
        }
        return result;
    }

    private boolean checkInstantButtonMotionEvent(MotionEvent event) {
        if (!currentMessageObject.isSponsored() && (!drawInstantView || currentMessageObject.type == MessageObject.TYPE_TEXT)) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (drawInstantView && instantButtonRect.contains(x, y)) {
                selectorDrawableMaskType[0] = lastPoll != null ? 2 : 0;
                instantPressed = true;
                if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                    if (instantButtonRect.contains(x, y)) {
                        selectorDrawable[0].setHotspot(x, y);
                        selectorDrawable[0].setState(pressedState);
                        setInstantButtonPressed(true);
                    }
                }
                invalidate();
                return true;
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (instantPressed) {
                if (delegate != null) {
                    if (lastPoll != null) {
                        if (currentMessageObject.scheduled) {
                            Toast.makeText(getContext(), LocaleController.getString("MessageScheduledVoteResults", R.string.MessageScheduledVoteResults), Toast.LENGTH_LONG).show();
                        } else {
                            if (pollVoted || pollClosed) {
                                delegate.didPressInstantButton(this, drawInstantViewType);
                            } else {
                                if (!currentMessageObject.checkedVotes.isEmpty()) {
                                    pollVoteInProgressNum = -1;
                                    pollVoteInProgress = true;
                                    vibrateOnPollVote = true;
                                    voteCurrentProgressTime = 0.0f;
                                    firstCircleLength = true;
                                    voteCurrentCircleLength = 360;
                                    voteRisingCircleLength = false;
                                }
                                delegate.didPressVoteButtons(this, currentMessageObject.checkedVotes, -1, 0, namesOffset);
                            }
                        }
                    } else {
                        delegate.didPressInstantButton(this, drawInstantViewType);
                    }
                }
                playSoundEffect(SoundEffectConstants.CLICK);
                if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                    selectorDrawable[0].setState(StateSet.NOTHING);
                }
                setInstantButtonPressed(instantPressed = false);
                invalidate();
            }
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            if (instantButtonPressed && Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                selectorDrawable[0].setHotspot(x, y);
            }
        }
        return false;
    }

    private void invalidateWithParent() {
        if (currentMessagesGroup != null && getParent() != null) {
            ((ViewGroup) getParent()).invalidate();
        }
        invalidate();
    }

    private boolean checkCommentButtonMotionEvent(MotionEvent event) {
        if (!drawCommentButton) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();
        if (currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0 && commentButtonRect.contains(x, y)) {
            ViewGroup parent = (ViewGroup) getParent();
            for (int a = 0, N = parent.getChildCount(); a < N; a++) {
                View view = parent.getChildAt(a);
                if (view != this && view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    if (cell.drawCommentButton && cell.currentMessagesGroup == currentMessagesGroup && (cell.currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                        MotionEvent childEvent = MotionEvent.obtain(0, 0, event.getActionMasked(), event.getX() + getLeft() - cell.getLeft(), event.getY() + getTop() - cell.getTop(), 0);
                        cell.checkCommentButtonMotionEvent(childEvent);
                        childEvent.recycle();
                        break;
                    }
                }
            }
            return true;
        }
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (commentButtonRect.contains(x, y)) {
                if (currentMessageObject.isSent()) {
                    selectorDrawableMaskType[1] = 2;
                    commentButtonPressed = true;
                    if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[1] != null) {
                        selectorDrawable[1].setHotspot(x, y);
                        selectorDrawable[1].setState(pressedState);
                    }
                    invalidateWithParent();
                }
                return true;
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (commentButtonPressed) {
                if (delegate != null) {
                    if (isRepliesChat) {
                        delegate.didPressSideButton(this);
                    } else {
                        delegate.didPressCommentButton(this);
                    }
                }
                playSoundEffect(SoundEffectConstants.CLICK);
                if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[1] != null) {
                    selectorDrawable[1].setState(StateSet.NOTHING);
                }
                commentButtonPressed = false;
                invalidateWithParent();
            }
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            if (commentButtonPressed && Build.VERSION.SDK_INT >= 21 && selectorDrawable[1] != null) {
                selectorDrawable[1].setHotspot(x, y);
            }
        }
        return false;
    }

    private boolean checkOtherButtonMotionEvent(MotionEvent event) {
        if ((documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) && currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
            return false;
        }
        boolean allow = currentMessageObject.type == MessageObject.TYPE_PHONE_CALL;
        if (!allow) {
            allow = !(
                documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT &&
                currentMessageObject.type != MessageObject.TYPE_CONTACT &&
                documentAttachType != DOCUMENT_ATTACH_TYPE_MUSIC &&
                documentAttachType != DOCUMENT_ATTACH_TYPE_VIDEO &&
                documentAttachType != DOCUMENT_ATTACH_TYPE_GIF &&
                currentMessageObject.type != MessageObject.TYPE_GIF
                || hasGamePreview || hasInvoicePreview
            );
        }
        if (!allow) {
            return false;
        }

        int x = (int) event.getX();
        int y = (int) event.getY();

        boolean result = false;
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
                int idx = currentMessageObject.isVideoCall() ? 1 : 0;
                if (x >= otherX && x <= otherX + AndroidUtilities.dp(30 + (idx == 0 ? 202 : 200)) && y >= otherY - AndroidUtilities.dp(14) && y <= otherY + AndroidUtilities.dp(50)) {
                    otherPressed = true;
                    result = true;
                    selectorDrawableMaskType[0] = 4;
                    if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                        int cx = otherX + AndroidUtilities.dp(idx == 0 ? 202 : 200) + Theme.chat_msgInCallDrawable[idx].getIntrinsicWidth() / 2;
                        int cy = otherY + Theme.chat_msgInCallDrawable[idx].getIntrinsicHeight() / 2;
                        selectorDrawable[0].setBounds(cx - AndroidUtilities.dp(20), cy - AndroidUtilities.dp(20), cx + AndroidUtilities.dp(20), cy + AndroidUtilities.dp(20));
                        selectorDrawable[0].setHotspot(x, y);
                        selectorDrawable[0].setState(pressedState);
                    }
                    invalidate();
                }
            } else {
                if (x >= otherX - AndroidUtilities.dp(20) && x <= otherX + AndroidUtilities.dp(20) && y >= otherY - AndroidUtilities.dp(4) && y <= otherY + AndroidUtilities.dp(30)) {
                    otherPressed = true;
                    result = true;
                    invalidate();
                }
            }
        } else {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                if (otherPressed) {
                    if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL && Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                        selectorDrawable[0].setState(StateSet.NOTHING);
                    }
                    otherPressed = false;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    delegate.didPressOther(this, otherX, otherY);
                    invalidate();
                    result = true;
                }
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL && otherPressed && Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                    selectorDrawable[0].setHotspot(x, y);
                }
            }
        }
        return result;
    }

    private void setInstantButtonPressed(boolean pressed) {
        if (instantButtonPressed != pressed) {
            invalidate();
            if (pressed) {
                if (instantButtonPressAnimator != null) {
                    instantButtonPressAnimator.removeAllListeners();
                    instantButtonPressAnimator.cancel();
                }
            }
            if (!pressed && instantButtonPressProgress != 0) {
                instantButtonPressAnimator = ValueAnimator.ofFloat(instantButtonPressProgress, 0);
                instantButtonPressAnimator.addUpdateListener(animation -> {
                    instantButtonPressProgress = (float) animation.getAnimatedValue();
                    invalidate();
                });
                instantButtonPressAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        instantButtonPressAnimator = null;
                    }
                });
                instantButtonPressAnimator.setInterpolator(new OvershootInterpolator(5.0f));
                instantButtonPressAnimator.setDuration(350);
                instantButtonPressAnimator.start();
            }
            instantButtonPressed = pressed;
        }
    }

    private boolean checkDateMotionEvent(MotionEvent event) {
        if (!currentMessageObject.isImportedForward()) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();

        boolean result = false;
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (x >= drawTimeX && x <= drawTimeX + timeWidth && y >= drawTimeY && y <= drawTimeY + AndroidUtilities.dp(20)) {
                timePressed = true;
                result = true;
                invalidate();
            }
        } else {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                if (timePressed) {
                    timePressed = false;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    delegate.didPressTime(this);
                    invalidate();
                    result = true;
                }
            }
        }
        return result;
    }

    private boolean checkRoundSeekbar(MotionEvent event) {
        if (!MediaController.getInstance().isPlayingMessage(currentMessageObject) || !MediaController.getInstance().isMessagePaused()) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (x >= seekbarRoundX - AndroidUtilities.dp(20) && x <= seekbarRoundX + AndroidUtilities.dp(20) && y >= seekbarRoundY - AndroidUtilities.dp(20) && y <= seekbarRoundY + AndroidUtilities.dp(20)) {
                getParent().requestDisallowInterceptTouchEvent(true);
                cancelCheckLongPress();
                roundSeekbarTouched = 1;
                invalidate();
            } else {
                float localX = x - photoImage.getCenterX();
                float localY = y - photoImage.getCenterY();
                float r2 = (photoImage.getImageWidth() - AndroidUtilities.dp(64)) / 2;
                if (localX * localX + localY * localY < photoImage.getImageWidth() / 2 * photoImage.getImageWidth() / 2 && localX * localX + localY * localY > r2 * r2) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                    cancelCheckLongPress();
                    roundSeekbarTouched = 1;
                    invalidate();
                }
            }
        } else if (roundSeekbarTouched == 1 && event.getAction() == MotionEvent.ACTION_MOVE) {
            float localX = x - photoImage.getCenterX();
            float localY = y - photoImage.getCenterY();
            float a = (float) Math.toDegrees(Math.atan2(localY, localX)) + 90;
            if (a < 0) {
                a += 360;
            }
            float p = a / 360f;
            if (Math.abs(currentMessageObject.audioProgress - p) > 0.9f) {
                if (roundSeekbarOutAlpha == 0) {
                    performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
                }
                roundSeekbarOutAlpha = 1f;
                roundSeekbarOutProgress = currentMessageObject.audioProgress;
            }
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastSeekUpdateTime > 100) {
                MediaController.getInstance().seekToProgress(currentMessageObject, p);
                lastSeekUpdateTime = currentTime;
            }
            currentMessageObject.audioProgress = p;
            updatePlayingMessageProgress();
        }
        if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            if (roundSeekbarTouched != 0) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    float localX = x - photoImage.getCenterX();
                    float localY = y - photoImage.getCenterY();
                    float a = (float) Math.toDegrees(Math.atan2(localY, localX)) + 90;
                    if (a < 0) {
                        a += 360;
                    }
                    float p = a / 360f;
                    currentMessageObject.audioProgress = p;
                    MediaController.getInstance().seekToProgress(currentMessageObject, p);
                    updatePlayingMessageProgress();
                }
                MediaController.getInstance().playMessage(currentMessageObject);
                roundSeekbarTouched = 0;
                getParent().requestDisallowInterceptTouchEvent(false);
            }
        }
        return roundSeekbarTouched != 0;
    }

    private boolean checkPhotoImageMotionEvent(MotionEvent event) {
        if (!drawPhotoImage && documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT || currentMessageObject.isSending() && buttonState != 1) {
            return false;
        }

        int x = (int) event.getX();
        int y = (int) event.getY();

        boolean result = false;
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            boolean area2 = false;
            int side = AndroidUtilities.dp(48);

            if (miniButtonState >= 0) {
                int offset = AndroidUtilities.dp(27);
                area2 = x >= buttonX + offset && x <= buttonX + offset + side && y >= buttonY + offset && y <= buttonY + offset + side;
            }
            boolean allowClickButtons = currentMessageObject == null || !currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || buttonState == 1;
            if (area2) {
                miniButtonPressed = 1;
                invalidate();
                result = true;
            } else if (buttonState != -1 && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE && x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side && allowClickButtons) {
                buttonPressed = 1;
                invalidate();
                result = true;
            } else if (drawVideoImageButton && buttonState != -1 && x >= videoButtonX && x <= videoButtonX + AndroidUtilities.dp(26 + 8) + Math.max(infoWidth, docTitleWidth) && y >= videoButtonY && y <= videoButtonY + AndroidUtilities.dp(30) && allowClickButtons) {
                videoButtonPressed = 1;
                invalidate();
                result = true;
            } else {
                if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                    if (x >= photoImage.getImageX() && x <= photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(50) && y >= photoImage.getImageY() && y <= photoImage.getImageY() + photoImage.getImageHeight()) {
                        imagePressed = true;
                        result = true;
                    }
                } else if (!currentMessageObject.isAnyKindOfSticker() || currentMessageObject.getInputStickerSet() != null || currentMessageObject.isAnimatedEmoji() || currentMessageObject.isDice()) {
                    if (x >= photoImage.getImageX() && x <= photoImage.getImageX() + photoImage.getImageWidth() && y >= photoImage.getImageY() && y <= photoImage.getImageY() + photoImage.getImageHeight()) {
                        if (isRoundVideo) {
                            if ((x - photoImage.getCenterX()) * (x - photoImage.getCenterX()) + (y - photoImage.getCenterY()) * (y - photoImage.getCenterY()) < (photoImage.getImageWidth() / 2f) * (photoImage.getImageWidth() / 2)) {
                                imagePressed = true;
                                result = true;
                            }
                        } else {
                            imagePressed = true;
                            result = true;
                        }
                    }
                    if (currentMessageObject.type == MessageObject.TYPE_CONTACT) {
                        long uid = MessageObject.getMedia(currentMessageObject.messageOwner).user_id;
                        TLRPC.User user = null;
                        if (uid != 0) {
                            user = MessagesController.getInstance(currentAccount).getUser(uid);
                        }
                        if (user == null) {
                            imagePressed = false;
                            result = false;
                        }
                    }
                }
            }
            if (imagePressed) {
                if (currentMessageObject.isSendError()) {
                    imagePressed = false;
                    result = false;
                } else if (currentMessageObject.type == MessageObject.TYPE_GIF && buttonState == -1 && SharedConfig.isAutoplayGifs() && photoImage.getAnimation() == null) {
                    imagePressed = false;
                    result = false;
                }
            }
        } else {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                if (videoButtonPressed == 1) {
                    videoButtonPressed = 0;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    didPressButton(true, true);
                    invalidate();
                } else if (buttonPressed == 1) {
                    buttonPressed = 0;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    if (drawVideoImageButton) {
                        didClickedImage();
                    } else {
                        didPressButton(true, false);
                    }
                    invalidate();
                } else if (miniButtonPressed == 1) {
                    miniButtonPressed = 0;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    didPressMiniButton(true);
                    invalidate();
                } else if (imagePressed) {
                    imagePressed = false;
                    if (buttonState == -1 || buttonState == 1 && isRoundVideo || buttonState == 2 || buttonState == 3 || drawVideoImageButton) {
                        playSoundEffect(SoundEffectConstants.CLICK);
                        didClickedImage();
                    } else if (buttonState == 0) {
                        playSoundEffect(SoundEffectConstants.CLICK);
                        didPressButton(true, false);
                    }
                    invalidate();
                }
            }
        }
        return result;
    }

    private boolean checkAudioMotionEvent(MotionEvent event) {
        if (documentAttachType != DOCUMENT_ATTACH_TYPE_AUDIO && documentAttachType != DOCUMENT_ATTACH_TYPE_MUSIC && (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && !currentMessageObject.isVoiceTranscriptionOpen())) {
            return false;
        }
        if (AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
            return false;
        }

        int x = (int) event.getX();
        int y = (int) event.getY();
        boolean result;
        if (useSeekBarWaveform) {
            result = seekBarWaveform.onTouch(event.getAction(), event.getX() - seekBarX - AndroidUtilities.dp(13), event.getY() - seekBarY);
        } else {
            if (MediaController.getInstance().isPlayingMessage(currentMessageObject) || currentMessageObject != null && documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject.isVoiceTranscriptionOpen()) {
                result = seekBar.onTouch(event.getAction(), event.getX() - seekBarX, event.getY() - seekBarY);
            } else {
                result = false;
            }
        }
        if (result) {
            if (!useSeekBarWaveform && event.getAction() == MotionEvent.ACTION_DOWN) {
                getParent().requestDisallowInterceptTouchEvent(true);
            } else if (useSeekBarWaveform && !seekBarWaveform.isStartDraging() && event.getAction() == MotionEvent.ACTION_UP) {
                didPressButton(true, false);
            }
            disallowLongPress = true;
            invalidate();
        } else {
            int side = AndroidUtilities.dp(36);
            boolean area = false;
            boolean area2 = false;
            if (miniButtonState >= 0) {
                int offset = AndroidUtilities.dp(27);
                area2 = x >= buttonX + offset && x <= buttonX + offset + side && y >= buttonY + offset && y <= buttonY + offset + side;
            }
            if (!area2 && (currentMessageObject == null || !currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed)) {
                if (buttonState == 0 || buttonState == 1 || buttonState == 2) {
                    area = x >= buttonX - AndroidUtilities.dp(12) && x <= buttonX - AndroidUtilities.dp(12) + backgroundWidth && y >= (drawInstantView ? buttonY : namesOffset + mediaOffsetY) && y <= (drawInstantView ? buttonY + side : namesOffset + mediaOffsetY + AndroidUtilities.dp(82));
                } else {
                    area = x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side;
                }
            }
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (area || area2) {
                    if (area) {
                        buttonPressed = 1;
                    } else {
                        miniButtonPressed = 1;
                    }
                    invalidate();
                    result = true;
                }
            } else if (buttonPressed != 0) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    buttonPressed = 0;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    didPressButton(true, false);
                    invalidate();
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                    buttonPressed = 0;
                    invalidate();
                } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    if (!area) {
                        buttonPressed = 0;
                        invalidate();
                    }
                }
            } else if (miniButtonPressed != 0) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    miniButtonPressed = 0;
                    playSoundEffect(SoundEffectConstants.CLICK);
                    didPressMiniButton(true);
                    invalidate();
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                    miniButtonPressed = 0;
                    invalidate();
                } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    if (!area2) {
                        miniButtonPressed = 0;
                        invalidate();
                    }
                }
            }
        }
        return result;
    }

    public boolean checkSpoilersMotionEvent(MotionEvent event, int n) {
        if (n > 15 || getParent() == null) {
            return false;
        }
        if (currentMessageObject.hasValidGroupId() && currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
            ViewGroup parent = (ViewGroup) getParent();
            for (int i = 0; i < parent.getChildCount(); i++) {
                View v = parent.getChildAt(i);
                if (v instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) v;
                    MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
                    MessageObject.GroupedMessagePosition position = cell.getCurrentPosition();
                    if (group != null && group.groupId == currentMessagesGroup.groupId &&
                            (position.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 &&
                            (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                        if (cell != this) {
                            event.offsetLocation(this.getLeft() - cell.getLeft(), this.getTop() - cell.getTop());
                            boolean result = cell.checkSpoilersMotionEvent(event, n + 1);
                            event.offsetLocation(-(this.getLeft() - cell.getLeft()), -(this.getTop() - cell.getTop()));
                            return result;
                        }
                    }
                }
            }
        }

        if (isSpoilerRevealing) {
            return false;
        }

        int x = (int) event.getX();
        int y = (int) event.getY();
        int act = event.getActionMasked();
        if (act == MotionEvent.ACTION_DOWN) {
            if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
                List<MessageObject.TextLayoutBlock> blocks = currentMessageObject.textLayoutBlocks;
                for (int i = 0; i < blocks.size(); i++) {
                    if (blocks.get(i).textYOffset > y) {
                        break;
                    }
                    MessageObject.TextLayoutBlock block = blocks.get(i);
                    int offX = block.isRtl() ? (int) currentMessageObject.textXOffset : 0;
                    for (SpoilerEffect eff : block.spoilers) {
                        if (eff.getBounds().contains(x - textX + offX, (int) (y - textY - block.textYOffset))) {
                            spoilerPressed = eff;
                            isCaptionSpoilerPressed = false;
                            return true;
                        }
                    }
                }
            }

            if (hasCaptionLayout() && x >= captionX && y >= captionY && x <= captionX + captionLayout.getWidth() && y <= captionY + captionLayout.getHeight()) {
                for (SpoilerEffect eff : captionSpoilers) {
                    if (eff.getBounds().contains((int) (x - captionX), (int) (y - captionY))) {
                        spoilerPressed = eff;
                        isCaptionSpoilerPressed = true;
                        return true;
                    }
                }
            }
        } else if (act == MotionEvent.ACTION_UP && spoilerPressed != null) {
            playSoundEffect(SoundEffectConstants.CLICK);

            sPath.rewind();
            if (isCaptionSpoilerPressed) {
                for (SpoilerEffect eff : captionSpoilers) {
                    Rect b = eff.getBounds();
                    sPath.addRect(b.left, b.top, b.right, b.bottom, Path.Direction.CW);
                }
            } else {
                for (MessageObject.TextLayoutBlock block : currentMessageObject.textLayoutBlocks) {
                    for (SpoilerEffect eff : block.spoilers) {
                        Rect b = eff.getBounds();
                        sPath.addRect(b.left, b.top + block.textYOffset, b.right, b.bottom + block.textYOffset, Path.Direction.CW);
                    }
                }
            }
            sPath.computeBounds(rect, false);
            float width = rect.width(), height = rect.height();
            float rad = (float) Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

            isSpoilerRevealing = true;
            spoilerPressed.setOnRippleEndCallback(() -> post(() -> {
                isSpoilerRevealing = false;
                getMessageObject().isSpoilersRevealed = true;
                if (isCaptionSpoilerPressed) {
                    captionSpoilers.clear();
                } else if (currentMessageObject.textLayoutBlocks != null) {
                    for (MessageObject.TextLayoutBlock block : currentMessageObject.textLayoutBlocks) {
                        block.spoilers.clear();
                    }
                }
                invalidate();
            }));
            if (isCaptionSpoilerPressed) {
                for (SpoilerEffect eff : captionSpoilers) {
                    eff.startRipple(x - captionX, y - captionY, rad);
                }
            } else if (currentMessageObject.textLayoutBlocks != null) {
                for (MessageObject.TextLayoutBlock block : currentMessageObject.textLayoutBlocks) {
                    int offX = block.isRtl() ? (int) currentMessageObject.textXOffset : 0;
                    for (SpoilerEffect eff : block.spoilers) {
                        eff.startRipple(x - textX + offX, y - block.textYOffset - textY, rad);
                    }
                }
            }
            if (getParent() instanceof RecyclerListView) {
                ViewGroup vg = (ViewGroup) getParent();
                for (int i = 0; i < vg.getChildCount(); i++) {
                    View ch = vg.getChildAt(i);
                    if (ch instanceof ChatMessageCell) {
                        ChatMessageCell cell = (ChatMessageCell) ch;
                        if (cell.getMessageObject() != null && cell.getMessageObject().getReplyMsgId() == getMessageObject().getId()) {
                            if (!cell.replySpoilers.isEmpty()) {
                                cell.replySpoilers.get(0).setOnRippleEndCallback(() -> post(() -> {
                                    cell.getMessageObject().replyMessageObject.isSpoilersRevealed = true;
                                    cell.replySpoilers.clear();
                                    cell.invalidate();
                                }));
                                for (SpoilerEffect eff : cell.replySpoilers) {
                                    eff.startRipple(eff.getBounds().centerX(), eff.getBounds().centerY(), rad);
                                }
                            }
                        }
                    }
                }
            }

            spoilerPressed = null;
            return true;
        }

        return false;
    }

    private boolean checkBotButtonMotionEvent(MotionEvent event) {
        if (botButtons.isEmpty() || currentMessageObject.eventId != 0) {
            return false;
        }

        int x = (int) event.getX();
        int y = (int) event.getY();

        boolean result = false;
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            int addX;
            if (currentMessageObject.isOutOwner()) {
                addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
            } else {
                addX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground ? 1 : 7);
            }
            for (int a = 0; a < botButtons.size(); a++) {
                BotButton button = botButtons.get(a);
                int y2 = button.y + layoutHeight - AndroidUtilities.dp(2);
                if (x >= button.x + addX && x <= button.x + addX + button.width && y >= y2 && y <= y2 + button.height) {
                    pressedBotButton = a;
                    invalidateOutbounds();
                    result = true;
                    if (button.selectorDrawable == null) {
                        button.selectorDrawable = Theme.createRadSelectorDrawable(getThemedColor(Theme.key_chat_serviceBackgroundSelector), 6, 6);
                        button.selectorDrawable.setBounds(button.x + addX, y2, button.x + addX + button.width, y2 + button.height);
                    }
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        button.selectorDrawable.setHotspot(x, y);
                    }
                    button.selectorDrawable.setState(pressedState);
                    button.setPressed(true);
                    final int longPressedBotButton = pressedBotButton;
                    postDelayed(() -> {
                        if (longPressedBotButton == pressedBotButton) {
                            BotButton button2 = botButtons.get(pressedBotButton);
                            if (button2 != null) {
                                if (button2.selectorDrawable != null) {
                                    button2.selectorDrawable.setState(StateSet.NOTHING);
                                }
                                button2.setPressed(false);
                                if (!currentMessageObject.scheduled) {
                                    if (button2.button != null) {
                                        cancelCheckLongPress();
                                        delegate.didLongPressBotButton(this, button2.button);
                                    }
                                }
                            }
                            pressedBotButton = -1;
                            invalidateOutbounds();
                        }
                    }, ViewConfiguration.getLongPressTimeout() - 1);
                    break;
                }
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (pressedBotButton != -1) {
                playSoundEffect(SoundEffectConstants.CLICK);
                BotButton button = botButtons.get(pressedBotButton);
                if (button.selectorDrawable != null) {
                    button.selectorDrawable.setState(StateSet.NOTHING);
                }
                button.setPressed(false);
                if (currentMessageObject.scheduled) {
                    Toast.makeText(getContext(), LocaleController.getString("MessageScheduledBotAction", R.string.MessageScheduledBotAction), Toast.LENGTH_LONG).show();
                } else {
                    if (button.button != null) {
                        delegate.didPressBotButton(this, button.button);
                    }
                }
                pressedBotButton = -1;
                invalidateOutbounds();
            }
        } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
            if (pressedBotButton != -1) {
                BotButton button = botButtons.get(pressedBotButton);
                if (button.selectorDrawable != null) {
                    button.selectorDrawable.setState(StateSet.NOTHING);
                }
                button.setPressed(false);
                pressedBotButton = -1;
                invalidateOutbounds();
            }
        }
        return result;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (currentMessageObject == null || !delegate.canPerformActions() || animationRunning) {
            checkTextSelection(event);
            return super.onTouchEvent(event);
        }

        if (checkTextSelection(event)) {
            return true;
        }

        if (checkRoundSeekbar(event)) {
            return true;
        }

        if (checkReactionsTouchEvent(event)) {
            return true;
        }

        if (videoPlayerRewinder != null && videoPlayerRewinder.rewindCount > 0) {
            if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
                getParent().requestDisallowInterceptTouchEvent(false);
                videoPlayerRewinder.cancelRewind();
                return false;
            }
            return true;
        }

        disallowLongPress = false;
        lastTouchX = event.getX();
        lastTouchY = event.getY();
        backgroundDrawable.setTouchCoords(lastTouchX, lastTouchY);

        boolean result = checkSpoilersMotionEvent(event, 0);

        if (!result) {
            result = checkTextBlockMotionEvent(event);
        }
        if (!result) {
            result = checkPinchToZoom(event);
        }
        if (!result) {
            result = checkDateMotionEvent(event);
        }
        if (!result) {
            result = checkTextSelection(event);
        }
        if (!result && topicButton != null) {
            result = topicButton.checkTouchEvent(event);
        }
        if (!result) {
            result = checkOtherButtonMotionEvent(event);
        }
        if (!result) {
            result = checkCaptionMotionEvent(event);
        }
        if (!result) {
            result = checkTranscribeButtonMotionEvent(event);
        }
        if (!result) {
            result = checkAudioMotionEvent(event);
        }
        if (!result) {
            result = checkLinkPreviewMotionEvent(event);
        }
        if (!result) {
            result = checkInstantButtonMotionEvent(event);
        }
        if (!result) {
            result = checkCommentButtonMotionEvent(event);
        }
        if (!result) {
            result = checkGameMotionEvent(event);
        }
        if (!result) {
            result = checkPhotoImageMotionEvent(event);
        }
        if (!result) {
            result = checkBotButtonMotionEvent(event);
        }
        if (!result) {
            result = checkPollButtonMotionEvent(event);
        }

        if (event.getAction() == MotionEvent.ACTION_CANCEL) {
            spoilerPressed = null;
            isCaptionSpoilerPressed = false;
            buttonPressed = 0;
            miniButtonPressed = 0;
            pressedBotButton = -1;
            pressedVoteButton = -1;
            pollHintPressed = false;
            psaHintPressed = false;
            linkPreviewPressed = false;
            otherPressed = false;
            sideButtonPressed = false;
            imagePressed = false;
            timePressed = false;
            gamePreviewPressed = false;
            instantPressed = commentButtonPressed = false;
            setInstantButtonPressed(false);
            if (Build.VERSION.SDK_INT >= 21) {
                for (int a = 0; a < selectorDrawable.length; a++) {
                    if (selectorDrawable[a] != null) {
                        selectorDrawable[a].setState(StateSet.NOTHING);
                    }
                }
            }
            result = false;
            if (hadLongPress) {
                if (pressedLinkType != 2) {
                    hadLongPress = false;
                }
                pressedLink = null;
                pressedEmoji = null;
                pressedLinkType = -1;
            } else {
                resetPressedLink(-1);
            }
        }
        updateRadialProgressBackground();
        if (!disallowLongPress && result && event.getAction() == MotionEvent.ACTION_DOWN) {
            startCheckLongPress();
        }

        if (event.getAction() != MotionEvent.ACTION_DOWN && event.getAction() != MotionEvent.ACTION_MOVE) {
            cancelCheckLongPress();
        }

        if (!result) {
            float x = event.getX();
            float y = event.getY();
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (delegate == null || delegate.canPerformActions()) {
                    if (isAvatarVisible && avatarImage.isInsideImage(x, y + getTop())) {
                        avatarPressed = true;
                        result = true;
                    } else if (psaButtonVisible && hasPsaHint && x >= psaHelpX && x <= psaHelpX + AndroidUtilities.dp(40) && y >= psaHelpY && y <= psaHelpY + AndroidUtilities.dp(40)) {
                        psaHintPressed = true;
                        createSelectorDrawable(0);
                        selectorDrawableMaskType[0] = 3;
                        if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                            selectorDrawable[0].setBounds(psaHelpX - AndroidUtilities.dp(8), psaHelpY - AndroidUtilities.dp(8), psaHelpX + AndroidUtilities.dp(32), psaHelpY + AndroidUtilities.dp(32));
                            selectorDrawable[0].setHotspot(x, y);
                            selectorDrawable[0].setState(pressedState);
                        }
                        result = true;
                        invalidate();
                    } else if (drawForwardedName && forwardedNameLayout[0] != null && x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + forwardHeight) {
                        if (viaWidth != 0 && x >= forwardNameX + viaNameWidth + AndroidUtilities.dp(4)) {
                            forwardBotPressed = true;
                        } else {
                            forwardNamePressed = true;
                        }
                        result = true;
                    } else if (drawNameLayout && nameLayout != null && viaWidth != 0 && x >= nameX + viaNameWidth && x <= nameX + viaNameWidth + viaWidth && y >= nameY - AndroidUtilities.dp(4) && y <= nameY + AndroidUtilities.dp(20)) {
                        forwardBotPressed = true;
                        result = true;
                    } else if (drawSideButton != 0 && x >= sideStartX && x <= sideStartX + AndroidUtilities.dp(40) && y >= sideStartY && y <= sideStartY + AndroidUtilities.dp(32 + (drawSideButton == 3 && commentLayout != null ? 18 : 0))) {
                        if (currentMessageObject.isSent()) {
                            sideButtonPressed = true;
                        }
                        result = true;
                        invalidate();
                    } else if (replyNameLayout != null) {
                        int replyEnd;
                        if (currentMessageObject.shouldDrawWithoutBackground()) {
                            replyEnd = replyStartX + Math.max(replyNameWidth, replyTextWidth);
                        } else {
                            replyEnd = replyStartX + backgroundDrawableRight;
                        }
                        if (x >= replyStartX && x <= replyEnd && y >= replyStartY && y <= replyStartY + replyHeight) {
                            replyPressed = true;
                            replyTouchX = x;
                            replyTouchY = y + getY();
                            if (replySelector != null) {
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                    replySelector.setHotspot(x, y);
                                }
                                replySelectorPressed = false;
                                replySelectorCanBePressed = true;
                                postDelayed(() -> {
                                    if (replyPressed && !replySelectorPressed && replySelectorCanBePressed) {
                                        replySelectorPressed = true;
                                        replySelector.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
                                    }
                                }, ViewConfiguration.getTapTimeout() / 6);
                                invalidate();
                            }
                            result = true;
                        }
                    }
                    if (result) {
                        startCheckLongPress();
                    }
                }
            } else {
                if (event.getAction() != MotionEvent.ACTION_MOVE) {
                    cancelCheckLongPress();
                }
                if (avatarPressed) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        avatarPressed = false;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        if (delegate != null) {
                            if (currentUser != null) {
                                if (currentUser.id == 0) {
                                    delegate.didPressHiddenForward(this);
                                } else {
                                    delegate.didPressUserAvatar(this, currentUser, lastTouchX, lastTouchY);
                                }
                            } else if (currentChat != null) {
                                int id;
                                TLRPC.Chat chat = currentChat;
                                if (currentMessageObject.messageOwner.fwd_from != null) {
                                    if ((currentMessageObject.messageOwner.fwd_from.flags & 16) != 0) {
                                        id = currentMessageObject.messageOwner.fwd_from.saved_from_msg_id;
                                    } else {
                                        id = currentMessageObject.messageOwner.fwd_from.channel_post;
                                        chat = currentForwardChannel;
                                    }
                                } else {
                                    id = 0;
                                }
                                delegate.didPressChannelAvatar(this, chat != null ? chat : currentChat, id, lastTouchX, lastTouchY);
                            } else if (currentMessageObject != null && currentMessageObject.sponsoredChatInvite != null) {
                                delegate.didPressInstantButton(this, drawInstantViewType);
                            }
                        }
                    } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                        avatarPressed = false;
                    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                        if (isAvatarVisible && !avatarImage.isInsideImage(x, y + getTop())) {
                            avatarPressed = false;
                        }
                    }
                } else if (psaHintPressed) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        playSoundEffect(SoundEffectConstants.CLICK);
                        delegate.didPressHint(this, 1);
                        psaHintPressed = false;
                        if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
                            selectorDrawable[0].setState(StateSet.NOTHING);
                        }
                        invalidate();
                    }
                } else if (forwardNamePressed) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        forwardNamePressed = false;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        if (delegate != null) {
                            if (currentForwardChannel != null) {
                                delegate.didPressChannelAvatar(this, currentForwardChannel, currentMessageObject.messageOwner.fwd_from.channel_post, lastTouchX, lastTouchY);
                            } else if (currentForwardUser != null) {
                                delegate.didPressUserAvatar(this, currentForwardUser, lastTouchX, lastTouchY);
                            } else if (currentForwardName != null) {
                                delegate.didPressHiddenForward(this);
                            }
                        }
                    } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                        forwardNamePressed = false;
                    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                        if (!(x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + forwardHeight)) {
                            forwardNamePressed = false;
                        }
                    }
                } else if (forwardBotPressed) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        forwardBotPressed = false;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        if (delegate != null) {
                            if (currentViaBotUser != null && currentViaBotUser.bot_inline_placeholder == null) {
                                delegate.didPressViaBotNotInline(this, currentViaBotUser != null ? currentViaBotUser.id : 0);
                            } else {
                                delegate.didPressViaBot(this, currentViaBotUser != null ? currentViaBotUser.username : currentMessageObject.messageOwner.via_bot_name);
                            }
                        }
                    } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                        forwardBotPressed = false;
                    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                        if (drawForwardedName && forwardedNameLayout[0] != null) {
                            if (!(x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + forwardHeight)) {
                                forwardBotPressed = false;
                            }
                        } else {
                            if (!(x >= nameX + viaNameWidth && x <= nameX + viaNameWidth + viaWidth && y >= nameY - AndroidUtilities.dp(4) && y <= nameY + AndroidUtilities.dp(20))) {
                                forwardBotPressed = false;
                            }
                        }
                    }
                } else if (replyPressed) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        replyPressed = false;
                        if (replySelector != null) {
                            if (!replySelectorPressed) {
                                replySelector.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
                                post(() -> {
                                    replySelector.setState(new int[]{});
                                    invalidate();
                                });
                            } else {
                                replySelector.setState(new int[]{});
                            }
                            replySelectorPressed = false;
                            replySelectorCanBePressed = false;
                            invalidate();
                        }
                        playSoundEffect(SoundEffectConstants.CLICK);
                        if (replyPanelIsForward) {
                            if (delegate != null) {
                                if (currentForwardChannel != null) {
                                    delegate.didPressChannelAvatar(this, currentForwardChannel, currentMessageObject.messageOwner.fwd_from.channel_post, lastTouchX, lastTouchY);
                                } else if (currentForwardUser != null) {
                                    delegate.didPressUserAvatar(this, currentForwardUser, lastTouchX, lastTouchY);
                                } else if (currentForwardName != null) {
                                    delegate.didPressHiddenForward(this);
                                }
                            }
                        } else {
                            if (delegate != null && currentMessageObject.hasValidReplyMessageObject()) {
                                delegate.didPressReplyMessage(this, currentMessageObject.getReplyMsgId());
                            }
                        }
                    } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                        replyPressed = false;
                        replySelectorPressed = false;
                        if (replySelector != null) {
                            replySelector.setState(new int[]{});
                        }
                        invalidate();
                    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                        int replyEnd;
                        if (currentMessageObject.shouldDrawWithoutBackground()) {
                            replyEnd = replyStartX + Math.max(replyNameWidth, replyTextWidth);
                        } else {
                            replyEnd = replyStartX + backgroundDrawableRight;
                        }
                        if (!(x >= replyStartX && x <= replyEnd && y >= replyStartY && y <= replyStartY + replyHeight)) {
                            replyPressed = false;
                            replySelectorPressed = false;
                            replySelectorCanBePressed = false;
                            if (replySelector != null) {
                                replySelector.setState(new int[]{});
                            }
                            invalidate();
                        } else if (replySelector != null && replySelectorCanBePressed && Math.sqrt(Math.pow(x - replyTouchX, 2) + Math.pow((y + getY()) - replyTouchY, 2)) > 0.75f) {
                            replySelectorCanBePressed = false;
                        }
                    }
                } else if (sideButtonPressed) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        sideButtonPressed = false;
                        playSoundEffect(SoundEffectConstants.CLICK);
                        if (delegate != null) {
                            if (drawSideButton == 3) {
                                delegate.didPressCommentButton(this);
                            } else {
                                delegate.didPressSideButton(this);
                            }
                        }
                    } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                        sideButtonPressed = false;
                    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                        if (!(x >= sideStartX && x <= sideStartX + AndroidUtilities.dp(40) && y >= sideStartY && y <= sideStartY + AndroidUtilities.dp(32 + (drawSideButton == 3 && commentLayout != null ? 18 : 0)))) {
                            sideButtonPressed = false;
                        }
                    }
                    invalidate();
                }
            }
        }
        return result;
    }

    private boolean checkReactionsTouchEvent(MotionEvent event) {
        if (currentMessageObject.hasValidGroupId() && currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
            ViewGroup parent = (ViewGroup) getParent();
            if (parent == null) {
                return false;
            }
            for (int i = 0; i < parent.getChildCount(); i++) {
                View v = parent.getChildAt(i);
                if (v instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) v;
                    MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
                    MessageObject.GroupedMessagePosition position = cell.getCurrentPosition();
                    if (group != null && group.groupId == currentMessagesGroup.groupId &&
                            (position.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 &&
                            (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                        if (cell == this) {
                            return reactionsLayoutInBubble.chekTouchEvent(event);
                        } else {
                            event.offsetLocation(this.getLeft() - cell.getLeft(), this.getTop() - cell.getTop());
                            boolean result = cell.reactionsLayoutInBubble.chekTouchEvent(event);
                            event.offsetLocation(-(this.getLeft() - cell.getLeft()), -(this.getTop() - cell.getTop()));
                            return result;
                        }
                    }
                }
            }
            return false;
        }
        return reactionsLayoutInBubble.chekTouchEvent(event);
    }


    private boolean checkPinchToZoom(MotionEvent ev) {
        PinchToZoomHelper pinchToZoomHelper = delegate == null ? null : delegate.getPinchToZoomHelper();
        if (currentMessageObject == null || !photoImage.hasNotThumb() || pinchToZoomHelper == null || currentMessageObject.isSticker() ||
                currentMessageObject.isAnimatedEmoji() || (currentMessageObject.isVideo() && !autoPlayingMedia) ||
                isRoundVideo || currentMessageObject.isAnimatedSticker() || (currentMessageObject.isDocument() && !currentMessageObject.isGif()) || currentMessageObject.needDrawBluredPreview()) {
            return false;
        }
        return pinchToZoomHelper.checkPinchToZoom(ev, this, photoImage, currentMessageObject);
    }

    private boolean checkTextSelection(MotionEvent event) {
        TextSelectionHelper.ChatListTextSelectionHelper textSelectionHelper = delegate.getTextSelectionHelper();
        if (textSelectionHelper == null || MessagesController.getInstance(currentAccount).isChatNoForwards(currentMessageObject.getChatId()) || (currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.noforwards)) {
            return false;
        }
        boolean hasTextBlocks = currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty();
        if (!hasTextBlocks && !hasCaptionLayout()) {
            return false;
        }

        if ((!drawSelectionBackground && currentMessagesGroup == null) || (currentMessagesGroup != null && !delegate.hasSelectedMessages())) {
            return false;
        }

        if (currentMessageObject.hasValidGroupId() && currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
            ViewGroup parent = (ViewGroup) getParent();
            if (parent == null) {
                return false;
            }
            for (int i = 0; i < parent.getChildCount(); i++) {
                View v = parent.getChildAt(i);
                if (v instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) v;
                    MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
                    MessageObject.GroupedMessagePosition position = cell.getCurrentPosition();
                    if (group != null && group.groupId == currentMessagesGroup.groupId &&
                            (position.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 &&
                            (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                        textSelectionHelper.setMaybeTextCord((int) cell.captionX, (int) cell.captionY);
                        textSelectionHelper.setMessageObject(cell);
                        if (cell == this) {
                            return textSelectionHelper.onTouchEvent(event);
                        } else {
                            event.offsetLocation(this.getLeft() - cell.getLeft(), this.getTop() - cell.getTop());
                            boolean result = textSelectionHelper.onTouchEvent(event);
                            event.offsetLocation(-(this.getLeft() - cell.getLeft()), -(this.getTop() - cell.getTop()));
                            return result;
                        }
                    }
                }
            }
            return false;
        } else {
            if (hasCaptionLayout()) {
                textSelectionHelper.setIsDescription(false);
                textSelectionHelper.setMaybeTextCord((int) captionX, (int) captionY);
            } else {
                if (descriptionLayout != null && event.getY() > descriptionY) {
                    textSelectionHelper.setIsDescription(true);
                    int linkX;
                    if (hasGamePreview) {
                        linkX = unmovedTextX - AndroidUtilities.dp(10);
                    } else if (hasInvoicePreview) {
                        linkX = unmovedTextX + AndroidUtilities.dp(1);
                    } else {
                        linkX = unmovedTextX + AndroidUtilities.dp(1);
                    }
                    textSelectionHelper.setMaybeTextCord(linkX + AndroidUtilities.dp(10) + descriptionX, descriptionY);
                } else {
                    textSelectionHelper.setIsDescription(false);
                    textSelectionHelper.setMaybeTextCord(textX, textY);
                }
            }
            textSelectionHelper.setMessageObject(this);
        }

        return textSelectionHelper.onTouchEvent(event);
    }

    private void updateSelectionTextPosition() {
        if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
            int textSelectionType = getDelegate().getTextSelectionHelper().getTextSelectionType(this);
            if (textSelectionType == TextSelectionHelper.ChatListTextSelectionHelper.TYPE_DESCRIPTION) {
                int linkX;
                if (hasGamePreview) {
                    linkX = unmovedTextX - AndroidUtilities.dp(10);
                } else if (hasInvoicePreview) {
                    linkX = unmovedTextX + AndroidUtilities.dp(1);
                } else {
                    linkX = unmovedTextX + AndroidUtilities.dp(1);
                }
                getDelegate().getTextSelectionHelper().updateTextPosition(linkX + AndroidUtilities.dp(10) + descriptionX, descriptionY);
            } else if (textSelectionType == TextSelectionHelper.ChatListTextSelectionHelper.TYPE_CAPTION) {
                getDelegate().getTextSelectionHelper().updateTextPosition((int) captionX, (int) captionY);
            } else {
                getDelegate().getTextSelectionHelper().updateTextPosition(textX, textY);
            }
        }
    }

    public ArrayList<PollButton> getPollButtons() {
        return pollButtons;
    }

    public void updatePlayingMessageProgress() {
        if (currentMessageObject == null) {
            return;
        }
        if (videoPlayerRewinder != null && videoPlayerRewinder.rewindCount != 0 && videoPlayerRewinder.rewindByBackSeek) {
            currentMessageObject.audioProgress = videoPlayerRewinder.getVideoProgress();
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
            if (seekBar != null) {
                seekBar.clearTimestamps();
            }
            if (infoLayout != null && (PhotoViewer.isPlayingMessage(currentMessageObject) || MediaController.getInstance().isGoingToShowMessageObject(currentMessageObject))) {
                return;
            }
            int duration = 0;
            AnimatedFileDrawable animation = photoImage.getAnimation();
            if (animation != null) {
                duration = currentMessageObject.audioPlayerDuration = animation.getDurationMs() / 1000;
                if (currentMessageObject.messageOwner.ttl > 0 && currentMessageObject.messageOwner.destroyTime == 0 && !currentMessageObject.needDrawBluredPreview() && currentMessageObject.isVideo() && animation.hasBitmap()) {
                    delegate.didStartVideoStream(currentMessageObject);
                }
            }
            if (duration == 0) {
                duration = currentMessageObject.getDuration();
            }
            if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                duration -= duration * currentMessageObject.audioProgress;
            } else if (animation != null) {
                if (duration != 0) {
                    duration -= animation.getCurrentProgressMs() / 1000;
                }
                if (delegate != null && animation.getCurrentProgressMs() >= 3000) {
                    delegate.videoTimerReached();
                }
            }
            if (lastTime != duration) {
                String str = AndroidUtilities.formatShortDuration(duration);
                infoWidth = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
                infoLayout = new StaticLayout(str, Theme.chat_infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                lastTime = duration;
            }
        } else if (isRoundVideo) {
            if (useSeekBarWaveform) {
                if (!seekBarWaveform.isDragging()) {
                    seekBarWaveform.setProgress(currentMessageObject.audioProgress, true);
                }
            } else {
                if (!seekBar.isDragging()) {
                    seekBar.setProgress(currentMessageObject.audioProgress);
                    seekBar.setBufferedProgress(currentMessageObject.bufferedProgress);
                }
                seekBar.clearTimestamps();
            }

            int duration = 0;
            TLRPC.Document document = currentMessageObject.getDocument();
            for (int a = 0; a < document.attributes.size(); a++) {
                TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
                    duration = attribute.duration;
                    break;
                }
            }
            if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                duration = Math.max(0, duration - currentMessageObject.audioProgressSec);
            }
            if (lastTime != duration) {
                lastTime = duration;
                String timeString = AndroidUtilities.formatLongDuration(duration);
                timeWidthAudio = (int) Math.ceil(Theme.chat_timePaint.measureText(timeString));
                durationLayout = new StaticLayout(timeString, Theme.chat_timePaint, timeWidthAudio, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            }
            if (currentMessageObject.audioProgress != 0) {
                lastDrawingAudioProgress = currentMessageObject.audioProgress;
                if (lastDrawingAudioProgress > 0.9f) {
                    lastDrawingAudioProgress = 1f;
                }
            }
            invalidate();
        } else if (documentAttach != null) {
            if (useSeekBarWaveform) {
                if (!seekBarWaveform.isDragging()) {
                    seekBarWaveform.setProgress(currentMessageObject.audioProgress, true);
                }
            } else {
                if (!seekBar.isDragging()) {
                    seekBar.setProgress(currentMessageObject.audioProgress);
                    seekBar.setBufferedProgress(currentMessageObject.bufferedProgress);
                }
                seekBar.updateTimestamps(currentMessageObject, null);
            }

            int duration = 0;
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO) {
                if (!MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                    for (int a = 0; a < documentAttach.attributes.size(); a++) {
                        TLRPC.DocumentAttribute attribute = documentAttach.attributes.get(a);
                        if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
                            duration = attribute.duration;
                            break;
                        }
                    }
                } else {
                    duration = currentMessageObject.audioProgressSec;
                }

                if (lastTime != duration) {
                    lastTime = duration;
                    String timeString = AndroidUtilities.formatLongDuration(duration);
                    timeWidthAudio = (int) Math.ceil(Theme.chat_audioTimePaint.measureText(timeString));
                    durationLayout = new StaticLayout(timeString, Theme.chat_audioTimePaint, timeWidthAudio, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                }
            } else {
                int currentProgress = 0;
                duration = currentMessageObject.getDuration();
                if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                    currentProgress = currentMessageObject.audioProgressSec;
                }
                if (lastTime != currentProgress) {
                    lastTime = currentProgress;
                    String timeString = AndroidUtilities.formatShortDuration(currentProgress, duration);
                    int timeWidth = (int) Math.ceil(Theme.chat_audioTimePaint.measureText(timeString));
                    durationLayout = new StaticLayout(timeString, Theme.chat_audioTimePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                }
            }
            invalidate();
        }
    }

    public void setFullyDraw(boolean draw) {
        fullyDraw = draw;
    }

    public void setParentViewSize(int parentW, int parentH) {
        parentWidth = parentW;
        parentHeight = parentH;
        backgroundHeight = parentH;

        if (currentMessageObject != null && (hasGradientService() && currentMessageObject.shouldDrawWithoutBackground()) || currentBackgroundDrawable != null && currentBackgroundDrawable.getGradientShader() != null) {
            invalidate();
        }
    }

    public void setVisiblePart(int position, int height, int parent, float parentOffset, float visibleTop, int parentW, int parentH, int blurredViewTopOffset, int blurredViewBottomOffset) {
        this.parentWidth = parentW;
        this.parentHeight = parentH;
        this.backgroundHeight = parentH;
        this.blurredViewTopOffset = blurredViewTopOffset;
        this.blurredViewBottomOffset = blurredViewBottomOffset;

        if (!botButtons.isEmpty() && viewTop != visibleTop) {
            invalidate();
        }
        viewTop = visibleTop;

        if (parent != parentHeight || parentOffset != this.parentViewTopOffset) {
            this.parentViewTopOffset = parentOffset;
            parentHeight = parent;
        }
        if (currentMessageObject != null && (hasGradientService() && currentMessageObject.shouldDrawWithoutBackground())) {
            invalidate();
        }

        if (currentMessageObject == null || currentMessageObject.textLayoutBlocks == null) {
            return;
        }
        position -= textY;

        int newFirst = -1, newLast = -1, newCount = 0;

        int startBlock = 0;
        for (int a = 0; a < currentMessageObject.textLayoutBlocks.size(); a++) {
            if (currentMessageObject.textLayoutBlocks.get(a).textYOffset > position) {
                break;
            }
            startBlock = a;
        }

        for (int a = startBlock; a < currentMessageObject.textLayoutBlocks.size(); a++) {
            MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(a);
            float y = block.textYOffset;
            if (intersect(y, y + block.height, position, position + height)) {
                if (newFirst == -1) {
                    newFirst = a;
                }
                newLast = a;
                newCount++;
            } else if (y > position) {
                break;
            }
        }

        if (lastVisibleBlockNum != newLast || firstVisibleBlockNum != newFirst || totalVisibleBlocksCount != newCount) {
            lastVisibleBlockNum = newLast;
            firstVisibleBlockNum = newFirst;
            totalVisibleBlocksCount = newCount;
            invalidate();
        } else if (animatedEmojiStack != null) {
            for (int i = 0; i < animatedEmojiStack.holders.size(); i++) {
                AnimatedEmojiSpan.AnimatedEmojiHolder holder = animatedEmojiStack.holders.get(i);
                if (holder != null && holder.skipDraw) {
                    float top = parentBoundsTop - getY() - holder.drawingYOffset;
                    float bottom = parentBoundsBottom - getY() - holder.drawingYOffset;
                    if (!holder.outOfBounds(top, bottom)) {
                        invalidate();
                        break;
                    }
                }
            }
        }
    }

    private boolean intersect(float left1, float right1, float left2, float right2) {
        if (left1 <= left2) {
            return right1 >= left2;
        }
        return left1 <= right2;
    }

    public static StaticLayout generateStaticLayout(CharSequence text, TextPaint paint, int maxWidth, int smallWidth, int linesCount, int maxLines) {
        SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text);
        int addedChars = 0;
        StaticLayout layout = new StaticLayout(text, paint, smallWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        for (int a = 0; a < linesCount; a++) {
            Layout.Directions directions = layout.getLineDirections(a);
            if (layout.getLineLeft(a) != 0 || layout.isRtlCharAt(layout.getLineStart(a)) || layout.isRtlCharAt(layout.getLineEnd(a))) {
                maxWidth = smallWidth;
            }
            int pos = layout.getLineEnd(a);
            if (pos == text.length()) {
                break;
            }
            pos--;
            if (stringBuilder.charAt(pos + addedChars) == ' ') {
                stringBuilder.replace(pos + addedChars, pos + addedChars + 1, "\n");
            } else if (stringBuilder.charAt(pos + addedChars) != '\n') {
                stringBuilder.insert(pos + addedChars, "\n");
                addedChars++;
            }
            if (a == layout.getLineCount() - 1 || a == maxLines - 1) {
                break;
            }
        }
        return StaticLayoutEx.createStaticLayout(stringBuilder, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, maxWidth, maxLines, true);
    }

    private void didClickedImage() {
        if (currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) {
            startRevealMedia(lastTouchX, lastTouchY);
            return;
        }
        if (currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW) {
            if (currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.media != null &&
                    currentMessageObject.messageOwner.media.extended_media != null && currentMessageObject.messageOwner.reply_markup != null) {
                for (TLRPC.TL_keyboardButtonRow row : currentMessageObject.messageOwner.reply_markup.rows) {
                    for (TLRPC.KeyboardButton button : row.buttons) {
                        delegate.didPressExtendedMediaPreview(this, button);
                        return;
                    }
                }
            }
        } else if (currentMessageObject.type == MessageObject.TYPE_PHOTO || currentMessageObject.isAnyKindOfSticker()) {
            if (buttonState == -1) {
                delegate.didPressImage(this, lastTouchX, lastTouchY);
            } else if (buttonState == 0) {
                didPressButton(true, false);
            }
        } else if (currentMessageObject.type == MessageObject.TYPE_CONTACT) {
            long uid = MessageObject.getMedia(currentMessageObject.messageOwner).user_id;
            TLRPC.User user = null;
            if (uid != 0) {
                user = MessagesController.getInstance(currentAccount).getUser(uid);
            }
            delegate.didPressUserAvatar(this, user, lastTouchX, lastTouchY);
        } else if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
            if (buttonState != -1) {
                didPressButton(true, false);
            } else {
                if (!MediaController.getInstance().isPlayingMessage(currentMessageObject) || MediaController.getInstance().isMessagePaused()) {
                    delegate.needPlayMessage(currentMessageObject, false);
                } else {
                    MediaController.getInstance().pauseMessage(currentMessageObject);
                }
            }
        } else if (currentMessageObject.type == MessageObject.TYPE_GIF) {
            if (buttonState == -1 || buttonState == 1 && canStreamVideo && autoPlayingMedia) {
                //if (SharedConfig.isAutoplayGifs()) {
                delegate.didPressImage(this, lastTouchX, lastTouchY);
                /*} else {
                    buttonState = 2;
                    currentMessageObject.gifState = 1;
                    photoImage.setAllowStartAnimation(false);
                    photoImage.stopAnimation();
                    radialProgress.setIcon(getIconForCurrentState(), false, true);
                    invalidate();
                }*/
            } else if (buttonState == 2 || buttonState == 0) {
                didPressButton(true, false);
            }
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
            if (buttonState == -1 || drawVideoImageButton && (autoPlayingMedia || SharedConfig.streamMedia && canStreamVideo)) {
                delegate.didPressImage(this, lastTouchX, lastTouchY);
            } else if (drawVideoImageButton) {
                didPressButton(true, true);
            } else if (buttonState == 0 || buttonState == 3) {
                didPressButton(true, false);
            }
        } else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
            delegate.didPressImage(this, lastTouchX, lastTouchY);
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
            if (buttonState == -1) {
                delegate.didPressImage(this, lastTouchX, lastTouchY);
            }
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
            if (buttonState == -1) {
                TLRPC.WebPage webPage = MessageObject.getMedia(currentMessageObject.messageOwner).webpage;
                if (webPage != null) {
                    if (webPage.embed_url != null && webPage.embed_url.length() != 0) {
                        delegate.needOpenWebView(currentMessageObject, webPage.embed_url, webPage.site_name, webPage.description, webPage.url, webPage.embed_width, webPage.embed_height);
                    } else {
                        Browser.openUrl(getContext(), webPage.url);
                    }
                }
            }
        } else if (hasInvoicePreview) {
            if (buttonState == -1) {
                delegate.didPressImage(this, lastTouchX, lastTouchY);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // open message options then
            if (delegate != null) {
                if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
                    delegate.didLongPress(this, 0, 0);
                } else {
                    delegate.didPressOther(this, otherX, otherY);
                }
            }
        }
    }

    private void updateSecretTimeText(MessageObject messageObject) {
        if (messageObject == null || !messageObject.needDrawBluredPreview()) {
            return;
        }
        String str = messageObject.getSecretTimeString();
        if (str == null) {
            return;
        }
        infoWidth = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
        CharSequence str2 = TextUtils.ellipsize(str, Theme.chat_infoPaint, infoWidth, TextUtils.TruncateAt.END);
        infoLayout = new StaticLayout(str2, Theme.chat_infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        invalidate();
    }

    private boolean isPhotoDataChanged(MessageObject object) {
        if (object.type == MessageObject.TYPE_TEXT || object.type == MessageObject.TYPE_MUSIC) {
            return false;
        }
        if (object.type == MessageObject.TYPE_GEO) {
            if (currentUrl == null) {
                return true;
            }
            double lat = object.messageOwner.media.geo.lat;
            double lon = object.messageOwner.media.geo._long;
            String url;
            int provider;
            if ((int) object.getDialogId() == 0) {
                if (SharedConfig.mapPreviewType == 0) {
                    provider = -1;
                } else if (SharedConfig.mapPreviewType == 1) {
                    provider = 4;
                } else if (SharedConfig.mapPreviewType == 3) {
                    provider = 1;
                } else {
                    provider = -1;
                }
            } else {
                provider = -1;
            }
            if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {
                int photoWidth = backgroundWidth - AndroidUtilities.dp(21);
                int photoHeight = AndroidUtilities.dp(195);

                int offset = 268435456;
                double rad = offset / Math.PI;
                double y = Math.round(offset - rad * Math.log((1 + Math.sin(lat * Math.PI / 180.0)) / (1 - Math.sin(lat * Math.PI / 180.0))) / 2) - (AndroidUtilities.dp(10.3f) << (21 - 15));
                lat = (Math.PI / 2.0 - 2 * Math.atan(Math.exp((y - offset) / rad))) * 180.0 / Math.PI;
                url = AndroidUtilities.formapMapUrl(currentAccount, lat, lon, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), false, 15, provider);
            } else if (!TextUtils.isEmpty(object.messageOwner.media.title)) {
                int photoWidth = backgroundWidth - AndroidUtilities.dp(21);
                int photoHeight = AndroidUtilities.dp(195);
                url = AndroidUtilities.formapMapUrl(currentAccount, lat, lon, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), true, 15, provider);
            } else {
                int photoWidth = backgroundWidth - AndroidUtilities.dp(12);
                int photoHeight = AndroidUtilities.dp(195);
                url = AndroidUtilities.formapMapUrl(currentAccount, lat, lon, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), true, 15, provider);
            }
            return !url.equals(currentUrl);
        } else if (currentPhotoObject == null || currentPhotoObject.location instanceof TLRPC.TL_fileLocationUnavailable) {
            return (
                object.type == MessageObject.TYPE_PHOTO ||
                object.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW ||
                object.type == MessageObject.TYPE_ROUND_VIDEO ||
                object.type == MessageObject.TYPE_VIDEO ||
                object.type == MessageObject.TYPE_GIF ||
                object.isAnyKindOfSticker()
            );
        } else if (currentMessageObject != null && photoNotSet) {
            File cacheFile = FileLoader.getInstance(currentAccount).getPathToMessage(currentMessageObject.messageOwner);
            return cacheFile.exists();
        }
        return false;
    }

    private int getRepliesCount() {
        if (currentMessagesGroup != null && !currentMessagesGroup.messages.isEmpty()) {
            MessageObject messageObject = currentMessagesGroup.messages.get(0);
            return messageObject.getRepliesCount();
        }
        return currentMessageObject.getRepliesCount();
    }

    private ArrayList<TLRPC.Peer> getRecentRepliers() {
        if (currentMessagesGroup != null && !currentMessagesGroup.messages.isEmpty()) {
            MessageObject messageObject = currentMessagesGroup.messages.get(0);
            if (messageObject.messageOwner.replies != null) {
                return messageObject.messageOwner.replies.recent_repliers;
            }
        }
        if (currentMessageObject.messageOwner.replies != null) {
            return currentMessageObject.messageOwner.replies.recent_repliers;
        }
        return null;
    }

    public void updateAnimatedEmojis() {
        if (!imageReceiversAttachState) {
            return;
        }
        int cache = currentMessageObject.wasJustSent ? AnimatedEmojiDrawable.getCacheTypeForEnterView() : AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES;
        if (captionLayout != null) {
            animatedEmojiStack = AnimatedEmojiSpan.update(cache, this, false, animatedEmojiStack, captionLayout);
        } else {
            animatedEmojiStack = AnimatedEmojiSpan.update(cache, this, delegate == null || !delegate.canDrawOutboundsContent(), animatedEmojiStack, currentMessageObject.textLayoutBlocks);
        }
    }

    private void updateCaptionSpoilers() {
        captionSpoilersPool.addAll(captionSpoilers);
        captionSpoilers.clear();

        if (captionLayout != null && !getMessageObject().isSpoilersRevealed) {
            SpoilerEffect.addSpoilers(this, captionLayout, captionSpoilersPool, captionSpoilers);
        }
    }

    private boolean isUserDataChanged() {
        if (currentMessageObject != null && (!hasLinkPreview && MessageObject.getMedia(currentMessageObject.messageOwner) != null && MessageObject.getMedia(currentMessageObject.messageOwner).webpage instanceof TLRPC.TL_webPage)) {
            return true;
        }
        if (currentMessageObject == null || currentUser == null && currentChat == null) {
            return false;
        }
        if (lastSendState != currentMessageObject.messageOwner.send_state) {
            return true;
        }
        if (lastDeleteDate != currentMessageObject.messageOwner.destroyTime) {
            return true;
        }
        if (lastViewsCount != currentMessageObject.messageOwner.views) {
            return true;
        }
        if (lastRepliesCount != getRepliesCount()) {
            return true;
        }
        if (lastReactions != currentMessageObject.messageOwner.reactions) {
            return true;
        }

        updateCurrentUserAndChat();
        TLRPC.FileLocation newPhoto = null;

        if (isAvatarVisible) {
            if (currentUser != null && currentUser.photo != null) {
                newPhoto = currentUser.photo.photo_small;
            } else if (currentChat != null && currentChat.photo != null) {
                newPhoto = currentChat.photo.photo_small;
            }
        }

        if (replyTextLayout == null && currentMessageObject.replyMessageObject != null) {
            if (!isThreadChat || currentMessageObject.replyMessageObject.messageOwner.fwd_from == null || currentMessageObject.replyMessageObject.messageOwner.fwd_from.channel_post == 0) {
                return true;
            }
        }

        if (currentPhoto == null && newPhoto != null || currentPhoto != null && newPhoto == null || currentPhoto != null && (currentPhoto.local_id != newPhoto.local_id || currentPhoto.volume_id != newPhoto.volume_id)) {
            return true;
        }

        TLRPC.PhotoSize newReplyPhoto = null;

        if (replyNameLayout != null && currentMessageObject.replyMessageObject != null) {
            TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.replyMessageObject.photoThumbs, 40);
            if (photoSize != null && !currentMessageObject.replyMessageObject.isAnyKindOfSticker()) {
                newReplyPhoto = photoSize;
            }
        }

        if (currentReplyPhoto == null && newReplyPhoto != null) {
            return true;
        }

        String newNameString = isNeedAuthorName() ? getAuthorName() : null;
        if (currentNameString == null && newNameString != null || currentNameString != null && newNameString == null || currentNameString != null && !currentNameString.equals(newNameString)) {
            return true;
        }

        if (drawForwardedName && currentMessageObject.needDrawForwarded()) {
            newNameString = currentMessageObject.getForwardedName();
            return currentForwardNameString == null && newNameString != null || currentForwardNameString != null && newNameString == null || currentForwardNameString != null && !currentForwardNameString.equals(newNameString);
        }
        return false;
    }

    public ImageReceiver getPhotoImage() {
        return photoImage;
    }

    public int getNoSoundIconCenterX() {
        return noSoundCenterX;
    }

    public int getForwardNameCenterX() {
        if (currentUser != null && currentUser.id == 0) {
            return (int) avatarImage.getCenterX();
        }
        return (int) (forwardNameX + forwardNameCenterX);
    }

    public int getChecksX() {
        return layoutWidth - AndroidUtilities.dp(SharedConfig.bubbleRadius >= 10 ? 27.3f : 25.3f);
    }

    public int getChecksY() {
        if (currentMessageObject.shouldDrawWithoutBackground()) {
            return (int) (drawTimeY - getThemedDrawable(Theme.key_drawable_msgStickerCheck).getIntrinsicHeight());
        } else {
            return (int) (drawTimeY - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight());
        }
    }

    public TLRPC.User getCurrentUser() {
        return currentUser;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.startSpoilers);
        NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopSpoilers);
        NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
        NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.userInfoDidLoad);

        cancelShakeAnimation();
        if (animationRunning) {
            return;
        }
        if (checkBox != null) {
            checkBox.onDetachedFromWindow();
        }
        if (mediaCheckBox != null) {
            mediaCheckBox.onDetachedFromWindow();
        }
        if (pollCheckBox != null) {
            for (int a = 0; a < pollCheckBox.length; a++) {
                pollCheckBox[a].onDetachedFromWindow();
            }
        }
        attachedToWindow = false;
        avatarImage.onDetachedFromWindow();
        checkImageReceiversAttachState();
        if (addedForTest && currentUrl != null && currentWebFile != null) {
            ImageLoader.getInstance().removeTestWebFile(currentUrl);
            addedForTest = false;
        }
        DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);

        if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null) {
            getDelegate().getTextSelectionHelper().onChatMessageCellDetached(this);
        }

        transitionParams.onDetach();
        if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
            Theme.getCurrentAudiVisualizerDrawable().setParentView(null);
        }

        if (statusDrawableAnimator != null) {
            statusDrawableAnimator.removeAllListeners();
            statusDrawableAnimator.cancel();
        }
        reactionsLayoutInBubble.onDetachFromWindow();
        statusDrawableAnimationInProgress = false;

        if (flagSecure != null) {
            flagSecure.detach();
        }
        if (topicButton != null) {
            topicButton.onDetached(this);
        }
        if (currentNameStatusDrawable != null) {
            currentNameStatusDrawable.detach();
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.startSpoilers);
        NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.stopSpoilers);
        NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
        NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.userInfoDidLoad);

//        if (currentMessageObject != null) {
//            currentMessageObject.onAttachedWindow(this);
//        }
        if (currentMessageObject != null) {
            currentMessageObject.animateComments = false;
        }
        if (messageObjectToSet != null) {
            messageObjectToSet.animateComments = false;
            setMessageContent(messageObjectToSet, groupedMessagesToSet, bottomNearToSet, topNearToSet);
            messageObjectToSet = null;
            groupedMessagesToSet = null;
        }
        if (checkBox != null) {
            checkBox.onAttachedToWindow();
        }
        if (mediaCheckBox != null) {
            mediaCheckBox.onAttachedToWindow();
        }
        if (pollCheckBox != null) {
            for (int a = 0; a < pollCheckBox.length; a++) {
                pollCheckBox[a].onAttachedToWindow();
            }
        }

        attachedToWindow = true;

        animationOffsetX = 0;
        slidingOffsetX = 0;
        checkBoxTranslation = 0;
        updateTranslation();

        avatarImage.setParentView((View) getParent());
        avatarImage.onAttachedToWindow();
        checkImageReceiversAttachState();
        if (currentMessageObject != null) {
            setAvatar(currentMessageObject);
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && autoPlayingMedia) {
            animatingNoSoundPlaying = MediaController.getInstance().isPlayingMessage(currentMessageObject);
            animatingNoSoundProgress = animatingNoSoundPlaying ? 0.0f : 1.0f;
            animatingNoSound = 0;
        } else {
            animatingNoSoundPlaying = false;
            animatingNoSoundProgress = 0;
            animatingDrawVideoImageButtonProgress = (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) && drawVideoSize ? 1.0f : 0.0f;
        }

        if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null) {
            getDelegate().getTextSelectionHelper().onChatMessageCellAttached(this);
        }

        if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
            boolean showSeekbar = MediaController.getInstance().isPlayingMessage(currentMessageObject);
            toSeekBarProgress = showSeekbar ? 1f : 0f;
        }
        reactionsLayoutInBubble.onAttachToWindow();
        if (flagSecure != null) {
            flagSecure.attach();
        }
        updateFlagSecure();

        if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW && unlockLayout != null) {
            invalidate();
        }
        if (topicButton != null) {
            topicButton.onAttached(this);
        }
        if (currentNameStatusDrawable != null) {
            currentNameStatusDrawable.attach();
        }
    }

    boolean imageReceiversAttachState;

    private void checkImageReceiversAttachState() {
        boolean newAttachState = attachedToWindow && (visibleOnScreen || !shouldCheckVisibleOnScreen);
        if (newAttachState == imageReceiversAttachState) {
            return;
        }
        imageReceiversAttachState = newAttachState;
        if (newAttachState) {
            radialProgress.onAttachedToWindow();
            videoRadialProgress.onAttachedToWindow();
            if (pollAvatarImages != null) {
                for (int a = 0; a < pollAvatarImages.length; a++) {
                    pollAvatarImages[a].onAttachedToWindow();
                }
            }
            if (commentAvatarImages != null) {
                for (int a = 0; a < commentAvatarImages.length; a++) {
                    commentAvatarImages[a].onAttachedToWindow();
                }
            }
            replyImageReceiver.onAttachedToWindow();
            locationImageReceiver.onAttachedToWindow();
            blurredPhotoImage.onAttachedToWindow();
            if (photoImage.onAttachedToWindow()) {
                if (drawPhotoImage) {
                    updateButtonState(false, false, false);
                }
            } else {
                updateButtonState(false, false, false);
            }
            if (currentMessageObject != null && (isRoundVideo || currentMessageObject.isVideo())) {
                checkVideoPlayback(true, null);
            }
            if (currentMessageObject != null && !currentMessageObject.mediaExists) {
                int canDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject.messageOwner);
                TLRPC.Document document = currentMessageObject.getDocument();
                boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document);
                if (!loadDocumentFromImageReceiver) {
                    TLRPC.PhotoSize photo = document == null ? FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize()) : null;
                    if (canDownload == 2 || canDownload == 1 && currentMessageObject.isVideo()) {
                        if (canDownload != 2 && document != null && !currentMessageObject.shouldEncryptPhotoOrVideo() && currentMessageObject.canStreamVideo()) {
                            FileLoader.getInstance(currentAccount).loadFile(document, currentMessageObject, FileLoader.PRIORITY_NORMAL, 0);
                        }
                    } else if (canDownload != 0) {
                        if (document != null) {
                            FileLoader.getInstance(currentAccount).loadFile(document, currentMessageObject, FileLoader.PRIORITY_NORMAL, MessageObject.isVideoDocument(document) && currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                        } else if (photo != null) {
                            FileLoader.getInstance(currentAccount).loadFile(ImageLocation.getForObject(photo, currentMessageObject.photoThumbsObject), currentMessageObject, null, FileLoader.PRIORITY_NORMAL, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                        }
                    }
                    updateButtonState(false, false, false);
                }
            }
            animatedEmojiReplyStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, false, animatedEmojiReplyStack, replyTextLayout);
            animatedEmojiDescriptionStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, false, animatedEmojiDescriptionStack, descriptionLayout);
            updateAnimatedEmojis();
        } else {
            radialProgress.onDetachedFromWindow();
            videoRadialProgress.onDetachedFromWindow();
            if (pollAvatarImages != null) {
                for (int a = 0; a < pollAvatarImages.length; a++) {
                    pollAvatarImages[a].onDetachedFromWindow();
                }
            }
            if (commentAvatarImages != null) {
                for (int a = 0; a < commentAvatarImages.length; a++) {
                    commentAvatarImages[a].onDetachedFromWindow();
                }
            }
            replyImageReceiver.onDetachedFromWindow();
            locationImageReceiver.onDetachedFromWindow();
            photoImage.onDetachedFromWindow();
            blurredPhotoImage.onDetachedFromWindow();

            if (currentMessageObject != null && !currentMessageObject.mediaExists && !currentMessageObject.putInDownloadsStore && !DownloadController.getInstance(currentAccount).isDownloading(currentMessageObject.messageOwner.id)) {
                TLRPC.Document document = currentMessageObject.getDocument();
                boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document);
                if (!loadDocumentFromImageReceiver) {
                    if (document != null) {
                        FileLoader.getInstance(currentAccount).cancelLoadFile(document);
                    } else {
                        TLRPC.PhotoSize photo = FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize());
                        if (photo != null) {
                            FileLoader.getInstance(currentAccount).cancelLoadFile(photo);
                        }
                    }
                }
            }
            AnimatedEmojiSpan.release(this, animatedEmojiDescriptionStack);
            AnimatedEmojiSpan.release(this, animatedEmojiReplyStack);
            AnimatedEmojiSpan.release(this, animatedEmojiStack);
        }
    }

    //设置文字内容
    private void setMessageContent(MessageObject messageObject, MessageObject.GroupedMessages groupedMessages, boolean bottomNear, boolean topNear) {
        if (messageObject.checkLayout() || currentPosition != null && lastHeight != AndroidUtilities.displaySize.y) {
            currentMessageObject = null;
        }
        messageObject.isOutOwnerCached = null;
        boolean widthChanged = lastWidth != getParentWidth();
        lastHeight = AndroidUtilities.displaySize.y;
        lastWidth = getParentWidth();
        isRoundVideo = messageObject != null && messageObject.isRoundVideo();
        mediaSpoilerRevealProgress = 0f;
        TLRPC.Message newReply = messageObject.hasValidReplyMessageObject() ? messageObject.replyMessageObject.messageOwner : null;
        boolean messageIdChanged = currentMessageObject == null || currentMessageObject.getId() != messageObject.getId();
        boolean messageChanged = currentMessageObject != messageObject || messageObject.forceUpdate || (isRoundVideo && isPlayingRound != (MediaController.getInstance().isPlayingMessage(currentMessageObject) && delegate != null && !delegate.keyboardIsOpened()));
        boolean dataChanged = currentMessageObject != null && currentMessageObject.getId() == messageObject.getId() && lastSendState == MessageObject.MESSAGE_SEND_STATE_EDITING && messageObject.isSent() ||
                currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet) ||
                lastPostAuthor != messageObject.messageOwner.post_author ||
                wasPinned != isPinned ||
                newReply != lastReplyMessage ||
                messageObject.translated != lastTranslated;
        boolean groupChanged = groupedMessages != currentMessagesGroup;
        boolean pollChanged = false;

        if (!messageIdChanged && currentMessageObject != null) {
            messageObject.copyStableParams(currentMessageObject);
        }
        accessibilityText = null;
        if (drawCommentButton || useTranscribeButton || drawSideButton == 3 && !((hasDiscussion && messageObject.isLinkedToChat(linkedChatId) || isRepliesChat) && (currentPosition == null || currentPosition.siblingHeights == null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 || currentPosition.siblingHeights != null && (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0))) {
            dataChanged = true;
        }
        if (!messageChanged && messageObject.isDice()) {
            setCurrentDiceValue(isUpdating);
        }
        if (!messageChanged && messageObject.isPoll()) {
            ArrayList<TLRPC.TL_pollAnswerVoters> newResults = null;
            TLRPC.Poll newPoll = null;
            int newVoters = 0;
            if (MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaPoll) {
                TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) MessageObject.getMedia(messageObject.messageOwner);
                newResults = mediaPoll.results.results;
                newPoll = mediaPoll.poll;
                newVoters = mediaPoll.results.total_voters;
            }
            if (newResults != null && lastPollResults != null && newVoters != lastPollResultsVoters) {
                pollChanged = true;
            }
            if (!pollChanged && newResults != lastPollResults) {
                pollChanged = true;
            }
            if (lastPoll != newPoll && lastPoll.closed != newPoll.closed) {
                pollChanged = true;
                if (!pollVoted) {
                    pollVoteInProgress = true;
                    vibrateOnPollVote = false;
                }
            }
            animatePollAvatars = false;
            if (pollChanged && attachedToWindow) {
                pollAnimationProgressTime = 0.0f;
                if (pollVoted && !messageObject.isVoted()) {
                    pollUnvoteInProgress = true;
                }
                animatePollAvatars = lastPollResultsVoters == 0 || lastPollResultsVoters != 0 && newVoters == 0;
            }
            if (!messageIdChanged && newPoll != null && lastPoll.quiz && newPoll.quiz && currentMessageObject != null && !pollVoted && messageObject != null && messageObject.isVoted()) {
                TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) MessageObject.getMedia(messageObject.messageOwner);
                if (mediaPoll.results != null && !mediaPoll.results.results.isEmpty()) {
                    TLRPC.TL_pollAnswerVoters chosenAnswer = null;
                    int a;
                    final int count = mediaPoll.results.results.size();
                    for (a = 0; a < count; a++) {
                        TLRPC.TL_pollAnswerVoters answer = mediaPoll.results.results.get(a);
                        if (answer.chosen) {
                            chosenAnswer = answer;
                            break;
                        }
                    }
                    if (chosenAnswer != null) {
                        sendAccessibilityEventForVirtualView(MessageAccessibilityNodeProvider.POLL_BUTTONS_START + a, AccessibilityEvent.TYPE_VIEW_SELECTED, chosenAnswer.correct ? LocaleController.getString("AccDescrQuizCorrectAnswer", R.string.AccDescrQuizCorrectAnswer) : LocaleController.getString("AccDescrQuizIncorrectAnswer", R.string.AccDescrQuizIncorrectAnswer));
                    }
                }
            }
        }
        if (!groupChanged && groupedMessages != null) {
            MessageObject.GroupedMessagePosition newPosition;
            if (groupedMessages.messages.size() > 1) {
                newPosition = currentMessagesGroup.positions.get(currentMessageObject);
            } else {
                newPosition = null;
            }
            groupChanged = newPosition != currentPosition;
        }
        if (messageChanged || dataChanged || groupChanged || pollChanged || widthChanged && messageObject.isPoll() || isPhotoDataChanged(messageObject) || pinnedBottom != bottomNear || pinnedTop != topNear) {
            wasPinned = isPinned;
            pinnedBottom = bottomNear;
            pinnedTop = topNear;
            currentMessageObject = messageObject;
            currentMessagesGroup = groupedMessages;
            lastTime = -2;
            lastPostAuthor = messageObject.messageOwner.post_author;
            if (messageIdChanged || groupChanged) {
                isHighlightedAnimated = false;
                wasTranscriptionOpen = false;
            }
            widthBeforeNewTimeLine = -1;
            if (currentMessagesGroup != null && (currentMessagesGroup.posArray.size() > 1)) {
                currentPosition = currentMessagesGroup.positions.get(currentMessageObject);
                if (currentPosition == null) {
                    currentMessagesGroup = null;
                }
            } else {
                currentMessagesGroup = null;
                currentPosition = null;
            }
            if (currentMessagesGroup == null || currentMessagesGroup.isDocuments) {
                drawPinnedTop = pinnedTop;
                drawPinnedBottom = pinnedBottom;
            } else {
                drawPinnedTop = pinnedTop && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
                drawPinnedBottom = pinnedBottom && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0);
            }

            boolean wasPlayingRound = isPlayingRound;
            isPlayingRound = isRoundVideo && MediaController.getInstance().isPlayingMessage(currentMessageObject) && delegate != null && !delegate.keyboardIsOpened() && !delegate.isLandscape();
            photoImage.setCrossfadeWithOldImage(false);
            photoImage.setCrossfadeDuration(ImageReceiver.DEFAULT_CROSSFADE_DURATION);
            photoImage.setCrossfadeByScale(0);
            photoImage.setGradientBitmap(null);
            lastTranslated = messageObject.translated;
            lastSendState = messageObject.messageOwner.send_state;
            lastDeleteDate = messageObject.messageOwner.destroyTime;
            lastViewsCount = messageObject.messageOwner.views;
            lastRepliesCount = getRepliesCount();
            if (messageIdChanged) {
                isPressed = false;
                isCheckPressed = true;
            }
            gamePreviewPressed = false;
            sideButtonPressed = false;
            hasNewLineForTime = false;
            flipImage = false;
            isThreadPost = isThreadChat && messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.channel_post != 0 && messageObject.messageOwner.reply_to == null;
            isAvatarVisible = !BuildVars.IS_CHAT_AIR && !isThreadPost && isChat && !messageObject.isOutOwner() && messageObject.needDrawAvatar() && (currentPosition == null || currentPosition.edge);
            boolean drawAvatar = isChat && !isThreadPost && !messageObject.isOutOwner() && messageObject.needDrawAvatar();
            if (messageObject.customAvatarDrawable != null) {
                isAvatarVisible = true;
                drawAvatar = true;
            }
            wasLayout = false;
            groupPhotoInvisible = false;
            animatingDrawVideoImageButton = 0;
            drawVideoSize = false;
            canStreamVideo = false;
            animatingNoSound = 0;
            if (MessagesController.getInstance(currentAccount).isChatNoForwards(messageObject.getChatId()) || (messageObject.messageOwner != null && messageObject.messageOwner.noforwards)) {
                drawSideButton = 0;
            } else {
                drawSideButton = !isRepliesChat && checkNeedDrawShareButton(messageObject) && (currentPosition == null || currentPosition.last) ? 1 : 0;
                if (isPinnedChat || drawSideButton == 1 && messageObject.messageOwner.fwd_from != null && !messageObject.isOutOwner() && messageObject.messageOwner.fwd_from.saved_from_peer != null && messageObject.getDialogId() == UserConfig.getInstance(currentAccount).getClientUserId()) {
                    drawSideButton = 2;
                }
            }
            replyNameLayout = null;
            adminLayout = null;
            checkOnlyButtonPressed = false;
            replyTextLayout = null;
            AnimatedEmojiSpan.release(this, animatedEmojiReplyStack);
            lastReplyMessage = null;
            hasEmbed = false;
            autoPlayingMedia = false;
            replyNameWidth = 0;
            replyTextWidth = 0;
            viaWidth = 0;
            viaNameWidth = 0;
            addedCaptionHeight = 0;
            currentReplyPhoto = null;
            currentUser = null;
            currentChat = null;
            currentReplyUserId = 0;
            currentViaBotUser = null;
            instantViewLayout = null;
            drawNameLayout = false;
            lastLoadingSizeTotal = 0;
            if (scheduledInvalidate) {
                AndroidUtilities.cancelRunOnUIThread(invalidateRunnable);
                scheduledInvalidate = false;
            }
            links.clear();
            pressedLink = null;
            pressedEmoji = null;
            pressedLinkType = -1;
            messageObject.forceUpdate = false;
            drawPhotoImage = false;
            drawMediaCheckBox = false;
            hasLinkPreview = false;
            hasOldCaptionPreview = false;
            hasGamePreview = false;
            hasInvoicePreview = false;
            instantPressed = commentButtonPressed = false;
            setInstantButtonPressed(false);
            if (!pollChanged && Build.VERSION.SDK_INT >= 21) {
                for (int a = 0; a < selectorDrawable.length; a++) {
                    if (selectorDrawable[a] != null) {
                        selectorDrawable[a].setVisible(false, false);
                        selectorDrawable[a].setState(StateSet.NOTHING);
                    }
                }
            }
            spoilerPressed = null;
            isCaptionSpoilerPressed = false;
            isSpoilerRevealing = false;
            linkPreviewPressed = false;
            buttonPressed = 0;
            additionalTimeOffsetY = 0;
            miniButtonPressed = 0;
            pressedBotButton = -1;
            pressedVoteButton = -1;
            pollHintPressed = false;
            psaHintPressed = false;
            linkPreviewHeight = 0;
            mediaOffsetY = 0;
            documentAttachType = DOCUMENT_ATTACH_TYPE_NONE;
            documentAttach = null;
            descriptionLayout = null;
            titleLayout = null;
            videoInfoLayout = null;
            photosCountLayout = null;
            siteNameLayout = null;
            authorLayout = null;
            captionLayout = null;
            captionWidth = 0;
            captionHeight = 0;
            captionOffsetX = 0;
            currentCaption = null;
            docTitleLayout = null;
            drawImageButton = false;
            drawVideoImageButton = false;
            currentPhotoObject = null;
            photoParentObject = null;
            currentPhotoObjectThumb = null;
            currentPhotoObjectThumbStripped = null;
            if (messageChanged || messageIdChanged || dataChanged) {
                currentPhotoFilter = null;
            }
            buttonState = -1;
            miniButtonState = -1;
            hasMiniProgress = 0;
            if (addedForTest && currentUrl != null && currentWebFile != null) {
                ImageLoader.getInstance().removeTestWebFile(currentUrl);
            }
            addedForTest = false;
            photoNotSet = false;
            drawBackground = true;
            drawName = false;
            useSeekBarWaveform = false;
            useTranscribeButton = false;
            drawInstantView = false;
            drawInstantViewType = 0;
            drawForwardedName = false;
            drawCommentButton = false;
            photoImage.setSideClip(0);
            photoImage.setAspectFit(false);
            gradientShader = null;
            motionBackgroundDrawable = null;

            imageBackgroundColor = 0;
            imageBackgroundGradientColor1 = 0;
            imageBackgroundGradientColor2 = 0;
            imageBackgroundIntensity = 0;
            imageBackgroundGradientColor3 = 0;
            imageBackgroundGradientRotation = 45;
            imageBackgroundSideColor = 0;
            mediaBackground = false;
            isMedia = false;
            photoImage.animatedFileDrawableRepeatMaxCount = 0;
            hasPsaHint = messageObject.messageOwner.fwd_from != null && !TextUtils.isEmpty(messageObject.messageOwner.fwd_from.psa_type);
            if (hasPsaHint) {
                createSelectorDrawable(0);
            }
            photoImage.setAlpha(1.0f);
            if ((messageChanged || dataChanged) && !pollUnvoteInProgress) {
                pollButtons.clear();
            }
            int captionNewLine = 0;
            availableTimeWidth = 0;

            photoImage.setForceLoading(false);
            photoImage.setNeedsQualityThumb(false);
            photoImage.setShouldGenerateQualityThumb(false);
            photoImage.setAllowDecodeSingleFrame(false);
            photoImage.setColorFilter(null);
            photoImage.setMediaStartEndTime(-1, -1);
            boolean canChangeRadius = true;


            if (messageIdChanged || messageObject.reactionsChanged || wasPlayingRound != isPlayingRound) {
                messageObject.reactionsChanged = false;
                if (currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0)) {
                    boolean isSmall = !messageObject.shouldDrawReactionsInLayout();
                    if (isSmall && messageObject.messageOwner != null && messageObject.messageOwner.reactions != null && messageObject.messageOwner.reactions.results != null) {
                        int userCount = 0;
                        int user2Count = 0;
                        for (int i = 0; i < messageObject.messageOwner.reactions.results.size(); i++) {
                            TLRPC.ReactionCount reactionCount = messageObject.messageOwner.reactions.results.get(i);
                            if (reactionCount.count == 2) {
                                userCount++;
                                user2Count++;
                            } else {
                                if (reactionCount.chosen) {
                                    userCount++;
                                } else {
                                    user2Count++;
                                }
                            }
                            if (user2Count >= 2 || userCount >= 2) {
                                isSmall = false;
                                break;
                            }
                        }
                    }
                    if (currentPosition != null) {
                        reactionsLayoutInBubble.setMessage(groupedMessages.findPrimaryMessageObject(), !messageObject.shouldDrawReactionsInLayout(), resourcesProvider);
                    } else {
                        reactionsLayoutInBubble.setMessage(messageObject, isSmall, resourcesProvider);
                    }
                } else {
                    reactionsLayoutInBubble.setMessage(null, false, resourcesProvider);
                }
            }


            if (messageChanged) {
                firstVisibleBlockNum = 0;
                lastVisibleBlockNum = 0;
                if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && currentMessageObject.textLayoutBlocks.size() > 1) {
                    needNewVisiblePart = true;
                }
            }

            boolean linked = false;
            if (currentMessagesGroup != null && currentMessagesGroup.messages.size() > 0) {
                MessageObject object = currentMessagesGroup.messages.get(0);
                if (object.isLinkedToChat(linkedChatId)) {
                    linked = true;
                }
            } else {
                linked = messageObject.isLinkedToChat(linkedChatId);
            }
            if ((hasDiscussion && linked || isRepliesChat && !messageObject.isOutOwner()) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0)) {
                int commentCount = getRepliesCount();
                if (!messageObject.shouldDrawWithoutBackground() && !messageObject.isAnimatedEmoji()) {
                    drawCommentButton = true;
                    int avatarsOffset = 0;
                    String comment;
                    if (commentProgress == null) {
                        commentProgress = new InfiniteProgress(AndroidUtilities.dp(7));
                    }
                    if (isRepliesChat) {
                        comment = LocaleController.getString("ViewInChat", R.string.ViewInChat);
                    } else {
                        if (LocaleController.isRTL) {
                            comment = commentCount == 0 ? LocaleController.getString("LeaveAComment", R.string.LeaveAComment) : LocaleController.formatPluralString("CommentsCount", commentCount);
                        } else {
                            comment = commentCount == 0 ? LocaleController.getString("LeaveAComment", R.string.LeaveAComment) : LocaleController.getPluralString("CommentsNoNumber", commentCount);
                        }
                        ArrayList<TLRPC.Peer> recentRepliers = getRecentRepliers();
                        if (commentCount != 0 && recentRepliers != null && !recentRepliers.isEmpty()) {
                            createCommentUI();
                            int size = recentRepliers.size();
                            for (int a = 0; a < commentAvatarImages.length; a++) {
                                if (a < size) {
                                    commentAvatarImages[a].setImageCoords(0, 0, AndroidUtilities.dp(24), AndroidUtilities.dp(24));
                                    long id = MessageObject.getPeerId(recentRepliers.get(a));
                                    TLRPC.User user;
                                    TLRPC.Chat chat;
                                    if (DialogObject.isUserDialog(id)) {
                                        user = MessagesController.getInstance(currentAccount).getUser(id);
                                        chat = null;
                                    } else if (DialogObject.isChatDialog(id)) {
                                        user = null;
                                        chat = MessagesController.getInstance(currentAccount).getChat(-id);
                                    } else {
                                        user = null;
                                        chat = null;
                                    }
                                    final int A = a;
                                    post(() -> {
                                        if (user != null) {
                                            commentAvatarDrawables[A].setInfo(user);
                                            commentAvatarImages[A].setForUserOrChat(user, commentAvatarDrawables[A]);
                                        } else if (chat != null) {
                                            commentAvatarDrawables[A].setInfo(chat);
                                            commentAvatarImages[A].setForUserOrChat(chat, commentAvatarDrawables[A]);
                                        } else {
                                            commentAvatarDrawables[A].setInfo(id, "", "");
                                        }
                                    });
                                    commentAvatarImagesVisible[a] = true;
                                    avatarsOffset += a == 0 ? 2 : 17;
                                } else if (size != 0) {
                                    commentAvatarImages[a].setImageBitmap((Drawable) null);
                                    commentAvatarImagesVisible[a] = false;
                                }
                            }
                        } else if (commentAvatarImages != null) {
                            for (int a = 0; a < commentAvatarImages.length; a++) {
                                commentAvatarImages[a].setImageBitmap((Drawable) null);
                                commentAvatarImagesVisible[a] = false;
                            }
                        }
                    }
                    commentWidth = totalCommentWidth = (int) Math.ceil(Theme.chat_commentTextPaint.measureText(comment));
                    commentLayout = new StaticLayout(comment, Theme.chat_commentTextPaint, commentWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    if (commentCount != 0 && !LocaleController.isRTL) {
                        drawCommentNumber = true;
                        if (commentNumberLayout == null) {
                            commentNumberLayout = new AnimatedNumberLayout(this, Theme.chat_commentTextPaint);
                            commentNumberLayout.setNumber(commentCount, false);
                        } else {
                            commentNumberLayout.setNumber(commentCount, messageObject.animateComments);
                        }
                        messageObject.animateComments = false;
                        commentNumberWidth = commentNumberLayout.getWidth();
                        totalCommentWidth += commentNumberWidth + AndroidUtilities.dp(4);
                    } else {
                        drawCommentNumber = false;
                        if (commentNumberLayout != null) {
                            commentNumberLayout.setNumber(1, false);
                        }
                    }
                    totalCommentWidth += AndroidUtilities.dp(70 + avatarsOffset);
                } else {
                    if (!isRepliesChat && commentCount > 0) {
                        String comment = LocaleController.formatShortNumber(commentCount, null);
                        commentWidth = totalCommentWidth = (int) Math.ceil(Theme.chat_stickerCommentCountPaint.measureText(comment));
                        commentLayout = new StaticLayout(comment, Theme.chat_stickerCommentCountPaint, commentWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    } else {
                        commentLayout = null;
                    }
                    drawCommentNumber = false;
                    drawSideButton = isRepliesChat ? 2 : 3;
                }
            } else {
                commentLayout = null;
                drawCommentNumber = false;
            }

            if (messageObject.type == MessageObject.TYPE_TEXT) {
                drawForwardedName = !isRepliesChat;
                int maxWidth;

                if (drawAvatar) {
                    if (AndroidUtilities.isTablet()) {
                        maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(122);
                    } else {
                        maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122);
                    }
                    drawName = true;
                } else {
                    if (AndroidUtilities.isTablet()) {
                        maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(80);
                    } else {
                        maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80);
                    }
                    drawName = isPinnedChat || (messageObject.messageOwner.peer_id != null && messageObject.messageOwner.peer_id.channel_id != 0 && (!messageObject.isOutOwner() || messageObject.isSupergroup())) || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null;
                }

                availableTimeWidth = maxWidth;
                if (messageObject.isRoundVideo()) {
                    availableTimeWidth -= Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) + (messageObject.isOutOwner() ? 0 : AndroidUtilities.dp(64));
                }
                measureTime(messageObject);
                //核心去掉时间以及回执，则该值把设为0
                //时间加上空隙
                int timeMore = timeWidth + AndroidUtilities.dp(6);
                if (messageObject.isOutOwner()) {
                    //到达时间加上已读未读回执
                    timeMore += AndroidUtilities.dp(20.5f);
                }
                timeMore += getExtraTimeX();
                if (BuildVars.IS_CHAT_AIR) timeMore = 0;

                hasGamePreview = MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaGame && MessageObject.getMedia(messageObject.messageOwner).game instanceof TLRPC.TL_game;
                hasInvoicePreview = MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaInvoice;
                //是否显示网页预览
                hasLinkPreview = !messageObject.isRestrictedMessage && MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaWebPage && MessageObject.getMedia(messageObject.messageOwner).webpage instanceof TLRPC.TL_webPage;
                TLRPC.WebPage webpage = hasLinkPreview ? MessageObject.getMedia(messageObject.messageOwner).webpage : null;
                drawInstantView = hasLinkPreview && MessageObject.getMedia(messageObject.messageOwner).webpage.cached_page != null;
                String siteName = hasLinkPreview ? MessageObject.getMedia(messageObject.messageOwner).webpage.site_name : null;
                hasEmbed = hasLinkPreview && !TextUtils.isEmpty(MessageObject.getMedia(messageObject.messageOwner).webpage.embed_url) && !messageObject.isGif() && !"instangram".equalsIgnoreCase(siteName);
                boolean slideshow = false;
                String webpageType = webpage != null ? webpage.type : null;
                TLRPC.Document androidThemeDocument = null;
                TLRPC.ThemeSettings androidThemeSettings = null;
                if (!drawInstantView) {
                    if ("telegram_livestream".equals(webpageType)) {
                        drawInstantView = true;
                        drawInstantViewType = 11;
                    } else if ("telegram_voicechat".equals(webpageType)) {
                        drawInstantView = true;
                        drawInstantViewType = 9;
                    } else if ("telegram_channel".equals(webpageType)) {
                        drawInstantView = true;
                        drawInstantViewType = 1;
                    } else if ("telegram_user".equals(webpageType)) {
                        drawInstantView = true;
                        drawInstantViewType = 13;
                    } else if ("telegram_megagroup".equals(webpageType)) {
                        drawInstantView = true;
                        drawInstantViewType = 2;
                    } else if ("telegram_message".equals(webpageType) || "photo".equals(webpageType) && webpage != null && webpage.url != null && Browser.isInternalUri(Uri.parse(webpage.url), null)) {
                        drawInstantView = true;
                        drawInstantViewType = 3;
                    } else if ("telegram_theme".equals(webpageType)) {
                        for (int b = 0, N2 = MessageObject.getMedia(messageObject.messageOwner).webpage.attributes.size(); b < N2; b++) {
                            TLRPC.TL_webPageAttributeTheme attribute = MessageObject.getMedia(messageObject.messageOwner).webpage.attributes.get(b);
                            ArrayList<TLRPC.Document> documents = attribute.documents;
                            for (int a = 0, N = documents.size(); a < N; a++) {
                                TLRPC.Document document = documents.get(a);
                                if ("application/x-tgtheme-android".equals(document.mime_type)) {
                                    drawInstantView = true;
                                    drawInstantViewType = 7;
                                    androidThemeDocument = document;
                                    break;
                                }
                            }
                            if (drawInstantView) {
                                break;
                            }
                            if (attribute.settings != null) {
                                drawInstantView = true;
                                drawInstantViewType = 7;
                                androidThemeSettings = attribute.settings;
                                break;
                            }
                        }
                    } else if ("telegram_background".equals(webpageType)) {
                        drawInstantView = true;
                        drawInstantViewType = 6;
                        try {
                            Uri url = Uri.parse(MessageObject.getMedia(messageObject.messageOwner).webpage.url);
                            imageBackgroundIntensity = Utilities.parseInt(url.getQueryParameter("intensity"));
                            String bgColor = url.getQueryParameter("bg_color");
                            String rotation = url.getQueryParameter("rotation");
                            if (rotation != null) {
                                imageBackgroundGradientRotation = Utilities.parseInt(rotation);
                            }
                            if (TextUtils.isEmpty(bgColor)) {
                                TLRPC.Document document = messageObject.getDocument();
                                if (document != null && "image/png".equals(document.mime_type)) {
                                    bgColor = "ffffff";
                                }
                                if (imageBackgroundIntensity == 0) {
                                    imageBackgroundIntensity = 50;
                                }
                            }
                            if (bgColor != null) {
                                imageBackgroundColor = Integer.parseInt(bgColor.substring(0, 6), 16) | 0xff000000;
                                int averageColor = imageBackgroundColor;
                                if (bgColor.length() >= 13 && AndroidUtilities.isValidWallChar(bgColor.charAt(6))) {
                                    imageBackgroundGradientColor1 = Integer.parseInt(bgColor.substring(7, 13), 16) | 0xff000000;
                                    averageColor = AndroidUtilities.getAverageColor(imageBackgroundColor, imageBackgroundGradientColor1);
                                }
                                if (bgColor.length() >= 20 && AndroidUtilities.isValidWallChar(bgColor.charAt(13))) {
                                    imageBackgroundGradientColor2 = Integer.parseInt(bgColor.substring(14, 20), 16) | 0xff000000;
                                }
                                if (bgColor.length() == 27 && AndroidUtilities.isValidWallChar(bgColor.charAt(20))) {
                                    imageBackgroundGradientColor3 = Integer.parseInt(bgColor.substring(21), 16) | 0xff000000;
                                }
                                if (imageBackgroundIntensity < 0) {
                                    imageBackgroundSideColor = 0xff111111;
                                } else {
                                    imageBackgroundSideColor = AndroidUtilities.getPatternSideColor(averageColor);
                                }
                                photoImage.setColorFilter(new PorterDuffColorFilter(AndroidUtilities.getPatternColor(averageColor), PorterDuff.Mode.SRC_IN));
                                photoImage.setAlpha(Math.abs(imageBackgroundIntensity) / 100.0f);
                            } else {
                                String color = url.getLastPathSegment();
                                if (color != null && color.length() >= 6) {
                                    imageBackgroundColor = Integer.parseInt(color.substring(0, 6), 16) | 0xff000000;
                                    if (color.length() >= 13 && AndroidUtilities.isValidWallChar(color.charAt(6))) {
                                        imageBackgroundGradientColor1 = Integer.parseInt(color.substring(7, 13), 16) | 0xff000000;
                                    }
                                    if (color.length() >= 20 && AndroidUtilities.isValidWallChar(color.charAt(13))) {
                                        imageBackgroundGradientColor2 = Integer.parseInt(color.substring(14, 20), 16) | 0xff000000;
                                    }
                                    if (color.length() == 27 && AndroidUtilities.isValidWallChar(color.charAt(20))) {
                                        imageBackgroundGradientColor3 = Integer.parseInt(color.substring(21), 16) | 0xff000000;
                                    }
                                    currentPhotoObject = new TLRPC.TL_photoSizeEmpty();
                                    currentPhotoObject.type = "s";
                                    currentPhotoObject.w = AndroidUtilities.dp(180);
                                    currentPhotoObject.h = AndroidUtilities.dp(150);
                                    currentPhotoObject.location = new TLRPC.TL_fileLocationUnavailable();
                                }
                            }
                        } catch (Exception ignore) {

                        }
                    }
                } else if (siteName != null) {
                    siteName = siteName.toLowerCase();
                    if ((siteName.equals("instagram") || siteName.equals("twitter") || "telegram_album".equals(webpageType)) && MessageObject.getMedia(messageObject.messageOwner).webpage.cached_page instanceof TLRPC.TL_page &&
                            (MessageObject.getMedia(messageObject.messageOwner).webpage.photo instanceof TLRPC.TL_photo || MessageObject.isVideoDocument(MessageObject.getMedia(messageObject.messageOwner).webpage.document))) {
                        drawInstantView = false;
                        slideshow = true;
                        ArrayList<TLRPC.PageBlock> blocks = MessageObject.getMedia(messageObject.messageOwner).webpage.cached_page.blocks;
                        int count = 1;
                        for (int a = 0; a < blocks.size(); a++) {
                            TLRPC.PageBlock block = blocks.get(a);
                            if (block instanceof TLRPC.TL_pageBlockSlideshow) {
                                TLRPC.TL_pageBlockSlideshow b = (TLRPC.TL_pageBlockSlideshow) block;
                                count = b.items.size();
                            } else if (block instanceof TLRPC.TL_pageBlockCollage) {
                                TLRPC.TL_pageBlockCollage b = (TLRPC.TL_pageBlockCollage) block;
                                count = b.items.size();
                            }
                        }
                        String str = LocaleController.formatString("Of", R.string.Of, 1, count);
                        photosCountWidth = (int) Math.ceil(Theme.chat_durationPaint.measureText(str));
                        photosCountLayout = new StaticLayout(str, Theme.chat_durationPaint, photosCountWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    }
                }
                backgroundWidth = maxWidth;
                if (hasLinkPreview || hasGamePreview || hasInvoicePreview || maxWidth - messageObject.lastLineWidth < timeMore) {
                    backgroundWidth = Math.max(backgroundWidth, messageObject.lastLineWidth) + AndroidUtilities.dp(31);
                    backgroundWidth = Math.max(backgroundWidth, timeWidth + AndroidUtilities.dp(31));
                } else {
                    //判断最后一行是否能容纳下时间已读，如果容纳不了则换行
                    int diff = backgroundWidth - messageObject.lastLineWidth;
                    if (diff >= 0 && diff <= timeMore) {
                        backgroundWidth = backgroundWidth + timeMore - diff + AndroidUtilities.dp(31);
                    } else {
                        backgroundWidth = Math.max(backgroundWidth, messageObject.lastLineWidth + timeMore) + AndroidUtilities.dp(31);
                    }
                }
                availableTimeWidth = backgroundWidth - AndroidUtilities.dp(31);
                if (messageObject.isRoundVideo()) {
                    availableTimeWidth -= Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) + (messageObject.isOutOwner() ? 0 : AndroidUtilities.dp(64));
                }

                setMessageObjectInternal(messageObject);

                backgroundWidth = messageObject.textWidth + getExtraTextX() * 2 + (hasGamePreview || hasInvoicePreview ? AndroidUtilities.dp(10) : 0);
                totalHeight = messageObject.textHeight + AndroidUtilities.dp(19.5f) + namesOffset;

                if (!reactionsLayoutInBubble.isSmall) {
                    reactionsLayoutInBubble.measure(maxWidth, Gravity.LEFT);
                    if (!reactionsLayoutInBubble.isEmpty) {
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8);
                        if (reactionsLayoutInBubble.width > backgroundWidth) {
                            backgroundWidth = reactionsLayoutInBubble.width;
                        }

                        totalHeight += reactionsLayoutInBubble.totalHeight;
                    }
                }
                if (drawPinnedTop) {
                    namesOffset -= AndroidUtilities.dp(1);
                }

                int maxChildWidth = Math.max(backgroundWidth, nameWidth);
                maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
                maxChildWidth = Math.max(maxChildWidth, replyNameWidth);
                if (topicButton != null) {
                    maxChildWidth = Math.max(maxChildWidth, topicButton.width());
                }
                maxChildWidth = Math.max(maxChildWidth, replyTextWidth);
                if (commentLayout != null && drawSideButton != 3) {
                    maxChildWidth = Math.max(maxChildWidth, totalCommentWidth);
                }
                int maxWebWidth = 0;

                if (hasLinkPreview || hasGamePreview || hasInvoicePreview) {
                    int linkPreviewMaxWidth;
                    if (AndroidUtilities.isTablet()) {
                        if (drawAvatar) {
                            linkPreviewMaxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(80 + 52);
                        } else {
                            linkPreviewMaxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(80);
                        }
                    } else {
                        if (drawAvatar) {
                            linkPreviewMaxWidth = getParentWidth() - AndroidUtilities.dp(80 + 52);
                        } else {
                            linkPreviewMaxWidth = getParentWidth() - AndroidUtilities.dp(80);
                        }
                    }
                    if (drawSideButton != 0) {
                        linkPreviewMaxWidth -= AndroidUtilities.dp(20);
                    }
                    String site_name;
                    String title;
                    CharSequence author;
                    String description;
                    TLRPC.Photo photo;
                    TLRPC.Document document;
                    WebFile webDocument;
                    int duration;
                    boolean smallImage;
                    String type;
                    final int smallImageSide = AndroidUtilities.dp(48), smallSideMargin = AndroidUtilities.dp(10);
                    if (hasLinkPreview) {
                        TLRPC.TL_webPage webPage = (TLRPC.TL_webPage) MessageObject.getMedia(messageObject.messageOwner).webpage;
                        site_name = webPage.site_name;
                        title = drawInstantViewType != 6 && drawInstantViewType != 7 ? webPage.title : null;
                        author = drawInstantViewType != 6 && drawInstantViewType != 7 ? webPage.author : null;
                        description = drawInstantViewType != 6 && drawInstantViewType != 7 ? webPage.description : null;
                        photo = webPage.photo;
                        webDocument = null;
                        if (drawInstantViewType == 7) {
                            if (androidThemeSettings != null) {
                                document = new DocumentObject.ThemeDocument(androidThemeSettings);
                            } else {
                                document = androidThemeDocument;
                            }
                        } else {
                            document = webPage.document;
                        }
                        type = webPage.type;
                        duration = webPage.duration;
                        if (site_name != null && photo != null && site_name.toLowerCase().equals("instagram")) {
                            linkPreviewMaxWidth = Math.max(AndroidUtilities.displaySize.y / 3, currentMessageObject.textWidth);
                        }
                        boolean isSmallImageType = "app".equals(type) || "profile".equals(type) ||
                                "article".equals(type) || "telegram_bot".equals(type) ||
                                "telegram_user".equals(type) || "telegram_channel".equals(type) ||
                                "telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) ||
                                "telegram_livestream".equals(type);
                        smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 2 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13) && document == null && isSmallImageType;
                        isSmallImage = smallImage && type != null && currentMessageObject.photoThumbs != null;
                    } else if (hasInvoicePreview) {
                        TLRPC.TL_messageMediaInvoice invoice = (TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(messageObject.messageOwner);
                        site_name = MessageObject.getMedia(messageObject.messageOwner).title;
                        title = null;
                        description = null;
                        photo = null;
                        author = null;
                        document = null;
                        if (invoice.webPhoto instanceof TLRPC.TL_webDocument) {
                            webDocument = WebFile.createWithWebDocument(invoice.webPhoto);
                        } else {
                            webDocument = null;
                        }
                        duration = 0;
                        type = "invoice";
                        isSmallImage = false;
                        smallImage = false;
                    } else {
                        TLRPC.TL_game game = MessageObject.getMedia(messageObject.messageOwner).game;
                        site_name = game.title;
                        title = null;
                        webDocument = null;
                        description = TextUtils.isEmpty(messageObject.messageText) ? game.description : null;
                        photo = game.photo;
                        author = null;
                        document = game.document;
                        duration = 0;
                        type = "game";
                        isSmallImage = false;
                        smallImage = false;
                    }
                    if (drawInstantViewType == 11) {
                        site_name = LocaleController.getString("VoipChannelVoiceChat", R.string.VoipChannelVoiceChat);
                    } else if (drawInstantViewType == 9) {
                        site_name = LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat);
                    } else if (drawInstantViewType == 6) {
                        site_name = LocaleController.getString("ChatBackground", R.string.ChatBackground);
                    } else if ("telegram_theme".equals(webpageType)) {
                        site_name = LocaleController.getString("ColorTheme", R.string.ColorTheme);
                    }

                    int additinalWidth = hasInvoicePreview ? 0 : AndroidUtilities.dp(10);
                    int restLinesCount = 3;
                    linkPreviewMaxWidth -= additinalWidth;

                    if (currentMessageObject.photoThumbs == null && photo != null) {
                        currentMessageObject.generateThumbs(true);
                    }

                    if (site_name != null) {
                        try {
                            int width = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(site_name) + 1);
                            int restLines = 0;
                            if (!isSmallImage) {
                                siteNameLayout = new StaticLayout(site_name, Theme.chat_replyNamePaint, Math.min(width, linkPreviewMaxWidth), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                            } else {
                                restLines = restLinesCount;
                                siteNameLayout = generateStaticLayout(site_name, Theme.chat_replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - smallImageSide - smallSideMargin, restLinesCount, 1);
                                restLinesCount -= siteNameLayout.getLineCount();
                            }
                            siteNameRtl = Math.max(siteNameLayout.getLineLeft(0), 0) != 0;
                            int height = siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1);
                            linkPreviewHeight += height;
                            totalHeight += height;
                            int layoutWidth = 0;
                            for (int a = 0; a < siteNameLayout.getLineCount(); ++a) {
                                int lineLeft = (int) Math.max(0, siteNameLayout.getLineLeft(a));
                                int lineWidth;
                                if (lineLeft != 0) {
                                    lineWidth = siteNameLayout.getWidth() - lineLeft;
                                } else {
                                    int max = linkPreviewMaxWidth;
                                    if (a < restLines || lineLeft != 0 && isSmallImage) {
                                        max -= smallImageSide + smallSideMargin;
                                    }
                                    lineWidth = (int) Math.min(max, Math.ceil(siteNameLayout.getLineWidth(a)));
                                }
                                if (a < restLines || lineLeft != 0 && isSmallImage) {
                                    lineWidth += smallImageSide + smallSideMargin;
                                }
                                layoutWidth = Math.max(layoutWidth, lineWidth);
                            }
                            siteNameWidth = width = layoutWidth;
                            maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
                            maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }

                    boolean titleIsRTL = false;
                    if (!titleIsRTL && author != null) {
                        titleIsRTL = AndroidUtilities.isRTL(author);
                    }
                    if (!titleIsRTL && messageObject.linkDescription != null) {
                        titleIsRTL = AndroidUtilities.isRTL(messageObject.linkDescription);
                    }
                    if (title != null) {
                        try {
                            titleX = Integer.MAX_VALUE;
                            if (linkPreviewHeight != 0) {
                                linkPreviewHeight += AndroidUtilities.dp(2);
                                totalHeight += AndroidUtilities.dp(2);
                            }
                            int restLines = 0;
                            if (!isSmallImage) {
                                titleLayout = StaticLayoutEx.createStaticLayout(title, Theme.chat_replyNamePaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, 4);
                            } else {
                                restLines = restLinesCount;
                                titleLayout = generateStaticLayout(title, Theme.chat_replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - smallImageSide - smallSideMargin, restLinesCount, 4);
                                restLinesCount -= titleLayout.getLineCount();
                            }
                            int height = titleLayout.getLineBottom(titleLayout.getLineCount() - 1);
                            linkPreviewHeight += height;
                            totalHeight += height;
                            for (int a = 0; a < titleLayout.getLineCount(); a++) {
                                int lineLeft = (int) Math.max(0, titleLayout.getLineLeft(a));
                                if (lineLeft != 0) {
                                    titleIsRTL = true;
                                }
                                if (titleX == Integer.MAX_VALUE) {
                                    titleX = -lineLeft;
                                } else {
                                    titleX = Math.max(titleX, -lineLeft);
                                }
                                int width;
                                if (lineLeft != 0) {
                                    width = titleLayout.getWidth() - lineLeft;
                                } else {
                                    int max = linkPreviewMaxWidth;
                                    if (a < restLines || lineLeft != 0 && isSmallImage) {
                                        max -= smallImageSide + smallSideMargin;
                                    }
                                    width = (int) Math.min(max, Math.ceil(titleLayout.getLineWidth(a)));
                                }
                                if (a < restLines || lineLeft != 0 && isSmallImage) {
                                    width += smallImageSide + smallSideMargin;
                                }
                                maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
                                maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
                            }
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }
                    if (titleIsRTL && isSmallImage) {
                        linkPreviewMaxWidth -= AndroidUtilities.dp(48);
                    }

                    boolean authorIsRTL = false;
                    if (author != null && title == null) {
                        try {
                            if (linkPreviewHeight != 0) {
                                linkPreviewHeight += AndroidUtilities.dp(2);
                                totalHeight += AndroidUtilities.dp(2);
                            }
                            try {
                                author = Emoji.replaceEmoji(author, Theme.chat_replyNamePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                            } catch (Exception ignore) {
                            }
                            if (restLinesCount == 3 && (!isSmallImage || description == null)) {
                                authorLayout = new StaticLayout(author, Theme.chat_replyNamePaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                            } else {
                                authorLayout = generateStaticLayout(author, Theme.chat_replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - smallImageSide - smallSideMargin, restLinesCount, 1);
                                restLinesCount -= authorLayout.getLineCount();
                            }
                            int height = authorLayout.getLineBottom(authorLayout.getLineCount() - 1);
                            linkPreviewHeight += height;
                            totalHeight += height;
                            int lineLeft = (int) Math.max(authorLayout.getLineLeft(0), 0);
                            authorX = -lineLeft;
                            int width;
                            if (lineLeft != 0) {
                                width = authorLayout.getWidth() - lineLeft;
                                authorIsRTL = true;
                            } else {
                                width = (int) Math.ceil(authorLayout.getLineWidth(0));
                            }
                            maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
                            maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }

                    if (description != null) {
                        try {
                            descriptionX = 0;
                            currentMessageObject.generateLinkDescription();
                            if (linkPreviewHeight != 0) {
                                linkPreviewHeight += AndroidUtilities.dp(2);
                                totalHeight += AndroidUtilities.dp(2);
                            }
                            int restLines = 0;
                            boolean allowAllLines = site_name != null && site_name.toLowerCase().equals("twitter");
                            if (restLinesCount == 3 && !isSmallImage) {
                                descriptionLayout = StaticLayoutEx.createStaticLayout(messageObject.linkDescription, Theme.chat_replyTextPaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, allowAllLines ? 100 : 6);
                            } else {
                                restLines = restLinesCount;
                                descriptionLayout = generateStaticLayout(messageObject.linkDescription, Theme.chat_replyTextPaint, linkPreviewMaxWidth, linkPreviewMaxWidth - smallImageSide - smallSideMargin, restLinesCount, allowAllLines ? 100 : 6);
                            }
                            animatedEmojiDescriptionStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, false, animatedEmojiDescriptionStack, descriptionLayout);
                            int height = descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
                            linkPreviewHeight += height;
                            totalHeight += height;

                            boolean hasRTL = false;
                            for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
                                int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a));
                                if (lineLeft > 0) {
                                    hasRTL = true;
                                    if (descriptionX == 0) {
                                        descriptionX = -lineLeft;
                                    } else {
                                        descriptionX = Math.max(descriptionX, -lineLeft);
                                    }
                                }
                            }

                            int textWidth = descriptionLayout.getWidth();
                            for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
                                int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a));
                                if (lineLeft == 0 && descriptionX != 0) {
                                    descriptionX = 0;
                                }

                                int width;
                                if (lineLeft > 0) {
                                    width = textWidth - lineLeft;
                                } else {
                                    if (hasRTL) {
                                        width = textWidth;
                                    } else {
                                        width = Math.min((int) Math.ceil(descriptionLayout.getLineWidth(a)), textWidth);
                                    }
                                }
                                if (a < restLines || restLines != 0 && lineLeft != 0 && isSmallImage) {
                                    width += smallImageSide + smallSideMargin;
                                }
                                if (maxWebWidth < width + additinalWidth) {
                                    if (titleIsRTL) {
                                        titleX += (width + additinalWidth - maxWebWidth);
                                    }
                                    if (authorIsRTL) {
                                        authorX += (width + additinalWidth - maxWebWidth);
                                    }
                                    maxWebWidth = width + additinalWidth;
                                }
                                maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
                            }
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }

                    if (smallImage && (descriptionLayout == null && titleLayout == null)) {
                        smallImage = false;
                        isSmallImage = false;
                    }
                    int maxPhotoWidth = smallImage ? smallImageSide : linkPreviewMaxWidth;

                    if (document != null) {
                        if (MessageObject.isRoundVideoDocument(document)) {
                            currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90);
                            photoParentObject = document;
                            documentAttach = document;
                            documentAttachType = DOCUMENT_ATTACH_TYPE_ROUND;
                        } else if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId())) {
                            if (!messageObject.isGame() && !SharedConfig.isAutoplayGifs()) {
                                messageObject.gifState = 1;
                            }
                            photoImage.setAllowStartAnimation(messageObject.gifState != 1);
                            currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90);
                            if (currentPhotoObject != null) {
                                photoParentObject = document;
                            } else if (photo != null) {
                                currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 90);
                                photoParentObject = photo;
                            }
                            if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) {
                                for (int a = 0; a < document.attributes.size(); a++) {
                                    TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                                    if (attribute instanceof TLRPC.TL_documentAttributeImageSize || attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                        currentPhotoObject.w = attribute.w;
                                        currentPhotoObject.h = attribute.h;
                                        break;
                                    }
                                }
                                if (currentPhotoObject.w == 0 || currentPhotoObject.h == 0) {
                                    currentPhotoObject.w = currentPhotoObject.h = AndroidUtilities.dp(150);
                                }
                            }
                            documentAttach = document;
                            documentAttachType = DOCUMENT_ATTACH_TYPE_GIF;
                        } else if (MessageObject.isVideoDocument(document)) {
                            if (photo != null) {
                                currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, AndroidUtilities.getPhotoSize(), true);
                                currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 40);
                                photoParentObject = photo;
                            }
                            if (currentPhotoObject == null) {
                                currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 320);
                                currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 40);
                                photoParentObject = document;
                            }
                            if (currentPhotoObject == currentPhotoObjectThumb) {
                                currentPhotoObjectThumb = null;
                            }
                            if (currentMessageObject.strippedThumb != null) {
                                currentPhotoObjectThumb = null;
                                currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
                            }
                            if (currentPhotoObject == null) {
                                currentPhotoObject = new TLRPC.TL_photoSize();
                                currentPhotoObject.type = "s";
                                currentPhotoObject.location = new TLRPC.TL_fileLocationUnavailable();
                            }
                            if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0 || currentPhotoObject instanceof TLRPC.TL_photoStrippedSize)) {
                                for (int a = 0; a < document.attributes.size(); a++) {
                                    TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                                    if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                        if (currentPhotoObject instanceof TLRPC.TL_photoStrippedSize) {
                                            float scale = Math.max(attribute.w, attribute.w) / 50.0f;
                                            currentPhotoObject.w = (int) (attribute.w / scale);
                                            currentPhotoObject.h = (int) (attribute.h / scale);
                                        } else {
                                            currentPhotoObject.w = attribute.w;
                                            currentPhotoObject.h = attribute.h;
                                        }
                                        break;
                                    }
                                }
                                if (currentPhotoObject.w == 0 || currentPhotoObject.h == 0) {
                                    currentPhotoObject.w = currentPhotoObject.h = AndroidUtilities.dp(150);
                                }
                            }
                            createDocumentLayout(0, messageObject);
                        } else if (MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true)) {
                            currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90);
                            photoParentObject = document;
                            if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) {
                                for (int a = 0; a < document.attributes.size(); a++) {
                                    TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                                    if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
                                        currentPhotoObject.w = attribute.w;
                                        currentPhotoObject.h = attribute.h;
                                        break;
                                    }
                                }
                                if (currentPhotoObject.w == 0 || currentPhotoObject.h == 0) {
                                    currentPhotoObject.w = currentPhotoObject.h = AndroidUtilities.dp(150);
                                }
                            }
                            documentAttach = document;
                            documentAttachType = DOCUMENT_ATTACH_TYPE_STICKER;
                        } else if (drawInstantViewType == 6) {
                            currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 320);
                            photoParentObject = document;
                            if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) {
                                for (int a = 0; a < document.attributes.size(); a++) {
                                    TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                                    if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
                                        currentPhotoObject.w = attribute.w;
                                        currentPhotoObject.h = attribute.h;
                                        break;
                                    }
                                }
                                if (currentPhotoObject.w == 0 || currentPhotoObject.h == 0) {
                                    currentPhotoObject.w = currentPhotoObject.h = AndroidUtilities.dp(150);
                                }
                            }
                            documentAttach = document;
                            documentAttachType = DOCUMENT_ATTACH_TYPE_WALLPAPER;
                            String str = AndroidUtilities.formatFileSize(documentAttach.size);
                            durationWidth = (int) Math.ceil(Theme.chat_durationPaint.measureText(str));
                            videoInfoLayout = new StaticLayout(str, Theme.chat_durationPaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                        } else if (drawInstantViewType == 7) {
                            currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 700);
                            if (currentMessageObject.strippedThumb == null) {
                                currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 40);
                            } else {
                                currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
                            }
                            photoParentObject = document;
                            if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) {
                                for (int a = 0; a < document.attributes.size(); a++) {
                                    TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                                    if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
                                        currentPhotoObject.w = attribute.w;
                                        currentPhotoObject.h = attribute.h;
                                        break;
                                    }
                                }
                                if (currentPhotoObject.w == 0 || currentPhotoObject.h == 0) {
                                    currentPhotoObject.w = currentPhotoObject.h = AndroidUtilities.dp(150);
                                }
                            }
                            documentAttach = document;
                            documentAttachType = DOCUMENT_ATTACH_TYPE_THEME;
                        } else {
                            calcBackgroundWidth(maxWidth, timeMore, maxChildWidth);
                            if (backgroundWidth < maxWidth + AndroidUtilities.dp(20)) {
                                backgroundWidth = maxWidth + AndroidUtilities.dp(20);
                            }
                            if (MessageObject.isVoiceDocument(document)) {
                                createDocumentLayout(backgroundWidth - AndroidUtilities.dp(10), messageObject);
                                mediaOffsetY = currentMessageObject.textHeight + AndroidUtilities.dp(8) + linkPreviewHeight;
                                totalHeight += AndroidUtilities.dp(30 + 14);
                                linkPreviewHeight += AndroidUtilities.dp(44);

                                maxWidth = maxWidth - AndroidUtilities.dp(86);
                                if (AndroidUtilities.isTablet()) {
                                    maxChildWidth = Math.max(maxChildWidth, Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 52 : 0), AndroidUtilities.dp(220)) - AndroidUtilities.dp(30) + additinalWidth);
                                } else {
                                    maxChildWidth = Math.max(maxChildWidth, Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 52 : 0), AndroidUtilities.dp(220)) - AndroidUtilities.dp(30) + additinalWidth);
                                }
                                calcBackgroundWidth(maxWidth, timeMore, maxChildWidth);
                            } else if (MessageObject.isMusicDocument(document)) {
                                int durationWidth = createDocumentLayout(backgroundWidth - AndroidUtilities.dp(10), messageObject);
                                mediaOffsetY = currentMessageObject.textHeight + AndroidUtilities.dp(8) + linkPreviewHeight;
                                totalHeight += AndroidUtilities.dp(42 + 14);
                                linkPreviewHeight += AndroidUtilities.dp(56);

                                maxWidth = maxWidth - AndroidUtilities.dp(86);
                                maxChildWidth = Math.max(maxChildWidth, durationWidth + additinalWidth + AndroidUtilities.dp(86 + 8));
                                if (songLayout != null && songLayout.getLineCount() > 0) {
                                    maxChildWidth = (int) Math.max(maxChildWidth, songLayout.getLineWidth(0) + additinalWidth + AndroidUtilities.dp(86));
                                }
                                if (performerLayout != null && performerLayout.getLineCount() > 0) {
                                    maxChildWidth = (int) Math.max(maxChildWidth, performerLayout.getLineWidth(0) + additinalWidth + AndroidUtilities.dp(86));
                                }

                                calcBackgroundWidth(maxWidth, timeMore, maxChildWidth);
                            } else {
                                createDocumentLayout(backgroundWidth - AndroidUtilities.dp(86 + 24 + 58), messageObject);
                                drawImageButton = true;
                                if (drawPhotoImage) {
                                    totalHeight += AndroidUtilities.dp(86 + 14);
                                    linkPreviewHeight += AndroidUtilities.dp(86);
                                    photoImage.setImageCoords(0, totalHeight + namesOffset, AndroidUtilities.dp(86), AndroidUtilities.dp(86));
                                } else {
                                    mediaOffsetY = currentMessageObject.textHeight + AndroidUtilities.dp(8) + linkPreviewHeight;
                                    photoImage.setImageCoords(0, totalHeight + namesOffset - AndroidUtilities.dp(14), AndroidUtilities.dp(56), AndroidUtilities.dp(56));
                                    totalHeight += AndroidUtilities.dp(50 + 14);
                                    linkPreviewHeight += AndroidUtilities.dp(50);
                                    if (docTitleLayout != null && docTitleLayout.getLineCount() > 1) {
                                        int h = (docTitleLayout.getLineCount() - 1) * AndroidUtilities.dp(16);
                                        totalHeight += h;
                                        linkPreviewHeight += h;
                                    }
                                }
                            }
                        }
                    } else if (photo != null) {
                        boolean isPhoto = type != null && type.equals("photo");
                        currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, isPhoto || !smallImage ? AndroidUtilities.getPhotoSize() : maxPhotoWidth, !isPhoto);
                        photoParentObject = messageObject.photoThumbsObject;
                        checkOnlyButtonPressed = !isPhoto;
                        if (currentMessageObject.strippedThumb == null) {
                            currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
                        } else {
                            currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
                        }
                        if (currentPhotoObjectThumb == currentPhotoObject) {
                            currentPhotoObjectThumb = null;
                        }
                    } else if (webDocument != null) {
                        if (!webDocument.mime_type.startsWith("image/")) {
                            webDocument = null;
                        }
                        drawImageButton = false;
                    }

                    if (documentAttachType != DOCUMENT_ATTACH_TYPE_MUSIC && documentAttachType != DOCUMENT_ATTACH_TYPE_AUDIO && documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                        if (currentPhotoObject != null || webDocument != null || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER || documentAttachType == DOCUMENT_ATTACH_TYPE_THEME) {
                            drawImageButton = photo != null && !smallImage || type != null && (type.equals("photo") || type.equals("document") && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER || type.equals("gif") || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER);
                            if (linkPreviewHeight != 0) {
                                linkPreviewHeight += AndroidUtilities.dp(2);
                                totalHeight += AndroidUtilities.dp(2);
                            }

                            if (imageBackgroundSideColor != 0) {
                                maxPhotoWidth = AndroidUtilities.dp(208);
                            } else if (currentPhotoObject instanceof TLRPC.TL_photoSizeEmpty && currentPhotoObject.w != 0) {
                                maxPhotoWidth = currentPhotoObject.w;
                            } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER || documentAttachType == DOCUMENT_ATTACH_TYPE_THEME) {
                                if (AndroidUtilities.isTablet()) {
                                    maxPhotoWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.5f);
                                } else {
                                    maxPhotoWidth = (int) (getParentWidth() * 0.5f);
                                }
                            } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                                maxPhotoWidth = AndroidUtilities.roundMessageSize;
                                photoImage.setAllowDecodeSingleFrame(true);
                            }
                            if (hasInvoicePreview && maxPhotoWidth < messageObject.textWidth) {
                                maxPhotoWidth = messageObject.textWidth + AndroidUtilities.dp(22);
                            }

                            maxChildWidth = Math.max(maxChildWidth, maxPhotoWidth - (hasInvoicePreview ? AndroidUtilities.dp(12) : 0) + additinalWidth);
                            if (currentPhotoObject != null) {
                                currentPhotoObject.size = -1;
                                if (currentPhotoObjectThumb != null) {
                                    currentPhotoObjectThumb.size = -1;
                                }
                            } else if (webDocument != null) {
                                webDocument.size = -1;
                            }
                            if (imageBackgroundSideColor != 0) {
                                imageBackgroundSideWidth = maxChildWidth - AndroidUtilities.dp(13);
                            }

                            int width;
                            int height;
                            if (smallImage || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                                width = height = maxPhotoWidth;
                            } else {
                                if (hasGamePreview || hasInvoicePreview) {
                                    if (hasInvoicePreview) {
                                        width = 640;
                                        height = 360;
                                        for (int a = 0, N = webDocument.attributes.size(); a < N; a++) {
                                            TLRPC.DocumentAttribute attribute = webDocument.attributes.get(a);
                                            if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
                                                width = attribute.w;
                                                height = attribute.h;
                                                break;
                                            }
                                        }
                                    } else {
                                        width = 640;
                                        height = 360;
                                    }
                                    float scale = width / (float) (maxPhotoWidth - AndroidUtilities.dp(2));
                                    width /= scale;
                                    height /= scale;
                                } else {
                                    if (drawInstantViewType == 7) {
                                        width = 560;
                                        height = 678;
                                    } else if (currentPhotoObject != null) {
                                        width = currentPhotoObject.w;
                                        height = currentPhotoObject.h;
                                    } else {
                                        width = 30;
                                        height = 50;
                                    }
                                    float scale = width / (float) (maxPhotoWidth - AndroidUtilities.dp(2));
                                    width /= scale;
                                    height /= scale;
                                    if (site_name == null || site_name != null && !site_name.toLowerCase().equals("instagram") && documentAttachType == 0) {
                                        if (height > AndroidUtilities.displaySize.y / 3) {
                                            height = AndroidUtilities.displaySize.y / 3;
                                        }
                                    } else {
                                        if (height > AndroidUtilities.displaySize.y / 2) {
                                            height = AndroidUtilities.displaySize.y / 2;
                                        }
                                    }
                                    if (imageBackgroundSideColor != 0) {
                                        scale = height / (float) AndroidUtilities.dp(160);
                                        width /= scale;
                                        height /= scale;
                                    }
                                    if (height < AndroidUtilities.dp(60)) {
                                        height = AndroidUtilities.dp(60);
                                    }
                                }
                            }
                            if (isSmallImage) {
                                if (AndroidUtilities.dp(50) > linkPreviewHeight) {
                                    totalHeight += AndroidUtilities.dp(50) - linkPreviewHeight + AndroidUtilities.dp(8);
                                    linkPreviewHeight = AndroidUtilities.dp(50);
                                }
                                linkPreviewHeight -= AndroidUtilities.dp(8);
                            } else {
                                totalHeight += height + AndroidUtilities.dp(12);
                                linkPreviewHeight += height;
                            }

                            if (documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER && imageBackgroundSideColor == 0) {
                                photoImage.setImageCoords(0, 0, Math.max(maxChildWidth - AndroidUtilities.dp(13), width), height);
                            } else {
                                photoImage.setImageCoords(0, 0, width, height);
                            }

                            int w = (int) (width / AndroidUtilities.density);
                            int h = (int) (height / AndroidUtilities.density);
                            currentPhotoFilter = String.format(Locale.US, "%d_%d", w, h);
                            currentPhotoFilterThumb = String.format(Locale.US, "%d_%d_b", w, h);

                            if (webDocument != null) {
                                /*TODO*/
                                photoImage.setImage(ImageLocation.getForWebFile(webDocument), currentPhotoFilter, null, null, webDocument.size, null, messageObject, 1);
                            } else {
                                if (documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER) {
                                    if (messageObject.mediaExists) {
                                        photoImage.setImage(ImageLocation.getForDocument(documentAttach), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObject, document), "b1", 0, "jpg", messageObject, 1);
                                    } else {
                                        photoImage.setImage(null, null, ImageLocation.getForDocument(currentPhotoObject, document), "b1", 0, "jpg", messageObject, 1);
                                    }
                                } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_THEME) {
                                    if (document instanceof DocumentObject.ThemeDocument) {
                                        photoImage.setImage(ImageLocation.getForDocument(document), currentPhotoFilter, null, "b1", 0, "jpg", messageObject, 1);
                                    } else {
                                        photoImage.setImage(ImageLocation.getForDocument(currentPhotoObject, document), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), "b1", currentPhotoObjectThumbStripped, 0, "jpg", messageObject, 1);
                                    }
                                } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER) {
                                    boolean isWebpSticker = messageObject.isSticker();
                                    if (!SharedConfig.loopStickers() && messageObject.isVideoSticker()) {
                                        photoImage.animatedFileDrawableRepeatMaxCount = 1;
                                    }
                                    if (SharedConfig.loopStickers() || (isWebpSticker && !messageObject.isVideoSticker())) {
                                        photoImage.setAutoRepeat(1);
                                    } else {
                                        currentPhotoFilter = String.format(Locale.US, "%d_%d_nr_messageId=%d", w, h, messageObject.stableId);
                                        photoImage.setAutoRepeat(delegate != null && delegate.shouldRepeatSticker(messageObject) ? 2 : 3);
                                    }
                                    photoImage.setImage(ImageLocation.getForDocument(documentAttach), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObject, documentAttach), "b1", documentAttach.size, "webp", messageObject, 1);
                                } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
                                    photoImage.setNeedsQualityThumb(true);
                                    photoImage.setShouldGenerateQualityThumb(true);
                                    if (SharedConfig.isAutoplayVideo() && (!currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || currentMessageObject.revealingMediaSpoilers) && (
                                            currentMessageObject.mediaExists ||
                                                    messageObject.canStreamVideo() && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject)
                                    )) {
                                        photoImage.setAllowDecodeSingleFrame(true);
                                        photoImage.setAllowStartAnimation(true);
                                        photoImage.startAnimation();
                                        photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, documentAttach), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, messageObject, 0);
                                        autoPlayingMedia = true;
                                    } else {
                                        if (currentPhotoObjectThumb != null || currentPhotoObjectThumbStripped != null) {
                                            photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                                        } else {
                                            photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                                        }
                                    }
                                } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                                    photoImage.setAllowDecodeSingleFrame(true);
                                    boolean autoDownload = false;
                                    if (MessageObject.isRoundVideoDocument(document)) {
                                        photoImage.setRoundRadius(AndroidUtilities.roundMessageSize / 2);
                                        canChangeRadius = false;
                                        autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
                                    } else if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId())) {
                                        autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
                                    }
                                    String filter = currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter;
                                    if (messageObject.mediaExists || autoDownload) {
                                        autoPlayingMedia = true;
                                        TLRPC.VideoSize videoSize = MessageObject.getDocumentVideoThumb(document);
                                        if (!messageObject.mediaExists && videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
                                            photoImage.setImage(ImageLocation.getForDocument(document), document.size < 1024 * 32 ? null : ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? filter : currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
                                        } else {
                                            photoImage.setImage(ImageLocation.getForDocument(document), document.size < 1024 * 32 ? null : ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(currentPhotoObject, documentAttach), filter, ImageLocation.getForDocument(currentPhotoObjectThumb, documentAttach), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
                                        }
                                    } else {
                                        photoImage.setImage(null, null, ImageLocation.getForDocument(currentPhotoObject, documentAttach), filter, 0, null, currentMessageObject, 0);
                                    }
                                } else {
                                    boolean photoExist = messageObject.mediaExists;
                                    String fileName = FileLoader.getAttachFileName(currentPhotoObject);
                                    if (hasGamePreview || photoExist || DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject) || FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                                        photoNotSet = false;
                                        photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                                    } else {
                                        photoNotSet = true;
                                        if (currentPhotoObjectThumb != null || currentPhotoObjectThumbStripped != null) {
                                            photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), String.format(Locale.US, "%d_%d_b", w, h), currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                                        } else {
                                            photoImage.setImageBitmap((Drawable) null);
                                        }
                                    }
                                }
                            }
                            if (blurredPhotoImage.getBitmap() != null) {
                                blurredPhotoImage.getBitmap().recycle();
                                blurredPhotoImage.setImageBitmap((Bitmap) null);
                            }
                            if (photoImage.getBitmap() != null && !photoImage.getBitmap().isRecycled() && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) {
                                blurredPhotoImage.setImageBitmap(Utilities.stackBlurBitmapMax(photoImage.getBitmap()));
                            }
                            drawPhotoImage = true;

                            if (type != null && type.equals("video") && duration != 0) {
                                String str = AndroidUtilities.formatShortDuration(duration);
                                durationWidth = (int) Math.ceil(Theme.chat_durationPaint.measureText(str));
                                videoInfoLayout = new StaticLayout(str, Theme.chat_durationPaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                            } else if (hasGamePreview) {
                                boolean showGameOverlay = true;
                                try {
                                    long bot_id = messageObject.messageOwner.via_bot_id != 0 ? messageObject.messageOwner.via_bot_id : messageObject.messageOwner.from_id.user_id;
                                    if (bot_id != 0) {
                                        TLRPC.User botUser = MessagesController.getInstance(currentAccount).getUser(bot_id);
                                        if (botUser != null && botUser.username != null && botUser.username.equals("donate")) {
                                            showGameOverlay = false;
                                        }
                                    }
                                } catch (Exception e) {
                                }
                                if (showGameOverlay) {
                                    String str = LocaleController.getString("AttachGame", R.string.AttachGame).toUpperCase();
                                    durationWidth = (int) Math.ceil(Theme.chat_gamePaint.measureText(str));
                                    videoInfoLayout = new StaticLayout(str, Theme.chat_gamePaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                                }
                            }
                        } else {
                            photoImage.setImageBitmap((Drawable) null);
                            if (blurredPhotoImage.getBitmap() != null) {
                                blurredPhotoImage.getBitmap().recycle();
                                blurredPhotoImage.setImageBitmap((Bitmap) null);
                            }
                            linkPreviewHeight -= AndroidUtilities.dp(6);
                            totalHeight += AndroidUtilities.dp(4);
                        }
                        if (hasInvoicePreview) {
                            CharSequence str;
                            if ((MessageObject.getMedia(messageObject.messageOwner).flags & 4) != 0) {
                                str = LocaleController.getString("PaymentReceipt", R.string.PaymentReceipt).toUpperCase();
                            } else {
                                if (MessageObject.getMedia(messageObject.messageOwner).test) {
                                    str = LocaleController.getString("PaymentTestInvoice", R.string.PaymentTestInvoice).toUpperCase();
                                } else {
                                    str = LocaleController.getString("PaymentInvoice", R.string.PaymentInvoice).toUpperCase();
                                }
                            }
                            String price = LocaleController.getInstance().formatCurrencyString(MessageObject.getMedia(messageObject.messageOwner).total_amount, MessageObject.getMedia(messageObject.messageOwner).currency);
                            SpannableStringBuilder stringBuilder = new SpannableStringBuilder(price + " " + str);
                            stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, price.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                            durationWidth = (int) Math.ceil(Theme.chat_shipmentPaint.measureText(stringBuilder, 0, stringBuilder.length()));
                            videoInfoLayout = new StaticLayout(stringBuilder, Theme.chat_shipmentPaint, durationWidth + AndroidUtilities.dp(10), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                            if (!drawPhotoImage) {
                                totalHeight += AndroidUtilities.dp(6);
                                int timeWidthTotal = timeWidth + AndroidUtilities.dp(14 + (messageObject.isOutOwner() ? 20 : 0));
                                if (durationWidth + timeWidthTotal > maxWidth) {
                                    maxChildWidth = Math.max(durationWidth, maxChildWidth);
                                    totalHeight += AndroidUtilities.dp(12);
                                } else {
                                    maxChildWidth = Math.max(durationWidth + timeWidthTotal, maxChildWidth);
                                }
                            }
                        }
                        if (hasGamePreview && messageObject.textHeight != 0) {
                            linkPreviewHeight += messageObject.textHeight + AndroidUtilities.dp(6);
                            totalHeight += AndroidUtilities.dp(4);
                        }
                        calcBackgroundWidth(maxWidth, timeMore, maxChildWidth);
                    }
                    createInstantViewButton();
                } else {
                    photoImage.setImageBitmap((Drawable) null);
                    //核心计算背景宽度
                    calcBackgroundWidth(maxWidth, timeMore, maxChildWidth);

                    if (blurredPhotoImage.getBitmap() != null) {
                        blurredPhotoImage.getBitmap().recycle();
                        blurredPhotoImage.setImageBitmap((Bitmap) null);
                    }
                }
            } else if (messageObject.type == MessageObject.TYPE_PHONE_CALL) {
                createSelectorDrawable(0);
                drawName = false;
                drawForwardedName = false;
                drawPhotoImage = false;
                if (AndroidUtilities.isTablet()) {
                    backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                } else {
                    backgroundWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                }
                availableTimeWidth = backgroundWidth - AndroidUtilities.dp(31);

                int maxWidth = getMaxNameWidth() - AndroidUtilities.dp(50);
                if (maxWidth < 0) {
                    maxWidth = AndroidUtilities.dp(10);
                }

                String text;
                String time = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
                TLRPC.TL_messageActionPhoneCall call = (TLRPC.TL_messageActionPhoneCall) messageObject.messageOwner.action;
                boolean isMissed = call.reason instanceof TLRPC.TL_phoneCallDiscardReasonMissed;
                if (messageObject.isOutOwner()) {
                    if (isMissed) {
                        if (call.video) {
                            text = LocaleController.getString("CallMessageVideoOutgoingMissed", R.string.CallMessageVideoOutgoingMissed);
                        } else {
                            text = LocaleController.getString("CallMessageOutgoingMissed", R.string.CallMessageOutgoingMissed);
                        }
                    } else {
                        if (call.video) {
                            text = LocaleController.getString("CallMessageVideoOutgoing", R.string.CallMessageVideoOutgoing);
                        } else {
                            text = LocaleController.getString("CallMessageOutgoing", R.string.CallMessageOutgoing);
                        }
                    }
                } else {
                    if (isMissed) {
                        if (call.video) {
                            text = LocaleController.getString("CallMessageVideoIncomingMissed", R.string.CallMessageVideoIncomingMissed);
                        } else {
                            text = LocaleController.getString("CallMessageIncomingMissed", R.string.CallMessageIncomingMissed);
                        }
                    } else if (call.reason instanceof TLRPC.TL_phoneCallDiscardReasonBusy) {
                        if (call.video) {
                            text = LocaleController.getString("CallMessageVideoIncomingDeclined", R.string.CallMessageVideoIncomingDeclined);
                        } else {
                            text = LocaleController.getString("CallMessageIncomingDeclined", R.string.CallMessageIncomingDeclined);
                        }
                    } else {
                        if (call.video) {
                            text = LocaleController.getString("CallMessageVideoIncoming", R.string.CallMessageVideoIncoming);
                        } else {
                            text = LocaleController.getString("CallMessageIncoming", R.string.CallMessageIncoming);
                        }
                    }
                }
                if (call.duration > 0) {
                    time += ", " + LocaleController.formatCallDuration(call.duration);
                }

                titleLayout = new StaticLayout(TextUtils.ellipsize(text, Theme.chat_audioTitlePaint, maxWidth, TextUtils.TruncateAt.END), Theme.chat_audioTitlePaint, maxWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                docTitleLayout = new StaticLayout(TextUtils.ellipsize(time, Theme.chat_contactPhonePaint, maxWidth, TextUtils.TruncateAt.END), Theme.chat_contactPhonePaint, maxWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

                setMessageObjectInternal(messageObject);

                totalHeight = AndroidUtilities.dp(65) + namesOffset;
                if (drawPinnedTop) {
                    namesOffset -= AndroidUtilities.dp(1);
                }
            } else if (messageObject.type == MessageObject.TYPE_CONTACT) {
                drawName = messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null;
                drawForwardedName = !isRepliesChat;
                drawPhotoImage = true;
                photoImage.setRoundRadius(AndroidUtilities.dp(22));
                canChangeRadius = false;
                if (AndroidUtilities.isTablet()) {
                    backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                } else {
                    backgroundWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                }
                availableTimeWidth = backgroundWidth - AndroidUtilities.dp(31);

                long uid = MessageObject.getMedia(messageObject.messageOwner).user_id;
                TLRPC.User user = null;
                if (uid != 0) {
                    user = MessagesController.getInstance(currentAccount).getUser(uid);
                }

                int maxWidth = getMaxNameWidth() - AndroidUtilities.dp(80);
                if (maxWidth < 0) {
                    maxWidth = AndroidUtilities.dp(10);
                }
                boolean hasName;
                if (user != null) {
                    contactAvatarDrawable.setInfo(user);
                    hasName = true;
                } else if (!TextUtils.isEmpty(MessageObject.getMedia(messageObject.messageOwner).first_name) || !TextUtils.isEmpty(MessageObject.getMedia(messageObject.messageOwner).last_name)) {
                    contactAvatarDrawable.setInfo(0, MessageObject.getMedia(messageObject.messageOwner).first_name, MessageObject.getMedia(messageObject.messageOwner).last_name);
                    hasName = true;
                } else {
                    hasName = false;
                }
                photoImage.setForUserOrChat(user, hasName ? contactAvatarDrawable : Theme.chat_contactDrawable[messageObject.isOutOwner() ? 1 : 0], messageObject);

                CharSequence phone;
                if (!TextUtils.isEmpty(messageObject.vCardData)) {
                    phone = messageObject.vCardData;
                } else {
                    if (user != null && !TextUtils.isEmpty(user.phone)) {
                        phone = PhoneFormat.getInstance().format("+" + user.phone);
                    } else {
                        phone = MessageObject.getMedia(messageObject.messageOwner).phone_number;
                        if (!TextUtils.isEmpty(phone)) {
                            phone = PhoneFormat.getInstance().format((String) phone);
                        } else {
                            phone = LocaleController.getString("NumberUnknown", R.string.NumberUnknown);
                        }
                    }
                }

                if (user != null || !TextUtils.isEmpty(messageObject.vCardData) || MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaContact) {
                    drawInstantView = true;
                    drawInstantViewType = 5;
                }

                CharSequence currentNameString = ContactsController.formatName(MessageObject.getMedia(messageObject.messageOwner).first_name, MessageObject.getMedia(messageObject.messageOwner).last_name).replace('\n', ' ');
                if (currentNameString.length() == 0) {
                    currentNameString = MessageObject.getMedia(messageObject.messageOwner).phone_number;
                    if (currentNameString == null) {
                        currentNameString = "";
                    }
                }
                titleLayout = new StaticLayout(TextUtils.ellipsize(currentNameString, Theme.chat_contactNamePaint, maxWidth, TextUtils.TruncateAt.END), Theme.chat_contactNamePaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                docTitleLayout = new StaticLayout(phone, Theme.chat_contactPhonePaint, maxWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false);

                setMessageObjectInternal(messageObject);

                if (drawForwardedName && messageObject.needDrawForwarded() && (currentPosition == null || currentPosition.minY == 0)) {
                    namesOffset += AndroidUtilities.dp(5);
                } else if (drawNameLayout && messageObject.getReplyMsgId() == 0) {
                    namesOffset += AndroidUtilities.dp(7);
                }

                totalHeight = AndroidUtilities.dp(70 - 15) + namesOffset + docTitleLayout.getHeight();
                if (drawPinnedTop) {
                    namesOffset -= AndroidUtilities.dp(1);
                }
                if (drawInstantView) {
                    createInstantViewButton();
                } else {
                    if (docTitleLayout.getLineCount() > 0) {
                        int timeLeft = backgroundWidth - AndroidUtilities.dp(40 + 18 + 44 + 8) - (int) Math.ceil(docTitleLayout.getLineWidth(docTitleLayout.getLineCount() - 1));
                        if (timeLeft < timeWidth) {
                            totalHeight += AndroidUtilities.dp(8);
                        }
                    }
                }
                if (!reactionsLayoutInBubble.isSmall) {
                    if (!reactionsLayoutInBubble.isEmpty) {
                        reactionsLayoutInBubble.measure(backgroundWidth - AndroidUtilities.dp(32), Gravity.LEFT);
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(12);
                        reactionsLayoutInBubble.positionOffsetY += -AndroidUtilities.dp(4);
                        if (backgroundWidth - AndroidUtilities.dp(32) - reactionsLayoutInBubble.lastLineX < timeWidth) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12);
                            reactionsLayoutInBubble.positionOffsetY += -AndroidUtilities.dp(12);
                        }
                        totalHeight += reactionsLayoutInBubble.totalHeight;
                    }
                }
            } else if (messageObject.type == MessageObject.TYPE_VOICE) {
                drawForwardedName = !isRepliesChat;
                drawName = messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null;
                int maxWidth;
                if (AndroidUtilities.isTablet()) {
                    backgroundWidth = maxWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                } else {
                    backgroundWidth = maxWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                }
                createDocumentLayout(backgroundWidth, messageObject);

                setMessageObjectInternal(messageObject);

                totalHeight = AndroidUtilities.dp(70) + namesOffset;
                if (drawPinnedTop) {
                    namesOffset -= AndroidUtilities.dp(1);
                }
                if (!reactionsLayoutInBubble.isSmall) {
                    reactionsLayoutInBubble.measure(maxWidth - (messageObject.isOutOwner() ? AndroidUtilities.dp(32) : AndroidUtilities.dp(24)), Gravity.LEFT);
                    if (!reactionsLayoutInBubble.isEmpty) {
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height;
                        if (TextUtils.isEmpty(messageObject.caption)) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12);
                        } else {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(8);
                        }
                        if (reactionsLayoutInBubble.width > backgroundWidth) {
                            backgroundWidth = reactionsLayoutInBubble.width;
                        }
                        int timeMore = timeWidth + AndroidUtilities.dp(6);
                        if (messageObject.isOutOwner()) {
                            timeMore += AndroidUtilities.dp(20.5f);
                        }
                        timeMore += getExtraTimeX();
                        if (reactionsLayoutInBubble.lastLineX + timeMore >= backgroundWidth) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12);
                            reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(12);
                        }
                        totalHeight += reactionsLayoutInBubble.totalHeight;
                    }
                }
            } else if (messageObject.type == MessageObject.TYPE_MUSIC) {
                drawName = (messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
                int maxWidth;
                if (AndroidUtilities.isTablet()) {
                    backgroundWidth = maxWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                } else {
                    backgroundWidth = maxWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
                }

                createDocumentLayout(backgroundWidth, messageObject);

                setMessageObjectInternal(messageObject);

                totalHeight = AndroidUtilities.dp(82) + namesOffset;
                if (currentPosition != null && currentMessagesGroup != null && currentMessagesGroup.messages.size() > 1) {
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                        totalHeight -= AndroidUtilities.dp(6);
                        mediaOffsetY -= AndroidUtilities.dp(6);
                    }
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                        totalHeight -= AndroidUtilities.dp(6);
                    }
                }
                if (drawPinnedTop) {
                    namesOffset -= AndroidUtilities.dp(1);
                }
                if (!reactionsLayoutInBubble.isSmall) {
                    reactionsLayoutInBubble.measure(maxWidth - AndroidUtilities.dp(24), Gravity.LEFT);
                    if (!reactionsLayoutInBubble.isEmpty) {
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(12);
                        measureTime(messageObject);
                        if (reactionsLayoutInBubble.width > backgroundWidth) {
                            backgroundWidth = reactionsLayoutInBubble.width;
                        }
                        if (reactionsLayoutInBubble.lastLineX + timeWidth + AndroidUtilities.dp(24) > backgroundWidth) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12);
                            reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(12);
                        }
                        if (!messageObject.isRestrictedMessage && messageObject.caption != null) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(14);
                        }
                        totalHeight += reactionsLayoutInBubble.totalHeight;
                    }
                }
            } else if (messageObject.type == MessageObject.TYPE_POLL) {
                if (timerParticles == null) {
                    timerParticles = new TimerParticles();
                }
                createSelectorDrawable(0);
                drawName = true;
                drawForwardedName = !isRepliesChat;
                drawPhotoImage = false;
                int maxWidth = Math.min(AndroidUtilities.dp(500), messageObject.getMaxMessageTextWidth());
                backgroundWidth = maxWidth + AndroidUtilities.dp(31);

                TLRPC.TL_messageMediaPoll media = (TLRPC.TL_messageMediaPoll) MessageObject.getMedia(messageObject.messageOwner);

                timerTransitionProgress = media.poll.close_date - ConnectionsManager.getInstance(currentAccount).getCurrentTime() < 60 ? 0.0f : 1.0f;
                pollClosed = media.poll.closed;
                pollVoted = messageObject.isVoted();
                if (pollVoted) {
                    messageObject.checkedVotes.clear();
                }
                titleLayout = new StaticLayout(Emoji.replaceEmoji(media.poll.question, Theme.chat_audioTitlePaint.getFontMetricsInt(), AndroidUtilities.dp(16), false), Theme.chat_audioTitlePaint, maxWidth + AndroidUtilities.dp(2) - getExtraTextX() * 2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                boolean titleRtl = false;
                if (titleLayout != null) {
                    for (int a = 0, N = titleLayout.getLineCount(); a < N; a++) {
                        if (titleLayout.getLineLeft(a) > 0) {
                            titleRtl = true;
                            break;
                        }
                    }
                }
                String title;
                if (pollClosed) {
                    title = LocaleController.getString("FinalResults", R.string.FinalResults);
                } else {
                    if (media.poll.quiz) {
                        if (media.poll.public_voters) {
                            title = LocaleController.getString("QuizPoll", R.string.QuizPoll);
                        } else {
                            title = LocaleController.getString("AnonymousQuizPoll", R.string.AnonymousQuizPoll);
                        }
                    } else if (media.poll.public_voters) {
                        title = LocaleController.getString("PublicPoll", R.string.PublicPoll);
                    } else {
                        title = LocaleController.getString("AnonymousPoll", R.string.AnonymousPoll);
                    }
                }
                docTitleLayout = new StaticLayout(TextUtils.ellipsize(title, Theme.chat_timePaint, maxWidth, TextUtils.TruncateAt.END), Theme.chat_timePaint, maxWidth + AndroidUtilities.dp(2) - getExtraTextX() * 2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                if (docTitleLayout != null && docTitleLayout.getLineCount() > 0) {
                    if (titleRtl && !LocaleController.isRTL) {
                        docTitleOffsetX = (int) Math.ceil(maxWidth - docTitleLayout.getLineWidth(0));
                    } else if (!titleRtl && LocaleController.isRTL) {
                        docTitleOffsetX = -(int) Math.ceil(docTitleLayout.getLineLeft(0));
                    } else {
                        docTitleOffsetX = 0;
                    }
                }
                int w = maxWidth - AndroidUtilities.dp(messageObject.isOutOwner() ? 28 : 8);

                if (!isBot) {
                    TextPaint textPaint = !media.poll.public_voters && !media.poll.multiple_choice ? Theme.chat_livePaint : Theme.chat_locationAddressPaint;
                    CharSequence votes;
                    if (media.poll.quiz) {
                        votes = TextUtils.ellipsize(media.results.total_voters == 0 ? LocaleController.getString("NoVotesQuiz", R.string.NoVotesQuiz) : LocaleController.formatPluralString("Answer", media.results.total_voters), textPaint, w, TextUtils.TruncateAt.END);
                    } else {
                        votes = TextUtils.ellipsize(media.results.total_voters == 0 ? LocaleController.getString("NoVotes", R.string.NoVotes) : LocaleController.formatPluralString("Vote", media.results.total_voters), textPaint, w, TextUtils.TruncateAt.END);
                    }
                    infoLayout = new StaticLayout(votes, textPaint, w, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    if (infoLayout != null) {
                        if (!media.poll.public_voters && !media.poll.multiple_choice) {
                            infoX = (int) Math.ceil(infoLayout.getLineCount() > 0 ? -infoLayout.getLineLeft(0) : 0);
                            availableTimeWidth = (int) (maxWidth - infoLayout.getLineWidth(0) - AndroidUtilities.dp(16));
                        } else {
                            infoX = (int) ((backgroundWidth - AndroidUtilities.dp(28) - Math.ceil(infoLayout.getLineWidth(0))) / 2 - infoLayout.getLineLeft(0));
                            availableTimeWidth = maxWidth;
                        }
                    }
                }
                measureTime(messageObject);

                lastPoll = media.poll;
                lastPollResults = media.results.results;
                lastPollResultsVoters = media.results.total_voters;
                if (
                    media.poll.multiple_choice && !pollVoted && !pollClosed ||
                    !isBot && media.poll.public_voters && (
                        pollVoted ||
                        pollClosed && media.results != null && media.results.total_voters != 0
                    )
                ) {
                    drawInstantView = true;
                    drawInstantViewType = 8;
                    createInstantViewButton();
                }
                if (media.poll.multiple_choice) {
                    createPollUI();
                }
                if (media.results != null) {
                    createPollUI();
                    int size = media.results.recent_voters.size();
                    for (int a = 0; a < pollAvatarImages.length; a++) {
                        if (!isBot && a < size) {
                            pollAvatarImages[a].setImageCoords(0, 0, AndroidUtilities.dp(16), AndroidUtilities.dp(16));
                            Long id = media.results.recent_voters.get(a);
                            TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(id);
                            if (user != null) {
                                pollAvatarDrawables[a].setInfo(user);
                                pollAvatarImages[a].setForUserOrChat(user, pollAvatarDrawables[a]);
                            } else {
                                pollAvatarDrawables[a].setInfo(id, "", "");
                            }
                            pollAvatarImagesVisible[a] = true;
                        } else if (!pollUnvoteInProgress || size != 0) {
                            pollAvatarImages[a].setImageBitmap((Drawable) null);
                            pollAvatarImagesVisible[a] = false;
                        }
                    }
                } else if (pollAvatarImages != null) {
                    for (int a = 0; a < pollAvatarImages.length; a++) {
                        pollAvatarImages[a].setImageBitmap((Drawable) null);
                        pollAvatarImagesVisible[a] = false;
                    }
                }

                int maxVote = 0;
                if (!animatePollAnswer && pollVoteInProgress && vibrateOnPollVote) {
                    performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
                }
                animatePollAnswerAlpha = animatePollAnswer = attachedToWindow && (pollVoteInProgress || pollUnvoteInProgress);
                ArrayList<PollButton> previousPollButtons = null;
                ArrayList<PollButton> sortedPollButtons = new ArrayList<>();
                if (!pollButtons.isEmpty()) {
                    previousPollButtons = new ArrayList<>(pollButtons);
                    pollButtons.clear();
                    if (!animatePollAnswer) {
                        animatePollAnswer = attachedToWindow && (pollVoted || pollClosed);
                    }
                    if (pollAnimationProgress > 0 && pollAnimationProgress < 1.0f) {
                        for (int b = 0, N2 = previousPollButtons.size(); b < N2; b++) {
                            PollButton button = previousPollButtons.get(b);
                            button.percent = (int) Math.ceil(button.prevPercent + (button.percent - button.prevPercent) * pollAnimationProgress);
                            button.percentProgress = button.prevPercentProgress + (button.percentProgress - button.prevPercentProgress) * pollAnimationProgress;
                        }
                    }
                }

                pollAnimationProgress = animatePollAnswer ? 0.0f : 1.0f;
                byte[] votingFor;
                if (!animatePollAnswerAlpha) {
                    pollVoteInProgress = false;
                    pollVoteInProgressNum = -1;
                    votingFor = SendMessagesHelper.getInstance(currentAccount).isSendingVote(currentMessageObject);
                } else {
                    votingFor = null;
                }

                int height = titleLayout != null ? titleLayout.getHeight() : 0;
                int restPercent = 100;
                boolean hasDifferent = false;
                int previousPercent = 0;
                for (int a = 0, N = media.poll.answers.size(); a < N; a++) {
                    PollButton button = new PollButton();
                    button.answer = media.poll.answers.get(a);
                    button.title = new StaticLayout(Emoji.replaceEmoji(button.answer.text, Theme.chat_audioPerformerPaint.getFontMetricsInt(), AndroidUtilities.dp(15), false), Theme.chat_audioPerformerPaint, maxWidth - AndroidUtilities.dp(33), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    button.y = height + AndroidUtilities.dp(52);
                    button.height = button.title.getHeight();
                    pollButtons.add(button);
                    sortedPollButtons.add(button);
                    height += button.height + AndroidUtilities.dp(26);
                    if (!media.results.results.isEmpty()) {
                        for (int b = 0, N2 = media.results.results.size(); b < N2; b++) {
                            TLRPC.TL_pollAnswerVoters answer = media.results.results.get(b);
                            if (Arrays.equals(button.answer.option, answer.option)) {
                                button.chosen = answer.chosen;
                                button.count = answer.voters;
                                button.correct = answer.correct;
                                if ((pollVoted || pollClosed) && media.results.total_voters > 0) {
                                    button.decimal = 100 * (answer.voters / (float) media.results.total_voters);
                                    button.percent = (int) button.decimal;
                                    button.decimal -= button.percent;
                                } else {
                                    button.percent = 0;
                                    button.decimal = 0;
                                }
                                if (previousPercent == 0) {
                                    previousPercent = button.percent;
                                } else if (button.percent != 0 && previousPercent != button.percent) {
                                    hasDifferent = true;
                                }
                                restPercent -= button.percent;
                                maxVote = Math.max(button.percent, maxVote);
                                break;
                            }
                        }
                    }
                    if (previousPollButtons != null) {
                        for (int b = 0, N2 = previousPollButtons.size(); b < N2; b++) {
                            PollButton prevButton = previousPollButtons.get(b);
                            if (Arrays.equals(button.answer.option, prevButton.answer.option)) {
                                button.prevPercent = prevButton.percent;
                                button.prevPercentProgress = prevButton.percentProgress;
                                button.prevChosen = prevButton.chosen;
                                break;
                            }
                        }
                    }
                    if (votingFor != null && button.answer.option.length > 0 && Arrays.binarySearch(votingFor, button.answer.option[0]) >= 0) {
                        pollVoteInProgressNum = a;
                        pollVoteInProgress = true;
                        vibrateOnPollVote = true;
                        votingFor = null;
                    }

                    if (currentMessageObject.checkedVotes.contains(button.answer)) {
                        pollCheckBox[a].setChecked(true, false);
                    } else {
                        pollCheckBox[a].setChecked(false, false);
                    }
                }
                if (hasDifferent && restPercent != 0) {
                    Collections.sort(sortedPollButtons, (o1, o2) -> {
                        if (o1.decimal > o2.decimal) {
                            return -1;
                        } else if (o1.decimal < o2.decimal) {
                            return 1;
                        }
                        if (o1.decimal == o2.decimal) {
                            if (o1.percent > o2.percent) {
                                return 1;
                            } else if (o1.percent < o2.percent) {
                                return -1;
                            }
                        }
                        return 0;
                    });
                    for (int a = 0, N = Math.min(restPercent, sortedPollButtons.size()); a < N; a++) {
                        sortedPollButtons.get(a).percent += 1;
                    }
                }
                int width = backgroundWidth - AndroidUtilities.dp(76);
                for (int b = 0, N2 = pollButtons.size(); b < N2; b++) {
                    PollButton button = pollButtons.get(b);
                    button.percentProgress = Math.max(AndroidUtilities.dp(5) / (float) width, maxVote != 0 ? button.percent / (float) maxVote : 0);
                }

                setMessageObjectInternal(messageObject);

                pollInstantViewTouchesBottom = false;
                if (isBot && !drawInstantView) {
                    height -= AndroidUtilities.dp(10);
                } else if (media.poll.public_voters || media.poll.multiple_choice) {
                    pollInstantViewTouchesBottom = true;
                    height += AndroidUtilities.dp(13);
                }
                totalHeight = AndroidUtilities.dp(46 + 27) + namesOffset + height;
                if (drawPinnedTop) {
                    namesOffset -= AndroidUtilities.dp(1);
                }
                instantTextNewLine = false;
                if (media.poll.public_voters || media.poll.multiple_choice) {
                    int instantTextWidth = 0;
                    for (int a = 0; a < 3; a++) {
                        String str;
                        if (a == 0) {
                            str = LocaleController.getString("PollViewResults", R.string.PollViewResults);
                        } else if (a == 1) {
                            str = LocaleController.getString("PollSubmitVotes", R.string.PollSubmitVotes);
                        } else {
                            str = LocaleController.getString("NoVotes", R.string.NoVotes);
                        }
                        instantTextWidth = Math.max(instantTextWidth, (int) Math.ceil(Theme.chat_instantViewPaint.measureText(str)));
                    }
                    int timeWidthTotal = timeWidth + (messageObject.isOutOwner() ? AndroidUtilities.dp(20) : 0) + getExtraTimeX();
                    if (!reactionsLayoutInBubble.isSmall && reactionsLayoutInBubble.isEmpty && timeWidthTotal >= (backgroundWidth - AndroidUtilities.dp(76) - instantTextWidth) / 2) {
                        totalHeight += AndroidUtilities.dp(18);
                        instantTextNewLine = true;
                    }
                }
                if (!reactionsLayoutInBubble.isSmall) {
                    if (!reactionsLayoutInBubble.isEmpty) {
                        reactionsLayoutInBubble.measure(maxWidth, Gravity.LEFT);
                        totalHeight += reactionsLayoutInBubble.height + AndroidUtilities.dp(12);
                        int timeWidthTotal = timeWidth + (messageObject.isOutOwner() ? AndroidUtilities.dp(20) : 0) + getExtraTimeX();
                        if (timeWidthTotal >= (backgroundWidth - AndroidUtilities.dp(24) - reactionsLayoutInBubble.lastLineX)) {
                            totalHeight += AndroidUtilities.dp(16);
                            reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(16);
                        }
                    }
                }
            } else {
                drawForwardedName = messageObject.messageOwner.fwd_from != null && !(messageObject.isAnyKindOfSticker() && messageObject.isDice());
                if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
                    drawName = (messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
                }
                mediaBackground = isMedia = messageObject.type != MessageObject.TYPE_FILE;
                drawImageButton = true;
                drawPhotoImage = true;

                int photoWidth = 0;
                int photoHeight = 0;
                int additionHeight = 0;

                if (messageObject.gifState != 2 && !SharedConfig.isAutoplayGifs() && (messageObject.type == MessageObject.TYPE_GIF || messageObject.type == MessageObject.TYPE_ROUND_VIDEO)) {
                    messageObject.gifState = 1;
                }

                photoImage.setAllowDecodeSingleFrame(true);
                if (messageObject.isVideo()) {
                    photoImage.setAllowStartAnimation(true);
                } else if (messageObject.isRoundVideo()) {
                    MessageObject playingMessage = MediaController.getInstance().getPlayingMessageObject();
                    photoImage.setAllowStartAnimation(playingMessage == null || !playingMessage.isRoundVideo());
                } else {
                    photoImage.setAllowStartAnimation(messageObject.gifState == 0);
                }

                photoImage.setForcePreview(messageObject.needDrawBluredPreview());
                if (messageObject.type == MessageObject.TYPE_FILE) {
                    if (AndroidUtilities.isTablet()) {
                        backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(300));
                    } else {
                        backgroundWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(300));
                    }
                    if (checkNeedDrawShareButton(messageObject)) {
                        backgroundWidth -= AndroidUtilities.dp(20);
                    }
                    int maxTextWidth = 0;
                    int maxWidth = backgroundWidth - AndroidUtilities.dp(86 + 52);
                    int widthForCaption = 0;
                    createDocumentLayout(maxWidth, messageObject);
                    int width = backgroundWidth - AndroidUtilities.dp(31);
                    widthForCaption = width - AndroidUtilities.dp(10) - getExtraTextX() * 2;

                    if (!messageObject.isRestrictedMessage && !TextUtils.isEmpty(messageObject.caption)) {
                        try {
                            currentCaption = messageObject.caption;
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                captionLayout = StaticLayout.Builder.obtain(messageObject.caption, 0, messageObject.caption.length(), Theme.chat_msgTextPaint, widthForCaption)
                                        .setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
                                        .setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
                                        .setAlignment(Layout.Alignment.ALIGN_NORMAL)
                                        .build();
                            } else {
                                captionLayout = new StaticLayout(messageObject.caption, Theme.chat_msgTextPaint, widthForCaption, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                            }
                            updateCaptionSpoilers();
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }

                    if (docTitleLayout != null) {
                        for (int a = 0, N = docTitleLayout.getLineCount(); a < N; a++) {
                            maxTextWidth = Math.max(maxTextWidth, (int) Math.ceil(docTitleLayout.getLineWidth(a) + docTitleLayout.getLineLeft(a)) + AndroidUtilities.dp(86 + (drawPhotoImage ? 52 : 22)));
                        }
                    }
                    if (infoLayout != null) {
                        for (int a = 0, N = infoLayout.getLineCount(); a < N; a++) {
                            maxTextWidth = Math.max(maxTextWidth, infoWidth + AndroidUtilities.dp(86 + (drawPhotoImage ? 52 : 22)));
                        }
                    }
                    if (captionLayout != null) {
                        for (int a = 0, N = captionLayout.getLineCount(); a < N; a++) {
                            int w = (int) Math.ceil(Math.min(widthForCaption, captionLayout.getLineWidth(a) + captionLayout.getLineLeft(a))) + AndroidUtilities.dp(31);
                            if (w > maxTextWidth) {
                                maxTextWidth = w;
                            }
                        }
                    }
                    if (!reactionsLayoutInBubble.isSmall) {
                        reactionsLayoutInBubble.measure(widthForCaption, Gravity.LEFT);
                        if (!reactionsLayoutInBubble.isEmpty && reactionsLayoutInBubble.width + AndroidUtilities.dp(31) > maxTextWidth) {
                            maxTextWidth = reactionsLayoutInBubble.width + AndroidUtilities.dp(31);
                        }
                    }
                    if (maxTextWidth > 0 && currentPosition == null) {
                        backgroundWidth = maxTextWidth;
                        maxWidth = maxTextWidth - AndroidUtilities.dp(31);
                    }
                    availableTimeWidth = maxWidth;
                    if (drawPhotoImage) {
                        photoWidth = AndroidUtilities.dp(86);
                        photoHeight = AndroidUtilities.dp(86);
                        availableTimeWidth -= photoWidth;
                    } else {
                        photoWidth = AndroidUtilities.dp(56);
                        photoHeight = AndroidUtilities.dp(56);
                        if (docTitleLayout != null && docTitleLayout.getLineCount() > 1) {
                            photoHeight += (docTitleLayout.getLineCount() - 1) * AndroidUtilities.dp(16);
                        }
                        if (TextUtils.isEmpty(messageObject.caption) && infoLayout != null) {
                            int lineCount = infoLayout.getLineCount();
                            measureTime(messageObject);
                            int timeLeft = backgroundWidth - AndroidUtilities.dp(40 + 18 + 56 + 8) - infoWidth;
                            if (reactionsLayoutInBubble.isSmall || reactionsLayoutInBubble.isEmpty) {
                                if (timeLeft < timeWidth) {
                                    photoHeight += AndroidUtilities.dp(12);
                                } else if (lineCount == 1) {
                                    photoHeight += AndroidUtilities.dp(4);
                                }
                            }
                        }
                    }
                    if (!reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
                        if (!drawPhotoImage) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(2);
                        }
                        if (captionLayout != null && currentPosition != null && currentMessagesGroup != null && currentMessagesGroup.isDocuments) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
                        } else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && ((docTitleLayout != null && docTitleLayout.getLineCount() > 1) || currentMessageObject.hasValidReplyMessageObject())) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
                        } else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && !currentMessageObject.isOutOwner()) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
                        }
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8);
                        measureTime(messageObject);

                        if (drawPhotoImage && captionLayout == null) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(8);
                        }
                        if (captionLayout != null && currentMessageObject != null && currentMessageObject.isOutOwner() && currentMessageObject.isDocument() && currentMessagesGroup == null && !currentMessageObject.isForwarded() && !currentMessageObject.isReply()) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
                        }

                        int timeLeft = backgroundWidth - reactionsLayoutInBubble.lastLineX - AndroidUtilities.dp(31);

                        if (timeLeft < timeWidth) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12);
                            reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(12);
                        }
                        additionHeight += reactionsLayoutInBubble.totalHeight;
                    }
                } else if (messageObject.type == MessageObject.TYPE_GEO) {
                    TLRPC.GeoPoint point = MessageObject.getMedia(messageObject.messageOwner).geo;
                    double lat = point.lat;
                    double lon = point._long;

                    int provider;
                    if ((int) messageObject.getDialogId() == 0) {
                        if (SharedConfig.mapPreviewType == 0) {
                            provider = -1;
                        } else if (SharedConfig.mapPreviewType == 1) {
                            provider = 4;
                        } else if (SharedConfig.mapPreviewType == 3) {
                            provider = 1;
                        } else {
                            provider = -1;
                        }
                    } else {
                        provider = -1;
                    }

                    if (MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaGeoLive) {
                        if (AndroidUtilities.isTablet()) {
                            backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(252 + 37));
                        } else {
                            backgroundWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(252 + 37));
                        }
                        backgroundWidth -= AndroidUtilities.dp(4);
                        if (checkNeedDrawShareButton(messageObject)) {
                            backgroundWidth -= AndroidUtilities.dp(20);
                        }
                        int maxWidth = backgroundWidth - AndroidUtilities.dp(37);
                        availableTimeWidth = maxWidth;
                        maxWidth -= AndroidUtilities.dp(54);

                        photoWidth = backgroundWidth - AndroidUtilities.dp(17);
                        photoHeight = AndroidUtilities.dp(195);

                        int offset = 268435456;
                        double rad = offset / Math.PI;
                        double y = Math.round(offset - rad * Math.log((1 + Math.sin(lat * Math.PI / 180.0)) / (1 - Math.sin(lat * Math.PI / 180.0))) / 2) - (AndroidUtilities.dp(10.3f) << (21 - 15));
                        lat = (Math.PI / 2.0 - 2 * Math.atan(Math.exp((y - offset) / rad))) * 180.0 / Math.PI;
                        currentUrl = AndroidUtilities.formapMapUrl(currentAccount, lat, lon, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), false, 15, provider);
                        lastWebFile = currentWebFile;
                        currentWebFile = WebFile.createWithGeoPoint(lat, lon, point.access_hash, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), 15, Math.min(2, (int) Math.ceil(AndroidUtilities.density)));

                        photoImage.setCrossfadeWithOldImage(true);
                        if (!(locationExpired = isCurrentLocationTimeExpired(messageObject))) {
                            mediaBackground = false;
                            additionHeight = AndroidUtilities.dp(56);
                            AndroidUtilities.runOnUIThread(invalidateRunnable, 1000);
                            scheduledInvalidate = true;
                        } else {
                            backgroundWidth -= AndroidUtilities.dp(9);
                        }
                        docTitleLayout = new StaticLayout(TextUtils.ellipsize(LocaleController.getString("AttachLiveLocation", R.string.AttachLiveLocation), Theme.chat_locationTitlePaint, maxWidth, TextUtils.TruncateAt.END), Theme.chat_locationTitlePaint, maxWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

                        updateCurrentUserAndChat();
                        if (currentUser != null) {
                            contactAvatarDrawable.setInfo(currentUser);
                            locationImageReceiver.setForUserOrChat(currentUser, contactAvatarDrawable);
                        } else if (currentChat != null) {
                            if (currentChat.photo != null) {
                                currentPhoto = currentChat.photo.photo_small;
                            }
                            contactAvatarDrawable.setInfo(currentChat);
                            locationImageReceiver.setForUserOrChat(currentChat, contactAvatarDrawable);
                        } else {
                            locationImageReceiver.setImage(null, null, contactAvatarDrawable, null, null, 0);
                        }
                        infoLayout = new StaticLayout(TextUtils.ellipsize(LocaleController.formatLocationUpdateDate(messageObject.messageOwner.edit_date != 0 ? messageObject.messageOwner.edit_date : messageObject.messageOwner.date), Theme.chat_locationAddressPaint, maxWidth + AndroidUtilities.dp(2), TextUtils.TruncateAt.END), Theme.chat_locationAddressPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    } else if (!TextUtils.isEmpty(MessageObject.getMedia(messageObject.messageOwner).title)) {
                        if (AndroidUtilities.isTablet()) {
                            backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(252 + 37));
                        } else {
                            backgroundWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(252 + 37));
                        }
                        backgroundWidth -= AndroidUtilities.dp(4);
                        if (checkNeedDrawShareButton(messageObject)) {
                            backgroundWidth -= AndroidUtilities.dp(20);
                        }
                        int maxWidth = backgroundWidth - AndroidUtilities.dp(34);
                        availableTimeWidth = maxWidth;

                        photoWidth = backgroundWidth - AndroidUtilities.dp(17);
                        photoHeight = AndroidUtilities.dp(195);

                        mediaBackground = false;
                        currentUrl = AndroidUtilities.formapMapUrl(currentAccount, lat, lon, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), true, 15, provider);
                        currentWebFile = WebFile.createWithGeoPoint(point, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), 15, Math.min(2, (int) Math.ceil(AndroidUtilities.density)));

                        docTitleLayout = StaticLayoutEx.createStaticLayout(MessageObject.getMedia(messageObject.messageOwner).title, Theme.chat_locationTitlePaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, maxWidth, 1);
                        additionHeight += AndroidUtilities.dp(50);
                        int lineCount = docTitleLayout.getLineCount();
                        if (!TextUtils.isEmpty(MessageObject.getMedia(messageObject.messageOwner).address)) {
                            infoLayout = StaticLayoutEx.createStaticLayout(MessageObject.getMedia(messageObject.messageOwner).address, Theme.chat_locationAddressPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, maxWidth, 1);
                            measureTime(messageObject);
                            int timeLeft = backgroundWidth - (int) Math.ceil(infoLayout.getLineWidth(0)) - AndroidUtilities.dp(24);
                            boolean isRtl = infoLayout.getLineLeft(0) > 0;
                            if (isRtl || timeLeft < timeWidth + AndroidUtilities.dp(20 + (messageObject.isOutOwner() ? 20 : 0))) {
                                additionHeight += AndroidUtilities.dp(isRtl ? 10 : 8);
                            }
                        } else {
                            infoLayout = null;
                        }
                    } else {
                        if (AndroidUtilities.isTablet()) {
                            backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(252 + 37));
                        } else {
                            backgroundWidth = Math.min(getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(252 + 37));
                        }
                        backgroundWidth -= AndroidUtilities.dp(4);
                        if (checkNeedDrawShareButton(messageObject)) {
                            backgroundWidth -= AndroidUtilities.dp(20);
                        }
                        availableTimeWidth = backgroundWidth - AndroidUtilities.dp(34);

                        photoWidth = backgroundWidth - AndroidUtilities.dp(8);
                        photoHeight = AndroidUtilities.dp(195);

                        currentUrl = AndroidUtilities.formapMapUrl(currentAccount, lat, lon, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), true, 15, provider);
                        currentWebFile = WebFile.createWithGeoPoint(point, (int) (photoWidth / AndroidUtilities.density), (int) (photoHeight / AndroidUtilities.density), 15, Math.min(2, (int) Math.ceil(AndroidUtilities.density)));
                    }
                    if ((int) messageObject.getDialogId() == 0) {
                        if (SharedConfig.mapPreviewType == 0) {
                            currentMapProvider = 2;
                        } else if (SharedConfig.mapPreviewType == 1) {
                            currentMapProvider = 1;
                        } else if (SharedConfig.mapPreviewType == 3) {
                            currentMapProvider = 1;
                        } else {
                            currentMapProvider = -1;
                        }
                    } else {
                        currentMapProvider = MessagesController.getInstance(messageObject.currentAccount).mapProvider;
                    }
                    if (locationLoadingThumb == null) {
                        SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(R.raw.map_placeholder, Theme.key_chat_outLocationIcon, (Theme.isCurrentThemeDark() ? 3 : 6) * .12f);
                        svgThumb.setAspectCenter(true);
                        locationLoadingThumb = new ClipRoundedDrawable(svgThumb);
                    }
                    if (locationLoadingThumb instanceof ClipRoundedDrawable && ((ClipRoundedDrawable) locationLoadingThumb).getDrawable() instanceof SvgHelper.SvgDrawable) {
                        SvgHelper.SvgDrawable drawable = (SvgHelper.SvgDrawable) ((ClipRoundedDrawable) locationLoadingThumb).getDrawable();
                        drawable.setColorKey(messageObject.isOutOwner() ? Theme.key_chat_outLocationIcon : Theme.key_chat_inLocationIcon, resourcesProvider);
                    }
                    photoImage.setCrossfadeDuration(2 * ImageReceiver.DEFAULT_CROSSFADE_DURATION);
                    photoImage.setCrossfadeByScale(.05f);
                    if (currentMapProvider == -1) {
                        photoImage.setImage(null, null, null, null, messageObject, 0);
                    } else if (currentMapProvider == 2) {
                        if (currentWebFile != null) {
                            ImageLocation lastLocation;
                            if (messageObject.lastGeoWebFileLoaded instanceof ImageLocation) {
                                lastLocation = (ImageLocation) messageObject.lastGeoWebFileLoaded;
                            } else {
                                lastLocation = null;
                            }
                            messageObject.lastGeoWebFileSet = ImageLocation.getForWebFile(currentWebFile);
                            photoImage.setImage(ImageLocation.getForWebFile(currentWebFile), null, lastLocation, null, locationLoadingThumb, messageObject, 0);
                        }
                    } else {
                        if (currentMapProvider == 3 || currentMapProvider == 4) {
                            ImageLoader.getInstance().addTestWebFile(currentUrl, currentWebFile);
                            addedForTest = true;
                        }
                        if (currentUrl != null) {
                            photoImage.setImage(currentUrl, null, locationLoadingThumb, null, 0);
                        }
                    }
                    if (!reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
                        reactionsLayoutInBubble.measure(backgroundWidth - AndroidUtilities.dp(16), Gravity.LEFT);
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(14);
                        measureTime(messageObject);
                        if (reactionsLayoutInBubble.lastLineX + timeWidth + AndroidUtilities.dp(24) > backgroundWidth) {
                            reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12);
                            reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(12);
                        }
                        additionHeight += reactionsLayoutInBubble.totalHeight;
                    }
                } else if (messageObject.type == MessageObject.TYPE_EMOJIS) {
                    drawBackground = false;
                    photoWidth = (int) messageObject.textWidth;
                    photoHeight = (int) messageObject.textHeight + AndroidUtilities.dp(32);
                    backgroundWidth = photoWidth + AndroidUtilities.dp(14);
                    availableTimeWidth = photoWidth - AndroidUtilities.dp(12);
                    int maxWidth;
                    if (AndroidUtilities.isTablet()) {
                        maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.4f);
                    } else {
                        maxWidth = (int) (Math.min(getParentWidth(), AndroidUtilities.displaySize.y) * 0.5f);
                    }
                    maxWidth = Math.max(backgroundWidth, maxWidth);
                    if (!reactionsLayoutInBubble.isSmall) {
                        reactionsLayoutInBubble.measure(maxWidth, currentMessageObject.isOutOwner() ? Gravity.RIGHT : Gravity.LEFT);
                        reactionsLayoutInBubble.drawServiceShaderBackground = 1f;
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height;// + AndroidUtilities.dp(8);
                        additionHeight += reactionsLayoutInBubble.totalHeight + AndroidUtilities.dp(8);
                        reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(8);
                    }
                    if (!(drawTopic && (currentMessageObject != null && currentMessageObject.replyMessageObject != null || forwardedNameLayout != null && forwardedNameLayout[0] != null))) {
                        additionHeight -= AndroidUtilities.dp(17);
                    }
                } else if (messageObject.isAnyKindOfSticker()) {

                    drawBackground = false;
                    boolean isWebpSticker = messageObject.type == MessageObject.TYPE_STICKER;
                    TLRPC.Document stickerDocument = messageObject.getDocument();
                    if (stickerDocument != null) {
                        for (int a = 0; a < stickerDocument.attributes.size(); a++) {
                            TLRPC.DocumentAttribute attribute = stickerDocument.attributes.get(a);
                            if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
                                photoWidth = attribute.w;
                                photoHeight = attribute.h;
                                break;
                            }
                            if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                photoWidth = attribute.w;
                                photoHeight = attribute.h;
                                break;
                            }
                        }
                    }
                    if ((messageObject.isAnimatedSticker() || messageObject.isVideoSticker()) && photoWidth == 0 && photoHeight == 0) {
                        photoWidth = photoHeight = 512;
                    }
                    if (messageObject.isAnimatedAnimatedEmoji()) {
                        photoWidth = Math.max(512, photoWidth);
                        photoHeight = Math.max(512, photoHeight);
                        if (MessageObject.isTextColorEmoji(messageObject.getDocument())) {
                            photoImage.setColorFilter(Theme.chat_animatedEmojiTextColorFilter);
                        }
                    }
                    float maxHeight;
                    int maxWidth;
                    if (AndroidUtilities.isTablet()) {
                        maxHeight = maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.4f);
                    } else {
                        maxHeight = maxWidth = (int) (Math.min(getParentWidth(), AndroidUtilities.displaySize.y) * 0.5f);
                    }
                    String filter;
                    if (messageObject.isAnimatedEmoji() || messageObject.isDice()) {
                        float zoom = MessagesController.getInstance(currentAccount).animatedEmojisZoom;
                        photoWidth = (int) ((photoWidth / 512.0f) * maxWidth * zoom);
                        photoHeight = (int) ((photoHeight / 512.0f) * maxHeight * zoom);
                    } else {
                        if (photoWidth == 0) {
                            photoHeight = (int) maxHeight;
                            photoWidth = photoHeight + AndroidUtilities.dp(100);
                        }
                        photoHeight *= maxWidth / (float) photoWidth;
                        photoWidth = (int) maxWidth;
                        if (photoHeight > maxHeight) {
                            photoWidth *= maxHeight / photoHeight;
                            photoHeight = (int) maxHeight;
                        }
                    }
                    Object parentObject = messageObject;
                    int w = (int) (photoWidth / AndroidUtilities.density);
                    int h = (int) (photoHeight / AndroidUtilities.density);
                    boolean shouldRepeatSticker = delegate != null && delegate.shouldRepeatSticker(messageObject);
                    if (currentMessageObject.strippedThumb == null) {
                        currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
                    } else {
                        currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
                    }
                    photoParentObject = messageObject.photoThumbsObject;
                    Drawable thumb = null;
                    if (messageObject.isDice()) {
                        filter = String.format(Locale.US, "%d_%d_dice_%s_%s", w, h, messageObject.getDiceEmoji(), messageObject.toString());
                        photoImage.setAutoRepeat(2);
                        String emoji = currentMessageObject.getDiceEmoji();
                        TLRPC.TL_messages_stickerSet stickerSet = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(emoji);
                        if (stickerSet != null) {
                            if (stickerSet.documents.size() > 0) {
                                int value = currentMessageObject.getDiceValue();
                                if (value <= 0) {
                                    TLRPC.Document document = stickerSet.documents.get(0);
                                    if ("\uD83C\uDFB0".equals(emoji)) {
                                        currentPhotoObjectThumb = null;
                                    } else {
                                        currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 40);
                                    }
                                    photoParentObject = document;
                                }
                            }
                        }
                    } else if (messageObject.isAnimatedEmoji()) {
                        if (!LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_CHAT)) {
                            filter = String.format(Locale.US, "%d_%d_nr_messageId=%d" + messageObject.emojiAnimatedStickerColor, w, h, messageObject.stableId);
                            thumb = DocumentObject.getCircleThumb(.4f, Theme.key_chat_serviceBackground, resourcesProvider, 0.65f);
                            photoImage.setAutoRepeat(3);
                            messageObject.loadAnimatedEmojiDocument();
                        } else if (messageObject.emojiAnimatedSticker == null && messageObject.emojiAnimatedStickerId != null) {
                            filter = String.format(Locale.US, "%d_%d_nr_messageId=%d" + messageObject.emojiAnimatedStickerColor, w, h, messageObject.stableId);
                            thumb = DocumentObject.getCircleThumb(.4f, Theme.key_chat_serviceBackground, resourcesProvider, 0.65f);
                            photoImage.setAutoRepeat(1);
                            messageObject.loadAnimatedEmojiDocument();
                        } else {
                            filter = String.format(Locale.US, "%d_%d_nr_messageId=%d" + messageObject.emojiAnimatedStickerColor, w, h, messageObject.stableId);
                            if (MessageObject.isAnimatedEmoji(messageObject.emojiAnimatedSticker)) {
                                photoImage.setAutoRepeat(1);
                            } else {
                                photoImage.setAutoRepeat(shouldRepeatSticker ? 2 : 3);
                            }
                            parentObject = MessageObject.getInputStickerSet(messageObject.emojiAnimatedSticker);
                            if (messageObject.emojiAnimatedStickerId != null) {
                                photoImage.setCrossfadeWithOldImage(true);
                            }
                        }
                    } else if (SharedConfig.loopStickers() || (isWebpSticker && !messageObject.isVideoSticker())) {
                        filter = String.format(Locale.US, "%d_%d", w, h);
                        photoImage.setAutoRepeat(1);
                    } else {
                        filter = String.format(Locale.US, "%d_%d_nr_messageId=%d", w, h, messageObject.stableId);
                        photoImage.setAutoRepeat(shouldRepeatSticker ? 2 : 3);
                    }
                    documentAttachType = DOCUMENT_ATTACH_TYPE_STICKER;
                    availableTimeWidth = photoWidth - AndroidUtilities.dp(14);
                    backgroundWidth = photoWidth + AndroidUtilities.dp(12);

                    photoImage.setRoundRadius(0);
                    canChangeRadius = false;
                    if (!messageObject.isOutOwner() && MessageObject.isPremiumSticker(messageObject.getDocument())) {
                        flipImage = true;
                    }
                    if (messageObject.getDocument() != null) {
                        if (messageObject.isVideoSticker()) {
                            if (!loopStickers()) {
                                photoImage.animatedFileDrawableRepeatMaxCount = 1;
                            }
                            photoImage.setImage(ImageLocation.getForDocument(messageObject.getDocument()), ImageLoader.AUTOPLAY_FILTER,
                                    null, null,
                                    messageObject.pathThumb,
                                    messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
                        } else if (messageObject.pathThumb != null) {
                            photoImage.setImage(ImageLocation.getForDocument(messageObject.getDocument()), filter,
                                    messageObject.pathThumb,
                                    messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
                        } else if (messageObject.attachPathExists) {
                            photoImage.setImage(ImageLocation.getForPath(messageObject.messageOwner.attachPath), filter,
                                    ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1", thumb != null ? thumb : currentPhotoObjectThumbStripped,
                                    messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
                        } else if (messageObject.getDocument().id != 0) {
                            photoImage.setImage(ImageLocation.getForDocument(messageObject.getDocument()), filter,
                                    ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1", thumb != null ? thumb : currentPhotoObjectThumbStripped,
                                    messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
                        } else {
                            photoImage.setImage(null, null, thumb, null, messageObject, 0);
                        }
                    } else {
                        photoImage.setImage(null, null, thumb, null, messageObject, 0);
                    }
                    if (!reactionsLayoutInBubble.isSmall) {
                        reactionsLayoutInBubble.measure(maxWidth, currentMessageObject.isOutOwner() && (currentMessageObject.isAnimatedEmoji() || currentMessageObject.isAnyKindOfSticker()) ? Gravity.RIGHT : Gravity.LEFT);
                        reactionsLayoutInBubble.drawServiceShaderBackground = 1f;
                        reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8);
                        additionHeight += reactionsLayoutInBubble.totalHeight;
                        if (!currentMessageObject.isAnimatedEmoji()) {
                            reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(4);
                        }
                    }

                    if (blurredPhotoImage.getBitmap() != null) {
                        blurredPhotoImage.getBitmap().recycle();
                        blurredPhotoImage.setImageBitmap((Bitmap) null);
                    }
                    if (photoImage.getBitmap() != null && !photoImage.getBitmap().isRecycled() && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) {
                        blurredPhotoImage.setImageBitmap(Utilities.stackBlurBitmapMax(photoImage.getBitmap()));
                    }
                } else {
                    currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize());
                    photoParentObject = messageObject.photoThumbsObject;
                    boolean useFullWidth = false;
                    if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        documentAttach = messageObject.getDocument();
                        documentAttachType = DOCUMENT_ATTACH_TYPE_ROUND;
                    } else {
                        if (AndroidUtilities.isTablet()) {
                            photoWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
                        } else {
                            if (
                                currentPhotoObject != null && (
                                    messageObject.type == MessageObject.TYPE_PHOTO ||
                                    messageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW ||
                                    messageObject.type == MessageObject.TYPE_VIDEO ||
                                    messageObject.type == MessageObject.TYPE_GIF
                                ) && currentPhotoObject.w >= currentPhotoObject.h
                            ) {
                                photoWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(64 + (checkNeedDrawShareButton(messageObject) ? 10 : 0));
                                useFullWidth = true;
                            } else {
                                photoWidth = (int) (Math.min(getParentWidth(), AndroidUtilities.displaySize.y) * 0.7f);
                            }
                        }
                    }
                    photoHeight = photoWidth + AndroidUtilities.dp(100);
                    if (!useFullWidth) {
                        if (messageObject.type != MessageObject.TYPE_ROUND_VIDEO && checkNeedDrawShareButton(messageObject)) {
                            photoWidth -= AndroidUtilities.dp(20);
                        }
                        if (photoWidth > AndroidUtilities.getPhotoSize()) {
                            photoWidth = AndroidUtilities.getPhotoSize();
                        }
                        if (photoHeight > AndroidUtilities.getPhotoSize()) {
                            photoHeight = AndroidUtilities.getPhotoSize();
                        }
                    } else if (drawAvatar) {
                        photoWidth -= AndroidUtilities.dp(52);
                    }

                    boolean needQualityPreview = false;

                    if (messageObject.type == MessageObject.TYPE_PHOTO || messageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW) { // photo
                        updateSecretTimeText(messageObject);
                        currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
                    } else if (messageObject.type == MessageObject.TYPE_VIDEO || messageObject.type == MessageObject.TYPE_GIF) {
                        createDocumentLayout(0, messageObject);
                        currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
                        updateSecretTimeText(messageObject);
                        needQualityPreview = true;
                    } else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
                        needQualityPreview = true;
                    }
                    if (currentMessageObject.strippedThumb != null) {
                        currentPhotoObjectThumb = null;
                        currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
                    }
                    int w;
                    int h;
                    if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        if (isPlayingRound && !messageObject.isVoiceTranscriptionOpen()) {
                            w = h = AndroidUtilities.roundPlayingMessageSize;
                        } else {
                            w = h = AndroidUtilities.roundMessageSize;
                        }
                    } else {
                        TLRPC.PhotoSize size = currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb;
                        int imageW = 0;
                        int imageH = 0;
                        if (messageObject.hasExtendedMediaPreview()) {
                            TLRPC.TL_messageExtendedMediaPreview preview = (TLRPC.TL_messageExtendedMediaPreview) messageObject.messageOwner.media.extended_media;
                            if (preview.w != 0 && preview.h != 0) {
                                imageW = preview.w;
                                imageH = preview.h;
                            } else if (preview.thumb != null) {
                                imageW = preview.thumb.w;
                                imageH = preview.thumb.h;
                            }
                        } else if (size != null && !(size instanceof TLRPC.TL_photoStrippedSize)) {
                            imageW = size.w;
                            imageH = size.h;
                        } else if (documentAttach != null) {
                            for (int a = 0, N = documentAttach.attributes.size(); a < N; a++) {
                                TLRPC.DocumentAttribute attribute = documentAttach.attributes.get(a);
                                if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                    imageW = attribute.w;
                                    imageH = attribute.h;
                                }
                            }
                        }
                        Point point = getMessageSize(imageW, imageH, photoWidth, photoHeight);
                        w = (int) point.x;
                        h = (int) point.y;
                    }
                    if (currentPhotoObject != null && "s".equals(currentPhotoObject.type)) {
                        currentPhotoObject = null;
                    }

                    if (currentPhotoObject != null && currentPhotoObject == currentPhotoObjectThumb) {
                        if (messageObject.type == MessageObject.TYPE_PHOTO || messageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW) {
                            currentPhotoObjectThumb = null;
                            currentPhotoObjectThumbStripped = null;
                        } else {
                            currentPhotoObject = null;
                        }
                    }

                    if (needQualityPreview) {
                        if (!messageObject.needDrawBluredPreview() && (currentPhotoObject == null || currentPhotoObject == currentPhotoObjectThumb) && (currentPhotoObjectThumb == null || !"m".equals(currentPhotoObjectThumb.type))) {
                            photoImage.setNeedsQualityThumb(true);
                            photoImage.setShouldGenerateQualityThumb(true);
                        }
                    }

                    if (currentMessagesGroup == null && messageObject.caption != null) {
                        mediaBackground = false;
                    }

                    if ((w == 0 || h == 0) && messageObject.type == MessageObject.TYPE_GIF) {
                        TLRPC.Document document = messageObject.getDocument();
                        if (document != null) {
                            for (int a = 0; a < document.attributes.size(); a++) {
                                TLRPC.DocumentAttribute attribute = document.attributes.get(a);
                                if (attribute instanceof TLRPC.TL_documentAttributeImageSize || attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                    float scale = (float) attribute.w / (float) photoWidth;
                                    w = (int) (attribute.w / scale);
                                    h = (int) (attribute.h / scale);
                                    if (h > photoHeight) {
                                        float scale2 = h;
                                        h = photoHeight;
                                        scale2 /= h;
                                        w = (int) (w / scale2);
                                    } else if (h < AndroidUtilities.dp(120)) {
                                        h = AndroidUtilities.dp(120);
                                        float hScale = (float) attribute.h / h;
                                        if (attribute.w / hScale < photoWidth) {
                                            w = (int) (attribute.w / hScale);
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }

                    if (w == 0 || h == 0) {
                        w = h = AndroidUtilities.dp(150);
                    }
                    if (messageObject.type == MessageObject.TYPE_VIDEO) {
                        if (w < infoWidth + AndroidUtilities.dp(16 + 24)) {
                            w = infoWidth + AndroidUtilities.dp(16 + 24);
                        }
                    }
                    if (commentLayout != null && drawSideButton != 3 && w < totalCommentWidth + AndroidUtilities.dp(10)) {
                        w = totalCommentWidth + AndroidUtilities.dp(10);
                    }

                    if (currentMessagesGroup != null) {
                        int firstLineWidth = 0;
                        int dWidth = getGroupPhotosWidth();
                        for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                            MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                            if (position.minY == 0) {
                                firstLineWidth += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
                            } else {
                                break;
                            }
                        }
                        availableTimeWidth = firstLineWidth - AndroidUtilities.dp(35);
                    } else {
                        availableTimeWidth = photoWidth - AndroidUtilities.dp(14);
                    }

                    if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        availableTimeWidth = (int) (AndroidUtilities.roundMessageSize - Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) - AndroidUtilities.dp(46));
                    }
                    measureTime(messageObject);
                    int timeWidthTotal = timeWidth + AndroidUtilities.dp((SharedConfig.bubbleRadius >= 10 ? 22 : 18) + (messageObject.isOutOwner() ? 20 : 0));
                    if (w < timeWidthTotal) {
                        w = timeWidthTotal;
                    }

                    if (messageObject.isRoundVideo()) {
                        w = h = Math.min(w, h);
                        drawBackground = messageObject.isVoiceTranscriptionOpen();
                        mediaBackground = !drawBackground;
                        if (drawBackground) {
                            h = 0;
                        }
                        photoImage.setRoundRadius(w / 2);
                        canChangeRadius = false;
                    } else if (messageObject.needDrawBluredPreview() && !messageObject.hasExtendedMediaPreview()) {
                        if (AndroidUtilities.isTablet()) {
                            w = h = (int) (AndroidUtilities.getMinTabletSide() * 0.5f);
                        } else {
                            w = h = (int) (Math.min(getParentWidth(), AndroidUtilities.displaySize.y) * 0.5f);
                        }
                    }

                    int widthForCaption = 0;
                    int widthCaptionMin = -1;
                    boolean fixPhotoWidth = false;
                    if (currentMessagesGroup != null) {
                        float maxHeight = Math.max(getParentWidth(), AndroidUtilities.displaySize.y) * 0.5f;
                        int dWidth = getGroupPhotosWidth();
                        w = (int) Math.ceil(currentPosition.pw / 1000.0f * dWidth);
                        if (currentPosition.minY != 0 && (messageObject.isOutOwner() && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 || !messageObject.isOutOwner() && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0)) {
                            int firstLineWidth = 0;
                            int currentLineWidth = 0;
                            for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                                MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                                if (position.minY == 0) {
                                    firstLineWidth += Math.ceil(position.pw / 1000.0f * dWidth) + (position.leftSpanOffset != 0 ? Math.ceil(position.leftSpanOffset / 1000.0f * dWidth) : 0);
                                } else if (position.minY == currentPosition.minY) {
                                    currentLineWidth += Math.ceil((position.pw) / 1000.0f * dWidth) + (position.leftSpanOffset != 0 ? Math.ceil(position.leftSpanOffset / 1000.0f * dWidth) : 0);
                                } else if (position.minY > currentPosition.minY) {
                                    break;
                                }
                            }
                            w += firstLineWidth - currentLineWidth;
                        }
                        w -= AndroidUtilities.dp(9);
                        if (isAvatarVisible) {
                            w -= AndroidUtilities.dp(48);
                        }
                        if (currentPosition.siblingHeights != null) {
                            h = 0;
                            for (int a = 0; a < currentPosition.siblingHeights.length; a++) {
                                h += (int) Math.ceil(maxHeight * currentPosition.siblingHeights[a]);
                            }
                            h += (currentPosition.maxY - currentPosition.minY) * Math.round(7 * AndroidUtilities.density); //TODO fix
                        } else {
                            h = (int) Math.ceil(maxHeight * currentPosition.ph);
                        }
                        backgroundWidth = w;
                        if ((currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                            w -= AndroidUtilities.dp(8);
                        } else if ((currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                            w -= AndroidUtilities.dp(11);
                        } else if ((currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0) {
                            w -= AndroidUtilities.dp(10);
                        } else {
                            w -= AndroidUtilities.dp(9);
                        }
                        photoWidth = w;
                        if (!currentPosition.edge) {
                            photoWidth += AndroidUtilities.dp(10);
                        }
                        photoHeight = h;
                        widthForCaption += photoWidth - AndroidUtilities.dp(10);
                        boolean checkCaption = true;
                        if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 || currentMessagesGroup.hasSibling && (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                            widthForCaption += getAdditionalWidthForPosition(currentPosition);
                            int count = currentMessagesGroup.messages.size();
                            for (int i = 0; i < count; i++) {
                                MessageObject m = currentMessagesGroup.messages.get(i);
                                MessageObject.GroupedMessagePosition rowPosition = currentMessagesGroup.posArray.get(i);
                                if (rowPosition != currentPosition && (rowPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0) {
                                    w = (int) Math.ceil(rowPosition.pw / 1000.0f * dWidth);
                                    if (rowPosition.minY != 0 && (messageObject.isOutOwner() && (rowPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 || !messageObject.isOutOwner() && (rowPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0)) {
                                        int firstLineWidth = 0;
                                        int currentLineWidth = 0;
                                        for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                                            MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                                            if (position.minY == 0) {
                                                firstLineWidth += Math.ceil(position.pw / 1000.0f * dWidth) + (position.leftSpanOffset != 0 ? Math.ceil(position.leftSpanOffset / 1000.0f * dWidth) : 0);
                                            } else if (position.minY == rowPosition.minY) {
                                                currentLineWidth += Math.ceil((position.pw) / 1000.0f * dWidth) + (position.leftSpanOffset != 0 ? Math.ceil(position.leftSpanOffset / 1000.0f * dWidth) : 0);
                                            } else if (position.minY > rowPosition.minY) {
                                                break;
                                            }
                                        }
                                        w += firstLineWidth - currentLineWidth;
                                    }
                                    w -= AndroidUtilities.dp(9);
                                    if ((rowPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0 && (rowPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                                        w -= AndroidUtilities.dp(8);
                                    } else if ((rowPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0 && (rowPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                                        w -= AndroidUtilities.dp(11);
                                    } else if ((rowPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0) {
                                        w -= AndroidUtilities.dp(10);
                                    } else {
                                        w -= AndroidUtilities.dp(9);
                                    }
                                    if (isChat && !isThreadPost && !m.isOutOwner() && m.needDrawAvatar() && (rowPosition == null || rowPosition.edge)) {
                                        w -= AndroidUtilities.dp(48);
                                    }
                                    w += getAdditionalWidthForPosition(rowPosition);
                                    if (!rowPosition.edge) {
                                        w += AndroidUtilities.dp(10);
                                    }
                                    widthForCaption += w;
                                    if (rowPosition.minX < currentPosition.minX || currentMessagesGroup.hasSibling && rowPosition.minY != rowPosition.maxY) {
                                        captionOffsetX -= w;
                                    }
                                }
                                if (checkCaption) {
                                    if (m.caption != null) {
                                        if (currentCaption != null) {
                                            currentCaption = null;
                                            checkCaption = false;
                                        } else {
                                            currentCaption = m.caption;
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        photoHeight = h;
                        photoWidth = w;
                        currentCaption = messageObject.caption;

                        int minCaptionWidth;
                        if (AndroidUtilities.isTablet()) {
                            minCaptionWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.65f);
                        } else {
                            minCaptionWidth = (int) (Math.min(getParentWidth(), AndroidUtilities.displaySize.y) * 0.65f);
                        }
                        if (!messageObject.needDrawBluredPreview() && (currentCaption != null || (!reactionsLayoutInBubble.isEmpty && !reactionsLayoutInBubble.isSmall)) && photoWidth < minCaptionWidth) {
                            widthForCaption = minCaptionWidth;
                            fixPhotoWidth = true;
                        } else {
                            widthForCaption = photoWidth - AndroidUtilities.dp(10);
                        }

                        backgroundWidth = photoWidth + AndroidUtilities.dp(8);
                        if (!mediaBackground) {
                            backgroundWidth += AndroidUtilities.dp(9);
                        }
                    }

                    if (currentCaption != null) {
                        try {
                            widthForCaption -= getExtraTextX() * 2;
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                captionLayout = StaticLayout.Builder.obtain(currentCaption, 0, currentCaption.length(), Theme.chat_msgTextPaint, widthForCaption)
                                        .setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
                                        .setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
                                        .setAlignment(Layout.Alignment.ALIGN_NORMAL)
                                        .build();
                            } else {
                                captionLayout = new StaticLayout(currentCaption, Theme.chat_msgTextPaint, widthForCaption, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                            }
                            updateCaptionSpoilers();
                            int lineCount = captionLayout.getLineCount();
                            if (lineCount > 0) {
                                if (fixPhotoWidth) {
                                    captionWidth = 0;
                                    for (int a = 0; a < lineCount; a++) {
                                        captionWidth = (int) Math.max(captionWidth, Math.ceil(captionLayout.getLineWidth(a)));
                                        if (captionLayout.getLineLeft(a) != 0) {
                                            captionWidth = widthForCaption;
                                            break;
                                        }
                                    }
                                    if (captionWidth > widthForCaption) {
                                        captionWidth = widthForCaption;
                                    }
                                } else {
                                    captionWidth = widthForCaption;
                                }
                                if (widthCaptionMin > 0 && captionWidth > widthCaptionMin) {
                                    photoWidth += captionWidth - widthCaptionMin;
                                    backgroundWidth += captionWidth - widthCaptionMin;
                                }
                                captionHeight = captionLayout.getHeight();
                                addedCaptionHeight = captionHeight + AndroidUtilities.dp(9);
                                if (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0) {
                                    additionHeight += addedCaptionHeight;
                                    int widthToCheck = Math.max(captionWidth, photoWidth - AndroidUtilities.dp(10));
                                    float lastLineWidth = captionLayout.getLineWidth(captionLayout.getLineCount() - 1) + captionLayout.getLineLeft(captionLayout.getLineCount() - 1);
                                    if ((reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) && !shouldDrawTimeOnMedia() && widthToCheck + AndroidUtilities.dp(2) - lastLineWidth < timeWidthTotal + getExtraTimeX()) {
                                        additionHeight += AndroidUtilities.dp(14);
                                        addedCaptionHeight += AndroidUtilities.dp(14);
                                        captionNewLine = 1;
                                    }
                                } else {
                                    captionLayout = null;
                                    updateCaptionSpoilers();
                                }
                            }
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }
                    if (!reactionsLayoutInBubble.isSmall) {
                        boolean useBackgroundWidth = backgroundWidth - AndroidUtilities.dp(24) > widthForCaption;
                        int maxWidth = Math.max(backgroundWidth - AndroidUtilities.dp(36), widthForCaption);
                        reactionsLayoutInBubble.measure(maxWidth, Gravity.LEFT);
                        if (!reactionsLayoutInBubble.isEmpty) {
                            if (isRoundVideo) {
                                reactionsLayoutInBubble.drawServiceShaderBackground = 1f - getVideoTranscriptionProgress();
                            } else if (shouldDrawTimeOnMedia()) {
                                reactionsLayoutInBubble.drawServiceShaderBackground = 1f;
                            }
                            int heightLocal = reactionsLayoutInBubble.height;
                            if (captionLayout == null) {
                                heightLocal += AndroidUtilities.dp(12);
                                heightLocal += AndroidUtilities.dp(4);
                            } else {
                                heightLocal += AndroidUtilities.dp(12);
                                reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(12);
                            }
                            reactionsLayoutInBubble.totalHeight = heightLocal;
                            additionHeight += reactionsLayoutInBubble.totalHeight;

                            if (isRoundVideo && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) {
                                reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(8);
                            }

                            if (!shouldDrawTimeOnMedia()) {

                                int widthToCheck = Math.min(maxWidth, reactionsLayoutInBubble.width + timeWidthTotal + getExtraTimeX() + AndroidUtilities.dp(2));
                                float lastLineWidth = reactionsLayoutInBubble.lastLineX;
                                if (!shouldDrawTimeOnMedia() && widthToCheck - lastLineWidth < timeWidthTotal + getExtraTimeX()) {
                                    additionHeight += AndroidUtilities.dp(14);
                                    reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(14);
                                    reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(14);
                                    captionNewLine = 1;
                                    if (!useBackgroundWidth && captionWidth < reactionsLayoutInBubble.width) {
                                        captionWidth = reactionsLayoutInBubble.width;
                                    }
                                } else if (!useBackgroundWidth) {
                                    if (reactionsLayoutInBubble.lastLineX + timeWidthTotal > captionWidth) {
                                        captionWidth = reactionsLayoutInBubble.lastLineX + timeWidthTotal;
                                    }
                                    if (reactionsLayoutInBubble.width > captionWidth) {
                                        captionWidth = reactionsLayoutInBubble.width;
                                    }
                                }
                            }
                        }
                    }

                    int minWidth = (int) (Theme.chat_infoPaint.measureText("100%") + AndroidUtilities.dp(100/*48*/)/* + timeWidth*/);
                    if (currentMessagesGroup == null && (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) && photoWidth < minWidth) {
                        photoWidth = minWidth;
                        backgroundWidth = photoWidth + AndroidUtilities.dp(8);
                        if (!mediaBackground) {
                            backgroundWidth += AndroidUtilities.dp(9);
                        }
                    }

                    if (fixPhotoWidth && photoWidth < captionWidth + AndroidUtilities.dp(10)) {
                        photoWidth = captionWidth + AndroidUtilities.dp(10);
                        backgroundWidth = photoWidth + AndroidUtilities.dp(8);
                        if (!mediaBackground) {
                            backgroundWidth += AndroidUtilities.dp(9);
                        }
                    }
                    if (messageChanged || messageIdChanged || dataChanged) {
                        currentPhotoFilter = currentPhotoFilterThumb = String.format(Locale.US, "%d_%d", (int) (w / AndroidUtilities.density), (int) (h / AndroidUtilities.density));
                        if (
                            messageObject.photoThumbs != null && messageObject.photoThumbs.size() > 1 ||
                            messageObject.type == MessageObject.TYPE_VIDEO ||
                            messageObject.type == MessageObject.TYPE_GIF ||
                            messageObject.type == MessageObject.TYPE_ROUND_VIDEO
                        ) {
                            if (messageObject.needDrawBluredPreview()) {
                                currentPhotoFilter += "_b2";
                                currentPhotoFilterThumb += "_b2";
                            } else {
                                currentPhotoFilterThumb += "_b";
                            }
                        }
                    } else {
                        String filterNew = String.format(Locale.US, "%d_%d", (int) (w / AndroidUtilities.density), (int) (h / AndroidUtilities.density));
                        if (!messageObject.needDrawBluredPreview() && !filterNew.equals(currentPhotoFilter)) {
                            ImageLocation location = ImageLocation.getForObject(currentPhotoObject, photoParentObject);
                            if (location != null) {
                                String key = location.getKey(photoParentObject, null, false) + "@" + currentPhotoFilter;
                                if (ImageLoader.getInstance().isInMemCache(key, false)) {
                                    currentPhotoObjectThumb = currentPhotoObject;
                                    currentPhotoFilterThumb = currentPhotoFilter;
                                    currentPhotoFilter = filterNew;
                                }
                            }
                        }
                    }

                    boolean noSize = false;
                    if (messageObject.type == MessageObject.TYPE_VIDEO || messageObject.type == MessageObject.TYPE_GIF || messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        noSize = true;
                    }
                    if (currentPhotoObject != null && !noSize && currentPhotoObject.size == 0) {
                        currentPhotoObject.size = -1;
                    }
                    if (currentPhotoObjectThumb != null && !noSize && currentPhotoObjectThumb.size == 0) {
                        currentPhotoObjectThumb.size = -1;
                    }

                    if (SharedConfig.isAutoplayVideo() && (!currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || currentMessageObject.revealingMediaSpoilers) && messageObject.type == MessageObject.TYPE_VIDEO && !messageObject.needDrawBluredPreview() &&
                            (currentMessageObject.mediaExists || messageObject.canStreamVideo() && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject))
                    ) {
                        if (currentPosition != null) {
                            autoPlayingMedia = (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0;
                        } else {
                            autoPlayingMedia = true;
                        }
                    }

                    if (autoPlayingMedia) {
                        photoImage.setAllowStartAnimation(true);
                        photoImage.startAnimation();
                        TLRPC.Document document = messageObject.getDocument();

                        if (currentMessageObject.videoEditedInfo != null && currentMessageObject.videoEditedInfo.canAutoPlaySourceVideo() && messageObject.getDocument() != null) {
                            photoImage.setImage(ImageLocation.getForPath(currentMessageObject.videoEditedInfo.originalPath), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, messageObject.getDocument().size, null, messageObject, 0);
                            photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
                        } else if (messageObject.getDocument() != null) {
                            if (!messageIdChanged && !dataChanged) {
                                photoImage.setCrossfadeWithOldImage(true);
                            }
                            photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, messageObject.getDocument().size, null, messageObject, 0);
                        }
                    } else if (messageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW) {
                        photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                    } else if (messageObject.type == MessageObject.TYPE_PHOTO) {
                        if (messageObject.useCustomPhoto) {
                            photoImage.setImageBitmap(getResources().getDrawable(R.drawable.theme_preview_image));
                        } else {
                            if (currentPhotoObject != null) {
                                boolean photoExist = true;
                                String fileName = FileLoader.getAttachFileName(currentPhotoObject);
                                if (messageObject.mediaExists) {
                                    DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                                } else {
                                    photoExist = false;
                                }
                                if (photoExist || !currentMessageObject.loadingCancelled && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject) || FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                                    photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, currentPhotoObject.size, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                                } else {
                                    photoNotSet = true;
                                    if (currentPhotoObjectThumb != null || currentPhotoObjectThumbStripped != null) {
                                        photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                                    } else {
                                        photoImage.setImageBitmap((Drawable) null);
                                    }
                                }
                            } else {
                                photoImage.setImageBitmap((Drawable) null);
                            }
                        }
                    } else if (messageObject.type == MessageObject.TYPE_GIF || messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        String fileName = FileLoader.getAttachFileName(messageObject.getDocument());
                        int localFile = 0;
                        if (messageObject.attachPathExists) {
                            DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                            localFile = 1;
                        } else if (messageObject.mediaExists) {
                            localFile = 2;
                        }
                        boolean autoDownload = false;
                        TLRPC.Document document = messageObject.getDocument();
                        if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId()) || messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                            autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
                        }
                        TLRPC.VideoSize videoSize = MessageObject.getDocumentVideoThumb(document);
                        if (((MessageObject.isGifDocument(document, messageObject.hasValidGroupId()) && messageObject.videoEditedInfo == null) || (!messageObject.isSending() && !messageObject.isEditing())) && (localFile != 0 || FileLoader.getInstance(currentAccount).isLoadingFile(fileName) || autoDownload)) {
                            if (localFile != 1 && !messageObject.needDrawBluredPreview() && (localFile != 0 || messageObject.canStreamVideo() && autoDownload)) {
                                autoPlayingMedia = true;
                                if (!messageIdChanged) {
                                    photoImage.setCrossfadeWithOldImage(true);
                                    photoImage.setCrossfadeDuration(250);
                                }
                                if (localFile == 0 && videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
                                    photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
                                } else {
                                    if (isRoundVideo && !messageIdChanged && photoImage.hasStaticThumb()) {
                                        photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, null, null, photoImage.getStaticThumb(), document.size, null, messageObject, 0);
                                    } else {
                                        photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
                                    }
                                }
                            } else if (localFile == 1) {
                                photoImage.setImage(ImageLocation.getForPath(messageObject.isSendError() ? null : messageObject.messageOwner.attachPath), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                            } else {
                                if (videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
                                    photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
                                } else {
                                    photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
                                }
                            }
                        } else {
                            if (messageObject.videoEditedInfo != null && messageObject.type == MessageObject.TYPE_ROUND_VIDEO && !currentMessageObject.needDrawBluredPreview()) {
                                photoImage.setImage(ImageLocation.getForPath(messageObject.videoEditedInfo.originalPath), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                                photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
                            } else {
                                if (!messageIdChanged && !currentMessageObject.needDrawBluredPreview()) {
                                    photoImage.setCrossfadeWithOldImage(true);
                                    photoImage.setCrossfadeDuration(250);
                                }
                                photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
                            }
                        }
                    } else {
                        if (messageObject.videoEditedInfo != null && messageObject.type == MessageObject.TYPE_ROUND_VIDEO && !currentMessageObject.needDrawBluredPreview()) {
                            photoImage.setImage(ImageLocation.getForPath(messageObject.videoEditedInfo.originalPath), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                            photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
                        } else {
                            if (!messageIdChanged && !currentMessageObject.needDrawBluredPreview()) {
                                photoImage.setCrossfadeWithOldImage(true);
                                photoImage.setCrossfadeDuration(250);
                            }
                            photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                        }
                    }
                }
                if (blurredPhotoImage.getBitmap() != null) {
                    blurredPhotoImage.getBitmap().recycle();
                    blurredPhotoImage.setImageBitmap((Bitmap) null);
                }
                if (photoImage.getBitmap() != null && !photoImage.getBitmap().isRecycled() && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) {
                    blurredPhotoImage.setImageBitmap(Utilities.stackBlurBitmapMax(photoImage.getBitmap()));
                }
                setMessageObjectInternal(messageObject);

                if (drawForwardedName && messageObject.needDrawForwarded() && (currentPosition == null || currentPosition.minY == 0)) {
                    if (messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
                        namesOffset += AndroidUtilities.dp(5);
                    }
                } else if (drawNameLayout && (messageObject.getReplyMsgId() == 0 || isThreadChat && messageObject.getReplyTopMsgId() == 0)) {
                    namesOffset += AndroidUtilities.dp(7);
                }
                totalHeight = photoHeight + AndroidUtilities.dp(14) + namesOffset + additionHeight;
                if (messageObject.isVoiceTranscriptionOpen()) {
                    totalHeight += AndroidUtilities.dp(70 - 14);
                }
                if (currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0 && !currentMessageObject.isDocument() && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
                    totalHeight -= AndroidUtilities.dp(3);
                }
                if (currentMessageObject.isDice()) {
                    totalHeight += AndroidUtilities.dp(21);
                    additionalTimeOffsetY = AndroidUtilities.dp(21);
                }

                int additionalTop = 0;
                if (currentPosition != null && !currentMessageObject.isDocument()) {
                    photoWidth += getAdditionalWidthForPosition(currentPosition);
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                        photoHeight += AndroidUtilities.dp(4);
                        additionalTop -= AndroidUtilities.dp(4);
                    }
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                        photoHeight += AndroidUtilities.dp(1);
                    }
                } else if (currentPosition != null && currentMessageObject.isDocument()) {
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && !messageObject.isOutOwner()) {
                        totalHeight -= AndroidUtilities.dp(2);
                    }
                }

                int y = 0;
                if (currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
                    if (drawPinnedTop) {
                        namesOffset -= AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ? 2 : 1);
                    }
                    if (drawPinnedTop && !messageObject.isOutOwner()) {
                        totalHeight += AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ? 2 : 0);
                    }
//                    if (drawPinnedBottom && !messageObject.isOutOwner()) {
//                        totalHeight += AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ? 1 : 0);
//                    }
                    if (namesOffset > 0) {
                        y = AndroidUtilities.dp(7);
                        totalHeight -= AndroidUtilities.dp(2);
                    } else {
                        y = AndroidUtilities.dp(5);
                        totalHeight -= AndroidUtilities.dp(4);
                    }
                }
                if (currentPosition != null && currentMessagesGroup.isDocuments && currentMessagesGroup.messages.size() > 1) {
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                        totalHeight -= AndroidUtilities.dp(drawPhotoImage ? 3 : 6);
                        mediaOffsetY -= AndroidUtilities.dp(drawPhotoImage ? 3 : 6);
                        y -= AndroidUtilities.dp(drawPhotoImage ? 3 : 6);
                    }
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                        totalHeight -= AndroidUtilities.dp(drawPhotoImage ? 3 : 6);
                    }
                }
                if (messageObject.isRoundVideo() && messageObject.isVoiceTranscriptionOpen()) {
                    photoImage.setImageCoords(0, AndroidUtilities.dp(13), AndroidUtilities.dp(44), AndroidUtilities.dp(44));
                } else {
                    photoImage.setImageCoords(0, y + namesOffset + additionalTop, photoWidth, photoHeight);
                }
                invalidate();
            }

            if ((currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.isDocument()) && !messageObject.isAnyKindOfSticker() && addedCaptionHeight == 0) {
                if (!messageObject.isRestrictedMessage && captionLayout == null && (messageObject.caption != null || messageObject.isVoiceTranscriptionOpen())) {
                    currentCaption = messageObject.isVoiceTranscriptionOpen() ? messageObject.getVoiceTranscription() : messageObject.caption;
                    if (currentCaption != null && !TextUtils.isEmpty(messageObject.messageOwner.voiceTranscription) && currentMessageObject.isVoiceTranscriptionOpen() && !currentMessageObject.messageOwner.voiceTranscriptionFinal) {
                        currentCaption += " ";
                        if (!(currentCaption instanceof Spannable)) {
                            currentCaption = new SpannableString(currentCaption);
                        }
                        ((SpannableString) currentCaption).setSpan(new TranscribeButton.LoadingPointsSpan(), currentCaption.length() - 1, currentCaption.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                    try {
                        int width = backgroundWidth;
                        if ((currentMessageObject.type == MessageObject.TYPE_VOICE || isRoundVideo) && messageObject.isVoiceTranscriptionOpen()) {
                            if (AndroidUtilities.isTablet()) {
                                width = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50);
                            } else {
                                width = getParentWidth() - AndroidUtilities.dp(drawAvatar ? 102 : 50);
                            }
                        }
                        if (drawSideButton != 0 && isRoundVideo) {
                            width -= AndroidUtilities.dp(24);
                        }
                        int widthForCaption = width - AndroidUtilities.dp(31 + (currentMessageObject.type != MessageObject.TYPE_ROUND_VIDEO ? 10 : 0)) - getExtraTextX() * 2;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            captionLayout = StaticLayout.Builder.obtain(currentCaption, 0, currentCaption.length(), Theme.chat_msgTextPaint, widthForCaption)
                                    .setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
                                    .setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
                                    .setAlignment(Layout.Alignment.ALIGN_NORMAL)
                                    .build();
                        } else {
                            captionLayout = new StaticLayout(currentCaption, Theme.chat_msgTextPaint, widthForCaption, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                        }
                        updateSeekBarWaveformWidth(null);
                        updateCaptionSpoilers();
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                }
                if (captionLayout != null || currentMessageObject.type == MessageObject.TYPE_VOICE || currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                    try {
                        if (messageObject.isVoiceTranscriptionOpen() && captionLayout != null) {
                            float startMaxWidth = backgroundWidth - AndroidUtilities.dp(31) - AndroidUtilities.dp(10) - getExtraTextX() * 2, maxWidth = startMaxWidth;
                            for (int i = 0; i < captionLayout.getLineCount(); ++i) {
                                float captionLineWidth = captionLayout.getLineWidth(i);
                                if (captionLineWidth > maxWidth) {
                                    maxWidth = captionLineWidth;
                                }
                            }
                            backgroundWidth += maxWidth - startMaxWidth;
                        }
                        int width = backgroundWidth - AndroidUtilities.dp(31);
                        Float lastCaptionLineWidth = null;
                        if (captionLayout != null && captionLayout.getLineCount() > 0) {
                            lastCaptionLineWidth = captionLayout.getLineWidth(captionLayout.getLineCount() - 1) + captionLayout.getLineLeft(captionLayout.getLineCount() - 1);
                        } else if (currentMessageObject.type == MessageObject.TYPE_VOICE) {
                            lastCaptionLineWidth = (float) AndroidUtilities.dp(64);
                        }
                        if (lastCaptionLineWidth != null) {
                            if (captionLayout != null) {
                                captionWidth = width;
                                captionHeight = captionLayout.getHeight();
                            }
                            totalHeight += captionHeight + AndroidUtilities.dp(9);
                            if ((reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0)) {
                                int timeWidthTotal = timeWidth + (messageObject.isOutOwner() ? AndroidUtilities.dp(20) : 0) + getExtraTimeX();
                                if (width - AndroidUtilities.dp(8) - lastCaptionLineWidth < timeWidthTotal) {
                                    totalHeight += AndroidUtilities.dp(14);
                                    if (captionLayout != null) {
                                        captionHeight += AndroidUtilities.dp(14);
                                        captionNewLine = 2;
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                }
            }
            if ((currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0) && captionLayout == null && widthBeforeNewTimeLine != -1 && availableTimeWidth - widthBeforeNewTimeLine < timeWidth) {
//                totalHeight += AndroidUtilities.dp(14);
            }

            if (currentMessageObject.eventId != 0 && !currentMessageObject.isMediaEmpty() && MessageObject.getMedia(currentMessageObject.messageOwner).webpage != null) {
                int linkPreviewMaxWidth = backgroundWidth - AndroidUtilities.dp(41);
                hasOldCaptionPreview = true;
                linkPreviewHeight = 0;
                TLRPC.WebPage webPage = MessageObject.getMedia(currentMessageObject.messageOwner).webpage;
                try {
                    int width = siteNameWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(webPage.site_name) + 1);
                    siteNameLayout = new StaticLayout(webPage.site_name, Theme.chat_replyNamePaint, Math.min(width, linkPreviewMaxWidth), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    siteNameRtl = siteNameLayout.getLineLeft(0) != 0;
                    int height = siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1);
                    linkPreviewHeight += height;
                    totalHeight += height;
                } catch (Exception e) {
                    FileLog.e(e);
                }

                try {
                    descriptionX = 0;
                    if (linkPreviewHeight != 0) {
                        totalHeight += AndroidUtilities.dp(2);
                    }

                    descriptionLayout = StaticLayoutEx.createStaticLayout(webPage.description, Theme.chat_replyTextPaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, 6);

                    int height = descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
                    linkPreviewHeight += height;
                    totalHeight += height;

                    boolean hasNonRtl = false;

                    for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
                        int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a));
                        if (lineLeft != 0) {
                            if (descriptionX == 0) {
                                descriptionX = -lineLeft;
                            } else {
                                descriptionX = Math.max(descriptionX, -lineLeft);
                            }
                        } else {
                            hasNonRtl = true;
                        }
                    }
                    if (hasNonRtl) {
                        descriptionX = 0;
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }

                if (
                    messageObject.type == MessageObject.TYPE_PHOTO ||
                    messageObject.type == MessageObject.TYPE_VIDEO ||
                    messageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW
                ) {
                    totalHeight += AndroidUtilities.dp(6);
                }

                totalHeight += AndroidUtilities.dp(17);
                if (captionNewLine != 0) {
                    totalHeight -= AndroidUtilities.dp(14);
                    if (captionNewLine == 2) {
                        captionHeight -= AndroidUtilities.dp(14);
                    }
                }
            }

            if (messageObject.isSponsored()) {
                drawInstantView = true;
                if (messageObject.sponsoredChannelPost != 0) {
                    drawInstantViewType = 12;
                } else {
                    drawInstantViewType = 1;
                }
                long id = MessageObject.getPeerId(messageObject.messageOwner.from_id);
                if (id > 0) {
                    TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(id);
                    if (user != null && user.bot) {
                        drawInstantViewType = 10;
                    }
                }
                createInstantViewButton();
            }

            botButtons.clear();
            if (messageIdChanged) {
                botButtonsByData.clear();
                botButtonsByPosition.clear();
                botButtonsLayout = null;
            }
            if (!messageObject.isRestrictedMessage && currentPosition == null && (messageObject.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) && !messageObject.hasExtendedMedia()) {
                int rows;

                if (messageObject.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) {
                    rows = messageObject.messageOwner.reply_markup.rows.size();
                } else {
                    rows = 1;
                }
                substractBackgroundHeight = keyboardHeight = AndroidUtilities.dp(44 + 4) * rows + AndroidUtilities.dp(1);
                widthForButtons = backgroundWidth - AndroidUtilities.dp(mediaBackground ? 0 : 9);
                boolean fullWidth = false;
                if (messageObject.wantedBotKeyboardWidth > widthForButtons) {
                    int maxButtonWidth = -AndroidUtilities.dp(drawAvatar ? 62 : 10);
                    if (AndroidUtilities.isTablet()) {
                        maxButtonWidth += AndroidUtilities.getMinTabletSide();
                    } else {
                        maxButtonWidth += Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(5);
                    }
                    widthForButtons = Math.max(backgroundWidth, Math.min(messageObject.wantedBotKeyboardWidth, maxButtonWidth));
                }

                int maxButtonsWidth = 0;
                HashMap<String, BotButton> oldByData = new HashMap<>(botButtonsByData);
                HashMap<String, BotButton> oldByPosition;
                if (messageObject.botButtonsLayout != null && botButtonsLayout != null && botButtonsLayout.equals(messageObject.botButtonsLayout.toString())) {
                    oldByPosition = new HashMap<>(botButtonsByPosition);
                } else {
                    if (messageObject.botButtonsLayout != null) {
                        botButtonsLayout = messageObject.botButtonsLayout.toString();
                    }
                    oldByPosition = null;
                }
                botButtonsByData.clear();
                if (messageObject.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) {
                    for (int a = 0; a < rows; a++) {
                        TLRPC.TL_keyboardButtonRow row = messageObject.messageOwner.reply_markup.rows.get(a);
                        int buttonsCount = row.buttons.size();
                        if (buttonsCount == 0) {
                            continue;
                        }
                        int buttonWidth = (widthForButtons - AndroidUtilities.dp(5) * (buttonsCount - 1) - AndroidUtilities.dp(2)) / buttonsCount;
                        for (int b = 0; b < row.buttons.size(); b++) {
                            BotButton botButton = new BotButton();
                            TLRPC.TL_keyboardButtonRequestPeer button = new TLRPC.TL_keyboardButtonRequestPeer();
                            button.button_id = 0;
                            button.text = "Request peer";
                            button.peer_type = new TLRPC.TL_requestPeerTypeChat();
                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).forum = true;
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights = new TLRPC.TL_chatAdminRights();
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.change_info = true;
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.delete_messages = true;
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.pin_messages = true;
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.anonymous = true;
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.post_messages = true;
//                            ((TLRPC.TL_requestPeerTypeChat) button.peer_type).premium = false;
//                            botButton.button = button;
                             botButton.button = row.buttons.get(b);
                            String key = Utilities.bytesToHex(botButton.button.data);
                            String position = a + "" + b;
                            BotButton oldButton;
                            if (oldByPosition != null) {
                                oldButton = oldByPosition.get(position);
                            } else {
                                oldButton = oldByData.get(key);
                            }
                            if (oldButton != null) {
                                botButton.progressAlpha = oldButton.progressAlpha;
                                botButton.angle = oldButton.angle;
                                botButton.lastUpdateTime = oldButton.lastUpdateTime;
                            } else {
                                botButton.lastUpdateTime = System.currentTimeMillis();
                            }
                            botButtonsByData.put(key, botButton);
                            botButtonsByPosition.put(position, botButton);
                            botButton.x = b * (buttonWidth + AndroidUtilities.dp(5));
                            botButton.y = a * AndroidUtilities.dp(44 + 4) + AndroidUtilities.dp(5);
                            botButton.width = buttonWidth;
                            botButton.height = AndroidUtilities.dp(44);
                            CharSequence buttonText;
                            TextPaint botButtonPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatBotButton);
                            if (botButton.button instanceof TLRPC.TL_keyboardButtonBuy && (MessageObject.getMedia(messageObject.messageOwner).flags & 4) != 0) {
                                buttonText = LocaleController.getString("PaymentReceipt", R.string.PaymentReceipt);
                            } else {
                                buttonText = botButton.button.text == null ? "" : botButton.button.text;
                                buttonText = Emoji.replaceEmoji(buttonText, botButtonPaint.getFontMetricsInt(), AndroidUtilities.dp(15), false);
                                buttonText = TextUtils.ellipsize(buttonText, botButtonPaint, buttonWidth - AndroidUtilities.dp(10), TextUtils.TruncateAt.END);
                            }
                            botButton.title = new StaticLayout(buttonText, botButtonPaint, buttonWidth - AndroidUtilities.dp(10), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
                            botButtons.add(botButton);
                            if (b == row.buttons.size() - 1) {
                                maxButtonsWidth = Math.max(maxButtonsWidth, botButton.x + botButton.width);
                            }
                            if (messageObject.isFromUser() && botButton.button instanceof TLRPC.TL_keyboardButtonUrl) {
                                try {
                                    final Uri uri = Uri.parse(botButton.button.url);
                                    final String host = uri.getHost().toLowerCase();
                                    botButton.isInviteButton = (uri.getQueryParameter("startgroup") != null && (
                                            ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) && ("t.me".equals(host) || "telegram.me".equals(host) || "telegram.dog".equals(host)) ||
                                                    "tg".equals(uri.getScheme()) && (botButton.button.url.startsWith("tg:resolve") || botButton.button.url.startsWith("tg://resolve"))
                                    ));
                                } catch (Exception ignore) {
                                }
                            }
                        }
                    }
                }
                widthForButtons = maxButtonsWidth;
            } else {
                substractBackgroundHeight = 0;
                keyboardHeight = 0;
            }
            if (drawCommentButton) {
                totalHeight += AndroidUtilities.dp(shouldDrawTimeOnMedia() ? 41.3f : 43);
                createSelectorDrawable(1);
            }
            if (drawPinnedBottom && drawPinnedTop) {
                totalHeight -= AndroidUtilities.dp(2);
            } else if (drawPinnedBottom) {
                totalHeight -= AndroidUtilities.dp(1);
            } else if (drawPinnedTop && pinnedBottom && currentPosition != null && currentPosition.siblingHeights == null) {
                totalHeight -= AndroidUtilities.dp(1);
            }
            if (!mediaBackground) {
                if (messageObject.type == MessageObject.TYPE_TEXT) {
                    totalHeight -= AndroidUtilities.dp(2);
                }
                if (drawPinnedBottom) {
                    totalHeight -= AndroidUtilities.dp(1);
                }
                if (drawPinnedTop) {
                    totalHeight -= AndroidUtilities.dp(1);
                }
            }
            if (messageObject.type != MessageObject.TYPE_EMOJIS) {
                if (messageObject.isAnyKindOfSticker() && totalHeight < AndroidUtilities.dp(70)) {
                    additionalTimeOffsetY = AndroidUtilities.dp(70) - totalHeight;
                    totalHeight += additionalTimeOffsetY;
                } else if (messageObject.isAnimatedEmoji()) {
                    additionalTimeOffsetY = AndroidUtilities.dp(16);
                    totalHeight += AndroidUtilities.dp(16);
                }
            }
            if (!drawPhotoImage) {
                photoImage.setImageBitmap((Drawable) null);

                if (blurredPhotoImage.getBitmap() != null) {
                    blurredPhotoImage.getBitmap().recycle();
                    blurredPhotoImage.setImageBitmap((Bitmap) null);
                }
            }
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
                if (MessageObject.isDocumentHasThumb(documentAttach)) {
                    TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(documentAttach.thumbs, 90);
                    radialProgress.setImageOverlay(thumb, documentAttach, messageObject);
                } else {
                    String artworkUrl = messageObject.getArtworkUrl(true);
                    if (!TextUtils.isEmpty(artworkUrl)) {
                        radialProgress.setImageOverlay(artworkUrl);
                    } else {
                        radialProgress.setImageOverlay(null, null, null);
                    }
                }
            } else {
                radialProgress.setImageOverlay(null, null, null);
            }

            calculateUnlockXY();

            if (canChangeRadius) {
                int tl, tr, bl, br;
                int minRad = AndroidUtilities.dp(4);
                int rad;
                if (SharedConfig.bubbleRadius > 2) {
                    rad = AndroidUtilities.dp(SharedConfig.bubbleRadius - 2);
                } else {
                    rad = AndroidUtilities.dp(SharedConfig.bubbleRadius);
                }
                int nearRad = Math.min(AndroidUtilities.dp(3), rad);
                tl = tr = bl = br = rad;
                if (minRad > tl) {
                    minRad = tl;
                }
                if (hasLinkPreview || hasGamePreview || hasInvoicePreview) {
                    tl = tr = bl = br = minRad;
                }
                if (forwardedNameLayout[0] != null || replyNameLayout != null || drawNameLayout) {
                    tl = tr = minRad;
                }
                if (captionLayout != null || drawCommentButton) {
                    bl = br = minRad;
                }
                if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                    tr = br = minRad;
                }
                if (currentPosition != null && currentMessagesGroup != null) {
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0) {
                        tr = br = minRad;
                    }
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                        tl = bl = minRad;
                    }
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                        bl = br = minRad;
                    }
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                        tl = tr = minRad;
                    }
                }
                if (pinnedTop) {
                    if (currentMessageObject.isOutOwner()) {
                        tr = nearRad;
                    } else {
                        tl = nearRad;
                    }
                }
                if (pinnedBottom) {
                    if (currentMessageObject.isOutOwner()) {
                        br = nearRad;
                    } else {
                        bl = nearRad;
                    }
                }
                if (!mediaBackground && !currentMessageObject.isOutOwner()) {
                    bl = nearRad;
                }
                if (currentMessageObject.type == MessageObject.TYPE_GEO && MessageObject.getMedia(currentMessageObject) instanceof TLRPC.TL_messageMediaVenue) {
                    br = bl = nearRad;
                }
                photoImage.setRoundRadius(tl, tr, br, bl);
            }
            updateAnimatedEmojis();
        }
        if (messageIdChanged) {
            currentUrl = null;
            currentWebFile = null;
            lastWebFile = null;
            loadingProgressLayout = null;
            animatingLoadingProgressProgress = 0;
            lastLoadingSizeTotal = 0;
            selectedBackgroundProgress = 0f;
            if (statusDrawableAnimator != null) {
                statusDrawableAnimator.removeAllListeners();
                statusDrawableAnimator.cancel();
            }
            if (translationLoadingFloat != null) {
                translationLoadingFloat.set(0, true);
            }
            if (translationLoadingPath != null) {
                translationLoadingPath.reset();
                translationLoadingPath = null;
            }
            if (translationLoadingDrawable != null) {
                translationLoadingDrawable.reset();
                translationLoadingDrawable = null;
            }
            transitionParams.lastStatusDrawableParams = -1;
            statusDrawableAnimationInProgress = false;

            if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
                boolean showSeekbar = MediaController.getInstance().isPlayingMessage(currentMessageObject);
                toSeekBarProgress = showSeekbar ? 1f : 0f;
            }

            if (seekBar != null) {
                seekBar.updateTimestamps(currentMessageObject, null);
            }

            seekBarWaveform.setProgress(0);

            if (currentNameStatusDrawable != null) {
                currentNameStatusDrawable.play();
            }
        }
        if (transcribeButton != null) {
            transcribeButton.setOpen(currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.voiceTranscriptionOpen && currentMessageObject.messageOwner.voiceTranscriptionFinal && TranscribeButton.isVideoTranscriptionOpen(currentMessageObject), !messageIdChanged);
            transcribeButton.setLoading(TranscribeButton.isTranscribing(currentMessageObject), !messageIdChanged);
        }
        updateWaveform();
        updateButtonState(false, !messageIdChanged && !messageObject.cancelEditing, true);

        if (!currentMessageObject.loadingCancelled && buttonState == 2 && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO && DownloadController.getInstance(currentAccount).canDownloadMedia(messageObject)) {
            FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL, 0);
            buttonState = 4;
            radialProgress.setIcon(getIconForCurrentState(), false, false);
        }

        if (delegate != null && delegate.getTextSelectionHelper() != null && !messageIdChanged && messageChanged && messageObject != null) {
            delegate.getTextSelectionHelper().checkDataChanged(messageObject);
        }
        accessibilityVirtualViewBounds.clear();
        transitionParams.updatePhotoImageX = true;

        updateFlagSecure();
    }

    private boolean loopStickers() {
        return LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_STICKERS_CHAT);
    }

    private void highlightCaptionLink(URLSpan link) {
        try {
            if (link != null && captionLayout != null && captionLayout.getText() instanceof Spanned) {
                if (link == highlightPathSpan) {
                    return;
                }
                highlightPathSpan = link;
                Spanned caption = (Spanned) captionLayout.getText();
                int start = caption.getSpanStart(highlightPathSpan);
                int end = caption.getSpanEnd(highlightPathSpan);
                if (highlightPath != null) {
                    highlightPath.rewind();
                } else {
                    highlightPath = new LinkPath(true);
                }
                highlightPath.setCurrentLayout(captionLayout, start, 0);
                captionLayout.getSelectionPath(start, end, highlightPath);
                highlightPathStart = System.currentTimeMillis();
                invalidate();
            }
        } catch (Exception e) {
            FileLog.e(e);
        }
    }

    private void calculateUnlockXY() {
        if (currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW && unlockLayout != null) {
            unlockX = backgroundDrawableLeft + (photoImage.getImageWidth() - unlockLayout.getWidth()) / 2f;
            unlockY = backgroundDrawableTop + photoImage.getImageY() + (photoImage.getImageHeight() - unlockLayout.getHeight()) / 2f;
        }
    }

    private void updateFlagSecure() {
        if (flagSecure == null) {
            Activity activity = AndroidUtilities.findActivity(getContext());
            Window window = activity == null ? null : activity.getWindow();
            if (window != null) {
                flagSecure = new FlagSecureReason(window, () -> currentMessageObject != null && currentMessageObject.messageOwner != null && (currentMessageObject.messageOwner.noforwards || currentMessageObject.hasRevealedExtendedMedia()));
                if (attachedToWindow) {
                    flagSecure.attach();
                }
            }
        }
        if (flagSecure != null) {
            flagSecure.invalidate();
        }
    }

    public void checkVideoPlayback(boolean allowStart, Bitmap thumb) {
        if (currentMessageObject.isVideo()) {
            if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                photoImage.setAllowStartAnimation(false);
                photoImage.stopAnimation();
            } else {
                photoImage.setAllowStartAnimation(true);
                photoImage.startAnimation();
            }
        } else {
            if (allowStart) {
                MessageObject playingMessage = MediaController.getInstance().getPlayingMessageObject();
                allowStart = playingMessage == null || !playingMessage.isRoundVideo();
            }
            photoImage.setAllowStartAnimation(allowStart);
            if (thumb != null) {
                photoImage.startCrossfadeFromStaticThumb(thumb);

            }
            if (allowStart) {
                photoImage.startAnimation();
            } else {
                photoImage.stopAnimation();
            }

        }
    }

    private boolean hadLongPress = false;

    private static boolean spanSupportsLongPress(CharacterStyle span) {
        return span instanceof URLSpanMono || span instanceof URLSpan;
    }

    @Override
    protected boolean onLongPress() {
        if (isRoundVideo && isPlayingRound && MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
            float touchRadius = (lastTouchX - photoImage.getCenterX()) * (lastTouchX - photoImage.getCenterX()) + (lastTouchY - photoImage.getCenterY()) * (lastTouchY - photoImage.getCenterY());
            float r1 = (photoImage.getImageWidth() / 2f) * (photoImage.getImageWidth() / 2f);
            if (touchRadius < r1 && (lastTouchX > photoImage.getCenterX() + photoImage.getImageWidth() / 4f || lastTouchX < photoImage.getCenterX() - photoImage.getImageWidth() / 4f)) {
                boolean forward = lastTouchX > photoImage.getCenterX();
                if (videoPlayerRewinder == null) {
                    videoForwardDrawable = new VideoForwardDrawable(true);
                    videoPlayerRewinder = new VideoPlayerRewinder() {
                        @Override
                        protected void onRewindCanceled() {
                            onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0));
                            videoForwardDrawable.setShowing(false);
                        }

                        @Override
                        protected void updateRewindProgressUi(long timeDiff, float progress, boolean rewindByBackSeek) {
                            videoForwardDrawable.setTime(Math.abs(timeDiff));
                            if (rewindByBackSeek) {
                                currentMessageObject.audioProgress = progress;
                                updatePlayingMessageProgress();
                            }
                        }

                        @Override
                        protected void onRewindStart(boolean rewindForward) {
                            videoForwardDrawable.setDelegate(new VideoForwardDrawable.VideoForwardDrawableDelegate() {
                                @Override
                                public void onAnimationEnd() {

                                }

                                @Override
                                public void invalidate() {
                                    ChatMessageCell.this.invalidate();
                                }
                            });
                            videoForwardDrawable.setOneShootAnimation(false);
                            videoForwardDrawable.setLeftSide(!rewindForward);
                            videoForwardDrawable.setShowing(true);
                            invalidate();
                        }
                    };
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                videoPlayerRewinder.startRewind(MediaController.getInstance().getVideoPlayer(), forward, MediaController.getInstance().getPlaybackSpeed(false));
                return false;
            }
        }
        if (replySelector != null) {
            replySelectorPressed = false;
            replySelector.setState(new int[]{});
            invalidate();
        }
        if (topicButton != null) {
            topicButton.resetClick();
        }
        if (pressedEmoji != null) {
//            hadLongPress = true;
//            if (delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
//                pressedEmoji = null;
//                resetPressedLink(-1);
//                return true;
//            }
            pressedEmoji = null;
        }
        if (pressedLink != null) {
            if (pressedLink.getSpan() instanceof URLSpanMono) {
                hadLongPress = true;
                delegate.didPressUrl(this, pressedLink.getSpan(), true);
                return true;
            } else if (pressedLink.getSpan() instanceof URLSpanNoUnderline) {
                URLSpanNoUnderline url = (URLSpanNoUnderline) pressedLink.getSpan();
                if (ChatActivity.isClickableLink(url.getURL()) || url.getURL().startsWith("/")) {
                    hadLongPress = true;
                    delegate.didPressUrl(this, pressedLink.getSpan(), true);
                    return true;
                }
            } else if (pressedLink.getSpan() instanceof URLSpan) {
                hadLongPress = true;
                delegate.didPressUrl(this, pressedLink.getSpan(), true);
                return true;
            }
        }
        resetPressedLink(-1);
        if (buttonPressed != 0 || miniButtonPressed != 0 || videoButtonPressed != 0 || pressedBotButton != -1) {
            buttonPressed = 0;
            miniButtonPressed = 0;
            videoButtonPressed = 0;
            pressedBotButton = -1;
            invalidate();
        }

        linkPreviewPressed = false;
        sideButtonPressed = false;
        imagePressed = false;
        timePressed = false;
        gamePreviewPressed = false;

        if (pressedVoteButton != -1 || pollHintPressed || psaHintPressed || instantPressed || otherPressed || commentButtonPressed) {
            instantPressed = commentButtonPressed = false;
            setInstantButtonPressed(false);
            pressedVoteButton = -1;
            pollHintPressed = false;
            psaHintPressed = false;
            otherPressed = false;
            if (Build.VERSION.SDK_INT >= 21) {
                for (int a = 0; a < selectorDrawable.length; a++) {
                    if (selectorDrawable[a] != null) {
                        selectorDrawable[a].setState(StateSet.NOTHING);
                    }
                }
            }
            invalidate();
        }
        if (delegate != null) {
            boolean handled = false;

            if (avatarPressed) {
                if (currentUser != null) {
                    if (currentUser.id != 0) {
                        handled = delegate.didLongPressUserAvatar(this, currentUser, lastTouchX, lastTouchY);
                    }
                } else if (currentChat != null) {
                    final int id;
                    if (currentMessageObject.messageOwner.fwd_from != null) {
                        if ((currentMessageObject.messageOwner.fwd_from.flags & 16) != 0) {
                            id = currentMessageObject.messageOwner.fwd_from.saved_from_msg_id;
                        } else {
                            id = currentMessageObject.messageOwner.fwd_from.channel_post;
                        }
                    } else {
                        id = 0;
                    }
                    handled = delegate.didLongPressChannelAvatar(this, currentChat, id, lastTouchX, lastTouchY);
                }
            }

            if (!handled) {
                delegate.didLongPress(this, lastTouchX, lastTouchY);
            }
        }
        return true;
    }

    public void showHintButton(boolean show, boolean animated, int type) {
        if (type == -1 || type == 0) {
            if (hintButtonVisible == show) {
                return;
            }
            hintButtonVisible = show;
            if (!animated) {
                hintButtonProgress = show ? 1.0f : 0.0f;
            } else {
                invalidate();
            }
        }
        if (type == -1 || type == 1) {
            if (psaButtonVisible == show) {
                return;
            }
            psaButtonVisible = show;
            if (!animated) {
                psaButtonProgress = show ? 1.0f : 0.0f;
            } else {
                setInvalidatesParent(true);
                invalidate();
            }
        }
    }

    public void setCheckPressed(boolean value, boolean pressed) {
        isCheckPressed = value;
        isPressed = pressed;
        updateRadialProgressBackground();
        if (useSeekBarWaveform) {
            seekBarWaveform.setSelected(isDrawSelectionBackground());
        } else {
            seekBar.setSelected(isDrawSelectionBackground());
        }
        invalidate();
    }

    public void setInvalidateSpoilersParent(boolean invalidateSpoilersParent) {
        this.invalidateSpoilersParent = invalidateSpoilersParent;
    }

    public void setInvalidatesParent(boolean value) {
        invalidatesParent = value;
    }

    private boolean invalidateParentForce() {
        return (
            !links.isEmpty() ||
            !reactionsLayoutInBubble.isEmpty
        );
    }

    public void invalidateOutbounds() {
        if (delegate == null || !delegate.canDrawOutboundsContent()) {
            if (getParent() instanceof View) {
                ((View) getParent()).invalidate();
            }
        } else {
            super.invalidate();
        }
    }

    @Override
    public void invalidate() {
        if (currentMessageObject == null) {
            return;
        }
        super.invalidate();
        if ((invalidatesParent || currentMessagesGroup != null && invalidateParentForce()) && getParent() != null) {
            View parent = (View) getParent();
            if (parent.getParent() != null) {
                parent.invalidate();
                parent = (View) parent.getParent();
                parent.invalidate();
            }
        }
        if (isBlurred && delegate != null) {
            delegate.invalidateBlur();
        }
    }


    @Override
    public void invalidate(int l, int t, int r, int b) {
        if (currentMessageObject == null) {
            return;
        }
        super.invalidate(l, t, r, b);
        if (invalidatesParent) {
            if (getParent() != null) {
                View parent = (View) getParent();
                parent.invalidate((int) getX() + l, (int) getY() + t, (int) getX() + r, (int) getY() + b);
            }
        }
        if (isBlurred && delegate != null) {
            delegate.invalidateBlur();
        }
    }

    public boolean isHighlightedAnimated() {
        return isHighlightedAnimated;
    }

    public void setHighlightedAnimated() {
        isHighlightedAnimated = true;
        highlightProgress = 1000;
        lastHighlightProgressTime = System.currentTimeMillis();
        invalidate();
        if (getParent() != null) {
            ((View) getParent()).invalidate();
        }
    }

    public boolean isHighlighted() {
        return isHighlighted;
    }

    public void setHighlighted(boolean value) {
        if (isHighlighted == value) {
            return;
        }
        isHighlighted = value;
        if (!isHighlighted) {
            lastHighlightProgressTime = System.currentTimeMillis();
            isHighlightedAnimated = true;
            highlightProgress = 300;
        } else {
            isHighlightedAnimated = false;
            highlightProgress = 0;
        }

        updateRadialProgressBackground();
        if (useSeekBarWaveform) {
            seekBarWaveform.setSelected(isDrawSelectionBackground());
        } else {
            seekBar.setSelected(isDrawSelectionBackground());
        }
        invalidate();
        if (getParent() != null) {
            ((View) getParent()).invalidate();
        }
    }

    @Override
    public void setPressed(boolean pressed) {
        super.setPressed(pressed);
        updateRadialProgressBackground();
        if (useSeekBarWaveform) {
            seekBarWaveform.setSelected(isDrawSelectionBackground());
        } else {
            seekBar.setSelected(isDrawSelectionBackground());
        }
        invalidate();
    }

    private void updateRadialProgressBackground() {
        if (drawRadialCheckBackground) {
            return;
        }
        boolean forcePressed = (isHighlighted || isPressed || isPressed()) && (!drawPhotoImage || !photoImage.hasBitmapImage());
        radialProgress.setPressed(forcePressed || buttonPressed != 0, false);
        if (hasMiniProgress != 0) {
            radialProgress.setPressed(forcePressed || miniButtonPressed != 0, true);
        }
        videoRadialProgress.setPressed(forcePressed || videoButtonPressed != 0, false);
    }

    @Override
    public void onSeekBarPressed() {
        requestDisallowInterceptTouchEvent(true);
    }

    @Override
    public void onSeekBarReleased() {
        requestDisallowInterceptTouchEvent(false);
    }

    @Override
    public void onSeekBarDrag(float progress) {
        if (currentMessageObject == null) {
            return;
        }
        currentMessageObject.audioProgress = progress;
        MediaController.getInstance().seekToProgress(currentMessageObject, progress);
        updatePlayingMessageProgress();
    }

    @Override
    public void onSeekBarContinuousDrag(float progress) {
        if (currentMessageObject == null) {
            return;
        }
        currentMessageObject.audioProgress = progress;
        currentMessageObject.audioProgressSec = (int) (currentMessageObject.getDuration() * progress);
        updatePlayingMessageProgress();
    }

    public boolean isAnimatingPollAnswer() {
        return animatePollAnswerAlpha;
    }

    private void updateWaveform() {
        if (currentMessageObject == null || documentAttachType != DOCUMENT_ATTACH_TYPE_AUDIO && documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND) {
            return;
        }
        byte[] waveform = currentMessageObject.getWaveform();
        useSeekBarWaveform = waveform != null;
        if (seekBarWaveform != null) {
            seekBarWaveform.setWaveform(waveform);
        }
        useTranscribeButton = (
            currentMessageObject != null &&
            (!currentMessageObject.isOutOwner() || currentMessageObject.isSent()) &&
            (
                UserConfig.getInstance(currentAccount).isPremium() ||
                !MessagesController.getInstance(currentAccount).didPressTranscribeButtonEnough() && !currentMessageObject.isOutOwner() && (
                    currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.voiceTranscriptionForce ||
                    currentMessageObject.getDuration() >= 60
                ) && !MessagesController.getInstance(currentAccount).premiumLocked
            ) && (
                currentMessageObject.isVoice() && useSeekBarWaveform ||
                currentMessageObject.isRoundVideo()
            ) && currentMessageObject.messageOwner != null && !(MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaWebPage)
        );
        updateSeekBarWaveformWidth(null);
    }

    private int seekBarWaveformTranslateX;
    private int seekBarTranslateX;

    private void updateSeekBarWaveformWidth(Canvas canvas) {
        seekBarWaveformTranslateX = 0;
        seekBarTranslateX = 0;
        int offset = -AndroidUtilities.dp(92 + (hasLinkPreview ? 10 : 0));
        if (transitionParams.animateBackgroundBoundsInner && (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND)) {
            int fromBackgroundWidth = this.backgroundWidth;
            int toBackgroundWidth = (int) (this.backgroundWidth - transitionParams.toDeltaLeft + transitionParams.toDeltaRight);
            int backgroundWidth = (int) (this.backgroundWidth - transitionParams.deltaLeft + transitionParams.deltaRight);
            if (isRoundVideo && !drawBackground) {
                backgroundWidth += getVideoTranscriptionProgress() * AndroidUtilities.dp(8);
                toBackgroundWidth += AndroidUtilities.dp(8);
            }
            if (!(transitionParams.toDeltaLeft != 0 || transitionParams.toDeltaRight != 0)) {
                toBackgroundWidth = backgroundWidth;
            }
            if (seekBarWaveform != null) {
                if (transitionParams.animateUseTranscribeButton) {
                    seekBarWaveform.setSize(
                        backgroundWidth + offset - (int) (AndroidUtilities.dp(34) * getUseTranscribeButtonProgress()),
                        AndroidUtilities.dp(30),
                        fromBackgroundWidth + offset + (!useTranscribeButton ? -AndroidUtilities.dp(34) : 0),
                        toBackgroundWidth + offset + (useTranscribeButton ? -AndroidUtilities.dp(34) : 0)
                    );
                } else {
                    seekBarWaveform.setSize(
                        backgroundWidth + offset - (int) (AndroidUtilities.dp(34) * getUseTranscribeButtonProgress()),
                        AndroidUtilities.dp(30),
                        fromBackgroundWidth + offset - (int) (AndroidUtilities.dp(34) * getUseTranscribeButtonProgress()),
                        toBackgroundWidth + offset - (int) (AndroidUtilities.dp(34) * getUseTranscribeButtonProgress())
                    );
                }
            }
            if (seekBar != null) {
                seekBar.setSize(backgroundWidth - (int) (getUseTranscribeButtonProgress() * AndroidUtilities.dp(34)) - AndroidUtilities.dp((documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC ? 65 : 72) + (hasLinkPreview ? 10 : 0)), AndroidUtilities.dp(30));
            }
        } else {
            if (seekBarWaveform != null) {
                if (transitionParams.animateUseTranscribeButton) {
                    seekBarWaveform.setSize(
                        backgroundWidth + offset - (int) (AndroidUtilities.dp(34) * getUseTranscribeButtonProgress()),
                        AndroidUtilities.dp(30),
                        backgroundWidth + offset + (!useTranscribeButton ? -AndroidUtilities.dp(34) : 0),
                        backgroundWidth + offset + (useTranscribeButton ? -AndroidUtilities.dp(34) : 0)
                    );
                } else {
                    seekBarWaveform.setSize(
                        backgroundWidth + offset - (int) (AndroidUtilities.dp(34) * getUseTranscribeButtonProgress()),
                        AndroidUtilities.dp(30)
                    );
                }
            }
            if (seekBar != null) {
                seekBar.setSize(backgroundWidth - (int) (getUseTranscribeButtonProgress() * AndroidUtilities.dp(34)) - AndroidUtilities.dp((documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC ? 65 : 72) + (hasLinkPreview ? 10 : 0)), AndroidUtilities.dp(30));
            }
        }
    }

    private int createDocumentLayout(int maxWidth, MessageObject messageObject) {
        if (messageObject.type == MessageObject.TYPE_TEXT) {
            documentAttach = MessageObject.getMedia(messageObject.messageOwner).webpage.document;
        } else {
            documentAttach = messageObject.getDocument();
        }
        if (documentAttach == null) {
            return 0;
        }
        if (MessageObject.isVoiceDocument(documentAttach)) {
            documentAttachType = DOCUMENT_ATTACH_TYPE_AUDIO;
            int duration = 0;
            for (int a = 0; a < documentAttach.attributes.size(); a++) {
                TLRPC.DocumentAttribute attribute = documentAttach.attributes.get(a);
                if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
                    duration = attribute.duration;
                    break;
                }
            }
            widthBeforeNewTimeLine = maxWidth - AndroidUtilities.dp(76 + 18) - (int) Math.ceil(Theme.chat_audioTimePaint.measureText("00:00"));
            availableTimeWidth = maxWidth - AndroidUtilities.dp(18);
            measureTime(messageObject);
            int minSize = AndroidUtilities.dp(40 + 14 + 20 + 90 + 10) + timeWidth;
            if (!hasLinkPreview) {
                String timeString = AndroidUtilities.formatLongDuration(duration);
                int w = (int) Math.ceil(Theme.chat_audioTimePaint.measureText(timeString));
                backgroundWidth = Math.min(maxWidth, minSize + w);
            }
            seekBarWaveform.setMessageObject(messageObject);
            return 0;
        } else if (MessageObject.isVideoDocument(documentAttach)) {
            documentAttachType = DOCUMENT_ATTACH_TYPE_VIDEO;
            if (!messageObject.needDrawBluredPreview()) {
                updatePlayingMessageProgress();
                String str;
                str = String.format("%s", AndroidUtilities.formatFileSize(documentAttach.size));
                docTitleWidth = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
                docTitleLayout = new StaticLayout(str, Theme.chat_infoPaint, docTitleWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            }
            return 0;
        } else if (MessageObject.isMusicDocument(documentAttach)) {
            documentAttachType = DOCUMENT_ATTACH_TYPE_MUSIC;

            maxWidth = maxWidth - AndroidUtilities.dp(92);
            if (maxWidth < 0) {
                maxWidth = AndroidUtilities.dp(100);
            }

            CharSequence stringFinal = TextUtils.ellipsize(messageObject.getMusicTitle().replace('\n', ' '), Theme.chat_audioTitlePaint, maxWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
            songLayout = new StaticLayout(stringFinal, Theme.chat_audioTitlePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            if (songLayout.getLineCount() > 0) {
                songX = -(int) Math.ceil(songLayout.getLineLeft(0));
            }

            stringFinal = TextUtils.ellipsize(messageObject.getMusicAuthor().replace('\n', ' '), Theme.chat_audioPerformerPaint, maxWidth, TextUtils.TruncateAt.END);
            performerLayout = new StaticLayout(stringFinal, Theme.chat_audioPerformerPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            if (performerLayout.getLineCount() > 0) {
                performerX = -(int) Math.ceil(performerLayout.getLineLeft(0));
            }

            int duration = 0;
            for (int a = 0; a < documentAttach.attributes.size(); a++) {
                TLRPC.DocumentAttribute attribute = documentAttach.attributes.get(a);
                if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
                    duration = attribute.duration;
                    break;
                }
            }
            int durationWidth = (int) Math.ceil(Theme.chat_audioTimePaint.measureText(AndroidUtilities.formatShortDuration(duration, duration)));
            widthBeforeNewTimeLine = backgroundWidth - AndroidUtilities.dp(10 + 76) - durationWidth;
            availableTimeWidth = backgroundWidth - AndroidUtilities.dp(28);
            return durationWidth;
        } else if (MessageObject.isGifDocument(documentAttach, messageObject.hasValidGroupId())) {
            documentAttachType = DOCUMENT_ATTACH_TYPE_GIF;
            if (!messageObject.needDrawBluredPreview()) {

                String str = LocaleController.getString("AttachGif", R.string.AttachGif);
                infoWidth = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
                infoLayout = new StaticLayout(str, Theme.chat_infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

                str = String.format("%s", AndroidUtilities.formatFileSize(documentAttach.size));
                docTitleWidth = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
                docTitleLayout = new StaticLayout(str, Theme.chat_infoPaint, docTitleWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            }
            return 0;
        } else {
            drawPhotoImage = documentAttach.mime_type != null && (documentAttach.mime_type.toLowerCase().startsWith("image/") || documentAttach.mime_type.toLowerCase().startsWith("video/mp4")) || MessageObject.isDocumentHasThumb(documentAttach);
            if (!drawPhotoImage) {
                maxWidth += AndroidUtilities.dp(30);
            }
            documentAttachType = DOCUMENT_ATTACH_TYPE_DOCUMENT;
            String name = FileLoader.getDocumentFileName(documentAttach);
            if (name.length() == 0) {
                name = LocaleController.getString("AttachDocument", R.string.AttachDocument);
            }
            docTitleLayout = StaticLayoutEx.createStaticLayout(name, Theme.chat_docNamePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.MIDDLE, maxWidth, 2, false);
            docTitleOffsetX = Integer.MIN_VALUE;
            int width;
            if (docTitleLayout != null && docTitleLayout.getLineCount() > 0) {
                int maxLineWidth = 0;
                for (int a = 0; a < docTitleLayout.getLineCount(); a++) {
                    maxLineWidth = Math.max(maxLineWidth, (int) Math.ceil(docTitleLayout.getLineWidth(a)));
                    docTitleOffsetX = Math.max(docTitleOffsetX, (int) Math.ceil(-docTitleLayout.getLineLeft(a)));
                }
                width = Math.min(maxWidth, maxLineWidth);
            } else {
                width = maxWidth;
                docTitleOffsetX = 0;
            }

            String str = AndroidUtilities.formatFileSize(documentAttach.size) + " " + FileLoader.getDocumentExtension(documentAttach);
            infoWidth = Math.min(maxWidth - AndroidUtilities.dp(30), (int) Math.ceil(Theme.chat_infoPaint.measureText("000.0 mm / " + AndroidUtilities.formatFileSize(documentAttach.size))));
            CharSequence str2 = TextUtils.ellipsize(str, Theme.chat_infoPaint, infoWidth, TextUtils.TruncateAt.END);
            try {
                if (infoWidth < 0) {
                    infoWidth = AndroidUtilities.dp(10);
                }
                infoLayout = new StaticLayout(str2, Theme.chat_infoPaint, infoWidth + AndroidUtilities.dp(6), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            } catch (Exception e) {
                FileLog.e(e);
            }

            if (drawPhotoImage) {
                currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 320);
                currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);

                if ((DownloadController.getInstance(currentAccount).getAutodownloadMask() & DownloadController.AUTODOWNLOAD_TYPE_PHOTO) == 0) {
                    currentPhotoObject = null;
                }
                if (currentPhotoObject == null || currentPhotoObject == currentPhotoObjectThumb) {
                    currentPhotoObject = null;
                    photoImage.setNeedsQualityThumb(true);
                    photoImage.setShouldGenerateQualityThumb(true);
                } else if (currentMessageObject.strippedThumb != null) {
                    currentPhotoObjectThumb = null;
                    currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
                }
                currentPhotoFilter = "86_86_b";
                photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "86_86", ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), currentPhotoFilter, currentPhotoObjectThumbStripped, 0, null, messageObject, 1);
            }
            return width;
        }
    }

    //计算背景大小，如果忽略时间以及回执状态，将timeMore设为0
    private void calcBackgroundWidth(int maxWidth, int timeMore, int maxChildWidth) {
        boolean newLineForTime;
        //最后一行宽度
        int lastLineWidth = (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) ? currentMessageObject.lastLineWidth : reactionsLayoutInBubble.lastLineX;
        if (!reactionsLayoutInBubble.isEmpty && !reactionsLayoutInBubble.isSmall) {
            newLineForTime = maxWidth - lastLineWidth < timeMore || currentMessageObject.hasRtl;
            if (hasInvoicePreview) {
                totalHeight += AndroidUtilities.dp(14);
            }
        } else {
            newLineForTime = hasLinkPreview || hasOldCaptionPreview || hasGamePreview || hasInvoicePreview || maxWidth - lastLineWidth < timeMore || currentMessageObject.hasRtl;
        }

        //是否为了时间新起一行
        if (newLineForTime) {
            totalHeight += AndroidUtilities.dp(14);
            hasNewLineForTime = true;
            backgroundWidth = Math.max(maxChildWidth, lastLineWidth) + AndroidUtilities.dp(31);
            backgroundWidth = Math.max(backgroundWidth, (currentMessageObject.isOutOwner() ? timeWidth + AndroidUtilities.dp(17) : timeWidth) + AndroidUtilities.dp(31));
        } else {
            int diff = maxChildWidth - getExtraTextX() - lastLineWidth;
            if (diff >= 0 && diff <= timeMore) {
                backgroundWidth = maxChildWidth + timeMore - diff + AndroidUtilities.dp(31);
            } else {
                backgroundWidth = Math.max(maxChildWidth, lastLineWidth + timeMore) + AndroidUtilities.dp(31);
            }
        }
    }

    public void setHighlightedText(String text) {
        MessageObject messageObject = messageObjectToSet != null ? messageObjectToSet : currentMessageObject;
        if (messageObject == null || messageObject.messageOwner.message == null || TextUtils.isEmpty(text)) {
            if (!urlPathSelection.isEmpty()) {
                linkSelectionBlockNum = -1;
                resetUrlPaths();
                invalidate();
            }
            return;
        }
        text = text.toLowerCase();
        String message = messageObject.messageOwner.message.toLowerCase();
        int start = -1;
        int length = -1;
        String punctuationsChars = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\n";
        for (int a = 0, N1 = message.length(); a < N1; a++) {
            int currentLen = 0;
            for (int b = 0, N2 = Math.min(text.length(), N1 - a); b < N2; b++) {
                boolean match = message.charAt(a + b) == text.charAt(b);
                if (match) {
                    if (currentLen != 0 || a == 0 || punctuationsChars.indexOf(message.charAt(a - 1)) >= 0) {
                        currentLen++;
                    } else {
                        match = false;
                    }
                }
                if (!match || b == N2 - 1) {
                    if (currentLen > 0 && currentLen > length) {
                        length = currentLen;
                        start = a;
                    }
                    break;
                }
            }
        }
        if (start == -1) {
            if (!urlPathSelection.isEmpty()) {
                linkSelectionBlockNum = -1;
                resetUrlPaths();
                invalidate();
            }
            return;
        }
        for (int a = start + length, N = message.length(); a < N; a++) {
            if (punctuationsChars.indexOf(message.charAt(a)) < 0) {
                length++;
            } else {
                break;
            }
        }
        int end = start + length;
        if (captionLayout != null && !TextUtils.isEmpty(messageObject.caption)) {
            resetUrlPaths();
            try {
                LinkPath path = obtainNewUrlPath();
                path.setCurrentLayout(captionLayout, start, 0);
                captionLayout.getSelectionPath(start, end, path);
            } catch (Exception e) {
                FileLog.e(e);
            }
            invalidate();
        } else if (messageObject.textLayoutBlocks != null) {
            for (int c = 0; c < messageObject.textLayoutBlocks.size(); c++) {
                MessageObject.TextLayoutBlock block = messageObject.textLayoutBlocks.get(c);
                if (start >= block.charactersOffset && start < block.charactersEnd) {
                    linkSelectionBlockNum = c;
                    resetUrlPaths();
                    try {
                        LinkPath path = obtainNewUrlPath();
                        path.setCurrentLayout(block.textLayout, start, 0);
                        block.textLayout.getSelectionPath(start, end, path);
                        if (end >= block.charactersOffset + length) {
                            for (int a = c + 1; a < messageObject.textLayoutBlocks.size(); a++) {
                                MessageObject.TextLayoutBlock nextBlock = messageObject.textLayoutBlocks.get(a);
                                length = nextBlock.charactersEnd - nextBlock.charactersOffset;
                                path = obtainNewUrlPath();
                                path.setCurrentLayout(nextBlock.textLayout, 0, nextBlock.height);
                                nextBlock.textLayout.getSelectionPath(0, end - nextBlock.charactersOffset, path);
                                if (end < block.charactersOffset + length - 1) {
                                    break;
                                }
                            }
                        }
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                    invalidate();
                    break;
                }
            }
        }
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        return super.verifyDrawable(who) || who == selectorDrawable[0] || who == selectorDrawable[1];
    }

    @Override
    public void invalidateDrawable(Drawable drawable) {
        super.invalidateDrawable(drawable);
        if (currentMessagesGroup != null) {
            invalidateWithParent();
        }
    }

    private boolean isCurrentLocationTimeExpired(MessageObject messageObject) {
        if (MessageObject.getMedia(currentMessageObject.messageOwner).period % 60 == 0) {
            return Math.abs(ConnectionsManager.getInstance(currentAccount).getCurrentTime() - messageObject.messageOwner.date) > MessageObject.getMedia(messageObject.messageOwner).period;
        } else {
            return Math.abs(ConnectionsManager.getInstance(currentAccount).getCurrentTime() - messageObject.messageOwner.date) > MessageObject.getMedia(messageObject.messageOwner).period - 5;
        }
    }

    private void checkLocationExpired() {
        if (currentMessageObject == null) {
            return;
        }
        boolean newExpired = isCurrentLocationTimeExpired(currentMessageObject);
        if (newExpired != locationExpired) {
            locationExpired = newExpired;
            if (!locationExpired) {
                AndroidUtilities.runOnUIThread(invalidateRunnable, 1000);
                scheduledInvalidate = true;
                int maxWidth = backgroundWidth - AndroidUtilities.dp(37 + 54);
                docTitleLayout = new StaticLayout(TextUtils.ellipsize(LocaleController.getString("AttachLiveLocation", R.string.AttachLiveLocation), Theme.chat_locationTitlePaint, maxWidth, TextUtils.TruncateAt.END), Theme.chat_locationTitlePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            } else {
                MessageObject messageObject = currentMessageObject;
                currentMessageObject = null;
                setMessageObject(messageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
            }
        }
    }

    public void setIsUpdating(boolean value) {
        isUpdating = true;
    }

    public void setMessageObject(MessageObject messageObject, MessageObject.GroupedMessages groupedMessages, boolean bottomNear, boolean topNear) {
        if (attachedToWindow) {
            setMessageContent(messageObject, groupedMessages, bottomNear, topNear);
        } else {
            messageObjectToSet = messageObject;
            groupedMessagesToSet = groupedMessages;
            bottomNearToSet = bottomNear;
            topNearToSet = topNear;
        }
    }

    private int getAdditionalWidthForPosition(MessageObject.GroupedMessagePosition position) {
        int w = 0;
        if (position != null) {
            if ((position.flags & MessageObject.POSITION_FLAG_RIGHT) == 0) {
                w += AndroidUtilities.dp(4);
            }
            if ((position.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                w += AndroidUtilities.dp(4);
            }
        }
        return w;
    }

    public void createSelectorDrawable(int num) {
        if (Build.VERSION.SDK_INT < 21) {
            return;
        }
        int color;
        if (psaHintPressed) {
            color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outViews : Theme.key_chat_inViews);
        } else {
            color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewInstantText : Theme.key_chat_inPreviewInstantText);
        }
        if (selectorDrawable[num] == null) {
            final Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            maskPaint.setColor(0xffffffff);
            Drawable maskDrawable = new Drawable() {

                RectF rect = new RectF();
                Path path = new Path();

                @Override
                public void draw(Canvas canvas) {
                    android.graphics.Rect bounds = getBounds();
                    rect.set(bounds.left, bounds.top, bounds.right, bounds.bottom);
                    if (selectorDrawableMaskType[num] == 3 || selectorDrawableMaskType[num] == 4) {
                        canvas.drawCircle(rect.centerX(), rect.centerY(), AndroidUtilities.dp(selectorDrawableMaskType[num] == 3 ? 16 : 20), maskPaint);
                    } else if (selectorDrawableMaskType[num] == 2) {
                        path.reset();
                        boolean out = currentMessageObject != null && currentMessageObject.isOutOwner();
                        for (int a = 0; a < 4; a++) {
                            if (!instantTextNewLine) {
                                if (a == 2 && !out) {
                                    radii[a * 2] = radii[a * 2 + 1] = AndroidUtilities.dp(SharedConfig.bubbleRadius);
                                    continue;
                                } else if (a == 3 && out) {
                                    radii[a * 2] = radii[a * 2 + 1] = AndroidUtilities.dp(SharedConfig.bubbleRadius);
                                    continue;
                                }
                                if ((mediaBackground || pinnedBottom) && (a == 2 || a == 3)) {
                                    radii[a * 2] = radii[a * 2 + 1] = AndroidUtilities.dp(pinnedBottom ? Math.min(5, SharedConfig.bubbleRadius) : SharedConfig.bubbleRadius);
                                    continue;
                                }
                            }
                            radii[a * 2] = radii[a * 2 + 1] = 0;
                        }
                        if (!out && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL || pollInstantViewTouchesBottom)) {
                            path.moveTo(rect.left + AndroidUtilities.dp(6), rect.top);
                            path.lineTo(rect.left + AndroidUtilities.dp(6), rect.bottom - AndroidUtilities.dp(6) - AndroidUtilities.dp(2 + 3));
                            AndroidUtilities.rectTmp.set(
                                rect.left + AndroidUtilities.dp(7 - 12 - 2),
                                rect.bottom - AndroidUtilities.dp(12 + 2 + 9),
                                rect.left + AndroidUtilities.dp(8 - 2),
                                rect.bottom// - AndroidUtilities.dp(2 + 1)
                            );
                            path.arcTo(AndroidUtilities.rectTmp, 0, 83, false);
                            AndroidUtilities.rectTmp.set(rect.right - radii[4] * 2, rect.bottom - radii[5] * 2, rect.right, rect.bottom);
                            path.arcTo(AndroidUtilities.rectTmp, 90, -90, false);
                            path.lineTo(rect.right, rect.top);
                            path.close();
                        } else {
                            path.addRoundRect(rect, radii, Path.Direction.CW);
                        }
                        path.close();
                        canvas.drawPath(path, maskPaint);
                    } else {
                        canvas.drawRoundRect(rect, selectorDrawableMaskType[num] == 0 ? AndroidUtilities.dp(6) : 0, selectorDrawableMaskType[num] == 0 ? AndroidUtilities.dp(6) : 0, maskPaint);
                    }
                }

                @Override
                public void setAlpha(int alpha) {

                }

                @Override
                public void setColorFilter(ColorFilter colorFilter) {

                }

                @Override
                public int getOpacity() {
                    return PixelFormat.TRANSPARENT;
                }
            };
            ColorStateList colorStateList = new ColorStateList(
                    new int[][]{StateSet.WILD_CARD},
                    new int[]{getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewInstantText : Theme.key_chat_inPreviewInstantText) & 0x19ffffff}
            );
            selectorDrawable[num] = new RippleDrawable(colorStateList, null, maskDrawable);
            selectorDrawable[num].setCallback(this);
        } else {
            Theme.setSelectorDrawableColor(selectorDrawable[num], color & 0x19ffffff, true);
        }
        selectorDrawable[num].setVisible(true, false);
    }

    private void createInstantViewButton() {
        if (Build.VERSION.SDK_INT >= 21 && drawInstantView) {
            createSelectorDrawable(0);
        }
        if (drawInstantView && instantViewLayout == null) {
            String str;
            instantWidth = AndroidUtilities.dp(12 + 9 + 12);
            if (drawInstantViewType == 12) {
                str = LocaleController.getString("OpenChannelPost", R.string.OpenChannelPost);
            } else if (drawInstantViewType == 1) {
                str = LocaleController.getString("OpenChannel", R.string.OpenChannel);
            } else if (drawInstantViewType == 13) {
                str = LocaleController.getString("SendMessage", R.string.SendMessage).toUpperCase();
            } else if (drawInstantViewType == 10) {
                str = LocaleController.getString("OpenBot", R.string.OpenBot);
            } else if (drawInstantViewType == 2) {
                str = LocaleController.getString("OpenGroup", R.string.OpenGroup);
            } else if (drawInstantViewType == 3) {
                str = LocaleController.getString("OpenMessage", R.string.OpenMessage);
            } else if (drawInstantViewType == 5) {
                str = LocaleController.getString("ViewContact", R.string.ViewContact);
            } else if (drawInstantViewType == 6) {
                str = LocaleController.getString("OpenBackground", R.string.OpenBackground);
            } else if (drawInstantViewType == 7) {
                str = LocaleController.getString("OpenTheme", R.string.OpenTheme);
            } else if (drawInstantViewType == 8) {
                if (pollVoted || pollClosed) {
                    str = LocaleController.getString("PollViewResults", R.string.PollViewResults);
                } else {
                    str = LocaleController.getString("PollSubmitVotes", R.string.PollSubmitVotes);
                }
            } else if (drawInstantViewType == 9 || drawInstantViewType == 11) {
                TLRPC.TL_webPage webPage = (TLRPC.TL_webPage) MessageObject.getMedia(currentMessageObject.messageOwner).webpage;
                if (webPage != null && webPage.url.contains("voicechat=")) {
                    str = LocaleController.getString("VoipGroupJoinAsSpeaker", R.string.VoipGroupJoinAsSpeaker);
                } else {
                    str = LocaleController.getString("VoipGroupJoinAsLinstener", R.string.VoipGroupJoinAsLinstener);
                }
            } else {
                str = LocaleController.getString("InstantView", R.string.InstantView);
            }
            if (currentMessageObject.isSponsored()) {
                int buttonWidth = (int) (Theme.chat_instantViewPaint.measureText(str) + AndroidUtilities.dp(10 + 24 + 10 + 31));
                if (backgroundWidth < buttonWidth) {
                    backgroundWidth = buttonWidth;
                }
            }
            int mWidth = backgroundWidth - AndroidUtilities.dp(10 + 24 + 10 + 31);
            instantViewLayout = new StaticLayout(TextUtils.ellipsize(str, Theme.chat_instantViewPaint, mWidth, TextUtils.TruncateAt.END), Theme.chat_instantViewPaint, mWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            if (drawInstantViewType == 8) {
                instantWidth = backgroundWidth - AndroidUtilities.dp(13);
            } else {
                instantWidth = backgroundWidth - AndroidUtilities.dp(34);
            }
            totalHeight += AndroidUtilities.dp(46);
            if (currentMessageObject.type == MessageObject.TYPE_CONTACT) {
                totalHeight += AndroidUtilities.dp(14);
            }
            if (currentMessageObject.isSponsored() && hasNewLineForTime) {
                totalHeight += AndroidUtilities.dp(16);
            }
            if (instantViewLayout != null && instantViewLayout.getLineCount() > 0) {
                instantTextX = (int) (instantWidth - Math.ceil(instantViewLayout.getLineWidth(0))) / 2 + (drawInstantViewType == 0 ? AndroidUtilities.dp(8) : 0);
                instantTextLeftX = (int) instantViewLayout.getLineLeft(0);
                instantTextX += -instantTextLeftX;
            }
        }
    }

    @Override
    public void requestLayout() {
        if (inLayout) {
            return;
        }
        super.requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (currentMessageObject != null && (currentMessageObject.checkLayout() || lastHeight != AndroidUtilities.displaySize.y)) {
            inLayout = true;
            MessageObject messageObject = currentMessageObject;
            currentMessageObject = null;
            setMessageObject(messageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
            inLayout = false;
        }
        updateSelectionTextPosition();
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), totalHeight + keyboardHeight);
    }

    public void forceResetMessageObject() {
        MessageObject messageObject = messageObjectToSet != null ? messageObjectToSet : currentMessageObject;
        currentMessageObject = null;
        setMessageObject(messageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
    }

    private int getGroupPhotosWidth() {
        int width = getParentWidth();
        if (currentMessageObject != null && currentMessageObject.preview) {
            width = parentWidth;
        }
        if (!AndroidUtilities.isInMultiwindow && AndroidUtilities.isTablet() && (!AndroidUtilities.isSmallTablet() || getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)) {
            int leftWidth = width / 100 * 35;
            if (leftWidth < AndroidUtilities.dp(320)) {
                leftWidth = AndroidUtilities.dp(320);
            }
            return width - leftWidth;
        } else {
            return width;
        }
    }

    //聊天弹窗边框
    private int getExtraTextX() {
        if (SharedConfig.bubbleRadius >= 15) {
            return AndroidUtilities.dp(2);
        } else if (SharedConfig.bubbleRadius >= 11) {
            return AndroidUtilities.dp(1);
        }
        return 0;
    }

    private int getExtraTimeX() {
        if (!currentMessageObject.isOutOwner() && (!mediaBackground || captionLayout != null) && SharedConfig.bubbleRadius > 11) {
            return AndroidUtilities.dp((SharedConfig.bubbleRadius - 11) / 1.5f);
        }
        if (!currentMessageObject.isOutOwner() && isPlayingRound && isAvatarVisible && currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
            return (int) ((AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f);
        }
        return 0;
    }

    int lastSize;

    @SuppressLint("DrawAllocation")
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (currentMessageObject == null) {
            return;
        }
        int currentSize = getMeasuredHeight() + (getMeasuredWidth() << 16);
        if (lastSize != currentSize || !wasLayout) {
            layoutWidth = getMeasuredWidth();
            layoutHeight = getMeasuredHeight() - substractBackgroundHeight;
            if (timeTextWidth < 0) {
                timeTextWidth = AndroidUtilities.dp(10);
            }
            timeLayout = new StaticLayout(currentTimeString, Theme.chat_timePaint, timeTextWidth + AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            if (mediaBackground) {
                if (currentMessageObject.isOutOwner()) {
                    timeX = layoutWidth - timeWidth - AndroidUtilities.dp(42.0f);
                } else {
                    timeX = backgroundWidth - AndroidUtilities.dp(4) - timeWidth;
                    if (currentMessageObject.isAnyKindOfSticker()) {
                        timeX = Math.max(AndroidUtilities.dp(26), timeX);
                    }
                    if (isAvatarVisible) {
                        timeX += AndroidUtilities.dp(48);
                    }
                    if (currentPosition != null && currentPosition.leftSpanOffset != 0) {
                        timeX += (int) Math.ceil(currentPosition.leftSpanOffset / 1000.0f * getGroupPhotosWidth());
                    }
                    if (captionLayout != null && currentPosition != null) {
                        timeX += AndroidUtilities.dp(4);
                    }
                }
                if (SharedConfig.bubbleRadius >= 10 && captionLayout == null && documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER) {
                    timeX -= AndroidUtilities.dp(2);
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    timeX = layoutWidth - timeWidth - AndroidUtilities.dp(38.5f);
                } else {
                    timeX = backgroundWidth - AndroidUtilities.dp(9) - timeWidth;
                    if (currentMessageObject.isAnyKindOfSticker()) {
                        timeX = Math.max(0, timeX);
                    }
                    if (isAvatarVisible) {
                        timeX += AndroidUtilities.dp(48);
                    }
                    if (shouldDrawTimeOnMedia()) {
                        timeX -= AndroidUtilities.dp(7);
                    }
                }
            }
            timeX -= getExtraTimeX();

            if ((currentMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
                viewsLayout = new StaticLayout(currentViewsString, Theme.chat_timePaint, viewsTextWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            } else {
                viewsLayout = null;
            }

            if (currentRepliesString != null && !currentMessageObject.scheduled) {
                repliesLayout = new StaticLayout(currentRepliesString, Theme.chat_timePaint, repliesTextWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            } else {
                repliesLayout = null;
            }

            if (isAvatarVisible) {
                avatarImage.setImageCoords(AndroidUtilities.dp(6), avatarImage.getImageY(), AndroidUtilities.dp(42), AndroidUtilities.dp(42));
            }

            if (currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW && currentUnlockString != null) {
                unlockLayout = new StaticLayout(currentUnlockString, Theme.chat_unlockExtendedMediaTextPaint, unlockTextWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);

                TLRPC.TL_messageExtendedMediaPreview preview = (TLRPC.TL_messageExtendedMediaPreview) currentMessageObject.messageOwner.media.extended_media;
                if (preview.video_duration != 0) {
                    String str = AndroidUtilities.formatDuration(preview.video_duration, false);
                    durationWidth = (int) Math.ceil(Theme.chat_durationPaint.measureText(str));
                    videoInfoLayout = new StaticLayout(str, Theme.chat_durationPaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                } else {
                    videoInfoLayout = null;
                }
            } else {
                unlockLayout = null;
            }

            wasLayout = true;
        }
        lastSize = currentSize;

        if (currentMessageObject.type == MessageObject.TYPE_TEXT) {
            textY = AndroidUtilities.dp(10) + namesOffset;
        }
        if (isRoundVideo) {
            updatePlayingMessageProgress();
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
            if (currentMessageObject.isOutOwner()) {
                seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(57);
                buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(14);
                timeAudioX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67);
            } else {
                if (isChat && !isThreadPost && currentMessageObject.needDrawAvatar()) {
                    seekBarX = AndroidUtilities.dp(114);
                    buttonX = AndroidUtilities.dp(71);
                    timeAudioX = AndroidUtilities.dp(124);
                } else {
                    seekBarX = AndroidUtilities.dp(66);
                    buttonX = AndroidUtilities.dp(23);
                    timeAudioX = AndroidUtilities.dp(76);
                }
            }
            if (hasLinkPreview) {
                seekBarX += AndroidUtilities.dp(10);
                buttonX += AndroidUtilities.dp(10);
                timeAudioX += AndroidUtilities.dp(10);
            }
            updateSeekBarWaveformWidth(null);
            seekBarY = AndroidUtilities.dp(13) + namesOffset + mediaOffsetY;
            buttonY = AndroidUtilities.dp(13) + namesOffset + mediaOffsetY;
            radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(44), buttonY + AndroidUtilities.dp(44));

            updatePlayingMessageProgress();

            if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                int x;
                if (currentMessageObject.type == MessageObject.TYPE_TEXT && (hasLinkPreview || hasGamePreview || hasInvoicePreview)) {
                    int linkX;
                    if (hasGamePreview) {
                        linkX = unmovedTextX - AndroidUtilities.dp(10);
                    } else if (hasInvoicePreview) {
                        linkX = unmovedTextX + AndroidUtilities.dp(1);
                    } else {
                        linkX = unmovedTextX + AndroidUtilities.dp(1);
                    }
                    if (isSmallImage) {
                        x = linkX + backgroundWidth - AndroidUtilities.dp(81);
                    } else {
                        x = linkX + (hasInvoicePreview ? -AndroidUtilities.dp(6.3f) : AndroidUtilities.dp(10));
                    }
                } else {
                    if (currentMessageObject.isOutOwner()) {
                        if (mediaBackground) {
                            x = layoutWidth - backgroundWidth - AndroidUtilities.dp(3);
                        } else {
                            x = layoutWidth - backgroundWidth + AndroidUtilities.dp(6);
                        }
                    } else {
                        if (isChat && isAvatarVisible && (!isPlayingRound || currentMessageObject.isVoiceTranscriptionOpen())) {
                            x = AndroidUtilities.dp(63);
                        } else {
                            x = AndroidUtilities.dp(15);
                        }
                        if (currentPosition != null && !currentPosition.edge) {
                            x -= AndroidUtilities.dp(10);
                        }
                    }
                }
                if (currentPosition != null) {
                    if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                        x -= AndroidUtilities.dp(2);
                    }
                    if (currentPosition.leftSpanOffset != 0) {
                        x += (int) Math.ceil(currentPosition.leftSpanOffset / 1000.0f * getGroupPhotosWidth());
                    }
                }
                if (currentMessageObject.type != MessageObject.TYPE_TEXT) {
                    x -= AndroidUtilities.dp(2);
                }
                if (currentMessageObject.isVoiceTranscriptionOpen()) {
                    x += AndroidUtilities.dp(10);
                }
                if (!transitionParams.imageChangeBoundsTransition || transitionParams.updatePhotoImageX) {
                    transitionParams.updatePhotoImageX = false;
                    photoImage.setImageCoords((float) x, photoImage.getImageY(), photoImage.getImageWidth(), photoImage.getImageHeight());
                }
            }
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
            if (currentMessageObject.isOutOwner()) {
                seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(56);
                buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(14);
                timeAudioX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67);
            } else {
                if (isChat && !isThreadPost && currentMessageObject.needDrawAvatar()) {
                    seekBarX = AndroidUtilities.dp(113);
                    buttonX = AndroidUtilities.dp(71);
                    timeAudioX = AndroidUtilities.dp(124);
                } else {
                    seekBarX = AndroidUtilities.dp(65);
                    buttonX = AndroidUtilities.dp(23);
                    timeAudioX = AndroidUtilities.dp(76);
                }
            }
            if (hasLinkPreview) {
                seekBarX += AndroidUtilities.dp(10);
                buttonX += AndroidUtilities.dp(10);
                timeAudioX += AndroidUtilities.dp(10);
            }
            updateSeekBarWaveformWidth(null);
            seekBarY = AndroidUtilities.dp(29) + namesOffset + mediaOffsetY;
            buttonY = AndroidUtilities.dp(13) + namesOffset + mediaOffsetY;
            radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(44), buttonY + AndroidUtilities.dp(44));

            updatePlayingMessageProgress();
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT && !drawPhotoImage) {
            if (currentMessageObject.isOutOwner()) {
                buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(14);
            } else {
                if (isChat && !isThreadPost && currentMessageObject.needDrawAvatar()) {
                    buttonX = AndroidUtilities.dp(71);
                } else {
                    buttonX = AndroidUtilities.dp(23);
                }
            }
            if (hasLinkPreview) {
                buttonX += AndroidUtilities.dp(10);
            }
            buttonY = AndroidUtilities.dp(13) + namesOffset + mediaOffsetY;
            radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(44), buttonY + AndroidUtilities.dp(44));
            photoImage.setImageCoords(buttonX - AndroidUtilities.dp(10), buttonY - AndroidUtilities.dp(10), photoImage.getImageWidth(), photoImage.getImageHeight());
        } else if (currentMessageObject.type == MessageObject.TYPE_CONTACT) {
            int x;
            if (currentMessageObject.isOutOwner()) {
                x = layoutWidth - backgroundWidth + AndroidUtilities.dp(14);
            } else if (isChat && !isThreadPost && currentMessageObject.needDrawAvatar()) {
                x = AndroidUtilities.dp(72);
            } else {
                x = AndroidUtilities.dp(23);
            }
            photoImage.setImageCoords(x, AndroidUtilities.dp(13) + namesOffset, AndroidUtilities.dp(44), AndroidUtilities.dp(44));
        } else {
            int x;
            if (currentMessageObject.type == MessageObject.TYPE_TEXT && (hasLinkPreview || hasGamePreview || hasInvoicePreview)) {
                int linkX;
                if (hasGamePreview) {
                    linkX = unmovedTextX - AndroidUtilities.dp(10);
                } else if (hasInvoicePreview) {
                    linkX = unmovedTextX + AndroidUtilities.dp(1);
                } else {
                    linkX = unmovedTextX + AndroidUtilities.dp(1);
                }
                if (isSmallImage) {
                    x = linkX + backgroundWidth - AndroidUtilities.dp(81);
                } else {
                    x = linkX + (hasInvoicePreview ? -AndroidUtilities.dp(6.3f) : AndroidUtilities.dp(10));
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    if (mediaBackground) {
                        x = layoutWidth - backgroundWidth - AndroidUtilities.dp(3);
                    } else {
                        x = layoutWidth - backgroundWidth + AndroidUtilities.dp(6);
                    }
                } else {
                    if (isChat && isAvatarVisible && !isPlayingRound) {
                        x = AndroidUtilities.dp(63);
                    } else {
                        x = AndroidUtilities.dp(15);
                    }
                    if (currentPosition != null && !currentPosition.edge) {
                        x -= AndroidUtilities.dp(10);
                    }
                }
            }
            if (currentPosition != null) {
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                    x -= AndroidUtilities.dp(2);
                }
                if (currentPosition.leftSpanOffset != 0) {
                    x += (int) Math.ceil(currentPosition.leftSpanOffset / 1000.0f * getGroupPhotosWidth());
                }
            }
            if (currentMessageObject.type != MessageObject.TYPE_TEXT) {
                x -= AndroidUtilities.dp(2);
            }
            if (!transitionParams.imageChangeBoundsTransition || transitionParams.updatePhotoImageX) {
                transitionParams.updatePhotoImageX = false;
                photoImage.setImageCoords((float) x, photoImage.getImageY(), photoImage.getImageWidth(), photoImage.getImageHeight());
            }
            buttonX = (int) (x + (photoImage.getImageWidth() - AndroidUtilities.dp(48)) / 2.0f);
            buttonY = (int) (photoImage.getImageY() + (photoImage.getImageHeight() - AndroidUtilities.dp(48)) / 2);
            radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48));
            deleteProgressRect.set(buttonX + AndroidUtilities.dp(5), buttonY + AndroidUtilities.dp(5), buttonX + AndroidUtilities.dp(43), buttonY + AndroidUtilities.dp(43));
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
                videoButtonX = (int) (photoImage.getImageX() + AndroidUtilities.dp(8));
                videoButtonY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8));
                videoRadialProgress.setProgressRect(videoButtonX, videoButtonY, videoButtonX + AndroidUtilities.dp(24), videoButtonY + AndroidUtilities.dp(24));
            }
        }
    }

    public boolean needDelayRoundProgressDraw() {
        return (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) && currentMessageObject.type != MessageObject.TYPE_ROUND_VIDEO && MediaController.getInstance().isPlayingMessage(currentMessageObject);
    }

    public void drawRoundProgress(Canvas canvas) {
        float inset = isPlayingRound ? AndroidUtilities.dp(4) : 0;
        boolean drawPause = MediaController.getInstance().isPlayingMessage(currentMessageObject) && MediaController.getInstance().isMessagePaused();
        boolean drawTouchedSeekbar = drawPause && roundSeekbarTouched == 1;

        if (drawPause && roundToPauseProgress != 1f) {
            roundToPauseProgress += 16 / 220f;
            if (roundToPauseProgress > 1f) {
                roundToPauseProgress = 1f;
            } else {
                invalidate();
            }
        } else if (!drawPause && roundToPauseProgress != 0f) {
            roundToPauseProgress -= 16 / 150f;
            if (roundToPauseProgress < 0) {
                roundToPauseProgress = 0f;
            } else {
                invalidate();
            }
        }

        if (drawTouchedSeekbar && roundToPauseProgress2 != 1f) {
            roundToPauseProgress2 += 16 / 150f;
            if (roundToPauseProgress2 > 1f) {
                roundToPauseProgress2 = 1f;
            } else {
                invalidate();
            }
        } else if (!drawTouchedSeekbar && roundToPauseProgress2 != 0f) {
            roundToPauseProgress2 -= 16 / 150f;
            if (roundToPauseProgress2 < 0) {
                roundToPauseProgress2 = 0f;
            } else {
                invalidate();
            }
        }

        float pauseProgress = drawPause ? AndroidUtilities.overshootInterpolator.getInterpolation(roundToPauseProgress) : roundToPauseProgress;

        if (transitionParams.animatePlayingRound) {
            inset = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * AndroidUtilities.dp(4);
        }
        inset += AndroidUtilities.dp(16) * pauseProgress;

        if (roundToPauseProgress > 0) {
            float r = photoImage.getImageWidth() / 2f;
            Theme.getRadialSeekbarShadowDrawable().draw(canvas, photoImage.getCenterX(), photoImage.getCenterY(), r, roundToPauseProgress);
        }

        rect.set(photoImage.getImageX() + AndroidUtilities.dpf2(1.5f) + inset, photoImage.getImageY() + AndroidUtilities.dpf2(1.5f) + inset, photoImage.getImageX2() - AndroidUtilities.dpf2(1.5f) - inset, photoImage.getImageY2() - AndroidUtilities.dpf2(1.5f) - inset);
        int oldAplha = -1;
        if (roundProgressAlpha != 1f || !hasLinkPreview && getVideoTranscriptionProgress() > 0) {
            oldAplha = Theme.chat_radialProgressPaint.getAlpha();
            Theme.chat_radialProgressPaint.setAlpha((int) (roundProgressAlpha * (!hasLinkPreview ? 1f - getVideoTranscriptionProgress() : 1f) * oldAplha));
        }

        if (videoForwardDrawable != null && videoForwardDrawable.isAnimating()) {
            videoForwardDrawable.setBounds((int) photoImage.getImageX(), (int) photoImage.getImageY(), (int) (photoImage.getImageX() + photoImage.getImageWidth()), (int) (photoImage.getImageY() + photoImage.getImageHeight()));
            videoForwardDrawable.draw(canvas);
        }

        int paintAlpha = Theme.chat_radialProgressPaint.getAlpha();
        float paintWidth = Theme.chat_radialProgressPaint.getStrokeWidth();
        float audioProgress = roundProgressAlpha == 1f ? currentMessageObject.audioProgress : lastDrawingAudioProgress;
        if (pauseProgress > 0) {
            float radius = rect.width() / 2f;
            Theme.chat_radialProgressPaint.setStrokeWidth(paintWidth + paintWidth * 0.5f * roundToPauseProgress);
            Theme.chat_radialProgressPaint.setAlpha((int) (paintAlpha * roundToPauseProgress * 0.3f));
            canvas.drawCircle(rect.centerX(), rect.centerY(), radius, Theme.chat_radialProgressPaint);
            Theme.chat_radialProgressPaint.setAlpha(paintAlpha);

            seekbarRoundX = (float) (rect.centerX() + Math.sin(Math.toRadians(-360 * audioProgress + 180)) * radius);
            seekbarRoundY = (float) (rect.centerY() + Math.cos(Math.toRadians(-360 * audioProgress + 180)) * radius);
            Theme.chat_radialProgressPausedSeekbarPaint.setColor(Color.WHITE);
            Theme.chat_radialProgressPausedSeekbarPaint.setAlpha((int) (255 * Math.min(1f, pauseProgress) * (!hasLinkPreview ? 1f - getVideoTranscriptionProgress() : 1)));
            canvas.drawCircle(seekbarRoundX, seekbarRoundY, AndroidUtilities.dp(3) + AndroidUtilities.dp(5) * pauseProgress + AndroidUtilities.dp(3) * roundToPauseProgress2, Theme.chat_radialProgressPausedSeekbarPaint);
        }
        if (roundSeekbarOutAlpha != 0f) {
            roundSeekbarOutAlpha -= 16f / 150f;
            if (roundSeekbarOutAlpha < 0) {
                roundSeekbarOutAlpha = 0f;
            } else {
                invalidate();
            }
        }
        if (roundSeekbarOutAlpha != 0f) {
            if (oldAplha == -1) {
                oldAplha = Theme.chat_radialProgressPaint.getAlpha();
            }
            Theme.chat_radialProgressPaint.setAlpha((int) (paintAlpha * (1f - roundSeekbarOutAlpha)));
            canvas.drawArc(rect, -90, 360 * audioProgress, false, Theme.chat_radialProgressPaint);
            Theme.chat_radialProgressPaint.setAlpha((int) (paintAlpha * roundSeekbarOutAlpha));
            canvas.drawArc(rect, -90, 360 * roundSeekbarOutProgress, false, Theme.chat_radialProgressPaint);
        } else {
            canvas.drawArc(rect, -90, 360 * audioProgress, false, Theme.chat_radialProgressPaint);
        }
        if (oldAplha != -1) {
            Theme.chat_radialProgressPaint.setAlpha(oldAplha);
        }
        Theme.chat_radialProgressPaint.setStrokeWidth(paintWidth);
    }

    private void updatePollAnimations(long dt) {
        if (pollVoteInProgress) {
            voteRadOffset += 360 * dt / 2000.0f;
            int count = (int) (voteRadOffset / 360);
            voteRadOffset -= count * 360;

            voteCurrentProgressTime += dt;
            if (voteCurrentProgressTime >= 500.0f) {
                voteCurrentProgressTime = 500.0f;
            }
            if (voteRisingCircleLength) {
                voteCurrentCircleLength = 4 + 266 * AndroidUtilities.accelerateInterpolator.getInterpolation(voteCurrentProgressTime / 500.0f);
            } else {
                voteCurrentCircleLength = 4 - (firstCircleLength ? 360 : 270) * (1.0f - AndroidUtilities.decelerateInterpolator.getInterpolation(voteCurrentProgressTime / 500.0f));
            }
            if (voteCurrentProgressTime == 500.0f) {
                if (voteRisingCircleLength) {
                    voteRadOffset += 270;
                    voteCurrentCircleLength = -266;
                }
                voteRisingCircleLength = !voteRisingCircleLength;
                if (firstCircleLength) {
                    firstCircleLength = false;
                }
                voteCurrentProgressTime = 0;
            }
            invalidate();
        }
        if (hintButtonVisible && hintButtonProgress < 1.0f) {
            hintButtonProgress += dt / 180.0f;
            if (hintButtonProgress > 1.0f) {
                hintButtonProgress = 1.0f;
            }
            invalidate();
        } else if (!hintButtonVisible && hintButtonProgress > 0.0f) {
            hintButtonProgress -= dt / 180.0f;
            if (hintButtonProgress < 0.0f) {
                hintButtonProgress = 0.0f;
            }
            invalidate();
        }
        if (animatePollAnswer) {
            pollAnimationProgressTime += dt;
            if (pollAnimationProgressTime >= 300.0f) {
                pollAnimationProgressTime = 300.0f;
            }
            pollAnimationProgress = AndroidUtilities.decelerateInterpolator.getInterpolation(pollAnimationProgressTime / 300.0f);
            if (pollAnimationProgress >= 1.0f) {
                pollAnimationProgress = 1.0f;
                animatePollAnswer = false;
                animatePollAnswerAlpha = false;
                pollVoteInProgress = false;
                if (pollUnvoteInProgress && animatePollAvatars) {
                    for (int a = 0; a < pollAvatarImages.length; a++) {
                        pollAvatarImages[a].setImageBitmap((Drawable) null);
                        pollAvatarImagesVisible[a] = false;
                    }
                }
                pollUnvoteInProgress = false;
                for (int a = 0, N = pollButtons.size(); a < N; a++) {
                    PollButton button = pollButtons.get(a);
                    button.prevChosen = false;
                }
            }
            invalidate();
        }
    }

    private void drawContent(Canvas canvas) {
        boolean newPart = needNewVisiblePart && currentMessageObject.type == MessageObject.TYPE_TEXT, hasSpoilers = hasSpoilers();
        if (newPart || hasSpoilers) {
            getLocalVisibleRect(scrollRect);
            if (hasSpoilers) {
                updateSpoilersVisiblePart(scrollRect.top, scrollRect.bottom);
            }
            if (newPart) {
                setVisiblePart(scrollRect.top, scrollRect.bottom - scrollRect.top, parentHeight, parentViewTopOffset, viewTop, parentWidth, backgroundHeight, blurredViewTopOffset, blurredViewBottomOffset);
                needNewVisiblePart = false;
            }
        }

        float buttonX = this.buttonX;
        float buttonY = this.buttonY;
        if (transitionParams.animateButton) {
            buttonX = transitionParams.animateFromButtonX * (1f - transitionParams.animateChangeProgress) + this.buttonX * (transitionParams.animateChangeProgress);
            buttonY = (transitionParams.animateFromButtonY * (1f - transitionParams.animateChangeProgress) + this.buttonY * (transitionParams.animateChangeProgress));
            radialProgress.setProgressRect((int) buttonX, (int) buttonY, (int) buttonX + AndroidUtilities.dp(44), (int) buttonY + AndroidUtilities.dp(44));
        }
        updateSeekBarWaveformWidth(canvas);
        forceNotDrawTime = currentMessagesGroup != null;
        photoImage.setPressed((isHighlightedAnimated || isHighlighted) && currentPosition != null ? 2 : 0);
        photoImage.setVisible(!PhotoViewer.isShowingImage(currentMessageObject) && !SecretMediaViewer.getInstance().isShowingImage(currentMessageObject), false);
        if (!photoImage.getVisible()) {
            mediaWasInvisible = true;
            timeWasInvisible = true;
            if (animatingNoSound == 1) {
                animatingNoSoundProgress = 0.0f;
                animatingNoSound = 0;
            } else if (animatingNoSound == 2) {
                animatingNoSoundProgress = 1.0f;
                animatingNoSound = 0;
            }
        } else if (groupPhotoInvisible) {
            timeWasInvisible = true;
        } else if (mediaWasInvisible || timeWasInvisible) {
            if (mediaWasInvisible) {
                controlsAlpha = 0.0f;
                mediaWasInvisible = false;
            }
            if (timeWasInvisible) {
                timeAlpha = 0.0f;
                timeWasInvisible = false;
            }
            lastControlsAlphaChangeTime = System.currentTimeMillis();
            totalChangeTime = 0;
        }
        radialProgress.setProgressColor(getThemedColor(Theme.key_chat_mediaProgress));
        videoRadialProgress.setProgressColor(getThemedColor(Theme.key_chat_mediaProgress));

        imageDrawn = false;
        radialProgress.setCircleCrossfadeColor(null, 0.0f, 1.0f);
        if (currentMessageObject.type == MessageObject.TYPE_TEXT || currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
            //绘制文字
            //设置文字起始位置
            if (currentMessageObject.isOutOwner()) {
                textX = getCurrentBackgroundLeft() + AndroidUtilities.dp(11) + getExtraTextX();
            } else {
                textX = getCurrentBackgroundLeft() + (currentMessageObject.type == MessageObject.TYPE_EMOJIS ? 0 : AndroidUtilities.dp(!mediaBackground && drawPinnedBottom ? 11 : 17)) + getExtraTextX();
            }
            //特殊文字配置
            if (hasGamePreview) {
                textX += AndroidUtilities.dp(11);
                textY = AndroidUtilities.dp(14) + namesOffset;
                if (siteNameLayout != null) {
                    textY += siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1);
                }
            } else if (hasInvoicePreview) {
                textY = AndroidUtilities.dp(14) + namesOffset;
                if (siteNameLayout != null) {
                    textY += siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1);
                }
            } else if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
                textY = AndroidUtilities.dp(6) + namesOffset;
                if (!currentMessageObject.isOut()) {
                    textX = getCurrentBackgroundLeft();
                } else {
                    textX -= AndroidUtilities.dp(4);
                }
            } else {
                textY = AndroidUtilities.dp(8) + namesOffset;
            }
            unmovedTextX = textX;
            if (currentMessageObject.textXOffset != 0 && replyNameLayout != null) {
                int diff = backgroundWidth - AndroidUtilities.dp(31) - currentMessageObject.textWidth;
                if (!hasNewLineForTime) {
                    diff -= timeWidth + AndroidUtilities.dp(4 + (currentMessageObject.isOutOwner() ? 20 : 0));
                }
                if (diff > 0) {
                    textX += diff - getExtraTimeX();
                }
            }
            if (!enterTransitionInProgress && currentMessageObject != null && !currentMessageObject.preview) {
                if (!drawForBlur && animatedEmojiStack != null && ((currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty()) || (transitionParams.animateOutTextBlocks != null && !transitionParams.animateOutTextBlocks.isEmpty()))) {
                    animatedEmojiStack.clearPositions();
                }
                if (transitionParams.animateChangeProgress != 1.0f && transitionParams.animateMessageText) {
                    //文字过度动画
                    canvas.save();
                    if (currentBackgroundDrawable != null) {
                        Rect r = currentBackgroundDrawable.getBounds();
                        if (currentMessageObject.isOutOwner() && !mediaBackground && !pinnedBottom) {
                            canvas.clipRect(
                                r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                                r.right - AndroidUtilities.dp(10), r.bottom - AndroidUtilities.dp(4)
                            );
                        } else {
                            canvas.clipRect(
                                r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                                r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
                            );
                        }
                    }
                    boolean noAlpha = BuildVars.IS_CHAT_AIR && UserConfig.getInstance(currentAccount).streamResponses;
                    drawMessageText(canvas, transitionParams.animateOutTextBlocks, transitionParams.animateOutTextXOffset, false, noAlpha  ? 0f : (1.0f - transitionParams.animateChangeProgress), false);
                    drawMessageText(canvas, currentMessageObject.textLayoutBlocks, currentMessageObject.textXOffset, true, noAlpha ? 1f : transitionParams.animateChangeProgress, false);
                    canvas.restore();
                } else {
                    //正常文字绘制
                    drawMessageText(canvas, currentMessageObject.textLayoutBlocks, currentMessageObject.textXOffset, true, 1.0f, false);
                }
            }

            if (!(enterTransitionInProgress && !currentMessageObject.isVoice())) {
                drawLinkPreview(canvas, 1f);
            }
            drawTime = true;
        } else if (drawPhotoImage) {
            //绘制图片
            float pipFloat = roundVideoPlayPipFloat.get();
            if (pipFloat > 0) {
                if (drillHolePaint == null) {
                    drillHolePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                }
                drillHolePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLoader : Theme.key_chat_inLoader));
                drillHolePaint.setAlpha((int) (drillHolePaint.getAlpha() * getVideoTranscriptionProgress()));
                canvas.drawCircle(photoImage.getCenterX(), photoImage.getCenterY(), photoImage.getImageWidth() / 2f, drillHolePaint);
            }
            if (isRoundVideo && (
                MediaController.getInstance().isPlayingMessage(currentMessageObject) &&
                MediaController.getInstance().isVideoDrawingReady() &&
                canvas.isHardwareAccelerated() &&
                (currentMessageObject == null || !currentMessageObject.isVoiceTranscriptionOpen() || pipFloat >= 1)
            )) {
                imageDrawn = true;
                drawTime = true;
            } else {
                if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO && Theme.chat_roundVideoShadow != null) {
                    float x = photoImage.getImageX() - AndroidUtilities.dp(3);
                    float y = photoImage.getImageY() - AndroidUtilities.dp(2);
                    int wasAlpha = 255; // Theme.chat_roundVideoShadow.getAlpha();
                    Theme.chat_roundVideoShadow.setAlpha((int) (255 * (1f - getVideoTranscriptionProgress())));
                    Theme.chat_roundVideoShadow.setBounds((int) x, (int) y, (int) (x + photoImage.getImageWidth() + AndroidUtilities.dp(6)), (int) (y + photoImage.getImageHeight() + AndroidUtilities.dp(6)));
                    Theme.chat_roundVideoShadow.draw(canvas);
                    Theme.chat_roundVideoShadow.setAlpha(wasAlpha);

                    if (!photoImage.hasBitmapImage() || photoImage.getCurrentAlpha() != 1) {
                        Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outBubble : Theme.key_chat_inBubble));
                        canvas.drawCircle(photoImage.getCenterX(), photoImage.getCenterY(), photoImage.getImageWidth() / 2, Theme.chat_docBackPaint);
                    }
                }
                drawMediaCheckBox = mediaCheckBox != null && (checkBoxVisible || mediaCheckBox.getProgress() != 0 || checkBoxAnimationInProgress) && currentMessagesGroup != null;
                if (drawMediaCheckBox && (mediaCheckBox.isChecked() || mediaCheckBox.getProgress() != 0 || checkBoxAnimationInProgress) && (!textIsSelectionMode())) {
                    if (!currentMessagesGroup.isDocuments) {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outBubbleSelected : Theme.key_chat_inBubbleSelected));
                        rect.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2());
                        int[] rad = photoImage.getRoundRadius();
                        rectPath.reset();
                        for (int a = 0; a < rad.length; a++) {
                            radii[a * 2] = radii[a * 2 + 1] = rad[a];
                        }
                        rectPath.addRoundRect(rect, radii, Path.Direction.CW);
                        rectPath.close();
                        canvas.drawPath(rectPath, Theme.chat_replyLinePaint);
                    }
                    photoImage.setSideClip(AndroidUtilities.dp(14) * mediaCheckBox.getProgress());
                    if (checkBoxAnimationInProgress) {
                        mediaCheckBox.setBackgroundAlpha(checkBoxAnimationProgress);
                    } else {
                        mediaCheckBox.setBackgroundAlpha(checkBoxVisible ? 1.0f : mediaCheckBox.getProgress());
                    }
                } else {
                    photoImage.setSideClip(0);
                }
                if (isRoundVideo && currentMessageObject.isVoiceTranscriptionOpen() && pipFloat > 0) {
                    canvas.save();
                    if (drillHolePath == null) {
                        drillHolePath = new Path();
                    } else {
                        drillHolePath.rewind();
                    }
                    drillHolePath.addCircle(photoImage.getCenterX(), photoImage.getCenterY(), photoImage.getImageWidth() / 2f * (1f - pipFloat), Path.Direction.CW);
                    canvas.clipPath(drillHolePath);
                }
                if (delegate == null || delegate.getPinchToZoomHelper() == null || !delegate.getPinchToZoomHelper().isInOverlayModeFor(this)) {
                    float top = getY() + photoImage.getImageY();
                    float bottom = top + photoImage.getImageHeight();
                    photoImageOutOfBounds = false;
                    if ((parentBoundsTop != 0 || parentBoundsBottom != 0) && (bottom < parentBoundsTop || top > parentBoundsBottom)) {
                        photoImageOutOfBounds = true;
                    }
                    if (!photoImageOutOfBounds || drawForBlur) {
                        photoImage.setSkipUpdateFrame(drawForBlur);
                        if (flipImage) {
                            canvas.save();
                            canvas.scale(-1f, 1, photoImage.getCenterX(), photoImage.getCenterY());
                            if (allowDrawPhotoImage()) {
                                imageDrawn = photoImage.draw(canvas);
                            } else {
                                imageDrawn = true;
                            }
                            if (currentMessageObject.hasMediaSpoilers()) {
                                drawBlurredPhoto(canvas);
                            }
                            canvas.restore();
                        } else {
                            if (allowDrawPhotoImage()) {
                                imageDrawn = photoImage.draw(canvas);
                            } else {
                                imageDrawn = true;
                            }
                            if (currentMessageObject.hasMediaSpoilers()) {
                                drawBlurredPhoto(canvas);
                            }
                        }
                        photoImage.setSkipUpdateFrame(false);
                    }
                }
                if (isRoundVideo && currentMessageObject.isVoiceTranscriptionOpen() && pipFloat > 0) {
                    canvas.restore();
                }
                boolean drawTimeOld = drawTime;
                boolean groupPhotoVisible = photoImage.getVisible();
                drawTime = groupPhotoVisible || currentMessageObject.shouldDrawReactionsInLayout() && currentMessageObject.hasReactions();
                if (currentPosition != null && drawTimeOld != drawTime) {
                    ViewGroup viewGroup = (ViewGroup) getParent();
                    if (viewGroup != null) {
                        if (!currentPosition.last) {
                            int count = viewGroup.getChildCount();
                            for (int a = 0; a < count; a++) {
                                View child = viewGroup.getChildAt(a);
                                if (child == this || !(child instanceof ChatMessageCell)) {
                                    continue;
                                }
                                ChatMessageCell cell = (ChatMessageCell) child;

                                if (cell.getCurrentMessagesGroup() == currentMessagesGroup) {
                                    MessageObject.GroupedMessagePosition position = cell.getCurrentPosition();
                                    if (position.last && position.maxY == currentPosition.maxY && cell.timeX - AndroidUtilities.dp(4) + cell.getLeft() < getRight()) {
                                        cell.groupPhotoInvisible = !groupPhotoVisible;
                                        cell.invalidate();
                                        viewGroup.invalidate();
                                    }
                                }
                            }
                        } else {
                            viewGroup.invalidate();
                        }
                    }
                }
            }
        } else {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                //绘制音乐链接或者文档
                drawMediaCheckBox = mediaCheckBox != null && (checkBoxVisible || mediaCheckBox.getProgress() != 0 || checkBoxAnimationInProgress) && currentMessagesGroup != null;
                if (drawMediaCheckBox) {
                    radialProgress.setCircleCrossfadeColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeText : Theme.key_chat_inTimeText, checkBoxAnimationProgress, 1.0f - mediaCheckBox.getProgress());
                }
                if (drawMediaCheckBox && !textIsSelectionMode() && (mediaCheckBox.isChecked() || mediaCheckBox.getProgress() != 0 || checkBoxAnimationInProgress)) {
                    if (checkBoxAnimationInProgress) {
                        mediaCheckBox.setBackgroundAlpha(checkBoxAnimationProgress);
                        if (radialProgress.getMiniIcon() == MediaActionDrawable.ICON_NONE) {
                            radialProgress.setMiniIconScale(checkBoxAnimationProgress);
                        }
                    } else {
                        mediaCheckBox.setBackgroundAlpha(checkBoxVisible ? 1.0f : mediaCheckBox.getProgress());
                    }
                } else if (mediaCheckBox != null) {
                    mediaCheckBox.setBackgroundAlpha(1.0f);
                }
            }
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
            //绘制gif动画
            if (drawPhotoImage && photoImage.getVisible() && !hasGamePreview && !currentMessageObject.needDrawBluredPreview()) {
                int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha();
                Theme.chat_msgMediaMenuDrawable.setAlpha((int) (oldAlpha * controlsAlpha));
                setDrawableBounds(Theme.chat_msgMediaMenuDrawable, otherX = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(14)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8.1f)));
                Theme.chat_msgMediaMenuDrawable.draw(canvas);
                Theme.chat_msgMediaMenuDrawable.setAlpha(oldAlpha);
            }
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
            //绘制音乐链接
            if (currentMessageObject.isOutOwner()) {
                Theme.chat_audioTitlePaint.setColor(getThemedColor(Theme.key_chat_outAudioTitleText));
                Theme.chat_audioPerformerPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outAudioPerformerSelectedText : Theme.key_chat_outAudioPerformerText));
                Theme.chat_audioTimePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outAudioDurationSelectedText : Theme.key_chat_outAudioDurationText));
                radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || buttonPressed != 0 ? Theme.key_chat_outAudioSelectedProgress : Theme.key_chat_outAudioProgress));
            } else {
                Theme.chat_audioTitlePaint.setColor(getThemedColor(Theme.key_chat_inAudioTitleText));
                Theme.chat_audioPerformerPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inAudioPerformerSelectedText : Theme.key_chat_inAudioPerformerText));
                Theme.chat_audioTimePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inAudioDurationSelectedText : Theme.key_chat_inAudioDurationText));
                radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || buttonPressed != 0 ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
            }

            radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable);
            radialProgress.draw(canvas);

            canvas.save();
            canvas.translate(timeAudioX + songX, AndroidUtilities.dp(13) + namesOffset + mediaOffsetY);
            songLayout.draw(canvas);
            canvas.restore();

            boolean showSeekbar = MediaController.getInstance().isPlayingMessage(currentMessageObject);
            if (showSeekbar && toSeekBarProgress != 1f) {
                toSeekBarProgress += 16f / 100f;
                if (toSeekBarProgress > 1f) {
                    toSeekBarProgress = 1f;
                }
                invalidate();
            } else if (!showSeekbar && toSeekBarProgress != 0) {
                toSeekBarProgress -= 16f / 100f;
                if (toSeekBarProgress < 0) {
                    toSeekBarProgress = 0;
                }
                invalidate();
            }
            if (toSeekBarProgress > 0) {
                if (toSeekBarProgress != 1f) {
                    canvas.saveLayerAlpha(seekBarX, seekBarY, seekBarX + seekBar.getWidth() + AndroidUtilities.dp(24), seekBarY + AndroidUtilities.dp(24), (int) (255 * (toSeekBarProgress)), Canvas.ALL_SAVE_FLAG);
                } else {
                    canvas.save();
                }
                canvas.translate(seekBarX, seekBarY);
                seekBar.draw(canvas);
                canvas.restore();
            }
            if (toSeekBarProgress < 1f) {
                float x = timeAudioX + performerX;
                float y = AndroidUtilities.dp(35) + namesOffset + mediaOffsetY;
                if (toSeekBarProgress != 0) {
                    canvas.saveLayerAlpha(x, y, x + performerLayout.getWidth(), y + performerLayout.getHeight(), (int) (255 * (1f - toSeekBarProgress)), Canvas.ALL_SAVE_FLAG);
                } else {
                    canvas.save();
                }
                if (toSeekBarProgress != 0) {
                    float s = 0.7f + 0.3f * (1f - toSeekBarProgress);
                    canvas.scale(s, s, x, y + performerLayout.getHeight() / 2f);
                }
                canvas.translate(x, y);
                performerLayout.draw(canvas);
                canvas.restore();
            }

            canvas.save();
            canvas.translate(timeAudioX, AndroidUtilities.dp(57) + namesOffset + mediaOffsetY);
            durationLayout.draw(canvas);
            canvas.restore();

            if (shouldDrawMenuDrawable()) {
                Drawable menuDrawable;
                if (currentMessageObject.isOutOwner()) {
                    menuDrawable = getThemedDrawable(isDrawSelectionBackground() ? Theme.key_drawable_msgOutMenuSelected : Theme.key_drawable_msgOutMenu);
                } else {
                    menuDrawable = isDrawSelectionBackground() ? Theme.chat_msgInMenuSelectedDrawable : Theme.chat_msgInMenuDrawable;
                }
                setDrawableBounds(menuDrawable, otherX = (int) buttonX + backgroundWidth - AndroidUtilities.dp(currentMessageObject.type == MessageObject.TYPE_TEXT ? 58 : 48), otherY = (int) buttonY - AndroidUtilities.dp(2));
                if (transitionParams.animateChangeProgress != 1f && transitionParams.animateShouldDrawMenuDrawable) {
                    menuDrawable.setAlpha((int) (255 * transitionParams.animateChangeProgress));
                }
                menuDrawable.draw(canvas);
                if (transitionParams.animateChangeProgress != 1f && transitionParams.animateShouldDrawMenuDrawable) {
                    menuDrawable.setAlpha(255);
                }
            }
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
            //绘制视频
            if (currentMessageObject.isOutOwner()) {
                Theme.chat_audioTimePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outAudioDurationSelectedText : Theme.key_chat_outAudioDurationText));
                radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || buttonPressed != 0 ? Theme.key_chat_outAudioSelectedProgress : Theme.key_chat_outAudioProgress));
            } else {
                Theme.chat_audioTimePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inAudioDurationSelectedText : Theme.key_chat_inAudioDurationText));
                radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || buttonPressed != 0 ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
            }
            AudioVisualizerDrawable audioVisualizerDrawable;
            if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                audioVisualizerDrawable = Theme.getCurrentAudiVisualizerDrawable();
            } else {
                audioVisualizerDrawable = Theme.getAnimatedOutAudioVisualizerDrawable(currentMessageObject);
            }

            if (audioVisualizerDrawable != null && !(documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && hasLinkPreview)) {
                audioVisualizerDrawable.setParentView(this);
                audioVisualizerDrawable.draw(canvas, buttonX + AndroidUtilities.dp(22), buttonY + AndroidUtilities.dp(22), currentMessageObject.isOutOwner(), documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND ? getVideoTranscriptionProgress() : 1, resourcesProvider);
            }

            if (!enterTransitionInProgress && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO) {
                radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable);
                radialProgress.draw(canvas);
            }

            int seekBarX = this.seekBarX;
            int timeAudioX = this.timeAudioX;
            int yoffset = 0;
            if (transitionParams.animateButton) {
                int offset = this.buttonX - (int) (transitionParams.animateFromButtonX * (1f - transitionParams.animateChangeProgress) + this.buttonX * (transitionParams.animateChangeProgress));
                seekBarX -= offset;
                timeAudioX -= offset;
            }
            if (isRoundVideo && currentMessageObject.isOutOwner()) {
                seekBarX = getCurrentBackgroundLeft() + AndroidUtilities.dp(57);
                timeAudioX = getCurrentBackgroundLeft() + AndroidUtilities.dp(67);
            }
            if (isRoundVideo) {
                yoffset += (1f - getVideoTranscriptionProgress()) * AndroidUtilities.roundMessageSize;
            }
            canvas.save();
            if (!(documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && hasLinkPreview)) {
                if (useSeekBarWaveform) {
                    canvas.translate(seekBarX + AndroidUtilities.dp(13) - seekBarWaveformTranslateX, seekBarY + yoffset);
                    seekBarWaveform.setAlpha(isRoundVideo ? CubicBezierInterpolator.EASE_IN.getInterpolation(getVideoTranscriptionProgress()) : 1f);
                    seekBarWaveform.draw(canvas, this);
                } else {
                    canvas.translate(seekBarX, seekBarY + yoffset);
                    seekBar.setAlpha(isRoundVideo ? CubicBezierInterpolator.EASE_IN.getInterpolation(getVideoTranscriptionProgress()) : 1f);
                    seekBar.draw(canvas);
                }
            }
            canvas.restore();

            float transcribeAlpha = getUseTranscribeButtonProgress();
            float playingRoundAlpha = 0;
            if (transitionParams.animatePlayingRound) {
                if (isPlayingRound) {
                    playingRoundAlpha = transitionParams.animateChangeProgress;
                } else {
                    playingRoundAlpha = 1f - transitionParams.animateChangeProgress;
                }
            } else if (isPlayingRound) {
                playingRoundAlpha = 1f;
            }
            if (!wasTranscriptionOpen) {
                transcribeAlpha = AndroidUtilities.lerp(transcribeAlpha * (1f - playingRoundAlpha), transcribeAlpha, getVideoTranscriptionProgress());
            }
            if (transcribeAlpha > 0 && !(documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && hasLinkPreview)) {
                canvas.save();
                int backgroundWidth = getCurrentBackgroundRight() - getCurrentBackgroundLeft() + AndroidUtilities.dp(pinnedBottom ? 6 : 0);
                int seekBarWidth = backgroundWidth - AndroidUtilities.dp(92 + (hasLinkPreview ? 10 : 0) + 36);
                if (transcribeButton == null) {
                    transcribeButton = new TranscribeButton(this, seekBarWaveform) {
                        @Override
                        public void drawGradientBackground(Canvas canvas, Rect bounds, float alpha) {
                            Paint paint;
                            if (currentMessageObject.shouldDrawWithoutBackground()) {
                                paint = getThemedPaint(Theme.key_paint_chatActionBackground);
                            } else {
                                paint = getThemedPaint(Theme.key_paint_chatTimeBackground);
                            }
                            int oldAlpha = paint.getAlpha();
                            paint.setAlpha((int) (oldAlpha * alpha));

                            applyServiceShaderMatrix();
                            canvas.drawRect(bounds, paint);
                            if (paint == getThemedPaint(Theme.key_paint_chatActionBackground) && hasGradientService()) {
                                int oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                                Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * alpha));
                                canvas.drawRect(bounds, Theme.chat_actionBackgroundGradientDarkenPaint);
                                Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
                            }
                            paint.setAlpha(oldAlpha);
                        }

                        @Override
                        protected void onOpen() {
                            wasTranscriptionOpen = true;
                        }
                    };
                    transcribeButton.setOpen(currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.voiceTranscriptionOpen && currentMessageObject.messageOwner.voiceTranscriptionFinal && TranscribeButton.isVideoTranscriptionOpen(currentMessageObject), false);
                    transcribeButton.setLoading(TranscribeButton.isTranscribing(currentMessageObject), false);
                }
                if (drawSideButton != 0) {
                    transcribeX = AndroidUtilities.lerp(
                        seekBarX + AndroidUtilities.dp(13 + 8) + seekBarWidth,
                        sideStartX,
                        1f - getVideoTranscriptionProgress()
                    );
                    transcribeY = AndroidUtilities.lerp(
                        seekBarY + AndroidUtilities.dp(3),
                        sideStartY - AndroidUtilities.dp(32 + 8),
                        1f - getVideoTranscriptionProgress()
                    );
                } else {
                    transcribeX = AndroidUtilities.lerp(
                        seekBarX + AndroidUtilities.dp(13 + 8) + seekBarWidth,
                        currentMessageObject != null && currentMessageObject.isOutOwner() ?
                            getCurrentBackgroundLeft() - AndroidUtilities.dp(32 + 8) + AndroidUtilities.dp(28) * playingRoundAlpha :
                            getCurrentBackgroundRight() + AndroidUtilities.dp(8) - AndroidUtilities.dp(40) * playingRoundAlpha,
                        1f - getVideoTranscriptionProgress()
                    );
                    float y = layoutHeight + transitionParams.deltaBottom - AndroidUtilities.dp(28 - (drawPinnedBottom ? 2 : 0));
                    if (!reactionsLayoutInBubble.isEmpty) {
                        y -= reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress);
                    }
                    y = AndroidUtilities.lerp(y, AndroidUtilities.dp(44) + namesOffset + mediaOffsetY - AndroidUtilities.dp(1.7f), getVideoTranscriptionProgress());
                    y += AndroidUtilities.dp(1.7f);
                    transcribeY = AndroidUtilities.lerp(
                        seekBarY + AndroidUtilities.dp(3),
                        y - AndroidUtilities.dp(12) - (currentMessageObject.isOutOwner() ? 0 : AndroidUtilities.dp(28) * playingRoundAlpha),
                        1f - getVideoTranscriptionProgress()
                    );
                }
                transcribeButton.setBounds(
                    (int) transcribeX,
                    (int) transcribeY,
                    AndroidUtilities.lerp(AndroidUtilities.dp(30), AndroidUtilities.dp(32), 1f - getVideoTranscriptionProgress()),
                    AndroidUtilities.lerp(AndroidUtilities.dp(24), AndroidUtilities.dp(32), 1f - getVideoTranscriptionProgress()),
                    AndroidUtilities.lerp(AndroidUtilities.dp(8), AndroidUtilities.dp(16), 1f - getVideoTranscriptionProgress())
                );
                transcribeButton.setColor(
                    ColorUtils.blendARGB(
                        getThemedColor(Theme.key_chat_serviceText),
                        getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground),
                        documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO ? 1 : getVideoTranscriptionProgress()
                    ),
                    getThemedColor(Theme.key_windowBackgroundWhiteGrayText),
                    currentMessageObject.isOut(),
                    documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO ? 0 : 1f - getVideoTranscriptionProgress()
                );
                transcribeButton.draw(canvas, transcribeAlpha);
                canvas.restore();
            }

            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO) {
                canvas.save();
                canvas.translate(timeAudioX, AndroidUtilities.dp(44) + namesOffset + mediaOffsetY + yoffset);
                durationLayout.draw(canvas);
                canvas.restore();

                if (currentMessageObject.type != MessageObject.TYPE_TEXT && currentMessageObject.isContentUnread()) {
                    Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outVoiceSeekbarFill : Theme.key_chat_inVoiceSeekbarFill));
                    canvas.drawCircle(timeAudioX + timeWidthAudio + AndroidUtilities.dp(6), AndroidUtilities.dp(51) + namesOffset + mediaOffsetY, AndroidUtilities.dp(3), Theme.chat_docBackPaint);
                }
            }

            if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                if (durationLayout != null) {
                    boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
                    if (playing || roundProgressAlpha != 0) {
                        if (playing) {
                            roundProgressAlpha = 1f;
                        } else {
                            roundProgressAlpha -= 16 / 150f;
                            if (roundProgressAlpha < 0) {
                                roundProgressAlpha = 0;
                            } else {
                                invalidate();
                            }
                        }
                        drawRoundProgress(canvas);
                    }
                }
            }
        }

        if (captionLayout != null) {
            updateCaptionLayout();
        }
        updateReactionLayoutPosition();
        if (shouldDrawCaptionLayout()) {
            drawCaptionLayout(canvas, false, 1f);
        }

        if (hasOldCaptionPreview) {
            int linkX;
            if (
                currentMessageObject.type == MessageObject.TYPE_PHOTO ||
                currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW ||
                documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
                currentMessageObject.type == MessageObject.TYPE_GIF
            ) {
                linkX = (int) (photoImage.getImageX() + AndroidUtilities.dp(5));
            } else {
                linkX = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() ? 11 : 17);
            }
            float startY = totalHeight - AndroidUtilities.dp(drawPinnedTop ? 9 : 10) - linkPreviewHeight - AndroidUtilities.dp(8);
            float linkPreviewY = startY;

            Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewLine : Theme.key_chat_inPreviewLine));
            AndroidUtilities.rectTmp.set(linkX, linkPreviewY - AndroidUtilities.dp(3), linkX + AndroidUtilities.dp(3), linkPreviewY + linkPreviewHeight);
            if (replyRoundRectPath == null) {
                replyRoundRectPath = new Path();
            } else {
                replyRoundRectPath.rewind();
            }
            if (replyRoundRectRadii == null) {
                replyRoundRectRadii = new float[8];
                replyRoundRectRadii[0] = replyRoundRectRadii[1] = replyRoundRectRadii[6] = replyRoundRectRadii[7] = AndroidUtilities.dp(2); // left
                replyRoundRectRadii[2] = replyRoundRectRadii[3] = replyRoundRectRadii[4] = replyRoundRectRadii[5] = AndroidUtilities.dp(1); // right
            }
            replyRoundRectPath.addRoundRect(AndroidUtilities.rectTmp, replyRoundRectRadii, Path.Direction.CW);
            canvas.drawPath(replyRoundRectPath, Theme.chat_replyLinePaint);

            if (siteNameLayout != null) {
                Theme.chat_replyNamePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outSiteNameText : Theme.key_chat_inSiteNameText));
                canvas.save();
                int x;
                if (siteNameRtl) {
                    x = backgroundWidth - siteNameWidth - AndroidUtilities.dp(32);
                } else {
                    x = (hasInvoicePreview ? 0 : AndroidUtilities.dp(10));
                }
                canvas.translate(linkX + x, linkPreviewY - AndroidUtilities.dp(3));
                siteNameLayout.draw(canvas);
                canvas.restore();
                linkPreviewY += siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1);
            }

            if (currentMessageObject.isOutOwner()) {
                Theme.chat_replyTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
            } else {
                Theme.chat_replyTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
            }

            if (descriptionLayout != null) {
                if (linkPreviewY != startY) {
                    linkPreviewY += AndroidUtilities.dp(2);
                }
                descriptionY = (int) linkPreviewY - AndroidUtilities.dp(3);
                canvas.save();
                canvas.translate(linkX + AndroidUtilities.dp(10) + descriptionX, descriptionY);
                descriptionLayout.draw(canvas);
                AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, animatedEmojiDescriptionStack, 0, null, 0, 0, 0, 1f, Theme.chat_animatedEmojiTextColorFilter);
                canvas.restore();
            }
            drawTime = true;
        }

        if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
            Drawable menuDrawable;
            if (currentMessageObject.isOutOwner()) {
                Theme.chat_docNamePaint.setColor(getThemedColor(Theme.key_chat_outFileNameText));
                Theme.chat_infoPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outFileInfoSelectedText : Theme.key_chat_outFileInfoText));
                Theme.chat_docBackPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outFileBackgroundSelected : Theme.key_chat_outFileBackground));
                menuDrawable = getThemedDrawable(isDrawSelectionBackground() ? Theme.key_drawable_msgOutMenuSelected : Theme.key_drawable_msgOutMenu);
            } else {
                Theme.chat_docNamePaint.setColor(getThemedColor(Theme.key_chat_inFileNameText));
                Theme.chat_infoPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inFileInfoSelectedText : Theme.key_chat_inFileInfoText));
                Theme.chat_docBackPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inFileBackgroundSelected : Theme.key_chat_inFileBackground));
                menuDrawable = isDrawSelectionBackground() ? Theme.chat_msgInMenuSelectedDrawable : Theme.chat_msgInMenuDrawable;
            }

            float x;
            int titleY;
            int subtitleY;
            if (drawPhotoImage) {
                if (currentMessageObject.type == MessageObject.TYPE_TEXT) {
                    setDrawableBounds(menuDrawable, otherX = (int) (photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(56)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(4)));
                } else {
                    setDrawableBounds(menuDrawable, otherX = (int) (photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(40)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(4)));
                }

                x = (int) (photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10));
                titleY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8));
                subtitleY = (int) (photoImage.getImageY() + (docTitleLayout != null ? docTitleLayout.getLineBottom(docTitleLayout.getLineCount() - 1) + AndroidUtilities.dp(13) : AndroidUtilities.dp(8)));
                if (!imageDrawn) {
                    if (currentMessageObject.isOutOwner()) {
                        radialProgress.setColors(Theme.key_chat_outLoader, Theme.key_chat_outLoaderSelected, Theme.key_chat_outMediaIcon, Theme.key_chat_outMediaIconSelected);
                        radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outFileProgressSelected : Theme.key_chat_outFileProgress));
                        videoRadialProgress.setColors(Theme.key_chat_outLoader, Theme.key_chat_outLoaderSelected, Theme.key_chat_outMediaIcon, Theme.key_chat_outMediaIconSelected);
                        videoRadialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outFileProgressSelected : Theme.key_chat_outFileProgress));
                    } else {
                        radialProgress.setColors(Theme.key_chat_inLoader, Theme.key_chat_inLoaderSelected, Theme.key_chat_inMediaIcon, Theme.key_chat_inMediaIconSelected);
                        radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inFileProgressSelected : Theme.key_chat_inFileProgress));
                        videoRadialProgress.setColors(Theme.key_chat_inLoader, Theme.key_chat_inLoaderSelected, Theme.key_chat_inMediaIcon, Theme.key_chat_inMediaIconSelected);
                        videoRadialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inFileProgressSelected : Theme.key_chat_inFileProgress));
                    }

                    rect.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX() + photoImage.getImageWidth(), photoImage.getImageY() + photoImage.getImageHeight());

                    int[] rad = photoImage.getRoundRadius();
                    rectPath.reset();
                    for (int a = 0; a < rad.length; a++) {
                        radii[a * 2] = rad[a];
                        radii[a * 2 + 1] = rad[a];
                    }
                    rectPath.addRoundRect(rect, radii, Path.Direction.CW);
                    rectPath.close();
                    canvas.drawPath(rectPath, Theme.chat_docBackPaint);
                } else {
                    radialProgress.setColors(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
                    radialProgress.setProgressColor(getThemedColor(Theme.key_chat_mediaProgress));
                    videoRadialProgress.setColors(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
                    videoRadialProgress.setProgressColor(getThemedColor(Theme.key_chat_mediaProgress));

                    if (buttonState == -1 && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE) {
                        radialProgress.setIcon(MediaActionDrawable.ICON_NONE, true, true);
                    }
                }
            } else {
                setDrawableBounds(menuDrawable, otherX = (int) buttonX + backgroundWidth - AndroidUtilities.dp(currentMessageObject.type == MessageObject.TYPE_TEXT ? 58 : 48), otherY = (int) buttonY - AndroidUtilities.dp(2));
                x = buttonX + AndroidUtilities.dp(53);
                titleY = (int) buttonY + AndroidUtilities.dp(4);
                subtitleY = (int) buttonY + AndroidUtilities.dp(27);
                if (docTitleLayout != null && docTitleLayout.getLineCount() > 1) {
                    subtitleY += (docTitleLayout.getLineCount() - 1) * AndroidUtilities.dp(16) + AndroidUtilities.dp(2);
                }
                if (currentMessageObject.isOutOwner()) {
                    radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || buttonPressed != 0 ? Theme.key_chat_outAudioSelectedProgress : Theme.key_chat_outAudioProgress));
                    videoRadialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || videoButtonPressed != 0 ? Theme.key_chat_outAudioSelectedProgress : Theme.key_chat_outAudioProgress));
                } else {
                    radialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || buttonPressed != 0 ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
                    videoRadialProgress.setProgressColor(getThemedColor(isDrawSelectionBackground() || videoButtonPressed != 0 ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
                }
            }
            if (shouldDrawMenuDrawable()) {
                if (transitionParams.animateChangeProgress != 1f && transitionParams.animateShouldDrawMenuDrawable) {
                    menuDrawable.setAlpha((int) (255 * transitionParams.animateChangeProgress));
                }
                menuDrawable.draw(canvas);
                if (transitionParams.animateChangeProgress != 1f && transitionParams.animateShouldDrawMenuDrawable) {
                    menuDrawable.setAlpha(255);
                }
            }

            try {
                if (docTitleLayout != null) {
                    canvas.save();
                    canvas.translate(x + docTitleOffsetX, titleY);
                    docTitleLayout.draw(canvas);
                    canvas.restore();
                }
            } catch (Exception e) {
                FileLog.e(e);
            }

            try {
                if (infoLayout != null) {
                    canvas.save();
                    canvas.translate(x, subtitleY);
                    if (buttonState == 1 && loadingProgressLayout != null) {
//                        loadingProgressLayout.copyStylesFrom(Theme.chat_infoPaint);
                        loadingProgressLayout.draw(canvas);
                    } else {
                        infoLayout.draw(canvas);
                    }
                    canvas.restore();
                }
            } catch (Exception e) {
                FileLog.e(e);
            }
        }
        if (currentMessageObject.type == MessageObject.TYPE_GEO && !(MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaGeoLive) && currentMapProvider == 2 && photoImage.hasNotThumb()) {
            int w = (int) (Theme.chat_redLocationIcon.getIntrinsicWidth() * 0.8f);
            int h = (int) (Theme.chat_redLocationIcon.getIntrinsicHeight() * 0.8f);
            int x = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - w) / 2);
            int y = (int) (photoImage.getImageY() + (photoImage.getImageHeight() / 2 - h) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(photoImage.getCurrentAlpha())));
            Theme.chat_redLocationIcon.setAlpha((int) (255 * Math.min(1, photoImage.getCurrentAlpha() * 5)));
            Theme.chat_redLocationIcon.setBounds(x, y, x + w, y + h);
            Theme.chat_redLocationIcon.draw(canvas);
            if (photoImage.getCurrentAlpha() < 1) {
                invalidate();
            }
        }
        transitionParams.recordDrawingState();
    }

    private void startRevealMedia(float x, float y) {
        mediaSpoilerRevealMaxRadius = (float) Math.sqrt(Math.pow(photoImage.getImageWidth(), 2) + Math.pow(photoImage.getImageHeight(), 2));
        startRevealMedia(x, y, mediaSpoilerRevealMaxRadius);
    }

    private void startRevealMedia(float x, float y, float maxRadius) {
        if (currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0f) {
            return;
        }

        if (currentMessageObject.type == MessageObject.TYPE_VIDEO) {
            currentMessageObject.forceUpdate = true;
            currentMessageObject.revealingMediaSpoilers = true;
            setMessageContent(currentMessageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
            currentMessageObject.revealingMediaSpoilers = false;
            currentMessageObject.forceUpdate = false;

            if (currentMessagesGroup != null) {
                radialProgress.setProgress(0f, false);
            }
        }

        mediaSpoilerRevealX = x;
        mediaSpoilerRevealY = y;

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration((long) MathUtils.clamp(mediaSpoilerRevealMaxRadius * 0.3f, 250, 550));
        animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH);
        animator.addUpdateListener(animation -> {
            mediaSpoilerRevealProgress = (float) animation.getAnimatedValue();
            invalidate();
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                currentMessageObject.isMediaSpoilersRevealed = true;
                invalidate();
            }
        });
        animator.start();
    }

    private void drawBlurredPhoto(Canvas canvas) {
        if (currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress == 1f) {
            return;
        }

        int[] rad = photoImage.getRoundRadius();
        mediaSpoilerRadii[0] = mediaSpoilerRadii[1] = rad[0];
        mediaSpoilerRadii[2] = mediaSpoilerRadii[3] = rad[1];
        mediaSpoilerRadii[4] = mediaSpoilerRadii[5] = rad[2];
        mediaSpoilerRadii[6] = mediaSpoilerRadii[7] = rad[3];

        mediaSpoilerPath.rewind();
        AndroidUtilities.rectTmp.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2());
        mediaSpoilerPath.addRoundRect(AndroidUtilities.rectTmp, mediaSpoilerRadii, Path.Direction.CW);

        canvas.save();
        canvas.clipPath(mediaSpoilerPath);

        if (mediaSpoilerRevealProgress != 0f) {
            mediaSpoilerPath.rewind();
            mediaSpoilerPath.addCircle(mediaSpoilerRevealX, mediaSpoilerRevealY, mediaSpoilerRevealMaxRadius * mediaSpoilerRevealProgress, Path.Direction.CW);
            canvas.clipPath(mediaSpoilerPath, Region.Op.DIFFERENCE);
        }

        blurredPhotoImage.setImageCoords(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageWidth(), photoImage.getImageHeight());
        blurredPhotoImage.setRoundRadius(photoImage.getRoundRadius());
        blurredPhotoImage.draw(canvas);

        int sColor = Color.WHITE;
        mediaSpoilerEffect.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f * photoImage.getAlpha())));
        mediaSpoilerEffect.setBounds((int) photoImage.getImageX(), (int) photoImage.getImageY(), (int) photoImage.getImageX2(), (int) photoImage.getImageY2());
        mediaSpoilerEffect.draw(canvas);
        canvas.restore();

        invalidate();
    }

    private float getUseTranscribeButtonProgress() {
        if (transitionParams.animateUseTranscribeButton) {
            if (useTranscribeButton) {
                return transitionParams.animateChangeProgress;
            } else {
                return 1f - transitionParams.animateChangeProgress;
            }
        } else {
            return useTranscribeButton ? 1 : 0;
        }
    }

    private void updateReactionLayoutPosition() {
        if (!reactionsLayoutInBubble.isEmpty && (currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) {
            if (currentMessageObject.type == MessageObject.TYPE_EMOJIS || currentMessageObject.isAnimatedEmoji() || currentMessageObject.isAnyKindOfSticker()) {
                if (currentMessageObject.isOutOwner()) {
                    reactionsLayoutInBubble.x = getMeasuredWidth() - reactionsLayoutInBubble.width - AndroidUtilities.dp(16);//AndroidUtilities.displaySize.x - maxWidth - AndroidUtilities.dp(17);
                } else {
                    reactionsLayoutInBubble.x = getCurrentBackgroundLeft();
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    reactionsLayoutInBubble.x = getCurrentBackgroundLeft() + AndroidUtilities.dp(11);
                } else {
                    if (isRoundVideo) {
                        reactionsLayoutInBubble.x = getCurrentBackgroundLeft() + AndroidUtilities.dp(11) + (int) AndroidUtilities.dp(AndroidUtilities.lerp(0, !drawPinnedBottom ? 6 : 0, getVideoTranscriptionProgress()));
                        reactionsLayoutInBubble.x -= (int) ((1f - getVideoTranscriptionProgress()) * AndroidUtilities.dp(9));
                    } else {
                        reactionsLayoutInBubble.x = getCurrentBackgroundLeft() + AndroidUtilities.dp(!mediaBackground && drawPinnedBottom ? 11 : 17);
                        if (mediaBackground) {
                            reactionsLayoutInBubble.x -= AndroidUtilities.dp(9);
                        }
                    }
                }
            }
            reactionsLayoutInBubble.y = getBackgroundDrawableBottom() - AndroidUtilities.dp(10) - reactionsLayoutInBubble.height;
            reactionsLayoutInBubble.y -= (drawCommentButton ? AndroidUtilities.dp(43) : 0);
            if (hasNewLineForTime && !(drawForwardedName && hasLinkPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO)) {
                reactionsLayoutInBubble.y -= AndroidUtilities.dp(16);
            }
            if (captionLayout != null && ((currentMessageObject.type != MessageObject.TYPE_VOICE && !(currentMessageObject.isOut() && drawForwardedName && !drawPhotoImage) && !(currentMessageObject.type == MessageObject.TYPE_FILE && drawPhotoImage)) || (currentPosition != null && currentMessagesGroup != null))) {
                reactionsLayoutInBubble.y -= AndroidUtilities.dp(14);
            }
            reactionsLayoutInBubble.y += reactionsLayoutInBubble.positionOffsetY;
        }
        if (reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
            int timeYOffset;
            if (shouldDrawTimeOnMedia()) {
                timeYOffset = -(drawCommentButton ? AndroidUtilities.dp(41.3f) : 0);
            } else {
                if (currentMessageObject.isSponsored()) {
                    timeYOffset = -AndroidUtilities.dp(48);
                    if (hasNewLineForTime) {
                        timeYOffset -= AndroidUtilities.dp(16);
                    }
                } else {
                    timeYOffset = -(drawCommentButton ? AndroidUtilities.dp(43) : 0);
                }
            }
            reactionsLayoutInBubble.y = (int) (shouldDrawTimeOnMedia() ? photoImage.getImageY2() + additionalTimeOffsetY - AndroidUtilities.dp(7.3f) - timeLayout.getHeight() : layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
            reactionsLayoutInBubble.y += timeLayout.getHeight() / 2f - AndroidUtilities.dp(7);
            reactionsLayoutInBubble.x = (int) timeX;
        }
    }

    public void drawLinkPreview(Canvas canvas, float alpha) {
        if (!currentMessageObject.isSponsored() && !hasLinkPreview && !hasGamePreview && !hasInvoicePreview) {
            return;
        }
        int startY;
        int linkX;
        if (hasGamePreview) {
            startY = AndroidUtilities.dp(14) + namesOffset;
            linkX = unmovedTextX - AndroidUtilities.dp(10);
        } else if (hasInvoicePreview) {
            startY = AndroidUtilities.dp(14) + namesOffset;
            linkX = unmovedTextX + AndroidUtilities.dp(1);
        } else if (currentMessageObject.isSponsored()) {
            startY = textY + currentMessageObject.textHeight - AndroidUtilities.dp(2);
            if (hasNewLineForTime) {
                startY += AndroidUtilities.dp(16);
            }
            linkX = unmovedTextX + AndroidUtilities.dp(1);
        } else {
            startY = textY + currentMessageObject.textHeight + AndroidUtilities.dp(8);
            linkX = unmovedTextX + AndroidUtilities.dp(1);
        }
        startY += (int) transitionParams.deltaBottom;
        int linkPreviewY = startY;
        int smallImageStartY = 0;

        if (!hasInvoicePreview && !currentMessageObject.isSponsored()) {
            Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewLine : Theme.key_chat_inPreviewLine));
            if (alpha != 1f) {
                Theme.chat_replyLinePaint.setAlpha((int) (alpha * Theme.chat_replyLinePaint.getAlpha()));
            }
            AndroidUtilities.rectTmp.set(linkX, linkPreviewY - AndroidUtilities.dp(3), linkX + AndroidUtilities.dp(3), linkPreviewY + linkPreviewHeight + AndroidUtilities.dp(3));
            if (replyRoundRectPath == null) {
                replyRoundRectPath = new Path();
            } else {
                replyRoundRectPath.rewind();
            }
            if (replyRoundRectRadii == null) {
                replyRoundRectRadii = new float[8];
                replyRoundRectRadii[0] = replyRoundRectRadii[1] = replyRoundRectRadii[6] = replyRoundRectRadii[7] = AndroidUtilities.dp(2); // left
                replyRoundRectRadii[2] = replyRoundRectRadii[3] = replyRoundRectRadii[4] = replyRoundRectRadii[5] = AndroidUtilities.dp(1); // right
            }
            replyRoundRectPath.addRoundRect(AndroidUtilities.rectTmp, replyRoundRectRadii, Path.Direction.CW);
            canvas.drawPath(replyRoundRectPath, Theme.chat_replyLinePaint);
        }

        if (siteNameLayout != null) {
            smallImageStartY = linkPreviewY - AndroidUtilities.dp(1);
            Theme.chat_replyNamePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outSiteNameText : Theme.key_chat_inSiteNameText));
            if (alpha != 1f) {
                Theme.chat_replyNamePaint.setAlpha((int) (alpha * Theme.chat_replyLinePaint.getAlpha()));
            }
            canvas.save();
            int x;
            if (siteNameRtl) {
                x = backgroundWidth - siteNameWidth - AndroidUtilities.dp(32);
                if (isSmallImage) {
                    x -= AndroidUtilities.dp(48 + 6);
                }
            } else {
                x = (hasInvoicePreview ? 0 : AndroidUtilities.dp(10));
            }
            canvas.translate(linkX + x, linkPreviewY - AndroidUtilities.dp(3));
            siteNameLayout.draw(canvas);
            canvas.restore();
            linkPreviewY += siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1);
        }
        if ((hasGamePreview || hasInvoicePreview) && currentMessageObject.textHeight != 0) {
            startY += currentMessageObject.textHeight + AndroidUtilities.dp(4);
            linkPreviewY += currentMessageObject.textHeight + AndroidUtilities.dp(4);
        }

        if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 && drawInstantViewType != 2 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 1 || drawInstantViewType == 6 && imageBackgroundColor != 0) {
            if (linkPreviewY != startY) {
                linkPreviewY += AndroidUtilities.dp(2);
            }
            if (imageBackgroundSideColor != 0) {
                int x = linkX + AndroidUtilities.dp(10);
                photoImage.setImageCoords(x + (imageBackgroundSideWidth - photoImage.getImageWidth()) / 2, linkPreviewY, photoImage.getImageWidth(), photoImage.getImageHeight());
                rect.set(x, photoImage.getImageY(), x + imageBackgroundSideWidth, photoImage.getImageY2());
                Theme.chat_instantViewPaint.setColor(ColorUtils.setAlphaComponent(imageBackgroundSideColor, (int) (255 * alpha)));
                canvas.drawRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), Theme.chat_instantViewPaint);
            } else {
                photoImage.setImageCoords(linkX + AndroidUtilities.dp(10), linkPreviewY, photoImage.getImageWidth(), photoImage.getImageHeight());
            }
            if (imageBackgroundColor != 0) {
                rect.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2());
                if (imageBackgroundGradientColor1 != 0) {
                    if (imageBackgroundGradientColor2 != 0) {
                        if (motionBackgroundDrawable == null) {
                            motionBackgroundDrawable = new MotionBackgroundDrawable(imageBackgroundColor, imageBackgroundGradientColor1, imageBackgroundGradientColor2, imageBackgroundGradientColor3, true);
                            if (imageBackgroundIntensity < 0) {
                                photoImage.setGradientBitmap(motionBackgroundDrawable.getBitmap());
                            }
                            if (!photoImage.hasImageSet()) {
                                motionBackgroundDrawable.setRoundRadius(AndroidUtilities.dp(4));
                            }
                        }
                    } else {
                        if (gradientShader == null) {
                            Rect r = BackgroundGradientDrawable.getGradientPoints(AndroidUtilities.getWallpaperRotation(imageBackgroundGradientRotation, false), (int) rect.width(), (int) rect.height());
                            gradientShader = new LinearGradient(r.left, r.top, r.right, r.bottom, new int[]{imageBackgroundColor, imageBackgroundGradientColor1}, null, Shader.TileMode.CLAMP);
                        }
                        Theme.chat_instantViewPaint.setShader(gradientShader);
                        if (alpha != 1f) {
                            Theme.chat_instantViewPaint.setAlpha((int) (255 * alpha));
                        }
                    }
                } else {
                    Theme.chat_instantViewPaint.setShader(null);
                    Theme.chat_instantViewPaint.setColor(imageBackgroundColor);
                    if (alpha != 1f) {
                        Theme.chat_instantViewPaint.setAlpha((int) (255 * alpha));
                    }
                }
                if (motionBackgroundDrawable != null) {
                    motionBackgroundDrawable.setBounds((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
                    motionBackgroundDrawable.draw(canvas);
                } else if (imageBackgroundSideColor != 0) {
                    canvas.drawRect(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2(), Theme.chat_instantViewPaint);
                } else {
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), Theme.chat_instantViewPaint);
                }
                Theme.chat_instantViewPaint.setShader(null);
                Theme.chat_instantViewPaint.setAlpha(255);
            }
            if (drawPhotoImage && drawInstantView && drawInstantViewType != 9) {
                if (drawImageButton) {
                    int size = AndroidUtilities.dp(48);
                    buttonX = this.buttonX = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - size) / 2.0f);
                    buttonY = this.buttonY = (int) (photoImage.getImageY() + (photoImage.getImageHeight() - size) / 2.0f);
                    radialProgress.setProgressRect((int) buttonX, (int) buttonY, (int) buttonX + size, (int) buttonY + size);
                }
                if (delegate == null || delegate.getPinchToZoomHelper() == null || !delegate.getPinchToZoomHelper().isInOverlayModeFor(this)) {
                    if (alpha != 1f) {
                        photoImage.setAlpha(alpha);
                        if (allowDrawPhotoImage()) {
                            imageDrawn = photoImage.draw(canvas);
                        } else {
                            imageDrawn = true;
                        }
                        if (currentMessageObject.hasMediaSpoilers()) {
                            blurredPhotoImage.setAlpha(alpha);
                            drawBlurredPhoto(canvas);
                            blurredPhotoImage.setAlpha(1f);
                        }
                        photoImage.setAlpha(1f);
                    } else {
                        if (allowDrawPhotoImage()) {
                            imageDrawn = photoImage.draw(canvas);
                        } else {
                            imageDrawn = true;
                        }
                        if (currentMessageObject.hasMediaSpoilers()) {
                            drawBlurredPhoto(canvas);
                        }
                    }
                }
            }
            linkPreviewY += photoImage.getImageHeight() + AndroidUtilities.dp(6);
        }

        if (currentMessageObject.isOutOwner()) {
            Theme.chat_replyNamePaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_messageTextOut), (int) (255 * alpha)));
            Theme.chat_replyTextPaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_messageTextOut), (int) (255 * alpha)));
        } else {
            Theme.chat_replyNamePaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_messageTextIn), (int) (255 * alpha)));
            Theme.chat_replyTextPaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_messageTextIn), (int) (255 * alpha)));
        }
        if (titleLayout != null) {
            if (linkPreviewY != startY) {
                linkPreviewY += AndroidUtilities.dp(2);
            }
            if (smallImageStartY == 0) {
                smallImageStartY = linkPreviewY - AndroidUtilities.dp(1);
            }
            canvas.save();
            canvas.translate(linkX + AndroidUtilities.dp(10) + titleX, linkPreviewY - AndroidUtilities.dp(3));
            titleLayout.draw(canvas);
            canvas.restore();
            linkPreviewY += titleLayout.getLineBottom(titleLayout.getLineCount() - 1);
        }

        if (authorLayout != null) {
            if (linkPreviewY != startY) {
                linkPreviewY += AndroidUtilities.dp(2);
            }
            if (smallImageStartY == 0) {
                smallImageStartY = linkPreviewY - AndroidUtilities.dp(1);
            }
            canvas.save();
            canvas.translate(linkX + AndroidUtilities.dp(10) + authorX, linkPreviewY - AndroidUtilities.dp(3));
            authorLayout.draw(canvas);
            canvas.restore();
            linkPreviewY += authorLayout.getLineBottom(authorLayout.getLineCount() - 1);
        }

        if (descriptionLayout != null) {
            if (linkPreviewY != startY) {
                linkPreviewY += AndroidUtilities.dp(2);
            }
            if (smallImageStartY == 0) {
                smallImageStartY = linkPreviewY - AndroidUtilities.dp(1);
            }
            descriptionY = linkPreviewY - AndroidUtilities.dp(3);
            canvas.save();
            canvas.translate(linkX + (hasInvoicePreview ? 0 : AndroidUtilities.dp(10)) + descriptionX, descriptionY);
            if (linkBlockNum == -10) {
                if (links.draw(canvas)) {
                    invalidate();
                }
            }
            drawProgressLoadingLink(canvas, -2);
            if (delegate != null && delegate.getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
                delegate.getTextSelectionHelper().drawDescription(currentMessageObject.isOutOwner(), descriptionLayout, canvas);
            }
            descriptionLayout.draw(canvas);
            AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, animatedEmojiDescriptionStack, 0, null, 0, 0, 0, 1f, Theme.chat_animatedEmojiTextColorFilter);
            canvas.restore();
            linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
        }

        if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 2 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 1)) {
            if (linkPreviewY != startY) {
                linkPreviewY += AndroidUtilities.dp(2);
            }

            if (isSmallImage) {
                photoImage.setImageCoords(linkX + backgroundWidth - AndroidUtilities.dp(81), smallImageStartY, photoImage.getImageWidth(), photoImage.getImageHeight());
            } else {
                photoImage.setImageCoords(linkX + (hasInvoicePreview ? -AndroidUtilities.dp(6.3f) : AndroidUtilities.dp(10)), linkPreviewY, photoImage.getImageWidth(), photoImage.getImageHeight());
                if (drawImageButton) {
                    int size = AndroidUtilities.dp(48);
                    buttonX = this.buttonX = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - size) / 2.0f);
                    buttonY = this.buttonY = (int) (photoImage.getImageY() + (photoImage.getImageHeight() - size) / 2.0f);
                    radialProgress.setProgressRect((int) buttonX, (int) buttonY, (int) buttonX + size, (int) buttonY + size);
                }
            }
            if (isRoundVideo && MediaController.getInstance().isPlayingMessage(currentMessageObject) && MediaController.getInstance().isVideoDrawingReady() && canvas.isHardwareAccelerated()) {
                imageDrawn = true;
                drawTime = true;
            } else {
                if (delegate == null || delegate.getPinchToZoomHelper() == null || !delegate.getPinchToZoomHelper().isInOverlayModeFor(this)) {
                    if (alpha != 1f) {
                        photoImage.setAlpha(alpha);
                        if (allowDrawPhotoImage()) {
                            imageDrawn = photoImage.draw(canvas);
                        } else {
                            imageDrawn = true;
                        }
                        if (currentMessageObject.hasMediaSpoilers()) {
                            blurredPhotoImage.setAlpha(alpha);
                            drawBlurredPhoto(canvas);
                            blurredPhotoImage.setAlpha(1f);
                        }
                        photoImage.setAlpha(1f);
                    } else {
                        if (allowDrawPhotoImage()) {
                            imageDrawn = photoImage.draw(canvas);
                        } else {
                            imageDrawn = true;
                        }
                        if (currentMessageObject.hasMediaSpoilers()) {
                            drawBlurredPhoto(canvas);
                        }
                    }
                }
            }
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
            videoButtonX = (int) (photoImage.getImageX() + AndroidUtilities.dp(8));
            videoButtonY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8));
            videoRadialProgress.setProgressRect(videoButtonX, videoButtonY, videoButtonX + AndroidUtilities.dp(24), videoButtonY + AndroidUtilities.dp(24));
        }
        Paint timeBackgroundPaint = getThemedPaint(Theme.key_paint_chatTimeBackground);
        if (photosCountLayout != null && photoImage.getVisible()) {
            int x = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(8) - photosCountWidth);
            int y = (int) (photoImage.getImageY() + photoImage.getImageHeight() - AndroidUtilities.dp(19));
            rect.set(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + photosCountWidth + AndroidUtilities.dp(4), y + AndroidUtilities.dp(14.5f));
            int oldAlpha = timeBackgroundPaint.getAlpha();
            timeBackgroundPaint.setAlpha((int) (oldAlpha * controlsAlpha));
            Theme.chat_durationPaint.setAlpha((int) (255 * controlsAlpha));
            canvas.drawRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), timeBackgroundPaint);
            timeBackgroundPaint.setAlpha(oldAlpha);
            canvas.save();
            canvas.translate(x, y);
            photosCountLayout.draw(canvas);
            canvas.restore();
            Theme.chat_durationPaint.setAlpha(255);
        }
        if (videoInfoLayout != null && (!drawPhotoImage || photoImage.getVisible()) && imageBackgroundSideColor == 0) {
            int x;
            int y;
            if (hasGamePreview || hasInvoicePreview || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER) {
                if (drawPhotoImage) {
                    x = (int) (photoImage.getImageX() + AndroidUtilities.dp(8.5f));
                    y = (int) (photoImage.getImageY() + AndroidUtilities.dp(6));
                    int height = AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER ? 14.5f : 16.5f);
                    rect.set(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + durationWidth + AndroidUtilities.dp(4), y + height);
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), timeBackgroundPaint);
                } else {
                    x = linkX;
                    y = linkPreviewY;
                }
            } else {
                x = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(8) - durationWidth);
                y = (int) (photoImage.getImageY() + photoImage.getImageHeight() - AndroidUtilities.dp(19));
                rect.set(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + durationWidth + AndroidUtilities.dp(4), y + AndroidUtilities.dp(14.5f));
                canvas.drawRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), getThemedPaint(Theme.key_paint_chatTimeBackground));
            }

            canvas.save();
            canvas.translate(x, y);
            if (hasInvoicePreview) {
                if (drawPhotoImage) {
                    Theme.chat_shipmentPaint.setColor(getThemedColor(Theme.key_chat_previewGameText));
                } else {
                    if (currentMessageObject.isOutOwner()) {
                        Theme.chat_shipmentPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
                    } else {
                        Theme.chat_shipmentPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
                    }
                }
            }
            videoInfoLayout.draw(canvas);
            canvas.restore();
        }

        if (drawInstantView) {
            Drawable instantDrawable;
            int instantY = startY + linkPreviewHeight + AndroidUtilities.dp(10);
            Paint backPaint = Theme.chat_instantViewRectPaint;
            boolean loading = delegate != null && delegate.isProgressLoading(this, ChatActivity.PROGRESS_INSTANT);
            if (instantButtonLoading != null && !loading && !instantButtonLoading.isDisappeared() && !instantButtonLoading.isDisappearing()) {
                instantButtonLoading.disappear();
            }
            if (instantButtonLoading == null && loading) {
                instantButtonLoading = new LoadingDrawable();
                instantButtonLoading.strokePaint.setStrokeWidth(AndroidUtilities.dp(1.25f));
                instantButtonLoading.setAppearByGradient(true);
            } else if (instantButtonLoading != null && loading && (instantButtonLoading.isDisappeared() || instantButtonLoading.isDisappearing())) {
                instantButtonLoading.reset();
                instantButtonLoading.resetDisappear();
            }
            if (currentMessageObject.isOutOwner()) {
                instantDrawable = getThemedDrawable(Theme.key_drawable_msgOutInstant);
                Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_outPreviewInstantText));
                backPaint.setColor(getThemedColor(Theme.key_chat_outPreviewInstantText));
                if (instantButtonLoading != null) {
                    instantButtonLoading.setColors(
                        Theme.multAlpha(getThemedColor(Theme.key_chat_outPreviewInstantText), .1f),
                        Theme.multAlpha(getThemedColor(Theme.key_chat_outPreviewInstantText), .3f),
                        Theme.multAlpha(getThemedColor(Theme.key_chat_outPreviewInstantText), .3f),
                        Theme.multAlpha(getThemedColor(Theme.key_chat_outPreviewInstantText), 1.2f)
                    );
                }
            } else {
                instantDrawable = getThemedDrawable(Theme.key_drawable_msgInInstant);
                Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_inPreviewInstantText));
                backPaint.setColor(getThemedColor(Theme.key_chat_inPreviewInstantText));
                if (instantButtonLoading != null) {
                    instantButtonLoading.setColors(
                        Theme.multAlpha(getThemedColor(Theme.key_chat_inPreviewInstantText), .1f),
                        Theme.multAlpha(getThemedColor(Theme.key_chat_inPreviewInstantText), .3f),
                        Theme.multAlpha(getThemedColor(Theme.key_chat_inPreviewInstantText), .3f),
                        Theme.multAlpha(getThemedColor(Theme.key_chat_inPreviewInstantText), 1.2f)
                    );
                }
            }

            instantButtonRect.set(linkX, instantY, linkX + instantWidth, instantY + AndroidUtilities.dp(36));
            if (instantButtonPressed && instantButtonPressProgress != 1f) {
                instantButtonPressProgress += (float) Math.min(40, 1000f / AndroidUtilities.screenRefreshRate) / 100f;
                instantButtonPressProgress = Utilities.clamp(instantButtonPressProgress, 1f, 0);
                invalidate();
            }
            float scale = 0.98f + 0.02f * (1f - instantButtonPressProgress);
            if (scale != 1) {
                canvas.save();
                canvas.scale(scale, scale, instantButtonRect.centerX(), instantButtonRect.centerY());
            }
            if (Build.VERSION.SDK_INT >= 21) {
                selectorDrawableMaskType[0] = 0;
                selectorDrawable[0].setBounds(linkX, instantY, linkX + instantWidth, instantY + AndroidUtilities.dp(36));
                selectorDrawable[0].draw(canvas);
            }
            if (instantButtonLoading != null && !instantButtonLoading.isDisappeared()) {
                instantButtonLoading.setBounds(instantButtonRect);
                instantButtonLoading.setRadiiDp(6);
                instantButtonLoading.draw(canvas);
                invalidate();
            }
            canvas.drawRoundRect(instantButtonRect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), backPaint);
            if (drawInstantViewType == 0) {
                setDrawableBounds(instantDrawable, instantTextLeftX + instantTextX + linkX - AndroidUtilities.dp(15), instantY + AndroidUtilities.dp(11.5f), AndroidUtilities.dp(9), AndroidUtilities.dp(13));
                instantDrawable.draw(canvas);
            }
            if (instantViewLayout != null) {
                canvas.save();
                canvas.translate(linkX + instantTextX, instantY + AndroidUtilities.dp(10.5f));
                instantViewLayout.draw(canvas);
                canvas.restore();
            }
            if (scale != 1) {
                canvas.restore();
            }
        }
    }

    private boolean shouldDrawMenuDrawable() {
        return currentMessagesGroup == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0;
    }

    private void drawBotButtons(Canvas canvas, ArrayList<BotButton> botButtons, int alpha) {
        int addX;
        if (currentMessageObject.isOutOwner()) {
            addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
        } else {
            addX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground || drawPinnedBottom ? 1 : 7);
        }
        float top = layoutHeight - AndroidUtilities.dp(2) + transitionParams.deltaBottom;
        float height = 0;
        for (int a = 0; a < botButtons.size(); a++) {
            BotButton button = botButtons.get(a);
            int bottom = button.y + button.height;
            if (bottom > height) {
                height = bottom;
            }
        }
        rect.set(0, top, getMeasuredWidth(), top + height);
        if (alpha != 0xFF) {
            canvas.saveLayerAlpha(rect, alpha, Canvas.ALL_SAVE_FLAG);
        } else {
            canvas.save();
        }

        for (int a = 0; a < botButtons.size(); a++) {
            BotButton button = botButtons.get(a);
            float y = button.y + layoutHeight - AndroidUtilities.dp(2) + transitionParams.deltaBottom;
            float s = button.getPressScale();

            rect.set(button.x + addX, y, button.x + addX + button.width, y + button.height);
            canvas.save();
            if (s != 1) {
                canvas.scale(s, s, rect.centerX(), rect.centerY());
            }
            applyServiceShaderMatrix();
            canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), getThemedPaint(Theme.key_paint_chatActionBackground));
            if (hasGradientService()) {
                canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
            }

            boolean drawProgress = (button.button instanceof TLRPC.TL_keyboardButtonCallback || button.button instanceof TLRPC.TL_keyboardButtonGame || button.button instanceof TLRPC.TL_keyboardButtonBuy || button.button instanceof TLRPC.TL_keyboardButtonUrlAuth) && SendMessagesHelper.getInstance(currentAccount).isSendingCallback(currentMessageObject, button.button) ||
                    button.button instanceof TLRPC.TL_keyboardButtonRequestGeoLocation && SendMessagesHelper.getInstance(currentAccount).isSendingCurrentLocation(currentMessageObject, button.button) ||
                    button.button instanceof TLRPC.TL_keyboardButtonUrl && delegate != null && delegate.isProgressLoading(this, ChatActivity.PROGRESS_BOT_BUTTON) && delegate.getProgressLoadingBotButtonUrl(this) == button.button.url;

            if (drawProgress) {
                if (button.loadingDrawable == null) {
                    button.loadingDrawable = new LoadingDrawable();
                    button.loadingDrawable.setRadiiDp(5.5f);
                    button.loadingDrawable.setAppearByGradient(true);
                    button.loadingDrawable.strokePaint.setStrokeWidth(AndroidUtilities.dpf2(1.25f));
                } else if (button.loadingDrawable.isDisappeared() || button.loadingDrawable.isDisappearing()) {
                    button.loadingDrawable.reset();
                    button.loadingDrawable.resetDisappear();
                }
            } else if (button.loadingDrawable != null && !button.loadingDrawable.isDisappearing() && !button.loadingDrawable.isDisappeared()) {
                button.loadingDrawable.disappear();
            }

            if (button.loadingDrawable != null && (drawProgress || button.loadingDrawable.isDisappearing())) {
                rect.inset(AndroidUtilities.dpf2(.625f), AndroidUtilities.dpf2(.625f));
                button.loadingDrawable.setBounds(rect);
                button.loadingDrawable.setColors(
                    Theme.multAlpha(Theme.getColor(Theme.key_chat_serviceBackgroundSelector, resourcesProvider), 1f),
                    Theme.multAlpha(Theme.getColor(Theme.key_chat_serviceBackgroundSelector, resourcesProvider), 2.5f),
                    Theme.multAlpha(Theme.getColor(Theme.key_chat_serviceBackgroundSelector, resourcesProvider), 3f),
                    Theme.multAlpha(Theme.getColor(Theme.key_chat_serviceBackgroundSelector, resourcesProvider), 10f)
                );
                button.loadingDrawable.setAlpha(0xFF);
                button.loadingDrawable.draw(canvas);
                invalidateOutbounds();
            }

            if (button.selectorDrawable != null) {
                button.selectorDrawable.setBounds(button.x + addX, (int) y, button.x + addX + button.width, (int) y + button.height);
                button.selectorDrawable.setAlpha(0xFF);
                button.selectorDrawable.draw(canvas);
            }

            canvas.save();
            canvas.translate(button.x + addX + AndroidUtilities.dp(5), y + (AndroidUtilities.dp(44) - button.title.getLineBottom(button.title.getLineCount() - 1)) / 2);
            button.title.draw(canvas);
            canvas.restore();
            if (button.button instanceof TLRPC.TL_keyboardButtonWebView) {
                Drawable drawable = getThemedDrawable(Theme.key_drawable_botWebView);
                int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
                setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
                drawable.draw(canvas);
            } else if (button.button instanceof TLRPC.TL_keyboardButtonUrl) {
                Drawable drawable;
                if (button.isInviteButton) {
                    drawable = getThemedDrawable(Theme.key_drawable_botInvite);
                } else {
                    drawable = getThemedDrawable(Theme.key_drawable_botLink);
                }
                int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
                setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
                drawable.draw(canvas);
            } else if (button.button instanceof TLRPC.TL_keyboardButtonSwitchInline || button.button instanceof TLRPC.TL_keyboardButtonRequestPeer) {
                Drawable drawable = getThemedDrawable(Theme.key_drawable_botInline);
                int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
                setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
                drawable.draw(canvas);
            } else if (button.button instanceof TLRPC.TL_keyboardButtonBuy) {
                int x = button.x + button.width - AndroidUtilities.dp(5) - Theme.chat_botCardDrawable.getIntrinsicWidth() + addX;
                setDrawableBounds(Theme.chat_botCardDrawable, x, y + AndroidUtilities.dp(4));
                Theme.chat_botCardDrawable.draw(canvas);
            }

            canvas.restore();
        }
        canvas.restore();
    }

    private boolean allowDrawPhotoImage() {
        return !currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0f || blurredPhotoImage.getBitmap() == null;
    }

    public void drawMessageText(Canvas canvas, ArrayList<MessageObject.TextLayoutBlock> textLayoutBlocks, boolean origin, float alpha, boolean drawOnlyText) {
        drawMessageText(canvas, textLayoutBlocks, currentMessageObject == null ? 0 : currentMessageObject.textXOffset, origin, alpha, drawOnlyText);
    }

    //绘制文字
    @SuppressLint("Range")
    public void drawMessageText(Canvas canvas, ArrayList<MessageObject.TextLayoutBlock> textLayoutBlocks, float rtlOffset, boolean origin, float alpha, boolean drawOnlyText) {
        if (textLayoutBlocks == null || textLayoutBlocks.isEmpty() || alpha == 0) {
            return;
        }
        int firstVisibleBlockNum;
        int lastVisibleBlockNum;
        if (origin) {
            if (fullyDraw) {
                this.firstVisibleBlockNum = 0;
                this.lastVisibleBlockNum = textLayoutBlocks.size();
            }
            firstVisibleBlockNum = this.firstVisibleBlockNum;
            lastVisibleBlockNum = this.lastVisibleBlockNum;
        } else {
            firstVisibleBlockNum = 0;
            lastVisibleBlockNum = textLayoutBlocks.size();
        }

        float textY = this.textY;
        if (transitionParams.animateText) {
            textY = transitionParams.animateFromTextY * (1f - transitionParams.animateChangeProgress) + this.textY * transitionParams.animateChangeProgress;
        }

        boolean translating = MessagesController.getInstance(currentAccount).getTranslateController().isTranslating(getMessageObject());
        //翻译模块
        if ((textLayoutBlocks == transitionParams.animateOutTextBlocks) == (currentMessageObject != null && currentMessageObject.translated)) {
            if (translationLoadingFloat == null) {
                translationLoadingFloat = new AnimatedFloat(this, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
            }
            float translationLoading = translationLoadingFloat.set(translating ? 1 : 0);
            if (translationLoading > 0) {
                if (translationLoadingDrawable == null) {
                    translationLoadingDrawable = new LoadingDrawable();
                    translationLoadingDrawable.setAppearByGradient(true);
                    if (translationLoadingPath == null) {
                        translationLoadingPath = new LinkPath(true);
                    }
                    translationLoadingDrawable.usePath(translationLoadingPath);
                    translationLoadingDrawable.setRadiiDp(5);

                    translationLoadingDrawable.reset();
                }

                if (translationLoadingDrawableText != textLayoutBlocks) {
                    translationLoadingDrawableText = textLayoutBlocks;
                    translationLoadingPath.reset();
                    for (int i = 0; i < textLayoutBlocks.size(); ++i) {
                        MessageObject.TextLayoutBlock block = textLayoutBlocks.get(i);
                        if (block != null && block.textLayout != null) {
                            translationLoadingPath.setCurrentLayout(block.textLayout, 0, block.isRtl() ? rtlOffset : 0, block.textYOffset);
                            block.textLayout.getSelectionPath(0, block.textLayout.getText().length(), translationLoadingPath);
                        }
                    }
                    translationLoadingDrawable.updateBounds();
                }

                if (translating && (translationLoadingDrawable.isDisappearing() || translationLoadingDrawable.isDisappeared())) {
                    translationLoadingDrawable.reset();
                    translationLoadingDrawable.resetDisappear();
                } else if (!translating && !translationLoadingDrawable.isDisappearing() && !translationLoadingDrawable.isDisappeared()) {
                    translationLoadingDrawable.disappear();
                }

                int color = getThemedColor(currentMessageObject != null && currentMessageObject.isOutOwner() ? Theme.key_chat_messageLinkOut : Theme.key_chat_messageLinkIn);
                translationLoadingDrawable.setColors(
                    Theme.multAlpha(color, .05f),
                    Theme.multAlpha(color, .15f),
                    Theme.multAlpha(color, .1f),
                    Theme.multAlpha(color, .3f)
                );
                canvas.save();
                canvas.translate(textX, textY + transitionYOffsetForDrawables);
                translationLoadingDrawable.setAlpha((int) (0xFF * alpha * translationLoading));
                translationLoadingDrawable.draw(canvas);
                canvas.restore();
                invalidate();
            }
        }

        if (firstVisibleBlockNum >= 0) {
            int restore = Integer.MIN_VALUE;
            int oldAlpha = 0;
            int oldLinkAlpha = 0;
            boolean needRestoreColor = false;
            if (alpha != 1.0f) {
                if (drawOnlyText) {
                    needRestoreColor = true;
                    oldAlpha = Theme.chat_msgTextPaint.getAlpha();
                    oldLinkAlpha = Color.alpha(Theme.chat_msgTextPaint.linkColor);
                    Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * alpha));
                    Theme.chat_msgTextPaint.linkColor = ColorUtils.setAlphaComponent(Theme.chat_msgTextPaint.linkColor, (int) (oldLinkAlpha * alpha));
                } else {
                    if (currentBackgroundDrawable != null) {
                        int top = currentBackgroundDrawable.getBounds().top;
                        int bottom = currentBackgroundDrawable.getBounds().bottom;

                        if (getY() < 0) {
                            top = (int) -getY();
                        }
                        if (getY() + getMeasuredHeight() > parentHeight) {
                            bottom = (int) (parentHeight - getY());
                        }
                        rect.set(
                            getCurrentBackgroundLeft(), top,
                            currentBackgroundDrawable.getBounds().right, bottom
                        );
                    } else {
                        rect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
                    }
                    restore = canvas.saveLayerAlpha(rect, (int) (alpha * 255), Canvas.ALL_SAVE_FLAG);
                }
            }
            int spoilersColor = currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount) ? getThemedColor(Theme.key_chat_outTimeText) : Theme.chat_msgTextPaint.getColor();
            for (int a = firstVisibleBlockNum; a <= lastVisibleBlockNum; a++) {
                if (a >= textLayoutBlocks.size()) {
                    break;
                }
                MessageObject.TextLayoutBlock block = textLayoutBlocks.get(a);
                canvas.save();
                canvas.translate(textX - (block.isRtl() ? rtlOffset : 0), textY + block.textYOffset + transitionYOffsetForDrawables);
                if (a == linkBlockNum) {
                    if (!drawOnlyText && links.draw(canvas)) {
                        invalidate();
                    }
                    drawProgressLoadingLink(canvas, a);
                }
                if (a == linkSelectionBlockNum && !urlPathSelection.isEmpty() && !drawOnlyText) {
                    for (int b = 0; b < urlPathSelection.size(); b++) {
                        canvas.drawPath(urlPathSelection.get(b), Theme.chat_textSearchSelectionPaint);
                    }
                }
                //核心绘制文字选中
                if (delegate.getTextSelectionHelper() != null && transitionParams.animateChangeProgress == 1f && !drawOnlyText) {
                    delegate.getTextSelectionHelper().draw(currentMessageObject, block, canvas);
                }
                //绘制文字
                try {
                    Emoji.emojiDrawingYOffset = -transitionYOffsetForDrawables;
                    SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, 0, block.spoilersPatchedTextLayout, block.textLayout, block.spoilers, canvas, false);
                    Emoji.emojiDrawingYOffset = 0;
                } catch (Exception e) {
                    FileLog.e(e);
                }
                canvas.restore();
            }
            if (needRestoreColor) {
                Theme.chat_msgTextPaint.setAlpha(oldAlpha);
                Theme.chat_msgTextPaint.linkColor = ColorUtils.setAlphaComponent(Theme.chat_msgTextPaint.linkColor, oldLinkAlpha);
            }

            if (restore != Integer.MIN_VALUE) {
                canvas.restoreToCount(restore);
            }
        }
    }

    public AnimatedEmojiSpan[] getAnimatedEmojiSpans() {
        AnimatedEmojiSpan[] messageTextSpans = currentMessageObject != null && currentMessageObject.messageText instanceof Spanned ? ((Spanned) currentMessageObject.messageText).getSpans(0, currentMessageObject.messageText.length(), AnimatedEmojiSpan.class) : null;
        AnimatedEmojiSpan[] captionTextSpans = currentMessageObject != null && currentMessageObject.caption instanceof Spanned ? ((Spanned) currentMessageObject.caption).getSpans(0, currentMessageObject.caption.length(), AnimatedEmojiSpan.class) : null;
        if ((messageTextSpans == null || messageTextSpans.length == 0) && (captionTextSpans == null || captionTextSpans.length == 0)) {
            return null;
        }
        AnimatedEmojiSpan[] array = new AnimatedEmojiSpan[(messageTextSpans == null ? 0 : messageTextSpans.length) + (captionTextSpans == null ? 0 : captionTextSpans.length)];
        int j = 0;
        if (messageTextSpans != null) {
            for (int i = 0; i < messageTextSpans.length; ++i, ++j) {
                array[j] = messageTextSpans[i];
            }
        }
        if (captionTextSpans != null) {
            for (int i = 0; i < captionTextSpans.length; ++i, ++j) {
                array[j] = captionTextSpans[i];
            }
        }
        return array;
    }

    public void updateCaptionLayout() {
        if (
            currentMessageObject.type == MessageObject.TYPE_PHOTO ||
            currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW ||
            documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
            currentMessageObject.type == MessageObject.TYPE_GIF
        ) {
            float x, y, h;
            if (transitionParams.imageChangeBoundsTransition) {
                x = transitionParams.animateToImageX;
                y = transitionParams.animateToImageY;
                h = transitionParams.animateToImageH;
            } else {
                x = photoImage.getImageX();
                y = photoImage.getImageY();
                h = photoImage.getImageHeight();
            }
            captionX = x + AndroidUtilities.dp(5) + captionOffsetX;
            captionY = y + h + AndroidUtilities.dp(6);
        } else if (hasOldCaptionPreview) {
            captionX = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() ? 11 : 17) + captionOffsetX;
            captionY = totalHeight - captionHeight - AndroidUtilities.dp(drawPinnedTop ? 9 : 10) - linkPreviewHeight - AndroidUtilities.dp(17);
            if (drawCommentButton && drawSideButton != 3) {
                captionY -= AndroidUtilities.dp(shouldDrawTimeOnMedia() ? 41.3f : 43);
            }
        } else {
            if (isRoundVideo) {
                captionX = getBackgroundDrawableLeft() + AndroidUtilities.dp(11 + (currentMessageObject.isOutOwner() ? 0 : 6));
            } else {
                captionX = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() || mediaBackground || drawPinnedBottom ? 11 : 17) + captionOffsetX;
            }
            captionY = totalHeight - captionHeight - AndroidUtilities.dp(drawPinnedTop ? 9 : 10);
            if (drawCommentButton && drawSideButton != 3) {
                captionY -= AndroidUtilities.dp(shouldDrawTimeOnMedia() ? 41.3f : 43);
            }
            if (!reactionsLayoutInBubble.isEmpty && !reactionsLayoutInBubble.isSmall) {
                captionY -= reactionsLayoutInBubble.totalHeight;
            }
        }
        captionX += getExtraTextX();
    }

    private boolean textIsSelectionMode() {
        if (getCurrentMessagesGroup() != null) {
            return false;
        }
        return delegate.getTextSelectionHelper() != null && delegate.getTextSelectionHelper().isSelected(currentMessageObject);
    }

    public float getViewTop() {
        return viewTop;
    }

    public int getBackgroundHeight() {
        return backgroundHeight;
    }

    private int getMiniIconForCurrentState() {
        if (miniButtonState < 0) {
            return MediaActionDrawable.ICON_NONE;
        }
        if (miniButtonState == 0) {
            return MediaActionDrawable.ICON_DOWNLOAD;
        } else {
            return MediaActionDrawable.ICON_CANCEL;
        }
    }

    private int getIconForCurrentState() {
        if (currentMessageObject == null || currentMessageObject != null && currentMessageObject.hasExtendedMedia()) {
            return MediaActionDrawable.ICON_NONE;
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject.isVoiceTranscriptionOpen() && canStreamVideo) {
            if (buttonState == 1 || buttonState == 4) {
                return MediaActionDrawable.ICON_PAUSE;
            }
            return MediaActionDrawable.ICON_PLAY;
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
            if (currentMessageObject.isOutOwner()) {
                radialProgress.setColors(Theme.key_chat_outLoader, Theme.key_chat_outLoaderSelected, Theme.key_chat_outMediaIcon, Theme.key_chat_outMediaIconSelected);
            } else {
                radialProgress.setColors(Theme.key_chat_inLoader, Theme.key_chat_inLoaderSelected, Theme.key_chat_inMediaIcon, Theme.key_chat_inMediaIconSelected);
            }
            if (buttonState == 1) {
                return MediaActionDrawable.ICON_PAUSE;
            } else if (buttonState == 2) {
                return MediaActionDrawable.ICON_DOWNLOAD;
            } else if (buttonState == 4) {
                return MediaActionDrawable.ICON_CANCEL;
            }
            return MediaActionDrawable.ICON_PLAY;
        } else {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT && !drawPhotoImage) {
                if (currentMessageObject.isOutOwner()) {
                    radialProgress.setColors(Theme.key_chat_outLoader, Theme.key_chat_outLoaderSelected, Theme.key_chat_outMediaIcon, Theme.key_chat_outMediaIconSelected);
                } else {
                    radialProgress.setColors(Theme.key_chat_inLoader, Theme.key_chat_inLoaderSelected, Theme.key_chat_inMediaIcon, Theme.key_chat_inMediaIconSelected);
                }
                if (buttonState == -1) {
                    return MediaActionDrawable.ICON_FILE;
                } else if (buttonState == 0) {
                    return MediaActionDrawable.ICON_DOWNLOAD;
                } else if (buttonState == 1) {
                    return MediaActionDrawable.ICON_CANCEL;
                }
            } else {
                radialProgress.setColors(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
                videoRadialProgress.setColors(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
                if (buttonState >= 0 && buttonState < 4) {
                    if (buttonState == 0) {
                        return MediaActionDrawable.ICON_DOWNLOAD;
                    } else if (buttonState == 1) {
                        return MediaActionDrawable.ICON_CANCEL;
                    } else if (buttonState == 2) {
                        return MediaActionDrawable.ICON_PLAY;
                    } else {
                        return autoPlayingMedia ? MediaActionDrawable.ICON_NONE : MediaActionDrawable.ICON_PLAY;
                    }
                } else if (buttonState == -1) {
                    if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                        return (drawPhotoImage && (currentPhotoObject != null || currentPhotoObjectThumb != null) && (photoImage.hasBitmapImage() || currentMessageObject.mediaExists || currentMessageObject.attachPathExists)) ? MediaActionDrawable.ICON_NONE : MediaActionDrawable.ICON_FILE;
                    } else if (currentMessageObject.needDrawBluredPreview()) {
                        if (currentMessageObject.messageOwner.destroyTime != 0) {
                            if (currentMessageObject.isOutOwner()) {
                                return MediaActionDrawable.ICON_SECRETCHECK;
                            } else {
                                return MediaActionDrawable.ICON_EMPTY_NOPROGRESS;
                            }
                        } else {
                            return MediaActionDrawable.ICON_FIRE;
                        }
                    } else if (hasEmbed) {
                        return MediaActionDrawable.ICON_PLAY;
                    }
                }
            }
        }
        if (currentMessageObject != null && isRoundVideo && currentMessageObject.isVoiceTranscriptionOpen()) {
            return MediaActionDrawable.ICON_PLAY;
        }
        return MediaActionDrawable.ICON_NONE;
    }

    private int getMaxNameWidth() {
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER || currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
            int maxWidth;
            if (AndroidUtilities.isTablet()) {
                if (isChat && !isThreadPost && !currentMessageObject.isOutOwner() && currentMessageObject.needDrawAvatar()) {
                    maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(42);
                } else {
                    maxWidth = AndroidUtilities.getMinTabletSide();
                }
            } else {
                if (isChat && !isThreadPost && !currentMessageObject.isOutOwner() && currentMessageObject.needDrawAvatar()) {
                    maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(42);
                } else {
                    maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y);
                }
            }
            if (isPlayingRound && (currentMessageObject == null || !currentMessageObject.isVoiceTranscriptionOpen())) {
                int backgroundWidthLocal = backgroundWidth - (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
                return maxWidth - backgroundWidthLocal - AndroidUtilities.dp(57);
            }
            return maxWidth - backgroundWidth - AndroidUtilities.dp(57);
        }
        if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
            int dWidth;
            if (AndroidUtilities.isTablet()) {
                dWidth = AndroidUtilities.getMinTabletSide();
            } else {
                dWidth = getParentWidth();
            }
            int firstLineWidth = 0;
            for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                if (position.minY == 0) {
                    firstLineWidth += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
                } else {
                    break;
                }
            }
            return firstLineWidth - AndroidUtilities.dp(31 + (isAvatarVisible ? 48 : 0));
        } else if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
            return Math.max(currentMessageObject.textWidth, (int) ((AndroidUtilities.displaySize.x - AndroidUtilities.dp(52) - (isAvatarVisible ? AndroidUtilities.dp(48) : 0)) * .5f));
        } else {
            return backgroundWidth - AndroidUtilities.dp(mediaBackground ? 22 : 31);
        }
    }

    public void updateButtonState(boolean ifSame, boolean animated, boolean fromSet) {
        if (currentMessageObject == null) {
            return;
        }
        if (animated && (PhotoViewer.isShowingImage(currentMessageObject) || !attachedToWindow)) {
            animated = false;
        }
        drawRadialCheckBackground = false;
        String fileName = null;
        boolean fileExists = false;
        if (currentMessageObject.type == MessageObject.TYPE_PHOTO) {
            if (currentPhotoObject == null) {
                radialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, animated);
                return;
            }
            fileName = FileLoader.getAttachFileName(currentPhotoObject);
            fileExists = currentMessageObject.mediaExists;
        } else if (
            currentMessageObject.type == MessageObject.TYPE_GIF ||
            documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND ||
            documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
            documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER ||
            currentMessageObject.type == MessageObject.TYPE_FILE ||
            documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO ||
            documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC
        ) {
            if (currentMessageObject.useCustomPhoto) {
                buttonState = 1;
                radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                return;
            }
            if (currentMessageObject.attachPathExists && !TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) {
                fileName = currentMessageObject.messageOwner.attachPath;
                fileExists = true;
            } else if (!currentMessageObject.isSendError() || documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
                fileName = currentMessageObject.getFileName();
                fileExists = currentMessageObject.mediaExists;
            }
        } else if (documentAttachType != DOCUMENT_ATTACH_TYPE_NONE) {
            fileName = FileLoader.getAttachFileName(documentAttach);
            fileExists = currentMessageObject.mediaExists;
        } else if (currentPhotoObject != null) {
            fileName = FileLoader.getAttachFileName(currentPhotoObject);
            fileExists = currentMessageObject.mediaExists;
        }

        boolean autoDownload;
        if (documentAttach != null && documentAttach.dc_id == Integer.MIN_VALUE) {
            autoDownload = false;
        } else {
            autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
        }
        canStreamVideo = (
            (currentMessageObject.isSent() || currentMessageObject.isForwarded()) &&
            (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
             documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND ||
             documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && autoDownload
            ) &&
            currentMessageObject.canStreamVideo() &&
            !currentMessageObject.needDrawBluredPreview()
        );
        if (
            SharedConfig.streamMedia &&
            (int) currentMessageObject.getDialogId() != 0 &&
            !currentMessageObject.isSecretMedia() && (
                documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC ||
                canStreamVideo && currentPosition != null && (
                    (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0 ||
                    (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0
                )
            )
        ) {
            hasMiniProgress = fileExists ? 1 : 2;
            fileExists = true;
        }
        if (currentMessageObject.isSendError() || TextUtils.isEmpty(fileName) && (currentMessageObject.isAnyKindOfSticker() || !currentMessageObject.isSending() && !currentMessageObject.isEditing())) {
            radialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
            radialProgress.setMiniIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
            videoRadialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
            videoRadialProgress.setMiniIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
            return;
        }
        boolean fromBot = currentMessageObject.messageOwner.params != null && currentMessageObject.messageOwner.params.containsKey("query_id");

        if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen() && canStreamVideo) {
            if (currentMessageObject.isOut() && (currentMessageObject.isSending() && !currentMessageObject.isForwarded() || currentMessageObject.isEditing() && currentMessageObject.isEditingMedia()) || currentMessageObject.isSendError() && fromBot) {
                if (!TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) {
                    DownloadController.getInstance(currentAccount).addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, currentMessageObject, this);
                    wasSending = true;
                    buttonState = 4;
                    boolean sending = SendMessagesHelper.getInstance(currentAccount).isSendingMessage(currentMessageObject.getId());
                    if (currentPosition != null && sending && buttonState == 4) {
                        drawRadialCheckBackground = true;
                        getIconForCurrentState();
                        radialProgress.setIcon(MediaActionDrawable.ICON_CHECK, ifSame, animated);
                    } else {
                        radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                    }
                    radialProgress.setMiniIcon(MediaActionDrawable.ICON_NONE, ifSame, animated);
                    if (!fromBot) {
                        long[] progress = ImageLoader.getInstance().getFileProgressSizes(currentMessageObject.messageOwner.attachPath);
                        float loadingProgress = 0;
                        if (progress == null && sending) {
                            loadingProgress = 1.0f;
                        } else if (progress != null) {
                            loadingProgress = DownloadController.getProgress(progress);
                        }
                        radialProgress.setProgress(loadingProgress, false);
                    } else {
                        radialProgress.setProgress(0, false);
                    }
                } else {
                    buttonState = -1;
                    getIconForCurrentState();
                    radialProgress.setIcon(MediaActionDrawable.ICON_CANCEL_NOPROFRESS, ifSame, false);
                    radialProgress.setProgress(0, false);
                    radialProgress.setMiniIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
                }
            } else {
                if (hasMiniProgress != 0) {
                    radialProgress.setMiniProgressBackgroundColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLoader : Theme.key_chat_inLoader));
                    boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
                    if (!playing || MediaController.getInstance().isMessagePaused()) {
                        buttonState = 0;
                    } else {
                        buttonState = 1;
                    }
                    radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                    if (hasMiniProgress == 1) {
                        DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                        miniButtonState = -1;
                    } else {
                        DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                        if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                            createLoadingProgressLayout(documentAttach);
                            miniButtonState = 0;
                        } else {
                            miniButtonState = 1;
                            long[] progress = ImageLoader.getInstance().getFileProgressSizes(fileName);
                            if (progress != null) {
                                radialProgress.setProgress(DownloadController.getProgress(progress), animated);
                                createLoadingProgressLayout(progress[0], progress[1]);
                            } else {
                                radialProgress.setProgress(0, animated);
                                createLoadingProgressLayout(0, currentMessageObject.getSize());
                            }
                        }
                    }
                    radialProgress.setMiniIcon(getMiniIconForCurrentState(), ifSame, animated);
                } else if (fileExists) {
                    DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                    boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
                    if (!playing || MediaController.getInstance().isMessagePaused()) {
                        buttonState = 0;
                    } else {
                        buttonState = 1;
                    }
                    radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                } else {
                    DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                    if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                        buttonState = 2;
                    } else {
                        buttonState = 4;
                        long[] progress = ImageLoader.getInstance().getFileProgressSizes(fileName);
                        if (progress != null) {
                            radialProgress.setProgress(DownloadController.getProgress(progress), animated);
                            createLoadingProgressLayout(progress[0], progress[1]);
                        } else {
                            createLoadingProgressLayout(documentAttach);
                            radialProgress.setProgress(0, animated);
                        }
                    }
                    radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                }
            }
            updatePlayingMessageProgress();
        } else if (
            currentMessageObject.type == MessageObject.TYPE_TEXT &&
            documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT &&
            documentAttachType != DOCUMENT_ATTACH_TYPE_GIF &&
            documentAttachType != DOCUMENT_ATTACH_TYPE_VIDEO &&
            documentAttachType != DOCUMENT_ATTACH_TYPE_WALLPAPER &&
            documentAttachType != DOCUMENT_ATTACH_TYPE_THEME
        ) {
            if (currentPhotoObject == null || !drawImageButton) {
                return;
            }
            if (!fileExists) {
                DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                float setProgress = 0;
                if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                    if (
                        !currentMessageObject.loadingCancelled && autoDownload && (
                            documentAttachType == 0 ||
                            documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && MessageObject.isGifDocument(documentAttach, currentMessageObject.hasValidGroupId())
                        )
                    ) {
                        buttonState = 1;
                    } else {
                        buttonState = 0;
                    }
                } else {
                    buttonState = 1;
                    long[] progress = ImageLoader.getInstance().getFileProgressSizes(fileName);
                    setProgress = progress != null ? DownloadController.getProgress(progress) : 0;
                    if (progress != null && progress[0] == progress[1]) {
                        createLoadingProgressLayout(progress[0], progress[1]);
                    } else {
                        if (currentMessageObject.getDocument() != null) {
                            createLoadingProgressLayout(currentMessageObject.loadedFileSize, currentMessageObject.getSize());
                        }
                    }
                }
                radialProgress.setProgress(setProgress, false);
            } else {
                DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && !photoImage.isAllowStartAnimation()) {
                    buttonState = 2;
                } else {
                    buttonState = -1;
                }
            }
            radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
            invalidate();
        } else {
            if (currentMessageObject.isOut() && (currentMessageObject.isSending() && !currentMessageObject.isForwarded() || currentMessageObject.isEditing() && currentMessageObject.isEditingMedia())) {
                if (!TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) {
                    DownloadController.getInstance(currentAccount).addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, currentMessageObject, this);
                    wasSending = true;
                    boolean needProgress = currentMessageObject.messageOwner.attachPath == null || !currentMessageObject.messageOwner.attachPath.startsWith("http");
                    HashMap<String, String> params = currentMessageObject.messageOwner.params;
                    if (currentMessageObject.messageOwner.message != null && params != null && (params.containsKey("url") || params.containsKey("bot"))) {
                        needProgress = false;
                        buttonState = -1;
                    } else {
                        buttonState = 1;
                    }
                    boolean sending = SendMessagesHelper.getInstance(currentAccount).isSendingMessage(currentMessageObject.getId());
                    if (currentPosition != null && sending && buttonState == 1) {
                        drawRadialCheckBackground = true;
                        getIconForCurrentState();
                        radialProgress.setIcon(MediaActionDrawable.ICON_CHECK, ifSame, animated);
                    } else {
                        radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                    }
                    if (needProgress) {
                        long[] progress = ImageLoader.getInstance().getFileProgressSizes(currentMessageObject.messageOwner.attachPath);
                        float loadingProgress = 0;
                        if (progress == null && sending) {
                            loadingProgress = 1.0f;
                        } else if (progress != null) {
                            loadingProgress = DownloadController.getProgress(progress);
                            createLoadingProgressLayout(progress[0], progress[1]);
                        }
                        radialProgress.setProgress(loadingProgress, false);
                    } else {
                        radialProgress.setProgress(0, false);
                    }
                    invalidate();
                } else {
                    getIconForCurrentState();
                    if (currentMessageObject.isSticker() || currentMessageObject.isAnimatedSticker() || currentMessageObject.isLocation() || currentMessageObject.isGif()) {
                        buttonState = -1;
                        radialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
                    } else {
                        buttonState = 1;
                        radialProgress.setIcon(MediaActionDrawable.ICON_CANCEL_NOPROFRESS, ifSame, false);
                    }
                    radialProgress.setProgress(0, false);
                }
                videoRadialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
            } else {
                if (wasSending && !TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) {
                    DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                }
                boolean isLoadingVideo = false;
                if ((documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) && autoPlayingMedia) {
                    isLoadingVideo = FileLoader.getInstance(currentAccount).isLoadingVideo(documentAttach, MediaController.getInstance().isPlayingMessage(currentMessageObject));
                    AnimatedFileDrawable animation = photoImage.getAnimation();
                    if (animation != null) {
                        if (currentMessageObject.hadAnimationNotReadyLoading) {
                            if (animation.hasBitmap()) {
                                currentMessageObject.hadAnimationNotReadyLoading = false;
                            }
                        } else {
                            currentMessageObject.hadAnimationNotReadyLoading = isLoadingVideo && !animation.hasBitmap();
                        }
                    } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && !fileExists) {
                        currentMessageObject.hadAnimationNotReadyLoading = true;
                    }
                }
                if (hasMiniProgress != 0) {
                    radialProgress.setMiniProgressBackgroundColor(getThemedColor(Theme.key_chat_inLoaderPhoto));
                    buttonState = 3;
                    radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                    if (hasMiniProgress == 1) {
                        DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                        miniButtonState = -1;
                    } else {
                        DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                        if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                            miniButtonState = 0;
                        } else {
                            miniButtonState = 1;
                            long[] progress = ImageLoader.getInstance().getFileProgressSizes(fileName);
                            if (progress != null) {
                                createLoadingProgressLayout(progress[0], progress[1]);
                                radialProgress.setProgress(DownloadController.getProgress(progress), animated);
                            } else {
                                createLoadingProgressLayout(documentAttach);
                                radialProgress.setProgress(0, animated);
                            }
                        }
                    }
                    radialProgress.setMiniIcon(getMiniIconForCurrentState(), ifSame, animated);
                } else if (fileExists || (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) && autoPlayingMedia && !currentMessageObject.hadAnimationNotReadyLoading && !isLoadingVideo) {
                    DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                    if (drawVideoImageButton && animated) {
                        if (animatingDrawVideoImageButton != 1 && animatingDrawVideoImageButtonProgress > 0) {
                            if (animatingDrawVideoImageButton == 0) {
                                animatingDrawVideoImageButtonProgress = 1.0f;
                            }
                            animatingDrawVideoImageButton = 1;
                        }
                    } else if (animatingDrawVideoImageButton == 0) {
                        animatingDrawVideoImageButton = 1;
                    }
                    drawVideoImageButton = false;
                    drawVideoSize = false;
                    if (currentMessageObject.needDrawBluredPreview()) {
                        buttonState = -1;
                    } else {
                        if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && currentMessageObject.gifState == 1) {
                            if (photoImage.isAnimationRunning()) {
                                currentMessageObject.gifState = 0;
                                buttonState = -1;
                            } else {
                                buttonState = 2;
                            }
                        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && !hasEmbed) {
                            buttonState = 3;
                        } else {
                            buttonState = -1;
                        }
                    }
                    videoRadialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, animatingDrawVideoImageButton != 0);
                    radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                    if (!fromSet && photoNotSet) {
                        setMessageObject(currentMessageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
                    }
                    invalidate();
                } else {
                    drawVideoSize = documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF;
                    if ((documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) && canStreamVideo && !drawVideoImageButton && animated) {
                        if (animatingDrawVideoImageButton != 2 && animatingDrawVideoImageButtonProgress < 1.0f) {
                            if (animatingDrawVideoImageButton == 0) {
                                animatingDrawVideoImageButtonProgress = 0.0f;
                            }
                            animatingDrawVideoImageButton = 2;
                        }
                    } else if (animatingDrawVideoImageButton == 0) {
                        animatingDrawVideoImageButtonProgress = 1.0f;
                    }
                    DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                    boolean progressVisible = false;
                    if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
                        if (!currentMessageObject.loadingCancelled && autoDownload) {
                            buttonState = 1;
                        } else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
                            buttonState = -1;
                        } else {
                            buttonState = 0;
                        }
                        boolean hasDocLayout = currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO;
                        boolean fullWidth = true;
                        if (currentPosition != null) {
                            int mask = MessageObject.POSITION_FLAG_LEFT | MessageObject.POSITION_FLAG_RIGHT;
                            fullWidth = (currentPosition.flags & mask) == mask;
                        }
                        if ((documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && autoDownload) && canStreamVideo && hasDocLayout && fullWidth) {
                            drawVideoImageButton = true;
                            getIconForCurrentState();
                            radialProgress.setIcon(autoPlayingMedia ? MediaActionDrawable.ICON_NONE : MediaActionDrawable.ICON_PLAY, ifSame, animated);
                            videoRadialProgress.setIcon(MediaActionDrawable.ICON_DOWNLOAD, ifSame, animated);
                        } else {
                            drawVideoImageButton = false;
                            radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                            videoRadialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
                            if (!drawVideoSize && animatingDrawVideoImageButton == 0) {
                                animatingDrawVideoImageButtonProgress = 0.0f;
                            }
                        }
                    } else {
                        buttonState = 1;
                        long[] progress = ImageLoader.getInstance().getFileProgressSizes(fileName);
                        if (progress != null) {
                            createLoadingProgressLayout(progress[0], progress[1]);
                        } else {
                            createLoadingProgressLayout(documentAttach);
                        }
                        boolean hasDocLayout = currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO;
                        boolean fullWidth = true;
                        if (currentPosition != null) {
                            int mask = MessageObject.POSITION_FLAG_LEFT | MessageObject.POSITION_FLAG_RIGHT;
                            fullWidth = (currentPosition.flags & mask) == mask;
                        }
                        if ((documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || MessageObject.isGifDocument(documentAttach, currentMessageObject.hasValidGroupId()) && autoDownload) && canStreamVideo && hasDocLayout && fullWidth) {
                            drawVideoImageButton = true;
                            getIconForCurrentState();
                            radialProgress.setIcon(autoPlayingMedia || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF ? MediaActionDrawable.ICON_NONE : MediaActionDrawable.ICON_PLAY, ifSame, animated);
                            videoRadialProgress.setProgress(progress != null ? DownloadController.getProgress(progress) : 0, animated);
                            videoRadialProgress.setIcon(MediaActionDrawable.ICON_CANCEL_FILL, ifSame, animated);
                        } else {
                            drawVideoImageButton = false;
                            radialProgress.setProgress(progress != null ? DownloadController.getProgress(progress) : 0, animated);
                            radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
                            videoRadialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
                            if (!drawVideoSize && animatingDrawVideoImageButton == 0) {
                                animatingDrawVideoImageButtonProgress = 0.0f;
                            }
                        }
                    }
                    invalidate();
                }
            }
        }
        if (hasMiniProgress == 0) {
            radialProgress.setMiniIcon(MediaActionDrawable.ICON_NONE, false, animated);
        }
    }

    private void didPressMiniButton(boolean animated) {
        if (miniButtonState == 0) {
            miniButtonState = 1;
            radialProgress.setProgress(0, false);
            if (currentMessageObject != null && !currentMessageObject.isAnyKindOfSticker()) {
                currentMessageObject.putInDownloadsStore = true;
            }
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
                FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                currentMessageObject.loadingCancelled = false;
            } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                createLoadingProgressLayout(documentAttach);
                FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                currentMessageObject.loadingCancelled = false;
            }
            radialProgress.setMiniIcon(getMiniIconForCurrentState(), false, true);
            invalidate();
        } else if (miniButtonState == 1) {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                    MediaController.getInstance().cleanupPlayer(true, true);
                }
            }
            miniButtonState = 0;
            currentMessageObject.loadingCancelled = true;
            FileLoader.getInstance(currentAccount).cancelLoadFile(documentAttach);
            radialProgress.setMiniIcon(getMiniIconForCurrentState(), false, true);
            invalidate();
        }
    }

    private void didPressButton(boolean animated, boolean video) {
        if (currentMessageObject != null && !currentMessageObject.isAnyKindOfSticker()) {
            currentMessageObject.putInDownloadsStore = true;
        }
        if (buttonState == 0 && (!drawVideoImageButton || video)) {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen() && currentMessageObject.mediaExists) {
                if (miniButtonState == 0) {
                    FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                    currentMessageObject.loadingCancelled = false;
                }
                if (delegate.needPlayMessage(currentMessageObject, false)) {
                    if (hasMiniProgress == 2 && miniButtonState != 1) {
                        miniButtonState = 1;
                        radialProgress.setProgress(0, false);
                        radialProgress.setMiniIcon(getMiniIconForCurrentState(), false, true);
                    }
                    updatePlayingMessageProgress();
                    buttonState = 1;
                    radialProgress.setIcon(getIconForCurrentState(), false, true);
                    invalidate();
                }
            } else {
                if (video) {
                    videoRadialProgress.setProgress(0, false);
                } else {
                    radialProgress.setProgress(0, false);
                }
                TLRPC.PhotoSize thumb;
                String thumbFilter;
                if (currentPhotoObject != null && (photoImage.hasNotThumb() || currentPhotoObjectThumb == null)) {
                    thumb = currentPhotoObject;
                    thumbFilter = thumb instanceof TLRPC.TL_photoStrippedSize || "s".equals(thumb.type) ? currentPhotoFilterThumb : currentPhotoFilter;
                } else {
                    thumb = currentPhotoObjectThumb;
                    thumbFilter = currentPhotoFilterThumb;
                }
                if (currentMessageObject.type == MessageObject.TYPE_PHOTO || currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW) {
                    photoImage.setForceLoading(true);
                    photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, currentPhotoObject.size, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                } else if (currentMessageObject.type == MessageObject.TYPE_GIF) {
                    FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                    if (currentMessageObject.loadedFileSize > 0) {
                        createLoadingProgressLayout(documentAttach);
                    }
                } else if (isRoundVideo) {
                    if (currentMessageObject.isSecretMedia()) {
                        FileLoader.getInstance(currentAccount).loadFile(currentMessageObject.getDocument(), currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 1);
                    } else {
                        currentMessageObject.gifState = 2;
                        TLRPC.Document document = currentMessageObject.getDocument();
                        photoImage.setForceLoading(true);
                        photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForObject(thumb, document), thumbFilter, document.size, null, currentMessageObject, 0);
                    }
                    wouldBeInPip = true;
                    ChatMessageCell.this.invalidate();
                } else if (currentMessageObject.type == MessageObject.TYPE_FILE) {
                    FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                    if (currentMessageObject.loadedFileSize > 0) {
                        createLoadingProgressLayout(documentAttach);
                    }
                } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
                    FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
                    if (currentMessageObject.loadedFileSize > 0) {
                        createLoadingProgressLayout(currentMessageObject.getDocument());
                    }
                } else if (currentMessageObject.type == MessageObject.TYPE_TEXT && documentAttachType != DOCUMENT_ATTACH_TYPE_NONE) {
                    if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
                        photoImage.setForceLoading(true);
                        photoImage.setImage(ImageLocation.getForDocument(documentAttach), null, ImageLocation.getForDocument(currentPhotoObject, documentAttach), currentPhotoFilterThumb, documentAttach.size, null, currentMessageObject, 0);
                        currentMessageObject.gifState = 2;
                        if (currentMessageObject.loadedFileSize > 0) {
                            createLoadingProgressLayout(currentMessageObject.getDocument());
                        }
                    } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                        FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                    } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER) {
                        photoImage.setImage(ImageLocation.getForDocument(documentAttach), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObject, documentAttach), "b1", 0, "jpg", currentMessageObject, 1);
                    }
                } else {
                    photoImage.setForceLoading(true);
                    photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, currentMessageObject, 0);
                }
                currentMessageObject.loadingCancelled = false;
                buttonState = 1;
                if (video) {
                    videoRadialProgress.setIcon(MediaActionDrawable.ICON_CANCEL_FILL, false, animated);
                } else {
                    radialProgress.setIcon(getIconForCurrentState(), false, animated);
                }
                invalidate();
            }
        } else if (buttonState == 1 && (!drawVideoImageButton || video)) {
            photoImage.setForceLoading(false);
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) {
                boolean result = MediaController.getInstance().pauseMessage(currentMessageObject);
                if (result) {
                    buttonState = 0;
                    radialProgress.setIcon(getIconForCurrentState(), false, animated);
                    invalidate();
                }
            } else {
                if (currentMessageObject.isOut() && !drawVideoImageButton && (currentMessageObject.isSending() || currentMessageObject.isEditing())) {
                    if (radialProgress.getIcon() != MediaActionDrawable.ICON_CHECK) {
                        delegate.didPressCancelSendButton(this);
                    }
                } else {
                    currentMessageObject.loadingCancelled = true;
                    if (
                        documentAttachType == DOCUMENT_ATTACH_TYPE_GIF ||
                        documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
                        documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ||
                        documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER
                    ) {
                        FileLoader.getInstance(currentAccount).cancelLoadFile(documentAttach);
                    } else if (
                        currentMessageObject.type == MessageObject.TYPE_TEXT ||
                        currentMessageObject.type == MessageObject.TYPE_PHOTO ||
                        currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW ||
                        currentMessageObject.type == MessageObject.TYPE_GIF ||
                        currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO
                    ) {
                        ImageLoader.getInstance().cancelForceLoadingForImageReceiver(photoImage);
                        photoImage.cancelLoadImage();
                    } else if (currentMessageObject.type == MessageObject.TYPE_FILE) {
                        FileLoader.getInstance(currentAccount).cancelLoadFile(currentMessageObject.getDocument());
                    }
                    buttonState = 0;
                    if (video) {
                        videoRadialProgress.setIcon(MediaActionDrawable.ICON_DOWNLOAD, false, animated);
                    } else {
                        radialProgress.setIcon(getIconForCurrentState(), false, animated);
                    }
                    invalidate();
                }
            }
        } else if (buttonState == 2) {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) {
                if (miniButtonState == 0) {
                    FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                    currentMessageObject.loadingCancelled = false;
                }
                if (delegate.needPlayMessage(currentMessageObject, false)) {
                    if (hasMiniProgress == 2 && miniButtonState != 1) {
                        miniButtonState = 1;
                        radialProgress.setProgress(0, false);
                        radialProgress.setMiniIcon(getMiniIconForCurrentState(), false, true);
                    }
                    updatePlayingMessageProgress();
                    buttonState = 1;
                    radialProgress.setIcon(getIconForCurrentState(), false, true);
                    invalidate();
                }
                if (isRoundVideo) {
                    wouldBeInPip = true;
                    ChatMessageCell.this.invalidate();
                }
            } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
                radialProgress.setProgress(0, false);
                FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
                currentMessageObject.loadingCancelled = false;
                buttonState = 4;
                radialProgress.setIcon(getIconForCurrentState(), true, animated);
                invalidate();
            } else {
                if (isRoundVideo) {
                    MessageObject playingMessage = MediaController.getInstance().getPlayingMessageObject();
                    if (playingMessage == null || !playingMessage.isRoundVideo()) {
                        photoImage.setAllowStartAnimation(true);
                        photoImage.startAnimation();
                    }
                } else {
                    photoImage.setAllowStartAnimation(true);
                    photoImage.startAnimation();
                }
                currentMessageObject.gifState = 0;
                buttonState = -1;
                radialProgress.setIcon(getIconForCurrentState(), false, animated);
            }
        } else if (buttonState == 3 || buttonState == 0) {
            if (hasMiniProgress == 2 && miniButtonState != 1) {
                miniButtonState = 1;
                radialProgress.setProgress(0, false);
                radialProgress.setMiniIcon(getMiniIconForCurrentState(), false, animated);
            }
            delegate.didPressImage(this, 0, 0);
        } else if (buttonState == 4) {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) {
                if (currentMessageObject.isOut() && (currentMessageObject.isSending() || currentMessageObject.isEditing()) || currentMessageObject.isSendError()) {
                    if (delegate != null && radialProgress.getIcon() != MediaActionDrawable.ICON_CHECK) {
                        delegate.didPressCancelSendButton(this);
                    }
                } else {
                    currentMessageObject.loadingCancelled = true;
                    FileLoader.getInstance(currentAccount).cancelLoadFile(documentAttach);
                    buttonState = 2;
                    radialProgress.setIcon(getIconForCurrentState(), false, animated);
                    invalidate();
                }
            }
        }
    }

    @Override
    public void onFailedDownload(String fileName, boolean canceled) {
        updateButtonState(true, documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC, false);
    }

    @Override
    public void onSuccessDownload(String fileName) {
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER && currentMessageObject.isDice()) {
            DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
            setCurrentDiceValue(true);
        } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
            updateButtonState(false, true, false);
            updateWaveform();
        } else {
            if (drawVideoImageButton) {
                videoRadialProgress.setProgress(1, true);
            } else {
                radialProgress.setProgress(1, true);
            }
            if (!currentMessageObject.needDrawBluredPreview() && !autoPlayingMedia && documentAttach != null) {
                if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                    photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
                    photoImage.setAllowStartAnimation(true);
                    photoImage.startAnimation();
                    autoPlayingMedia = true;
                } else if (SharedConfig.isAutoplayVideo() && documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0)) {
                    animatingNoSound = 2;
                    photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
                    if (!PhotoViewer.isPlayingMessage(currentMessageObject)) {
                        photoImage.setAllowStartAnimation(true);
                        photoImage.startAnimation();
                    } else {
                        photoImage.setAllowStartAnimation(false);
                    }
                    autoPlayingMedia = true;
                } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
                    photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
                    if (SharedConfig.isAutoplayGifs()) {
                        photoImage.setAllowStartAnimation(true);
                        photoImage.startAnimation();
                    } else {
                        photoImage.setAllowStartAnimation(false);
                        photoImage.stopAnimation();
                    }
                    autoPlayingMedia = true;
                }
            }
            if (currentMessageObject.type == MessageObject.TYPE_TEXT) {
                if (!autoPlayingMedia && documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && currentMessageObject.gifState != 1) {
                    buttonState = 2;
                    didPressButton(true, false);
                } else if (!photoNotSet) {
                    updateButtonState(false, true, false);
                } else {
                    setMessageObject(currentMessageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
                }
            } else {
                if (!photoNotSet) {
                    updateButtonState(false, true, false);
                }
                if (photoNotSet) {
                    setMessageObject(currentMessageObject, currentMessagesGroup, pinnedBottom, pinnedTop);
                }
            }
        }
    }

    @Override
    public void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb, boolean memCache) {
        if (currentMessageObject != null && set) {
            if (setCurrentDiceValue(!memCache && !currentMessageObject.wasUnread)) {
                return;
            }
            if (
                thumb && currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW && !currentMessageObject.mediaExists ||
                !thumb && !currentMessageObject.mediaExists && !currentMessageObject.attachPathExists && (
                    currentMessageObject.type == MessageObject.TYPE_TEXT && (
                        documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER ||
                        documentAttachType == DOCUMENT_ATTACH_TYPE_NONE ||
                        documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER
                    ) ||
                    currentMessageObject.type == MessageObject.TYPE_PHOTO
                )
            ) {
                currentMessageObject.mediaExists = true;
                updateButtonState(false, true, false);
            }
        }
        if (set && currentMessageObject != null) {
            if (blurredPhotoImage.getBitmap() != null) {
                blurredPhotoImage.getBitmap().recycle();
                blurredPhotoImage.setImageBitmap((Bitmap) null);
            }
            if (currentMessageObject.hasMediaSpoilers() && imageReceiver.getBitmap() != null && !imageReceiver.getBitmap().isRecycled()) {
                blurredPhotoImage.setImageBitmap(Utilities.stackBlurBitmapMax(imageReceiver.getBitmap()));
            }
        }
    }

    public boolean setCurrentDiceValue(boolean instant) {
        if (currentMessageObject.isDice()) {
            Drawable drawable = photoImage.getDrawable();
            if (drawable instanceof RLottieDrawable) {
                RLottieDrawable lottieDrawable = (RLottieDrawable) drawable;
                String emoji = currentMessageObject.getDiceEmoji();
                TLRPC.TL_messages_stickerSet stickerSet = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(emoji);
                if (stickerSet != null) {
                    int value = currentMessageObject.getDiceValue();
                    if ("\uD83C\uDFB0".equals(currentMessageObject.getDiceEmoji())) {
                        if (value >= 0 && value <= 64) {
                            ((SlotsDrawable) lottieDrawable).setDiceNumber(this, value, stickerSet, instant);
                            if (currentMessageObject.isOut()) {
                                lottieDrawable.setOnFinishCallback(diceFinishCallback, Integer.MAX_VALUE);
                            }
                            currentMessageObject.wasUnread = false;
                        }
                        if (!lottieDrawable.hasBaseDice() && stickerSet.documents.size() > 0) {
                            ((SlotsDrawable) lottieDrawable).setBaseDice(this, stickerSet);
                        }
                    } else {
                        if (!lottieDrawable.hasBaseDice() && stickerSet.documents.size() > 0) {
                            TLRPC.Document document = stickerSet.documents.get(0);
                            File path = FileLoader.getInstance(currentAccount).getPathToAttach(document, true);
                            if (lottieDrawable.setBaseDice(path)) {
                                DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                            } else {
                                String fileName = FileLoader.getAttachFileName(document);
                                DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                                FileLoader.getInstance(currentAccount).loadFile(document, stickerSet, FileLoader.PRIORITY_NORMAL, 1);
                            }
                        }
                        if (value >= 0 && value < stickerSet.documents.size()) {
                            if (!instant && currentMessageObject.isOut()) {
                                MessagesController.DiceFrameSuccess frameSuccess = MessagesController.getInstance(currentAccount).diceSuccess.get(emoji);
                                if (frameSuccess != null && frameSuccess.num == value) {
                                    lottieDrawable.setOnFinishCallback(diceFinishCallback, frameSuccess.frame);
                                }
                            }
                            TLRPC.Document document = stickerSet.documents.get(Math.max(value, 0));
                            File path = FileLoader.getInstance(currentAccount).getPathToAttach(document, true);
                            if (lottieDrawable.setDiceNumber(path, instant)) {
                                DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
                            } else {
                                String fileName = FileLoader.getAttachFileName(document);
                                DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
                                FileLoader.getInstance(currentAccount).loadFile(document, stickerSet, FileLoader.PRIORITY_NORMAL, 1);
                            }
                            currentMessageObject.wasUnread = false;
                        }
                    }
                } else {
                    MediaDataController.getInstance(currentAccount).loadStickersByEmojiOrName(emoji, true, true);
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public void onAnimationReady(ImageReceiver imageReceiver) {
        if (currentMessageObject != null && imageReceiver == photoImage && currentMessageObject.isAnimatedSticker()) {
            delegate.setShouldNotRepeatSticker(currentMessageObject);
        }
    }

    @Override
    public void onProgressDownload(String fileName, long downloadedSize, long totalSize) {
        float progress = totalSize == 0 ? 0 : Math.min(1f, downloadedSize / (float) totalSize);
        currentMessageObject.loadedFileSize = downloadedSize;
        createLoadingProgressLayout(downloadedSize, totalSize);
        if (drawVideoImageButton) {
            videoRadialProgress.setProgress(progress, true);
        } else {
            radialProgress.setProgress(progress, true);
        }
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
            if (hasMiniProgress != 0) {
                if (miniButtonState != 1) {
                    updateButtonState(false, false, false);
                }
            } else {
                if (buttonState != 4) {
                    updateButtonState(false, false, false);
                }
            }
        } else {
            if (hasMiniProgress != 0) {
                if (miniButtonState != 1) {
                    updateButtonState(false, false, false);
                }
            } else {
                if (buttonState != 1) {
                    updateButtonState(false, false, false);
                }
            }
        }
    }

    @Override
    public void onProgressUpload(String fileName, long uploadedSize, long totalSize, boolean isEncrypted) {
        float progress = totalSize == 0 ? 0 : Math.min(1f, uploadedSize / (float) totalSize);
        currentMessageObject.loadedFileSize = uploadedSize;
        radialProgress.setProgress(progress, true);
        if (uploadedSize == totalSize && currentPosition != null) {
            boolean sending = SendMessagesHelper.getInstance(currentAccount).isSendingMessage(currentMessageObject.getId());
            if (sending && (buttonState == 1 || buttonState == 4 && documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC)) {
                drawRadialCheckBackground = true;
                getIconForCurrentState();
                radialProgress.setIcon(MediaActionDrawable.ICON_CHECK, false, true);
            }
        }
        createLoadingProgressLayout(uploadedSize, totalSize);
    }

    private void createLoadingProgressLayout(TLRPC.Document document) {
        if (document == null) {
            return;
        }
        long[] progresses = ImageLoader.getInstance().getFileProgressSizes(FileLoader.getDocumentFileName(document));
        if (progresses != null) {
            createLoadingProgressLayout(progresses[0], progresses[1]);
        } else {
            createLoadingProgressLayout(currentMessageObject.loadedFileSize, document.size);
        }
    }

    private void createLoadingProgressLayout(long loadedSize, long totalSize) {
        if (totalSize <= 0 || documentAttach == null) {
            loadingProgressLayout = null;
            return;
        }

        if (lastLoadingSizeTotal == 0) {
            lastLoadingSizeTotal = totalSize;
        } else {
            totalSize = lastLoadingSizeTotal;
            if (loadedSize > lastLoadingSizeTotal) {
                loadedSize = lastLoadingSizeTotal;
            }
        }

        String totalStr = AndroidUtilities.formatFileSize(totalSize);
        String maxAvailableString = String.format("000.0 mm / %s", totalStr);
        String str;
        int w;
        w = (int) Math.ceil(Theme.chat_infoPaint.measureText(maxAvailableString));
        boolean fullWidth = true;
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
            int max = Math.max(this.infoWidth, docTitleWidth);
            if (w <= max) {
                str = String.format("%s / %s", AndroidUtilities.formatFileSize(loadedSize), totalStr);
            } else {
                str = AndroidUtilities.formatFileSize(loadedSize);
            }
        } else {
            if (currentPosition != null) {
                int mask = MessageObject.POSITION_FLAG_LEFT | MessageObject.POSITION_FLAG_RIGHT;
                fullWidth = (currentPosition.flags & mask) == mask;
            }
            if (!fullWidth) {
                int percent = (int) (Math.min(1f, loadedSize / (float) totalSize) * 100);
                if (percent >= 100) {
                    str = "100%";
                } else {
                    str = String.format(Locale.US, "%2d%%", percent);
                }
            } else {
                str = String.format("%s / %s", AndroidUtilities.formatFileSize(loadedSize), totalStr);
            }
        }
        w = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
        if (fullWidth && w > backgroundWidth - AndroidUtilities.dp(48)) {
            int percent = (int) (Math.min(1f, loadedSize / (float) totalSize) * 100);
            if (percent >= 100) {
                str = "100%";
            } else {
                str = String.format(Locale.US, "%2d%%", percent);
            }
            w = (int) Math.ceil(Theme.chat_infoPaint.measureText(str));
        }
        loadingProgressLayout = new StaticLayout(str, Theme.chat_infoPaint, w, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
//        if (loadingProgressLayout != null) {
//            loadingProgressLayout.copyStylesFrom(Theme.chat_infoPaint);
//            loadingProgressLayout.setBounds(0, 0, w, (int) Theme.chat_infoPaint.getTextSize());
//            loadingProgressLayout.setText(str, true);
//        } else {
//            loadingProgressLayout = new AnimatedTextView.AnimatedTextDrawable(false, true, true);
//            loadingProgressLayout.setAnimationProperties(0.3f, 0, 140, CubicBezierInterpolator.EASE_OUT);
//            loadingProgressLayout.setCallback(this);
//            loadingProgressLayout.copyStylesFrom(Theme.chat_infoPaint);
//            loadingProgressLayout.setBounds(0, 0, w, (int) Theme.chat_infoPaint.getTextSize());
//            loadingProgressLayout.setText(str, false);
//        }
    }


    @Override
    public void onProvideStructure(ViewStructure structure) {
        super.onProvideStructure(structure);
        if (allowAssistant && Build.VERSION.SDK_INT >= 23) {
            if (currentMessageObject.messageText != null && currentMessageObject.messageText.length() > 0) {
                structure.setText(currentMessageObject.messageText);
            } else if (currentMessageObject.caption != null && currentMessageObject.caption.length() > 0) {
                structure.setText(currentMessageObject.caption);
            }
        }
    }

    public void setDelegate(ChatMessageCellDelegate chatMessageCellDelegate) {
        delegate = chatMessageCellDelegate;
    }

    public ChatMessageCellDelegate getDelegate() {
        return delegate;
    }

    public void setAllowAssistant(boolean value) {
        allowAssistant = value;
    }

    private void measureTime(MessageObject messageObject) {
        CharSequence signString;
        long fromId = messageObject.getFromChatId();
        if (messageObject.scheduled) {
            signString = null;
        } else if (messageObject.messageOwner.post_author != null) {
            if (isMegagroup && messageObject.getFromChatId() == messageObject.getDialogId()) {
                signString = null;
            } else {
                signString = messageObject.messageOwner.post_author.replace("\n", "");
            }
        } else if (messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.post_author != null) {
            signString = messageObject.messageOwner.fwd_from.post_author.replace("\n", "");
        } else if (messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.imported) {
            if (messageObject.messageOwner.fwd_from.date == messageObject.messageOwner.date) {
                signString = LocaleController.getString("ImportedMessage", R.string.ImportedMessage);
            } else {
                signString = LocaleController.formatImportedDate(messageObject.messageOwner.fwd_from.date) + " " + LocaleController.getString("ImportedMessage", R.string.ImportedMessage);
            }
        } else if (!messageObject.isOutOwner() && fromId > 0 && messageObject.messageOwner.post) {
            TLRPC.User signUser = MessagesController.getInstance(currentAccount).getUser(fromId);
            if (signUser != null) {
                signString = ContactsController.formatName(signUser.first_name, signUser.last_name).replace('\n', ' ');
            } else {
                signString = null;
            }
        } else {
            signString = null;
        }
        String timeString;
        TLRPC.User author = null;
        if (currentMessageObject.isFromUser()) {
            author = MessagesController.getInstance(currentAccount).getUser(fromId);
        }
        boolean hasReplies = messageObject.hasReplies();
        if (messageObject.scheduled || messageObject.isLiveLocation() || messageObject.messageOwner.edit_hide || messageObject.getDialogId() == 777000 || messageObject.messageOwner.via_bot_id != 0 || messageObject.messageOwner.via_bot_name != null || author != null && author.bot) {
            edited = false;
        } else if (currentPosition == null || currentMessagesGroup == null || currentMessagesGroup.messages.isEmpty()) {
            edited = (messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_EDITED) != 0 || messageObject.isEditing();
        } else {
            edited = false;
            hasReplies = currentMessagesGroup.messages.get(0).hasReplies();
            if (!currentMessagesGroup.messages.get(0).messageOwner.edit_hide) {
                for (int a = 0, size = currentMessagesGroup.messages.size(); a < size; a++) {
                    MessageObject object = currentMessagesGroup.messages.get(a);
                    if ((object.messageOwner.flags & TLRPC.MESSAGE_FLAG_EDITED) != 0 || object.isEditing()) {
                        edited = true;
                        break;
                    }
                }
            }
        }
        if (currentMessageObject.isSponsored()) {
            if (currentMessageObject.sponsoredRecommended) {
                timeString = LocaleController.getString("SponsoredMessageRecommended", R.string.SponsoredMessageRecommended);
            } else {
                timeString = LocaleController.getString("SponsoredMessage", R.string.SponsoredMessage);
            }
        } else if (currentMessageObject.scheduled && currentMessageObject.messageOwner.date == 0x7FFFFFFE) {
            timeString = "";
        } else if (edited) {
            timeString = LocaleController.getString("EditedMessage", R.string.EditedMessage) + " " + LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
        } else {
            timeString = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
        }
        if (signString != null) {
            if (messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.imported) {
                currentTimeString = " " + timeString;
            } else {
                currentTimeString = ", " + timeString;
            }
        } else {
            currentTimeString = timeString;
        }
        timeTextWidth = timeWidth = (int) Math.ceil(Theme.chat_timePaint.measureText(currentTimeString, 0, currentTimeString == null ? 0 : currentTimeString.length()));
        if (currentMessageObject.scheduled && currentMessageObject.messageOwner.date == 0x7FFFFFFE) {
            timeWidth -= AndroidUtilities.dp(8);
        }
        if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
            currentViewsString = String.format("%s", LocaleController.formatShortNumber(Math.max(1, messageObject.messageOwner.views), null));
            viewsTextWidth = (int) Math.ceil(Theme.chat_timePaint.measureText(currentViewsString));
            float drawableWidth = Theme.chat_msgInViewsDrawable.getIntrinsicWidth() * (Theme.chat_timePaint.getTextSize() - AndroidUtilities.dp(2)) / Theme.chat_msgInViewsDrawable.getIntrinsicHeight();
            timeWidth += viewsTextWidth + drawableWidth + AndroidUtilities.dp(10);
        }
        if (messageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW) {
            String str = LocaleController.formatString(R.string.PaymentCheckoutPay, LocaleController.getInstance().formatCurrencyString(messageObject.messageOwner.media.total_amount, messageObject.messageOwner.media.currency).toUpperCase(Locale.ROOT));
            currentUnlockString = str.length() >= 2 ? str.substring(0, 1).toUpperCase(Locale.ROOT) + str.substring(1).toLowerCase(Locale.ROOT) : str;
            unlockTextWidth = (int) Math.ceil(Theme.chat_unlockExtendedMediaTextPaint.measureText(currentUnlockString));
        }
        if (isChat && isMegagroup && !isThreadChat && hasReplies) {
            currentRepliesString = String.format("%s", LocaleController.formatShortNumber(getRepliesCount(), null));
            repliesTextWidth = (int) Math.ceil(Theme.chat_timePaint.measureText(currentRepliesString));
            float drawableWidth = Theme.chat_msgInRepliesDrawable.getIntrinsicWidth() * (Theme.chat_timePaint.getTextSize() - AndroidUtilities.dp(2)) / Theme.chat_msgInRepliesDrawable.getIntrinsicHeight();
            timeWidth += repliesTextWidth + drawableWidth + AndroidUtilities.dp(10);
        } else {
            currentRepliesString = null;
        }
        if (isPinned) {
            timeWidth += Theme.chat_msgInPinnedDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3);
        }
        if (messageObject.scheduled) {
            if (messageObject.isSendError()) {
                timeWidth += AndroidUtilities.dp(18);
            } else if (messageObject.isSending() && messageObject.messageOwner.peer_id.channel_id != 0 && !messageObject.isSupergroup()) {
                timeWidth += AndroidUtilities.dp(18);
            }
        }
        if (reactionsLayoutInBubble.isSmall) {
            reactionsLayoutInBubble.measure(Integer.MAX_VALUE, Gravity.LEFT);
            timeWidth += reactionsLayoutInBubble.width;
        }
        if (signString != null) {
            if (availableTimeWidth == 0) {
                availableTimeWidth = AndroidUtilities.dp(1000);
            }
            int widthForSign = availableTimeWidth - timeWidth;
            if (messageObject.isOutOwner()) {
                if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                    widthForSign -= AndroidUtilities.dp(20);
                } else {
                    widthForSign -= AndroidUtilities.dp(96);
                }
            }
            signString = Emoji.replaceEmoji(signString, Theme.chat_timePaint.getFontMetricsInt(), AndroidUtilities.dp(10), false);
            int width = (int) Math.ceil(Theme.chat_timePaint.measureText(signString, 0, signString.length()));
            if (width > widthForSign) {
                if (widthForSign <= 0) {
                    signString = "";
                    width = 0;
                } else {
                    signString = TextUtils.ellipsize(signString, Theme.chat_timePaint, widthForSign, TextUtils.TruncateAt.END);
                    width = widthForSign;
                }
            }
            SpannableStringBuilder currentTimeStringBuilder = new SpannableStringBuilder(signString);
            currentTimeStringBuilder.append(currentTimeString);
            currentTimeString = currentTimeStringBuilder;
            timeTextWidth += width;
            timeWidth += width;
        }
    }

    private boolean shouldDrawSelectionOverlay() {
        return hasSelectionOverlay() &&
                (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted || isHighlightedAnimated) &&
                !textIsSelectionMode() &&
                (currentMessagesGroup == null || drawSelectionBackground) &&
                currentBackgroundDrawable != null;
    }

    private Integer getSelectionOverlayColor() {
        if (resourcesProvider == null) {
            return null;
        }
        return resourcesProvider.getColor(currentMessageObject != null && currentMessageObject.isOut() ? Theme.key_chat_outBubbleSelectedOverlay : Theme.key_chat_inBubbleSelectedOverlay);
    }

    private boolean hasSelectionOverlay() {
        Integer selectionOverlayColor = getSelectionOverlayColor();
        return selectionOverlayColor != null && selectionOverlayColor != 0xffff0000;
    }

    private boolean isDrawSelectionBackground() {
        return (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted) && !textIsSelectionMode() && !hasSelectionOverlay();
    }

    private boolean isOpenChatByShare(MessageObject messageObject) {
        return messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.saved_from_peer != null && (delegate == null || delegate.isReplyOrSelf());
    }

    private boolean checkNeedDrawShareButton(MessageObject messageObject) {
        if (currentMessageObject.deleted || currentMessageObject.isSponsored()) {
            return false;
        }
        if (currentPosition != null) {
            if (!currentMessagesGroup.isDocuments && !currentPosition.last) {
                return false;
            }
        }
        return messageObject.needDrawShareButton();
    }

    public boolean isInsideBackground(float x, float y) {
        return currentBackgroundDrawable != null && x >= backgroundDrawableLeft && x <= backgroundDrawableLeft + backgroundDrawableRight;
    }

    private void updateCurrentUserAndChat() {
        if (currentMessageObject == null) {
            return;
        }
        MessagesController messagesController = MessagesController.getInstance(currentAccount);
        TLRPC.MessageFwdHeader fwd_from = currentMessageObject.messageOwner.fwd_from;
        long currentUserId = UserConfig.getInstance(currentAccount).getClientUserId();
        if (fwd_from != null && fwd_from.from_id instanceof TLRPC.TL_peerChannel && currentMessageObject.getDialogId() == currentUserId) {
            currentChat = MessagesController.getInstance(currentAccount).getChat(fwd_from.from_id.channel_id);
        } else if (fwd_from != null && fwd_from.saved_from_peer != null) {
            if (fwd_from.saved_from_peer.user_id != 0) {
                if (fwd_from.from_id instanceof TLRPC.TL_peerUser) {
                    currentUser = messagesController.getUser(fwd_from.from_id.user_id);
                } else {
                    currentUser = messagesController.getUser(fwd_from.saved_from_peer.user_id);
                }
            } else if (fwd_from.saved_from_peer.channel_id != 0) {
                if (currentMessageObject.isSavedFromMegagroup() && fwd_from.from_id instanceof TLRPC.TL_peerUser) {
                    currentUser = messagesController.getUser(fwd_from.from_id.user_id);
                } else {
                    currentChat = messagesController.getChat(fwd_from.saved_from_peer.channel_id);
                }
            } else if (fwd_from.saved_from_peer.chat_id != 0) {
                if (fwd_from.from_id instanceof TLRPC.TL_peerUser) {
                    currentUser = messagesController.getUser(fwd_from.from_id.user_id);
                } else {
                    currentChat = messagesController.getChat(fwd_from.saved_from_peer.chat_id);
                }
            }
        } else if (fwd_from != null && fwd_from.from_id instanceof TLRPC.TL_peerUser && (fwd_from.imported || currentMessageObject.getDialogId() == currentUserId)) {
            currentUser = messagesController.getUser(fwd_from.from_id.user_id);
        } else if (fwd_from != null && !TextUtils.isEmpty(fwd_from.from_name) && (fwd_from.imported || currentMessageObject.getDialogId() == currentUserId)) {
            currentUser = new TLRPC.TL_user();
            currentUser.first_name = fwd_from.from_name;
        } else {
            long fromId = currentMessageObject.getFromChatId();
            if (DialogObject.isUserDialog(fromId) && !currentMessageObject.messageOwner.post) {
                currentUser = messagesController.getUser(fromId);
            } else if (DialogObject.isChatDialog(fromId)) {
                currentChat = messagesController.getChat(-fromId);
            } else if (currentMessageObject.messageOwner.post) {
                currentChat = messagesController.getChat(currentMessageObject.messageOwner.peer_id.channel_id);
            }
        }
        if (currentMessageObject != null && currentMessageObject.getChatId() != 0 && currentMessageObject.messageOwner != null && currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.isFromUser()) {
            currentReplyUserId = currentMessageObject.replyMessageObject.messageOwner.from_id.user_id;
        } else {
            currentReplyUserId = 0;
        }
    }

    private void setMessageObjectInternal(MessageObject messageObject) {
        if (((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0 || messageObject.messageOwner.replies != null) && !currentMessageObject.scheduled && !currentMessageObject.isSponsored()) {
            if (!currentMessageObject.viewsReloaded) {
                MessagesController.getInstance(currentAccount).addToViewsQueue(currentMessageObject);
                currentMessageObject.viewsReloaded = true;
            }
        }

        updateCurrentUserAndChat();
        setAvatar(messageObject);

        measureTime(messageObject);

        namesOffset = 0;

        String viaUsername = null;
        CharSequence viaString = null;
        if (messageObject.messageOwner.via_bot_id != 0) {
            TLRPC.User botUser = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.via_bot_id);
            if (botUser != null && !TextUtils.isEmpty(botUser.username)) {
                viaUsername = "@" + botUser.username;
                viaString = AndroidUtilities.replaceTags(String.format(" %s <b>%s</b>", LocaleController.getString("ViaBot", R.string.ViaBot), viaUsername));
                viaWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(viaString, 0, viaString.length()));
                currentViaBotUser = botUser;
            }
        } else if (!TextUtils.isEmpty(messageObject.messageOwner.via_bot_name)) {
            viaUsername = "@" + messageObject.messageOwner.via_bot_name;
            viaString = AndroidUtilities.replaceTags(String.format(" %s <b>%s</b>", LocaleController.getString("ViaBot", R.string.ViaBot), viaUsername));
            viaWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(viaString, 0, viaString.length()));
        }

        boolean needAuthorName = isNeedAuthorName();
        boolean viaBot = (messageObject.messageOwner.fwd_from == null || messageObject.type == MessageObject.TYPE_MUSIC) && viaUsername != null;
        if (!hasPsaHint && (needAuthorName || viaBot)) {
            drawNameLayout = true;
            nameWidth = getMaxNameWidth();
            if (nameWidth < 0) {
                nameWidth = AndroidUtilities.dp(100);
            }
            int adminWidth;
            String adminString;
            String adminLabel;
            if (isMegagroup && currentChat != null && messageObject.messageOwner.post_author != null && currentChat.id == -currentMessageObject.getFromChatId()) {
                adminString = messageObject.messageOwner.post_author.replace("\n", "");
                adminWidth = (int) Math.ceil(Theme.chat_adminPaint.measureText(adminString));
                nameWidth -= adminWidth;
            } else if (isMegagroup && currentChat != null && currentMessageObject.isForwardedChannelPost()) {
                adminString = LocaleController.getString("DiscussChannel", R.string.DiscussChannel);
                adminWidth = (int) Math.ceil(Theme.chat_adminPaint.measureText(adminString));
                nameWidth -= adminWidth;
            } else if ((currentUser != null || currentChat != null) && !currentMessageObject.isOutOwner() && !currentMessageObject.isAnyKindOfSticker() && currentMessageObject.type != MessageObject.TYPE_ROUND_VIDEO && delegate != null && (adminLabel = delegate.getAdminRank(currentUser != null ? currentUser.id : currentChat.id)) != null) {
                if (adminLabel.length() == 0) {
                    adminLabel = LocaleController.getString("ChatAdmin", R.string.ChatAdmin);
                }
                adminString = adminLabel;
                adminWidth = (int) Math.ceil(Theme.chat_adminPaint.measureText(adminString));
                nameWidth -= adminWidth;
            } else {
                adminString = null;
                adminWidth = 0;
            }

            currentNameStatus = null;
            if (messageObject.customName != null) {
                currentNameString = messageObject.customName;
            } else if (needAuthorName) {
                currentNameString = getAuthorName();
                currentNameStatus = getAuthorStatus();
            } else {
                currentNameString = "";
            }
            CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace('\n', ' ').replace('\u200F', ' '), Theme.chat_namePaint, nameWidth - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END);
            if (viaBot) {
                viaNameWidth = (int) Math.ceil(Theme.chat_namePaint.measureText(nameStringFinal, 0, nameStringFinal.length()));
                if (viaNameWidth != 0) {
                    viaNameWidth += AndroidUtilities.dp(4);
                }
                int color;
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    color = getThemedColor(Theme.key_chat_stickerViaBotNameText);
                } else {
                    color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outViaBotNameText : Theme.key_chat_inViaBotNameText);
                }
                String viaBotString = LocaleController.getString("ViaBot", R.string.ViaBot);
                if (currentNameString.length() > 0) {
                    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format("%s %s %s", nameStringFinal, viaBotString, viaUsername));
                    stringBuilder.setSpan(viaSpan1 = new TypefaceSpan(Typeface.DEFAULT, 0, color), nameStringFinal.length() + 1, nameStringFinal.length() + 1 + viaBotString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    stringBuilder.setSpan(viaSpan2 = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, color), nameStringFinal.length() + 2 + viaBotString.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    nameStringFinal = stringBuilder;
                } else {
                    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format("%s %s", viaBotString, viaUsername));
                    stringBuilder.setSpan(viaSpan1 = new TypefaceSpan(Typeface.DEFAULT, 0, color), 0, viaBotString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    stringBuilder.setSpan(viaSpan2 = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, color), 1 + viaBotString.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    nameStringFinal = stringBuilder;
                }
                nameStringFinal = TextUtils.ellipsize(nameStringFinal, Theme.chat_namePaint, nameWidth, TextUtils.TruncateAt.END);
            }
            try {
                nameStringFinal = Emoji.replaceEmoji(nameStringFinal, Theme.chat_namePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
            } catch (Exception ignore) {
            }
            try {
                nameLayout = new StaticLayout(nameStringFinal, Theme.chat_namePaint, nameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                if (nameLayout.getLineCount() > 0) {
                    nameWidth = nameLayoutWidth = (int) Math.ceil(nameLayout.getLineWidth(0));
                    if (!messageObject.isAnyKindOfSticker()) {
                        namesOffset += AndroidUtilities.dp(5) + Theme.chat_namePaint.getTextSize();
                    }
                    nameOffsetX = nameLayout.getLineLeft(0);
                } else {
                    nameWidth = nameLayoutWidth = 0;
                }
                if (currentNameStatus != null) {
                    nameWidth += AndroidUtilities.dp(4 + 12 + 4);
                }
                if (adminString != null) {
                    adminLayout = new StaticLayout(adminString, Theme.chat_adminPaint, adminWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    nameWidth += adminLayout.getLineWidth(0) + AndroidUtilities.dp(8);
                } else {
                    adminLayout = null;
                }
            } catch (Exception e) {
                FileLog.e(e);
            }
            if (currentNameStatusDrawable == null) {
                currentNameStatusDrawable = new AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable(this, true, AndroidUtilities.dp(20));
                if (attachedToWindow) {
                    currentNameStatusDrawable.attach();
                }
            }
            if (currentNameStatus == null) {
                currentNameStatusDrawable.set((Drawable) null, false);
            } else if (currentNameStatus instanceof Long) {
                currentNameStatusDrawable.set((long) currentNameStatus, false);
            } else if (currentNameStatus instanceof Drawable) {
                currentNameStatusDrawable.set((Drawable) currentNameStatus, false);
            }
            if (currentNameString.length() == 0) {
                currentNameString = null;
            }
        } else {
            currentNameString = null;
            nameLayout = null;
            nameWidth = 0;
        }

        currentForwardUser = null;
        currentForwardNameString = null;
        currentForwardChannel = null;
        currentForwardName = null;
        forwardedNameLayout[0] = null;
        forwardedNameLayout[1] = null;
        replyPanelIsForward = false;
        forwardedNameWidth = 0;
        if (messageObject.isForwarded()) {
            if (messageObject.messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChannel) {
                currentForwardChannel = MessagesController.getInstance(currentAccount).getChat(messageObject.messageOwner.fwd_from.from_id.channel_id);
            } else if (messageObject.messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChat) {
                currentForwardChannel = MessagesController.getInstance(currentAccount).getChat(messageObject.messageOwner.fwd_from.from_id.chat_id);
            } else if (messageObject.messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerUser) {
                currentForwardUser = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.fwd_from.from_id.user_id);
            }
        }
        if (drawForwardedName && messageObject.needDrawForwarded() && (currentPosition == null || currentPosition.minY == 0)) {
            if (messageObject.messageOwner.fwd_from.from_name != null) {
                currentForwardName = messageObject.messageOwner.fwd_from.from_name;
            }

            if (currentForwardUser != null || currentForwardChannel != null || currentForwardName != null) {
                if (currentForwardChannel != null) {
                    if (currentForwardUser != null) {
                        currentForwardNameString = String.format("%s (%s)", currentForwardChannel.title, UserObject.getUserName(currentForwardUser));
                    } else if (!TextUtils.isEmpty(messageObject.messageOwner.fwd_from.post_author)) {
                        currentForwardNameString = String.format("%s (%s)", currentForwardChannel.title, messageObject.messageOwner.fwd_from.post_author);
                    } else {
                        currentForwardNameString = currentForwardChannel.title;
                    }
                } else if (currentForwardUser != null) {
                    currentForwardNameString = UserObject.getUserName(currentForwardUser);
                } else {
                    currentForwardNameString = currentForwardName;
                }

                forwardedNameWidth = getMaxNameWidth();
                String forwardedString = getForwardedMessageText(messageObject);
                if (hasPsaHint) {
                    forwardedNameWidth -= AndroidUtilities.dp(36);
                }
                String from = LocaleController.getString("From", R.string.From);
                String fromFormattedString = LocaleController.getString("FromFormatted", R.string.FromFormatted);
                int idx = fromFormattedString.indexOf("%1$s");
                int fromWidth = (int) Math.ceil(Theme.chat_forwardNamePaint.measureText(from + " "));
                CharSequence name = TextUtils.ellipsize(currentForwardNameString.replace('\n', ' '), Theme.chat_replyNamePaint, forwardedNameWidth - fromWidth - viaWidth, TextUtils.TruncateAt.END);
                String fromString;
                try {
                    fromString = String.format(fromFormattedString, name);
                } catch (Exception e) {
                    fromString = name.toString();
                }
                CharSequence lastLine;
                SpannableStringBuilder stringBuilder;
                if (viaString != null) {
                    stringBuilder = new SpannableStringBuilder(String.format("%s %s %s", fromString, LocaleController.getString("ViaBot", R.string.ViaBot), viaUsername));
                    viaNameWidth = (int) Math.ceil(Theme.chat_forwardNamePaint.measureText(fromString));
                    stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), stringBuilder.length() - viaUsername.length() - 1, stringBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                } else {
                    stringBuilder = new SpannableStringBuilder(String.format(fromFormattedString, name));
                }
                forwardNameCenterX = fromWidth + (int) Math.ceil(Theme.chat_forwardNamePaint.measureText(name, 0, name.length())) / 2;
                if (idx >= 0 && (currentForwardName == null || messageObject.messageOwner.fwd_from.from_id != null)) {
                    stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), idx, idx + name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                lastLine = stringBuilder;
                lastLine = TextUtils.ellipsize(lastLine, Theme.chat_forwardNamePaint, forwardedNameWidth, TextUtils.TruncateAt.END);
                try {
                    lastLine = Emoji.replaceEmoji(lastLine, Theme.chat_forwardNamePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                } catch (Exception ignore) {}
                try {
                    forwardedNameLayout[1] = new StaticLayout(lastLine, Theme.chat_forwardNamePaint, forwardedNameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    lastLine = TextUtils.ellipsize(AndroidUtilities.replaceTags(forwardedString), Theme.chat_forwardNamePaint, forwardedNameWidth, TextUtils.TruncateAt.END);
                    forwardedNameLayout[0] = new StaticLayout(lastLine, Theme.chat_forwardNamePaint, forwardedNameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                    forwardedNameWidth = Math.max((int) Math.ceil(forwardedNameLayout[0].getLineWidth(0)), (int) Math.ceil(forwardedNameLayout[1].getLineWidth(0)));
                    if (hasPsaHint) {
                        forwardedNameWidth += AndroidUtilities.dp(36);
                    }
                    forwardNameOffsetX[0] = forwardedNameLayout[0].getLineLeft(0);
                    forwardNameOffsetX[1] = forwardedNameLayout[1].getLineLeft(0);
                    if (messageObject.type != MessageObject.TYPE_ROUND_VIDEO && !messageObject.isAnyKindOfSticker() || messageObject.type == MessageObject.TYPE_EMOJIS) {
                        namesOffset += AndroidUtilities.dp(8) + Theme.chat_forwardNamePaint.getTextSize() * 2;
                        if (messageObject.type == MessageObject.TYPE_EMOJIS) {
                            namesOffset += AndroidUtilities.dp(8);
                        }
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            }
        }

        drawTopic = false;
        if (!isThreadChat && (delegate != null && delegate.shouldShowTopicButton()) && !pinnedTop && (MessageObject.getTopicId(messageObject.messageOwner, true) != 0 || messageObject.replyToForumTopic != null)) {
            if (currentPosition == null || currentPosition.minY == 0) {
                int topicId = messageObject.replyToForumTopic == null ? MessageObject.getTopicId(messageObject.messageOwner, true) : messageObject.replyToForumTopic.id;
                TLRPC.TL_forumTopic topic = messageObject.replyToForumTopic == null ? MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), topicId) : messageObject.replyToForumTopic;
                if (topic != null) {
                    drawTopic = true;

                    int maxWidth = getMaxNameWidth();
                    if (!messageObject.shouldDrawWithoutBackground()) {
                        maxWidth -= AndroidUtilities.dp(10);
                    } else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                        maxWidth += AndroidUtilities.dp(13 + 35);
                    } else if (messageObject.isAnyKindOfSticker()) {
                        maxWidth += AndroidUtilities.dp(25);
                    }

                    if (topicButton == null) {
                        topicButton = new MessageTopicButton(getContext(), resourcesProvider) {
                            @Override
                            protected void onClick() {
                                if (delegate != null) {
                                    delegate.didPressTopicButton(ChatMessageCell.this);
                                }
                            }
                        };
                    }
                    namesOffset += topicButton.set(this, messageObject, topic, maxWidth);
                }
            }
        }
        if (!drawTopic && topicButton != null) {
            topicButton.onDetached(this);
            topicButton = null;
        }

        if ((!isThreadChat || messageObject.getReplyTopMsgId(isForum) != 0 || isForumGeneral) && messageObject.hasValidReplyMessageObject() || messageObject.messageOwner.fwd_from != null && messageObject.isDice()) {
            if (currentPosition == null || currentPosition.minY == 0) {
                if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO || messageObject.type == MessageObject.TYPE_EMOJIS) {
                    namesOffset += AndroidUtilities.dp(14) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
                    if (messageObject.type == MessageObject.TYPE_EMOJIS && !drawForwardedName) {
                        namesOffset += AndroidUtilities.dp(12);
                    } else if (messageObject.type != MessageObject.TYPE_TEXT) {
                        namesOffset += AndroidUtilities.dp(5);
                    }
                }
                if (drawForwardedName && forwardedNameLayout[0] != null) {
                    namesOffset += AndroidUtilities.dp(2);
                }

                int maxWidth = getMaxNameWidth();
                if (!messageObject.shouldDrawWithoutBackground()) {
                    maxWidth -= AndroidUtilities.dp(10);
                } else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                    maxWidth += AndroidUtilities.dp(13);
                }

                CharSequence stringFinalText = null;

                String name = null;
                if ((!isThreadChat || messageObject.getReplyTopMsgId(isForum) != 0 || isForumGeneral) && messageObject.hasValidReplyMessageObject()) {
                    lastReplyMessage = messageObject.replyMessageObject.messageOwner;
                    int cacheType = 1;
                    int size = 0;
                    boolean hasReplySpoiler = messageObject.replyMessageObject.hasMediaSpoilers();
                    TLObject photoObject;
                    TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.replyMessageObject.photoThumbs2, 320);
                    TLRPC.PhotoSize thumbPhotoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.replyMessageObject.photoThumbs2, 40);
                    photoObject = messageObject.replyMessageObject.photoThumbsObject2;
                    if (photoSize == null) {
                        if (messageObject.replyMessageObject.mediaExists) {
                            photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.replyMessageObject.photoThumbs, AndroidUtilities.getPhotoSize());
                            if (photoSize != null) {
                                size = photoSize.size;
                            }
                            cacheType = 0;
                        } else {
                            photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.replyMessageObject.photoThumbs, 320);
                        }
                        thumbPhotoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.replyMessageObject.photoThumbs, 40);
                        photoObject = messageObject.replyMessageObject.photoThumbsObject;
                    }
                    if (thumbPhotoSize == photoSize) {
                        thumbPhotoSize = null;
                    }
                    if (photoSize == null || messageObject.replyMessageObject.isAnyKindOfSticker() || messageObject.isAnyKindOfSticker() && !AndroidUtilities.isTablet() || messageObject.replyMessageObject.isSecretMedia() || messageObject.replyMessageObject.isWebpageDocument()) {
                        replyImageReceiver.setImageBitmap((Drawable) null);
                        needReplyImage = false;
                    } else {
                        if (messageObject.replyMessageObject.isRoundVideo()) {
                            replyImageReceiver.setRoundRadius(AndroidUtilities.dp(32));
                        } else {
                            replyImageReceiver.setRoundRadius(AndroidUtilities.dp(4));
                        }
                        currentReplyPhoto = photoSize;
                        replyImageReceiver.setImage(ImageLocation.getForObject(photoSize, photoObject), hasReplySpoiler ? "5_5_b" : "50_50", ImageLocation.getForObject(thumbPhotoSize, photoObject), hasReplySpoiler ? "50_50_b4" : "50_50_b", size, null, messageObject.replyMessageObject, cacheType);
                        needReplyImage = true;
                        maxWidth -= AndroidUtilities.dp(16) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
                    }

                    if (messageObject.hideSendersName) {
                        if (messageObject.sendAsPeer != null) {
                            if (messageObject.sendAsPeer.channel_id != 0) {
                                TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(messageObject.sendAsPeer.channel_id);
                                if (chat != null) {
                                    name = chat.title;
                                }
                            } else {
                                TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.sendAsPeer.user_id);
                                name = UserObject.getUserName(user);
                            }
                        } else {
                            name = UserObject.getUserName(AccountInstance.getInstance(currentAccount).getUserConfig().getCurrentUser());
                        }
                    } else if (messageObject.customReplyName != null) {
                        name = messageObject.customReplyName;
                    } else {
                        if (drawForwardedName) {
                            name = messageObject.replyMessageObject.getForwardedName();
                        }

                        if (name == null) {
                            long fromId = messageObject.replyMessageObject.getFromChatId();
                            if (fromId > 0) {
                                TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(fromId);
                                if (user != null) {
                                    name = UserObject.getUserName(user);
                                }
                            } else if (fromId < 0) {
                                TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-fromId);
                                if (chat != null) {
                                    name = chat.title;
                                }
                            } else {
                                TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(messageObject.replyMessageObject.messageOwner.peer_id.channel_id);
                                if (chat != null) {
                                    name = chat.title;
                                }
                            }
                        }
                    }

                    if (name == null) {
                        name = LocaleController.getString("Loading", R.string.Loading);
                    }
                    if (messageObject.replyMessageObject.messageTextForReply != null) {
                        stringFinalText = messageObject.replyMessageObject.messageTextForReply;
                    } else if (MessageObject.getMedia(messageObject.replyMessageObject) instanceof TLRPC.TL_messageMediaGame) {
                        stringFinalText = Emoji.replaceEmoji(MessageObject.getMedia(messageObject.replyMessageObject).game.title, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                        stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
                    } else if (MessageObject.getMedia(messageObject.replyMessageObject) instanceof TLRPC.TL_messageMediaInvoice) {
                        stringFinalText = Emoji.replaceEmoji(MessageObject.getMedia(messageObject.replyMessageObject).title, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                        stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
                    } else if (!TextUtils.isEmpty(messageObject.replyMessageObject.caption)) {
                        String mess = messageObject.replyMessageObject.caption.toString();
                        if (mess.length() > 150) {
                            mess = mess.substring(0, 150);
                        }
                        mess = mess.replace('\n', ' ');
                        stringFinalText = Emoji.replaceEmoji(mess, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                        if (messageObject.replyMessageObject.messageOwner != null) {
                            stringFinalText = MessageObject.replaceAnimatedEmoji(stringFinalText, messageObject.replyMessageObject.messageOwner.entities, Theme.chat_replyTextPaint.getFontMetricsInt(), true);
                        }
                        stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
                        if (stringFinalText instanceof Spannable && messageObject.replyMessageObject.messageOwner != null) {
                            MediaDataController.addTextStyleRuns(messageObject.replyMessageObject.messageOwner.entities, messageObject.replyMessageObject.caption, (Spannable) stringFinalText);
                        }
                    } else if (messageObject.replyMessageObject != null && messageObject.replyMessageObject.messageText != null && messageObject.replyMessageObject.messageText.length() > 0) {
                        String mess = messageObject.replyMessageObject.messageText.toString();
                        if (mess.length() > 150) {
                            mess = mess.substring(0, 150);
                        }
                        mess = mess.replace('\n', ' ');
                        stringFinalText = Emoji.replaceEmoji(mess, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                        if (messageObject.replyMessageObject.messageOwner != null) {
                            stringFinalText = MessageObject.replaceAnimatedEmoji(stringFinalText, messageObject.replyMessageObject.messageOwner.entities, Theme.chat_replyTextPaint.getFontMetricsInt(), true);
                        }
                        stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
                        if (stringFinalText instanceof Spannable) {
                            MediaDataController.addTextStyleRuns(messageObject.replyMessageObject, (Spannable) stringFinalText);
                        }
                    }
                } else {
                    replyImageReceiver.setImageBitmap((Drawable) null);
                    needReplyImage = false;
                    replyPanelIsForward = true;
                    if (messageObject.messageOwner.fwd_from != null) {
                        if (messageObject.messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChannel) {
                            currentForwardChannel = MessagesController.getInstance(currentAccount).getChat(messageObject.messageOwner.fwd_from.from_id.channel_id);
                        } else if (messageObject.messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChat) {
                            currentForwardChannel = MessagesController.getInstance(currentAccount).getChat(messageObject.messageOwner.fwd_from.from_id.chat_id);
                        } else if (messageObject.messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerUser) {
                            currentForwardUser = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.fwd_from.from_id.user_id);
                        }
                        if (messageObject.messageOwner.fwd_from.from_name != null) {
                            currentForwardName = messageObject.messageOwner.fwd_from.from_name;
                        }
                    }

                    if (currentForwardUser != null || currentForwardChannel != null || currentForwardName != null) {
                        if (currentForwardChannel != null) {
                            if (currentForwardUser != null) {
                                currentForwardNameString = String.format("%s (%s)", currentForwardChannel.title, UserObject.getUserName(currentForwardUser));
                            } else {
                                currentForwardNameString = currentForwardChannel.title;
                            }
                        } else if (currentForwardUser != null) {
                            currentForwardNameString = UserObject.getUserName(currentForwardUser);
                        } else {
                            currentForwardNameString = currentForwardName;
                        }
                        name = getForwardedMessageText(messageObject);
                        String from = LocaleController.getString("From", R.string.From);
                        String fromFormattedString = LocaleController.getString("FromFormatted", R.string.FromFormatted);
                        int idx = fromFormattedString.indexOf("%1$s");
                        int fromWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(from + " "));
                        CharSequence text = currentForwardNameString == null ? "" : currentForwardNameString.replace('\n', ' ');
                        CharSequence ellipsizedText = TextUtils.ellipsize(text, Theme.chat_replyNamePaint, maxWidth - fromWidth, TextUtils.TruncateAt.END);
                        SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format(fromFormattedString, ellipsizedText));
                        if (idx >= 0 && (currentForwardName == null || messageObject.messageOwner.fwd_from.from_id != null)) {
                            stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), idx, idx + ellipsizedText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                        stringFinalText = TextUtils.ellipsize(stringBuilder, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
                        forwardNameCenterX = fromWidth + (int) Math.ceil(Theme.chat_replyNamePaint.measureText(ellipsizedText, 0, ellipsizedText.length())) / 2;
                    }
                }
                CharSequence stringFinalName = name == null ? "" : TextUtils.ellipsize(name.replace('\n', ' '), Theme.chat_replyNamePaint, maxWidth, TextUtils.TruncateAt.END);
                try {
                    stringFinalName = Emoji.replaceEmoji(stringFinalName, Theme.chat_replyNamePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
                } catch (Exception ignore) {
                }
                try {
                    replyNameWidth = AndroidUtilities.dp(4) + (needReplyImage ? AndroidUtilities.dp(16) + (int) (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize()) : 0);
                    if (stringFinalName != null) {
                        replyNameLayout = new StaticLayout(stringFinalName, Theme.chat_replyNamePaint, maxWidth + AndroidUtilities.dp(6), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                        if (replyNameLayout.getLineCount() > 0) {
                            replyNameWidth += (int) Math.ceil(replyNameLayout.getLineWidth(0)) + AndroidUtilities.dp(8);
                            replyNameOffset = (int) replyNameLayout.getLineLeft(0);
                        }
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
                try {
                    replyTextWidth = AndroidUtilities.dp(4) + (needReplyImage ? AndroidUtilities.dp(16) + (int) (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize()) : 0);
                    if (stringFinalText != null) {
                        SpannableStringBuilder sb = new SpannableStringBuilder(stringFinalText);
                        boolean changed = false;
                        for (TextStyleSpan span : sb.getSpans(0, sb.length(), TextStyleSpan.class)) {
                            if ((span.getTextStyleRun().flags & TextStyleSpan.FLAG_STYLE_MONO) != 0) {
                                changed = true;
                                sb.removeSpan(span);
                            }
                        }
                        stringFinalText = TextUtils.ellipsize(sb, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
                        replyTextOffset = 0;
                        replyTextLayout = new StaticLayout(stringFinalText, Theme.chat_replyTextPaint, maxWidth + AndroidUtilities.dp(10), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                        if (replyTextLayout.getLineCount() > 0) {
                            replyTextWidth += (int) Math.ceil(replyTextLayout.getLineWidth(0)) + AndroidUtilities.dp(8);
                            replyTextOffset = (int) replyTextLayout.getLineLeft(0);
                        }
                        replySpoilers.clear();
                        if (getMessageObject().replyMessageObject != null && !getMessageObject().replyMessageObject.isSpoilersRevealed) {
                            SpoilerEffect.addSpoilers(this, replyTextLayout, replySpoilersPool, replySpoilers);
                        }
                        animatedEmojiReplyStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, false, animatedEmojiReplyStack, replyTextLayout);
                    }
                    if (replyNameWidth > replyTextWidth) {
                        replyNameWidth += AndroidUtilities.dp(Math.max(2, SharedConfig.bubbleRadius / 4f));
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            }
        } else if (!isThreadChat && messageObject.getReplyMsgId() != 0) {
            if (!(messageObject.replyMessageObject != null && (messageObject.replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty ||  messageObject.replyMessageObject.messageOwner != null && messageObject.replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionTopicCreate))) {
                if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
                    namesOffset += AndroidUtilities.dp(14) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
                    if (messageObject.type != MessageObject.TYPE_TEXT) {
                        namesOffset += AndroidUtilities.dp(5);
                    }
                }
                needReplyImage = false;

                int maxWidth = getMaxNameWidth();
                if (!messageObject.shouldDrawWithoutBackground()) {
                    maxWidth -= AndroidUtilities.dp(10);
                } else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                    maxWidth += AndroidUtilities.dp(13);
                }

                replyNameLayout = new StaticLayout(LocaleController.getString("Loading", R.string.Loading), Theme.chat_replyNamePaint, maxWidth + AndroidUtilities.dp(6), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                if (replyNameLayout.getLineCount() > 0) {
                    replyNameWidth += (int) Math.ceil(replyNameLayout.getLineWidth(0)) + AndroidUtilities.dp(8);
                    replyNameOffset = (int) replyNameLayout.getLineLeft(0);
                }
            }
        }

        requestLayout();
    }

    private boolean isNeedAuthorName() {
        return (
            isPinnedChat && currentMessageObject.type == MessageObject.TYPE_TEXT ||
            !pinnedTop && drawName && isChat && (!currentMessageObject.isOutOwner() || currentMessageObject.isSupergroup() && currentMessageObject.isFromGroup()) ||
            currentMessageObject.isImportedForward() && currentMessageObject.messageOwner.fwd_from.from_id == null
        );
    }

    private String getAuthorName() {
        if (currentUser != null) {
            if (!currentUser.self) {
                return UserObject.getUserName(currentUser);
            } else {
                return "SELF";
            }
        } else if (currentChat != null) {
            return currentChat.title;
        } else if (currentMessageObject != null && currentMessageObject.isSponsored()) {
            if (currentMessageObject.sponsoredChatInvite != null && currentMessageObject.sponsoredChatInvite.title != null) {
                return currentMessageObject.sponsoredChatInvite.title;
            }
            if (currentMessageObject.sponsoredChatInvite != null && currentMessageObject.sponsoredChatInvite.chat != null && currentMessageObject.sponsoredChatInvite.chat.title != null) {
                return currentMessageObject.sponsoredChatInvite.chat.title;
            }
            return "";
        }
        return "DELETED";
    }

    private Object getAuthorStatus() {
        if (currentUser != null) {
            Long emojiStatusId = UserObject.getEmojiStatusDocumentId(currentUser);
            if (emojiStatusId != null) {
                return emojiStatusId;
            } else if (currentUser.premium) {
                return ContextCompat.getDrawable(ApplicationLoader.applicationContext, R.drawable.msg_premium_liststar).mutate();
            }
        }
        return null;
    }

    private String getForwardedMessageText(MessageObject messageObject) {
        if (hasPsaHint) {
            String forwardedString = LocaleController.getString("PsaMessage_" + messageObject.messageOwner.fwd_from.psa_type);
            if (forwardedString == null) {
                forwardedString = LocaleController.getString("PsaMessageDefault", R.string.PsaMessageDefault);
            }
            return forwardedString;
        } else {
            return LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage);
        }
    }

    public int getExtraInsetHeight() {
        int h = addedCaptionHeight;
        if (drawCommentButton) {
            h += AndroidUtilities.dp(shouldDrawTimeOnMedia() ? 41.3f : 43);
        }
        if (!reactionsLayoutInBubble.isEmpty && currentMessageObject.shouldDrawReactionsInLayout()) {
            h += reactionsLayoutInBubble.totalHeight;
        }
        return h;
    }

    public ImageReceiver getAvatarImage() {
        return isAvatarVisible ? avatarImage : null;
    }

    public float getCheckBoxTranslation() {
        return checkBoxTranslation;
    }

    public boolean shouldDrawAlphaLayer() {
        return (currentMessagesGroup == null || !currentMessagesGroup.transitionParams.backgroundChangeBounds) && getAlpha() != 1f;
    }

    public float getCaptionX() {
        return captionX;
    }

    public boolean isDrawPinnedBottom() {
        boolean forceMediaByGroup = currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0 && currentMessagesGroup.isDocuments;
        return mediaBackground || drawPinnedBottom || forceMediaByGroup;
    }

    public void drawCheckBox(Canvas canvas) {
        if (currentMessageObject != null && !currentMessageObject.isSending() && !currentMessageObject.isSendError() && checkBox != null && (checkBoxVisible || checkBoxAnimationInProgress) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) {
            canvas.save();
            float y = getY();
            if (currentMessagesGroup != null && currentMessagesGroup.messages.size() > 1) {
                y = getTop() + currentMessagesGroup.transitionParams.offsetTop - getTranslationY();
            } else {
                y += transitionParams.deltaTop;
            }
            canvas.translate(0, y + transitionYOffsetForDrawables);
            checkBox.draw(canvas);
            canvas.restore();
        }
    }

    public void setBackgroundTopY(boolean fromParent) {
        for (int a = 0; a < 2; a++) {
            if (a == 1 && !fromParent) {
                return;
            }
            Theme.MessageDrawable drawable = a == 0 ? currentBackgroundDrawable : currentBackgroundSelectedDrawable;
            if (drawable == null) {
                continue;
            }
            int w = parentWidth;
            int h = parentHeight;
            if (h == 0) {
                w = getParentWidth();
                h = AndroidUtilities.displaySize.y;
                if (getParent() instanceof View) {
                    View view = (View) getParent();
                    w = view.getMeasuredWidth();
                    h = view.getMeasuredHeight();
                }
            }
            drawable.setTop((int) ((fromParent ? getY() : getTop()) + parentViewTopOffset), w, h, (int) parentViewTopOffset, blurredViewTopOffset, blurredViewBottomOffset, pinnedTop, pinnedBottom || transitionParams.changePinnedBottomProgress != 1);
        }
    }

    public void setBackgroundTopY(int offset) {
        Theme.MessageDrawable drawable = currentBackgroundDrawable;
        int w = parentWidth;
        int h = parentHeight;
        if (h == 0) {
            w = getParentWidth();
            h = AndroidUtilities.displaySize.y;
            if (getParent() instanceof View) {
                View view = (View) getParent();
                w = view.getMeasuredWidth();
                h = view.getMeasuredHeight();
            }
        }
        drawable.setTop((int) (parentViewTopOffset + offset), w, h, (int) parentViewTopOffset, blurredViewTopOffset, blurredViewBottomOffset, pinnedTop, pinnedBottom || transitionParams.changePinnedBottomProgress != 1);
    }

    float transitionYOffsetForDrawables;

    //设置drawable大小
    public void setDrawableBoundsInner(Drawable drawable, int x, int y, int w, int h) {
        if (drawable != null) {
            transitionYOffsetForDrawables = (y + h + transitionParams.deltaBottom) - ((int) (y + h + transitionParams.deltaBottom));
            drawable.setBounds((int) (x + transitionParams.deltaLeft), (int) (y + transitionParams.deltaTop), (int) (x + w + transitionParams.deltaRight), (int) (y + h + transitionParams.deltaBottom));
        }
    }

    private Paint selectionOverlayPaint;

    @SuppressLint("WrongCall")
    @Override
    protected void onDraw(Canvas canvas) {
        if (currentMessageObject == null) {
            return;
        }
        if (!wasLayout) {
            onLayout(false, getLeft(), getTop(), getRight(), getBottom());
        }

        if (enterTransitionInProgress && currentMessageObject.isAnimatedEmojiStickers()) {
            return;
        }

        if (currentMessageObject.isOutOwner()) {
            Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
            Theme.chat_msgGameTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
            Theme.chat_msgGameTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
            Theme.chat_replyTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
            Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
        } else {
            Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
            Theme.chat_msgGameTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
            Theme.chat_msgGameTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
            Theme.chat_replyTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
            Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
        }

        if (documentAttach != null) {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                if (currentMessageObject.isOutOwner()) {
                    seekBarWaveform.setColors(getThemedColor(Theme.key_chat_outVoiceSeekbar), getThemedColor(Theme.key_chat_outVoiceSeekbarFill), getThemedColor(Theme.key_chat_outVoiceSeekbarSelected));
                    seekBar.setColors(getThemedColor(Theme.key_chat_outAudioSeekbar), getThemedColor(Theme.key_chat_outAudioCacheSeekbar), getThemedColor(Theme.key_chat_outAudioSeekbarFill), getThemedColor(Theme.key_chat_outAudioSeekbarFill), getThemedColor(Theme.key_chat_outAudioSeekbarSelected));
                } else {
                    seekBarWaveform.setColors(getThemedColor(Theme.key_chat_inVoiceSeekbar), getThemedColor(Theme.key_chat_inVoiceSeekbarFill), getThemedColor(Theme.key_chat_inVoiceSeekbarSelected));
                    seekBar.setColors(getThemedColor(Theme.key_chat_inAudioSeekbar), getThemedColor(Theme.key_chat_inAudioCacheSeekbar), getThemedColor(Theme.key_chat_inAudioSeekbarFill), getThemedColor(Theme.key_chat_inAudioSeekbarFill), getThemedColor(Theme.key_chat_inAudioSeekbarSelected));
                }
            } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
                if (currentMessageObject.isOutOwner()) {
                    seekBar.setColors(getThemedColor(Theme.key_chat_outAudioSeekbar), getThemedColor(Theme.key_chat_outAudioCacheSeekbar), getThemedColor(Theme.key_chat_outAudioSeekbarFill), getThemedColor(Theme.key_chat_outAudioSeekbarFill), getThemedColor(Theme.key_chat_outAudioSeekbarSelected));
                } else {
                    seekBar.setColors(getThemedColor(Theme.key_chat_inAudioSeekbar), getThemedColor(Theme.key_chat_inAudioCacheSeekbar), getThemedColor(Theme.key_chat_inAudioSeekbarFill), getThemedColor(Theme.key_chat_inAudioSeekbarFill), getThemedColor(Theme.key_chat_inAudioSeekbarSelected));
                }
            }
        }
        //更改绘制画笔背景颜色
        if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
            Theme.chat_timePaint.setColor(
                ColorUtils.blendARGB(
                    getThemedColor(Theme.key_chat_serviceText),
                    getThemedColor(isDrawSelectionBackground() ?
                        (currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_inTimeSelectedText) :
                        (currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeText : Theme.key_chat_inTimeText)
                    ),
                    getVideoTranscriptionProgress()
                )
            );
        } else {
            if (mediaBackground) {
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_serviceText));
                } else {
                    Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_mediaTimeText));
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_timePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_outTimeText));
                } else {
                    Theme.chat_timePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inTimeSelectedText : Theme.key_chat_inTimeText));
                }
            }
        }

        //绘制背景
        drawBackgroundInternal(canvas, false);
        if (isHighlightedAnimated) {
            long newTime = System.currentTimeMillis();
            long dt = Math.abs(newTime - lastHighlightProgressTime);
            if (dt > 17) {
                dt = 17;
            }
            highlightProgress -= dt;
            lastHighlightProgressTime = newTime;
            if (highlightProgress <= 0) {
                highlightProgress = 0;
                isHighlightedAnimated = false;
            }
            invalidate();
            if (getParent() != null) {
                ((View) getParent()).invalidate();
            }
        }

        int restore = Integer.MIN_VALUE;
        if (alphaInternal != 1.0f) {
            int top = 0;
            int left = 0;
            int bottom = getMeasuredHeight();
            int right = getMeasuredWidth();

            if (currentBackgroundDrawable != null) {
                top = currentBackgroundDrawable.getBounds().top;
                bottom = currentBackgroundDrawable.getBounds().bottom;
                left = currentBackgroundDrawable.getBounds().left;
                right = currentBackgroundDrawable.getBounds().right;
            }

            if (drawSideButton != 0) {
                if (currentMessageObject.isOutOwner()) {
                    left -= AndroidUtilities.dp(8 + 32);
                } else {
                    right += AndroidUtilities.dp(8 + 32);
                }
            }
            if (getY() < 0) {
                top = (int) -getY();
            }
            if (getY() + getMeasuredHeight() > parentHeight) {
                bottom = (int) (parentHeight - getY());
            }
            rect.set(left, top, right, bottom);
            restore = canvas.saveLayerAlpha(rect, (int) (255 * alphaInternal), Canvas.ALL_SAVE_FLAG);
        }
        boolean clipContent = false;
        //绘制翻译背景
        if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null && !isRoundVideo) {
            Rect r = currentBackgroundDrawable.getBounds();
            canvas.save();
            canvas.clipRect(
                    r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                    r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
            );
            clipContent = true;
        }
        //核心绘制文字
        drawContent(canvas);
        if (clipContent) {
            canvas.restore();
        }

        if (delegate == null || delegate.canDrawOutboundsContent() || transitionParams.messageEntering || getAlpha() != 1f) {
            drawOutboundsContent(canvas);
        }

        if (replyNameLayout != null) {
            replyHeight = AndroidUtilities.dp(7) + Theme.chat_replyNamePaint.getTextSize() + Theme.chat_replyTextPaint.getTextSize();
            if (currentMessageObject.shouldDrawWithoutBackground() && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
                if (currentMessageObject.isOutOwner()) {
                    replyStartX = AndroidUtilities.dp(23);
                    if (isPlayingRound) {
                        replyStartX -= (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
                    }
                } else if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                    replyStartX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(4);
                } else {
                    replyStartX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(17);
                }
                if (drawForwardedName) {
                    forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
                    replyStartY = forwardNameY + forwardHeight + AndroidUtilities.dp(6);
                } else {
                    replyStartY = AndroidUtilities.dp(12);
                    if (drawTopic && topicButton != null) {
                        replyStartY += topicButton.height() + AndroidUtilities.dp(10);
                    }
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
                    if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
                        replyStartX -= Math.max(0, replyStartX + Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14) - AndroidUtilities.displaySize.x);
                    }
                } else {
                    if (mediaBackground) {
                        replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
                    } else {
                        replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
                    }
                }
                if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
                    replyStartX -= AndroidUtilities.dp(7);
                }
                forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
                replyStartY = AndroidUtilities.dp(12) + (drawNameLayout && nameLayout != null ? AndroidUtilities.dp(6) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawForwardedName && forwardedNameLayout[0] != null ? AndroidUtilities.dp(4) + forwardHeight : 0);
                if (drawTopic && topicButton != null) {
                    replyStartY += topicButton.height() + AndroidUtilities.dp(5);
                }
            }
        }
        //绘制聊天内容中的开头名字
        if (currentPosition == null && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && !currentMessageObject.isVoice())) {
            drawNamesLayout(canvas, 1f);
        }

        //绘制媒体
        if ((!autoPlayingMedia || !MediaController.getInstance().isPlayingMessageAndReadyToDraw(currentMessageObject) || isRoundVideo) && !transitionParams.animateBackgroundBoundsInner) {
            drawOverlays(canvas);
        }

        //绘制信息到达时间以及是否已读
        if ((drawTime || !mediaBackground) && !forceNotDrawTime && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && !currentMessageObject.isVoice())) {
            drawTime(canvas, 1f, false);
        }

        //媒体相关的信息配置
        if ((controlsAlpha != 1.0f || timeAlpha != 1.0f) && currentMessageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
            long newTime = System.currentTimeMillis();
            long dt = Math.abs(lastControlsAlphaChangeTime - newTime);
            if (dt > 17) {
                dt = 17;
            }
            totalChangeTime += dt;
            if (totalChangeTime > TIME_APPEAR_MS) {
                totalChangeTime = TIME_APPEAR_MS;
            }
            lastControlsAlphaChangeTime = newTime;
            if (controlsAlpha != 1.0f) {
                controlsAlpha = AndroidUtilities.decelerateInterpolator.getInterpolation(totalChangeTime / (float) TIME_APPEAR_MS);
            }
            if (timeAlpha != 1.0f) {
                timeAlpha = AndroidUtilities.decelerateInterpolator.getInterpolation(totalChangeTime / (float) TIME_APPEAR_MS);
            }
            invalidate();
            if (forceNotDrawTime && currentPosition != null && currentPosition.last && getParent() != null) {
                View parent = (View) getParent();
                parent.invalidate();
            }
        }

        //绘制已选择文字的背景
        if ((drawBackground || transitionParams.animateDrawBackground) && shouldDrawSelectionOverlay() && currentMessagesGroup == null && hasSelectionOverlay()) {
            if (selectionOverlayPaint == null) {
                selectionOverlayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            selectionOverlayPaint.setColor(getSelectionOverlayColor());
            int wasAlpha = selectionOverlayPaint.getAlpha();
            selectionOverlayPaint.setAlpha((int) (wasAlpha * getHighlightAlpha() * getAlpha()));
            if (selectionOverlayPaint.getAlpha() > 0) {
                canvas.save();
                canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
                currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams, selectionOverlayPaint);
                canvas.restore();
            }
            selectionOverlayPaint.setAlpha(wasAlpha);
        }

        if (restore != Integer.MIN_VALUE) {
            canvas.restoreToCount(restore);
        }
        //更新已选中的文字位置
        updateSelectionTextPosition();
    }

    @SuppressLint("WrongCall")
    public void drawBackgroundInternal(Canvas canvas, boolean fromParent) {
        if (currentMessageObject == null) {
            return;
        }
        if (!wasLayout && !animationRunning) {
            forceLayout();
            return;
        }
        if (!wasLayout) {
            onLayout(false, getLeft(), getTop(), getRight(), getBottom());
        }
        Drawable currentBackgroundShadowDrawable;
        int additionalTop = 0;
        int additionalBottom = 0;
        boolean forceMediaByGroup = currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0 && currentMessagesGroup.isDocuments && !drawPinnedBottom;
        //设置背景点击与未点击样式
        if (currentMessageObject.isOutOwner()) {
            if (transitionParams.changePinnedBottomProgress >= 1 && !mediaBackground && !drawPinnedBottom && !forceMediaByGroup) {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOut);
                currentBackgroundSelectedDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOutSelected);
                transitionParams.drawPinnedBottomBackground = false;
            } else {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOutMedia);
                currentBackgroundSelectedDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOutMediaSelected);
                transitionParams.drawPinnedBottomBackground = true;
            }
            setBackgroundTopY(true);
            if (isDrawSelectionBackground() && (currentPosition == null || getBackground() != null)) {
                currentBackgroundShadowDrawable = currentBackgroundSelectedDrawable.getShadowDrawable();
            } else {
                currentBackgroundShadowDrawable = currentBackgroundDrawable.getShadowDrawable();
            }
            //设置背景偏移
            backgroundDrawableLeft = layoutWidth - backgroundWidth - (!mediaBackground ? 0 : AndroidUtilities.dp(9));
            backgroundDrawableRight = backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(3));
            if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
                if (!currentPosition.edge) {
                    backgroundDrawableRight += AndroidUtilities.dp(10);
                }
            }
            int backgroundLeft = backgroundDrawableLeft;
            if (!forceMediaByGroup && transitionParams.changePinnedBottomProgress != 1) {
                if (!mediaBackground) {
                    backgroundDrawableRight -= AndroidUtilities.dp(6);
                }
            } else if (!mediaBackground && drawPinnedBottom) {
                backgroundDrawableRight -= AndroidUtilities.dp(6);
            }

            //不绘制群组消息
            if (currentPosition != null) {
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0) {
                    backgroundDrawableRight += AndroidUtilities.dp(SharedConfig.bubbleRadius + 2);
                }
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                    backgroundLeft -= AndroidUtilities.dp(SharedConfig.bubbleRadius + 2);
                    backgroundDrawableRight += AndroidUtilities.dp(SharedConfig.bubbleRadius + 2);
                }
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                    additionalTop -= AndroidUtilities.dp(SharedConfig.bubbleRadius + 3);
                    additionalBottom += AndroidUtilities.dp(SharedConfig.bubbleRadius + 3);
                }
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                    additionalBottom += AndroidUtilities.dp(SharedConfig.bubbleRadius + 3);
                }
            }
            int offsetBottom;
            if (drawPinnedBottom && drawPinnedTop) {
                offsetBottom = 0;
            } else if (drawPinnedBottom) {
                offsetBottom = AndroidUtilities.dp(1);
            } else {
                offsetBottom = AndroidUtilities.dp(2);
            }
            backgroundDrawableTop = additionalTop + (drawPinnedTop ? 0 : AndroidUtilities.dp(1));
            int backgroundHeight = layoutHeight - offsetBottom + additionalBottom;
            backgroundDrawableBottom = backgroundDrawableTop + backgroundHeight;

            if (!mediaBackground) {
                if (drawPinnedTop) {
                    backgroundDrawableTop -= AndroidUtilities.dp(1);
                    backgroundHeight += AndroidUtilities.dp(1);
                }
                if (drawPinnedBottom) {
                    backgroundDrawableBottom += AndroidUtilities.dp(1);
                    backgroundHeight += AndroidUtilities.dp(1);
                }
            }

            if (forceMediaByGroup) {
                setDrawableBoundsInner(currentBackgroundDrawable, backgroundLeft, backgroundDrawableTop - additionalTop, backgroundDrawableRight, backgroundHeight - additionalBottom + 10);
                setDrawableBoundsInner(currentBackgroundSelectedDrawable, backgroundDrawableLeft, backgroundDrawableTop, backgroundDrawableRight - AndroidUtilities.dp(6), backgroundHeight);
            } else {
                //设置背景四周大小距离
                setDrawableBoundsInner(currentBackgroundDrawable, backgroundLeft, backgroundDrawableTop, backgroundDrawableRight, backgroundHeight);
                setDrawableBoundsInner(currentBackgroundSelectedDrawable, backgroundLeft, backgroundDrawableTop, backgroundDrawableRight, backgroundHeight);
            }
            setDrawableBoundsInner(currentBackgroundShadowDrawable, backgroundLeft, backgroundDrawableTop, backgroundDrawableRight, backgroundHeight);
        } else {
            if (transitionParams.changePinnedBottomProgress >= 1 && !mediaBackground && !drawPinnedBottom && !forceMediaByGroup) {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgIn);
                currentBackgroundSelectedDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgInSelected);
                transitionParams.drawPinnedBottomBackground = false;
            } else {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgInMedia);
                currentBackgroundSelectedDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgInMediaSelected);
                transitionParams.drawPinnedBottomBackground = true;
            }
            setBackgroundTopY(true);
            if (isDrawSelectionBackground() && (currentPosition == null || getBackground() != null)) {
                currentBackgroundShadowDrawable = currentBackgroundSelectedDrawable.getShadowDrawable();
            } else {
                currentBackgroundShadowDrawable = currentBackgroundDrawable.getShadowDrawable();
            }

            backgroundDrawableLeft = AndroidUtilities.dp((isChat && isAvatarVisible ? 48 : 0) + (!mediaBackground ? 3 : 9));
            backgroundDrawableRight = backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(3));
            if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
                if (!currentPosition.edge) {
                    backgroundDrawableLeft -= AndroidUtilities.dp(10);
                    backgroundDrawableRight += AndroidUtilities.dp(10);
                }
                if (currentPosition.leftSpanOffset != 0) {
                    backgroundDrawableLeft += (int) Math.ceil(currentPosition.leftSpanOffset / 1000.0f * getGroupPhotosWidth());
                }
            }
            if ((!mediaBackground && drawPinnedBottom) || !forceMediaByGroup && transitionParams.changePinnedBottomProgress != 1) {
                if (!(!drawPinnedBottom && mediaBackground)) {
                    backgroundDrawableRight -= AndroidUtilities.dp(6);
                }
                if (!mediaBackground) {
                    backgroundDrawableLeft += AndroidUtilities.dp(6);
                }
            }
            if (currentPosition != null) {
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0) {
                    backgroundDrawableRight += AndroidUtilities.dp(SharedConfig.bubbleRadius + 2);
                }
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                    backgroundDrawableLeft -= AndroidUtilities.dp(SharedConfig.bubbleRadius + 2);
                    backgroundDrawableRight += AndroidUtilities.dp(SharedConfig.bubbleRadius + 2);
                }
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                    additionalTop -= AndroidUtilities.dp(SharedConfig.bubbleRadius + 3);
                    additionalBottom += AndroidUtilities.dp(SharedConfig.bubbleRadius + 3);
                }
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                    additionalBottom += AndroidUtilities.dp(SharedConfig.bubbleRadius + 4);
                }
            }
            int offsetBottom;
            if (drawPinnedBottom && drawPinnedTop) {
                offsetBottom = 0;
            } else if (drawPinnedBottom) {
                offsetBottom = AndroidUtilities.dp(1);
            } else {
                offsetBottom = AndroidUtilities.dp(2);
            }
            backgroundDrawableTop = additionalTop + (drawPinnedTop ? 0 : AndroidUtilities.dp(1));
            int backgroundHeight = layoutHeight - offsetBottom + additionalBottom;
            backgroundDrawableBottom = backgroundDrawableTop + backgroundHeight;

            if (!mediaBackground) {
                if (drawPinnedTop) {
                    backgroundDrawableTop -= AndroidUtilities.dp(1);
                    backgroundHeight += AndroidUtilities.dp(1);
                }
                if (drawPinnedBottom) {
                    backgroundDrawableBottom += AndroidUtilities.dp(1);
                    backgroundHeight += AndroidUtilities.dp(1);
                }
            }

            setDrawableBoundsInner(currentBackgroundDrawable, backgroundDrawableLeft, backgroundDrawableTop, backgroundDrawableRight, backgroundHeight);
            if (forceMediaByGroup) {
                setDrawableBoundsInner(currentBackgroundSelectedDrawable, backgroundDrawableLeft + AndroidUtilities.dp(6), backgroundDrawableTop, backgroundDrawableRight - AndroidUtilities.dp(6), backgroundHeight);
            } else {
                setDrawableBoundsInner(currentBackgroundSelectedDrawable, backgroundDrawableLeft, backgroundDrawableTop, backgroundDrawableRight, backgroundHeight);
            }
            setDrawableBoundsInner(currentBackgroundShadowDrawable, backgroundDrawableLeft, backgroundDrawableTop, backgroundDrawableRight, backgroundHeight);
        }

        if (!currentMessageObject.isOutOwner() && transitionParams.changePinnedBottomProgress != 1 && !mediaBackground && !drawPinnedBottom) {
            backgroundDrawableLeft -= AndroidUtilities.dp(6);
            backgroundDrawableRight += AndroidUtilities.dp(6);
        }

        //提醒背景
        if (hasPsaHint) {
            int x;
            if (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0) {
                x = currentBackgroundDrawable.getBounds().right;
            } else {
                x = 0;
                int dWidth = getGroupPhotosWidth();
                for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                    MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                    if (position.minY == 0) {
                        x += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
                    } else {
                        break;
                    }
                }
            }
            Drawable drawable = Theme.chat_psaHelpDrawable[currentMessageObject.isOutOwner() ? 1 : 0];

            int y;
            if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                y = AndroidUtilities.dp(12);
            } else {
                y = AndroidUtilities.dp(10 + (drawNameLayout ? 19 : 0));
            }

            psaHelpX = x - drawable.getIntrinsicWidth() - AndroidUtilities.dp(currentMessageObject.isOutOwner() ? 20 : 14);
            psaHelpY = y + AndroidUtilities.dp(4);
        }

        //选择框背景
        if (checkBoxVisible || checkBoxAnimationInProgress) {
            animateCheckboxTranslation();
            int size = AndroidUtilities.dp(21);
            checkBox.setBounds(AndroidUtilities.dp(8 - 35) + checkBoxTranslation, currentBackgroundDrawable.getBounds().bottom - AndroidUtilities.dp(8) - size, size, size);
        }

        if (!fromParent && drawBackgroundInParent()) {
            return;
        }

        int restoreCount = canvas.getSaveCount();
        //翻译背景
        if (transitionYOffsetForDrawables != 0) {
            canvas.save();
            canvas.translate(0, transitionYOffsetForDrawables);
        }

        float pinnedBottomOffset = 0;
        //视频背景
        if (currentMessageObject != null && currentMessageObject.isRoundVideo()) {
            float progress = getVideoTranscriptionProgress();
//            if (transitionParams.animateDrawBackground) {
//                Rect bounds = currentBackgroundDrawable.getBounds();
//                bounds.bottom = AndroidUtilities.lerp(bounds.top + bounds.width(), bounds.bottom, progress);
//            }
            currentBackgroundDrawable.setRoundingRadius(1f - progress);
            pinnedBottomOffset = AndroidUtilities.lerp(backgroundWidth / 2, 0, progress);
            canvas.saveLayerAlpha(0, 0, getWidth(), Math.max(currentBackgroundDrawable.getBounds().bottom, getHeight()), (int) (255 * progress), Canvas.ALL_SAVE_FLAG);

            roundVideoPlayPipFloat.set((MediaController.getInstance().isPiPShown() && MediaController.getInstance().isPlayingMessageAndReadyToDraw(currentMessageObject) || wouldBeInPip) && canvas.isHardwareAccelerated() ? 1f : 0f);
            if (MediaController.getInstance().isPiPShown()) {
                wouldBeInPip = false;
            }
        }

        if ((drawBackground || transitionParams.animateDrawBackground) && currentBackgroundDrawable != null && (currentPosition == null || isDrawSelectionBackground() && (currentMessageObject.isMusic() || currentMessageObject.isDocument())) && !(enterTransitionInProgress && !currentMessageObject.isVoice())) {
            //音乐、文档背景
            float alphaInternal = this.alphaInternal;
            if (fromParent) {
                alphaInternal *= getAlpha();
            }
            //是否被选中更改背景
            if (hasSelectionOverlay()) {
//                if ((isPressed() && isCheckPressed || !isCheckPressed && isPressed) && !textIsSelectionMode()) {
//                    currentSelectedBackgroundAlpha = 1f;
//                    currentBackgroundSelectedDrawable.setAlpha((int) (255 * alphaInternal));
//                    currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
//                } else {
                currentSelectedBackgroundAlpha = 0;
                currentBackgroundDrawable.setAlpha((int) (255 * alphaInternal));
                currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
//                }
                if (currentBackgroundShadowDrawable != null && currentPosition == null) {
                    currentBackgroundShadowDrawable.setAlpha((int) (255 * alphaInternal));
                    currentBackgroundShadowDrawable.draw(canvas);
                }
            } else {
                if (isHighlightedAnimated) {
                    //是否执行高亮背景
                    currentBackgroundDrawable.setAlpha((int) (255 * alphaInternal));
                    currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
                    currentSelectedBackgroundAlpha = getHighlightAlpha();
                    if (currentPosition == null) {
                        currentBackgroundSelectedDrawable.setAlpha((int) (alphaInternal * currentSelectedBackgroundAlpha * 255));
                        currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
                    }
                } else if (selectedBackgroundProgress != 0 && !(currentMessagesGroup != null && currentMessagesGroup.isDocuments)) {
                    //选择背景进度
                    currentBackgroundDrawable.setAlpha((int) (255 * alphaInternal));
                    currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
                    currentSelectedBackgroundAlpha = selectedBackgroundProgress;
                    currentBackgroundSelectedDrawable.setAlpha((int) (currentSelectedBackgroundAlpha * alphaInternal * 255));
                    currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
                    if (currentBackgroundDrawable.getGradientShader() == null) {
                        currentBackgroundShadowDrawable = null;
                    }
                } else {
                    //其他情况的背景
                    if (isDrawSelectionBackground() && (currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.isDocument() || getBackground() != null)) {
                        //绘制文档、音乐背景
                        if (currentPosition != null) {
                            canvas.save();
//                            canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
                        }
                        currentSelectedBackgroundAlpha = 1f;
                        currentBackgroundSelectedDrawable.setAlpha((int) (255 * alphaInternal));
                        currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
                        if (currentPosition != null) {
                            canvas.restore();
                        }
                    } else {
                        //核心绘制背景
                        currentSelectedBackgroundAlpha = 0;
                        currentBackgroundDrawable.setAlpha((int) (255 * alphaInternal));
                        currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
                    }
                }
                //不绘制背景阴影的情况
                if (currentBackgroundShadowDrawable != null && currentPosition == null) {
                    currentBackgroundShadowDrawable.setAlpha((int) (255 * alphaInternal));
                    currentBackgroundShadowDrawable.draw(canvas);
                }

                //绘制翻译背景
                if (transitionParams.changePinnedBottomProgress != 1f && currentPosition == null) {
                    if (currentMessageObject.isOutOwner()) {
                        Theme.MessageDrawable drawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOut);

                        Rect rect = currentBackgroundDrawable.getBounds();
                        drawable.setBounds(rect.left, rect.top, rect.right + AndroidUtilities.dp(6), rect.bottom);
                        canvas.save();
                        canvas.translate(-pinnedBottomOffset, 0);
                        canvas.clipRect(rect.right - AndroidUtilities.dp(16), rect.bottom - AndroidUtilities.dp(16), rect.right + AndroidUtilities.dp(16), rect.bottom);
                        int w = parentWidth;
                        int h = parentHeight;
                        if (h == 0) {
                            w = getParentWidth();
                            h = AndroidUtilities.displaySize.y;
                            if (getParent() instanceof View) {
                                View view = (View) getParent();
                                w = view.getMeasuredWidth();
                                h = view.getMeasuredHeight();
                            }
                        }
                        drawable.setTop((int) (getY() + parentViewTopOffset), w, h, (int) parentViewTopOffset, blurredViewTopOffset, blurredViewBottomOffset, pinnedTop, pinnedBottom);
                        float alpha = !mediaBackground && !pinnedBottom ? transitionParams.changePinnedBottomProgress : (1f - transitionParams.changePinnedBottomProgress);
                        drawable.setAlpha((int) (255 * alpha));
                        drawable.draw(canvas);
                        drawable.setAlpha(255);
                        canvas.restore();
                    } else {
                        Theme.MessageDrawable drawable;
                        if (transitionParams.drawPinnedBottomBackground) {
                            drawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgIn);
                        } else {
                            drawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgInMedia);
                        }
                        float alpha = !mediaBackground && !pinnedBottom ? transitionParams.changePinnedBottomProgress : (1f - transitionParams.changePinnedBottomProgress);
                        drawable.setAlpha((int) (255 * alpha));
                        Rect rect = currentBackgroundDrawable.getBounds();
                        drawable.setBounds(rect.left - AndroidUtilities.dp(6), rect.top, rect.right, rect.bottom);
                        canvas.save();
                        canvas.translate(pinnedBottomOffset, 0);
                        canvas.clipRect(rect.left - AndroidUtilities.dp(6), rect.bottom - AndroidUtilities.dp(16), rect.left + AndroidUtilities.dp(6 + 12), rect.bottom);
                        drawable.draw(canvas);
                        drawable.setAlpha(255);
                        canvas.restore();
                    }
                }
            }
        }
        //视频不加边框
        if (currentMessageObject != null && currentMessageObject.isRoundVideo()) {
            currentBackgroundDrawable.setRoundingRadius(0);
        }
        canvas.restoreToCount(restoreCount);
    }

    private void animateCheckboxTranslation() {
        if (checkBoxVisible || checkBoxAnimationInProgress) {
            if (checkBoxVisible && checkBoxAnimationProgress == 1.0f || !checkBoxVisible && checkBoxAnimationProgress == 0.0f) {
                checkBoxAnimationInProgress = false;
            }
            Interpolator interpolator = checkBoxVisible ? CubicBezierInterpolator.EASE_OUT : CubicBezierInterpolator.EASE_IN;
            checkBoxTranslation = (int) Math.ceil(interpolator.getInterpolation(checkBoxAnimationProgress) * AndroidUtilities.dp(35));
            if (!currentMessageObject.isOutOwner()) {
                updateTranslation();
            }

            if (checkBoxAnimationInProgress) {
                long newTime = SystemClock.elapsedRealtime();
                long dt = newTime - lastCheckBoxAnimationTime;
                lastCheckBoxAnimationTime = newTime;

                if (checkBoxVisible) {
                    checkBoxAnimationProgress += dt / 200.0f;
                    if (checkBoxAnimationProgress > 1.0f) {
                        checkBoxAnimationProgress = 1.0f;
                    }
                } else {
                    checkBoxAnimationProgress -= dt / 200.0f;
                    if (checkBoxAnimationProgress <= 0.0f) {
                        checkBoxAnimationProgress = 0.0f;
                    }
                }
                invalidate();
                ((View) getParent()).invalidate();
            }
        }
    }

    public boolean drawBackgroundInParent() {
        if (canDrawBackgroundInParent && currentMessageObject != null && currentMessageObject.isOutOwner()) {
            if (resourcesProvider != null) {
                return resourcesProvider.getCurrentColor(Theme.key_chat_outBubbleGradient1) != null;
            } else {
                return Theme.getColorOrNull(Theme.key_chat_outBubbleGradient1) != null;
            }
        }
        return false;
    }

    public void drawCommentButton(Canvas canvas, float alpha) {
        if (drawSideButton != 3) {
            return;
        }
        int height = AndroidUtilities.dp(32);
        if (commentLayout != null) {
            sideStartY -= AndroidUtilities.dp(18);
            height += AndroidUtilities.dp(18);
        }

        rect.set(sideStartX, sideStartY, sideStartX + AndroidUtilities.dp(32), sideStartY + height);
        applyServiceShaderMatrix();
        if (alpha != 1f) {
            int oldAlpha = getThemedPaint(Theme.key_paint_chatActionBackground).getAlpha();
            getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha((int) (alpha * oldAlpha));
            canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), getThemedPaint(Theme.key_paint_chatActionBackground));
            getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha(oldAlpha);
        } else {
            canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), getThemedPaint(sideButtonPressed ? Theme.key_paint_chatActionBackgroundSelected : Theme.key_paint_chatActionBackground));
        }
        if (hasGradientService()) {
            if (alpha != 1f) {
                int oldAlpha = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (alpha * oldAlpha));
                canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
                Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha);
            } else {
                canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
            }
        }

        Drawable commentStickerDrawable = Theme.getThemeDrawable(Theme.key_drawable_commentSticker);
        setDrawableBounds(commentStickerDrawable, sideStartX + AndroidUtilities.dp(4), sideStartY + AndroidUtilities.dp(4));
        if (alpha != 1f) {
            commentStickerDrawable.setAlpha((int) (255 * alpha));
            commentStickerDrawable.draw(canvas);
            commentStickerDrawable.setAlpha(255);
        } else {
            commentStickerDrawable.draw(canvas);
        }

        if (commentLayout != null) {
            Theme.chat_stickerCommentCountPaint.setColor(getThemedColor(Theme.key_chat_stickerReplyNameText));
            Theme.chat_stickerCommentCountPaint.setAlpha((int) (255 * alpha));
            if (transitionParams.animateComments) {
                if (transitionParams.animateCommentsLayout != null) {
                    canvas.save();
                    Theme.chat_stickerCommentCountPaint.setAlpha((int) (255 * (1.0 - transitionParams.animateChangeProgress) * alpha));
                    canvas.translate(sideStartX + (AndroidUtilities.dp(32) - transitionParams.animateTotalCommentWidth) / 2, sideStartY + AndroidUtilities.dp(30));
                    transitionParams.animateCommentsLayout.draw(canvas);
                    canvas.restore();
                }
                Theme.chat_stickerCommentCountPaint.setAlpha((int) (255 * transitionParams.animateChangeProgress));
            }
            canvas.save();
            canvas.translate(sideStartX + (AndroidUtilities.dp(32) - totalCommentWidth) / 2, sideStartY + AndroidUtilities.dp(30));
            commentLayout.draw(canvas);
            canvas.restore();
        }
    }

    public void applyServiceShaderMatrix() {
        applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
    }

    private void applyServiceShaderMatrix(int measuredWidth, int backgroundHeight, float x, float viewTop) {
        if (resourcesProvider != null) {
            resourcesProvider.applyServiceShaderMatrix(measuredWidth, backgroundHeight, x, viewTop);
        } else {
            Theme.applyServiceShaderMatrix(measuredWidth, backgroundHeight, x, viewTop);
        }
    }

    public boolean hasOutboundsContent() {
        if (getAlpha() != 1f) {
            return false;
        }
        return (
            (!transitionParams.transitionBotButtons.isEmpty() && transitionParams.animateBotButtonsChanged) ||
            !botButtons.isEmpty() ||
            drawSideButton != 0 ||
            drawNameLayout && nameLayout != null && currentNameStatusDrawable != null && currentNameStatusDrawable.getDrawable() != null ||
            animatedEmojiStack != null && !animatedEmojiStack.holders.isEmpty() ||
            drawTopic && topicButton != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) ||
            currentMessagesGroup == null &&
                (transitionParams.animateReplaceCaptionLayout && transitionParams.animateChangeProgress != 1f || transitionParams.animateChangeProgress != 1.0f && transitionParams.animateMessageText) &&
                transitionParams.animateOutAnimateEmoji != null && !transitionParams.animateOutAnimateEmoji.holders.isEmpty()
        );
    }

    public void drawOutboundsContent(Canvas canvas) {
        if (!enterTransitionInProgress) {
            drawAnimatedEmojis(canvas, 1f);
        }

        if (currentNameStatusDrawable != null && drawNameLayout && nameLayout != null) {
            int color;
            float nameX, nameY;
            if (currentMessageObject.shouldDrawWithoutBackground()) {
                color = getThemedColor(Theme.key_chat_stickerNameText);
                if (currentMessageObject.isOutOwner()) {
                    nameX = AndroidUtilities.dp(28);
                } else {
                    nameX = backgroundDrawableLeft + transitionParams.deltaLeft + backgroundDrawableRight + AndroidUtilities.dp(22);
                }
                nameY = layoutHeight - AndroidUtilities.dp(38);
                nameX -= nameOffsetX;
            } else {
                if (mediaBackground || currentMessageObject.isOutOwner()) {
                    nameX = backgroundDrawableLeft + transitionParams.deltaLeft + AndroidUtilities.dp(11) + getExtraTextX();
                } else {
                    nameX = backgroundDrawableLeft + transitionParams.deltaLeft + AndroidUtilities.dp(!mediaBackground && drawPinnedBottom ? 11 : 17) + getExtraTextX();
                }
                if (currentUser != null) {
                    if (currentBackgroundDrawable != null && currentBackgroundDrawable.hasGradient()) {
                        color = getThemedColor(Theme.key_chat_messageTextOut);
                    } else {
                        color = getThemedColor(AvatarDrawable.getNameColorNameForId(currentUser.id));
                    }
                } else if (currentChat != null) {
                    if (currentMessageObject.isOutOwner() && ChatObject.isChannel(currentChat)) {
                        if (currentBackgroundDrawable != null && currentBackgroundDrawable.hasGradient()) {
                            color = getThemedColor(Theme.key_chat_messageTextOut);
                        } else {
                            color = getThemedColor(Theme.key_chat_outForwardedNameText);
                        }
                    } else if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
                        color = Theme.changeColorAccent(getThemedColor(AvatarDrawable.getNameColorNameForId(5)));
                    } else if (currentMessageObject.isOutOwner()) {
                        color = getThemedColor(Theme.key_chat_outForwardedNameText);
                    } else {
                        color = getThemedColor(AvatarDrawable.getNameColorNameForId(currentChat.id));
                    }
                } else {
                    color = getThemedColor(AvatarDrawable.getNameColorNameForId(0));
                }
                nameY = AndroidUtilities.dp(drawPinnedTop ? 9 : 10);
            }
            if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                nameX += currentMessagesGroup.transitionParams.offsetLeft;
                nameY += currentMessagesGroup.transitionParams.offsetTop - getTranslationY();
            }
            nameX += animationOffsetX;
            nameY += transitionParams.deltaTop;
            float nx;
            if (transitionParams.animateSign) {
                nx = transitionParams.animateNameX + (nameX - transitionParams.animateNameX) * transitionParams.animateChangeProgress;
            } else {
                nx = nameX;
            }
            currentNameStatusDrawable.setBounds(
                (int) (Math.abs(nx) + nameLayoutWidth + AndroidUtilities.dp(2)),
                (int) (nameY + nameLayout.getHeight() / 2 - AndroidUtilities.dp(10)),
                (int) (Math.abs(nx) + nameLayoutWidth + AndroidUtilities.dp(22)),
                (int) (nameY + nameLayout.getHeight() / 2 + AndroidUtilities.dp(10))
            );
            currentNameStatusDrawable.setColor(ColorUtils.setAlphaComponent(color, 115));
            currentNameStatusDrawable.draw(canvas);
        }

        if (drawTopic && topicButton != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
            float replyForwardAlpha = 1f;
            if (isRoundVideo && !hasLinkPreview) {
                replyForwardAlpha *= 1f - getVideoTranscriptionProgress();
                if (transitionParams.animatePlayingRound) {
                    if (isPlayingRound) {
                        replyForwardAlpha *= (1f - transitionParams.animateChangeProgress);
                    } else {
                        replyForwardAlpha *= transitionParams.animateChangeProgress;
                    }
                } else if (isPlayingRound) {
                    replyForwardAlpha = 0;
                }
            }
            float animatingAlpha = 1f;
            if (transitionParams.animateForwardedLayout) {
                if (!currentMessageObject.needDrawForwarded()) {
                    animatingAlpha = 1f - transitionParams.animateChangeProgress;
                } else {
                    animatingAlpha = transitionParams.animateChangeProgress;
                }
            }
            topicButton.drawOutbounds(canvas, animatingAlpha * replyForwardAlpha);
        }

        if (!transitionParams.transitionBotButtons.isEmpty() && transitionParams.animateBotButtonsChanged) {
            float t = transitionParams.animateChangeProgress;
            t = MathUtils.clamp(1f - (float) Math.pow(t, 2f), 0f, 1f);
            drawBotButtons(canvas, transitionParams.transitionBotButtons, (int) (0xFF * t));
        }
        if (!botButtons.isEmpty()) {
            drawBotButtons(canvas, botButtons, transitionParams.animateBotButtonsChanged ? (int) (0xFF * transitionParams.animateChangeProgress) : 0xFF);
        }
        drawSideButton(canvas);
    }

    public void drawAnimatedEmojis(Canvas canvas, float alpha) {
        drawAnimatedEmojiMessageText(canvas, alpha);
//        if (shouldDrawCaptionLayout()) {
//            drawAnimatedEmojiCaption(canvas, 1f);
//        }
    }

    private void drawAnimatedEmojiMessageText(Canvas canvas, float alpha) {
        if (transitionParams.animateChangeProgress != 1.0f && transitionParams.animateMessageText) {
            canvas.save();
            if (currentBackgroundDrawable != null) {
                Rect r = currentBackgroundDrawable.getBounds();
                if (currentMessageObject.isOutOwner() && !mediaBackground && !pinnedBottom) {
                    canvas.clipRect(
                            r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                            r.right - AndroidUtilities.dp(10), r.bottom - AndroidUtilities.dp(4)
                    );
                } else {
                    canvas.clipRect(
                            r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                            r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
                    );
                }
            }
            drawAnimatedEmojiMessageText(canvas, transitionParams.animateOutTextBlocks, transitionParams.animateOutAnimateEmoji, false, alpha * (1.0f - transitionParams.animateChangeProgress));
            drawAnimatedEmojiMessageText(canvas, currentMessageObject.textLayoutBlocks, animatedEmojiStack, true, alpha * transitionParams.animateChangeProgress);
            canvas.restore();
        } else {
            drawAnimatedEmojiMessageText(canvas, currentMessageObject.textLayoutBlocks, animatedEmojiStack, true, alpha);
        }
    }

    private void drawAnimatedEmojiMessageText(Canvas canvas, ArrayList<MessageObject.TextLayoutBlock> textLayoutBlocks, AnimatedEmojiSpan.EmojiGroupedSpans stack, boolean origin, float alpha) {
        if (textLayoutBlocks == null || textLayoutBlocks.isEmpty() || alpha == 0) {
            return;
        }
        int firstVisibleBlockNum;
        int lastVisibleBlockNum;
        if (origin) {
            if (fullyDraw) {
                this.firstVisibleBlockNum = 0;
                this.lastVisibleBlockNum = textLayoutBlocks.size();
            }
            firstVisibleBlockNum = this.firstVisibleBlockNum;
            lastVisibleBlockNum = this.lastVisibleBlockNum;
        } else {
            firstVisibleBlockNum = 0;
            lastVisibleBlockNum = textLayoutBlocks.size();
        }

        float textY = this.textY;
        if (transitionParams.animateText) {
            textY = transitionParams.animateFromTextY * (1f - transitionParams.animateChangeProgress) + this.textY * transitionParams.animateChangeProgress;
        }
        for (int a = firstVisibleBlockNum; a <= lastVisibleBlockNum; a++) {
            if (a >= textLayoutBlocks.size()) {
                break;
            }
            if (a < 0) {
                continue;
            }
            MessageObject.TextLayoutBlock block = textLayoutBlocks.get(a);
            canvas.save();
            canvas.translate(textX - (block.isRtl() ? (int) Math.ceil(currentMessageObject.textXOffset) : 0), textY + block.textYOffset + transitionYOffsetForDrawables);
            float drawingYOffset = textY + block.textYOffset + transitionYOffsetForDrawables;
            float top = 0; // parentBoundsTop - getY() - drawingYOffset + AndroidUtilities.dp(20);
            float bottom = 0; // parentBoundsBottom - getY() - drawingYOffset - AndroidUtilities.dp(20);
            if (transitionParams.messageEntering) {
                top = bottom = 0;
            }
            AnimatedEmojiSpan.drawAnimatedEmojis(canvas, block.textLayout, stack, 0, block.spoilers, top, bottom, drawingYOffset, alpha, Theme.chat_animatedEmojiTextColorFilter);
            canvas.restore();
        }
    }

    public void drawAnimatedEmojiCaption(Canvas canvas, float alpha) {
        if (transitionParams.animateReplaceCaptionLayout && transitionParams.animateChangeProgress != 1f) {
            drawAnimatedEmojiCaption(canvas, transitionParams.animateOutCaptionLayout, transitionParams.animateOutAnimateEmoji, alpha * (1f - transitionParams.animateChangeProgress));
            drawAnimatedEmojiCaption(canvas, captionLayout, animatedEmojiStack, alpha * transitionParams.animateChangeProgress);
        } else {
            drawAnimatedEmojiCaption(canvas, captionLayout, animatedEmojiStack, alpha);
        }
    }

    private void drawAnimatedEmojiCaption(Canvas canvas, Layout layout, AnimatedEmojiSpan.EmojiGroupedSpans stack, float alpha) {
        if (layout == null || currentMessageObject.deleted && currentPosition != null || alpha <= 0) {
            return;
        }
        canvas.save();
        float renderingAlpha = alpha;
        if (currentMessagesGroup != null) {
            renderingAlpha = currentMessagesGroup.transitionParams.captionEnterProgress * alpha;
        }
        if (renderingAlpha == 0) {
            return;
        }

        float captionY = this.captionY;
        float captionX = this.captionX;

        if (transitionParams.animateBackgroundBoundsInner) {
            if (transitionParams.transformGroupToSingleMessage) {
                captionY -= getTranslationY();
                captionX += transitionParams.deltaLeft;
            } else if (transitionParams.moveCaption) {
                captionX = this.captionX * transitionParams.animateChangeProgress + transitionParams.captionFromX * (1f - transitionParams.animateChangeProgress);
                captionY = this.captionY * transitionParams.animateChangeProgress + transitionParams.captionFromY * (1f - transitionParams.animateChangeProgress);
            } else if (!currentMessageObject.isVoice() || !TextUtils.isEmpty(currentMessageObject.caption)) {
                captionX += transitionParams.deltaLeft;
            }
        }

        canvas.translate(captionX, captionY);
        try {
            AnimatedEmojiSpan.drawAnimatedEmojis(canvas, layout, stack, 0, captionSpoilers, 0, 0, captionY, renderingAlpha, Theme.chat_animatedEmojiTextColorFilter);
        } catch (Exception e) {
            FileLog.e(e);
        }
        canvas.restore();
    }

    private void drawSideButton(Canvas canvas) {
        if (drawSideButton != 0) {
            if (currentMessageObject.isOutOwner()) {
                sideStartX = transitionParams.lastBackgroundLeft - AndroidUtilities.dp(8 + 32);
                if (currentMessagesGroup != null) {
                    sideStartX += currentMessagesGroup.transitionParams.offsetLeft - animationOffsetX;
                }
            } else {
                sideStartX = transitionParams.lastBackgroundRight + AndroidUtilities.dp(8);
                if (currentMessagesGroup != null) {
                    sideStartX += currentMessagesGroup.transitionParams.offsetRight - animationOffsetX;
                }
            }
            sideStartY = layoutHeight + transitionParams.deltaBottom - AndroidUtilities.dp(41);
            if (currentMessageObject.type == MessageObject.TYPE_EMOJIS && currentMessageObject.textWidth < timeTextWidth) {
                sideStartY -= AndroidUtilities.dp(22);
            }
            if (currentMessagesGroup != null) {
                sideStartY += currentMessagesGroup.transitionParams.offsetBottom;
                if (currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                    sideStartY -= getTranslationY();
                }
            }
            if (!reactionsLayoutInBubble.isSmall) {
                if (isRoundVideo) {
                    sideStartY -= reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress) * (1f - getVideoTranscriptionProgress());
                } else if (reactionsLayoutInBubble.drawServiceShaderBackground > 0) {
                    sideStartY -= reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress);
                }
            }
            if (!currentMessageObject.isOutOwner() && isRoundVideo && !hasLinkPreview) {
                float offsetSize = isAvatarVisible ? ((AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f) : AndroidUtilities.dp(50);
                float offsetX = isPlayingRound ? offsetSize * (1f - getVideoTranscriptionProgress()) : 0;
                float offsetY = isPlayingRound ? AndroidUtilities.dp(28) * (1f - getVideoTranscriptionProgress()) : 0;
                if (transitionParams.animatePlayingRound) {
                    offsetX = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * (1f - getVideoTranscriptionProgress()) * offsetSize;
                    offsetY = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * (1f - getVideoTranscriptionProgress()) * AndroidUtilities.dp(28);
                }
                sideStartX -= offsetX;
                sideStartY -= offsetY;
            }
            if (drawSideButton == 3) {
                if (!(enterTransitionInProgress && !currentMessageObject.isVoice())) {
                    drawCommentButton(canvas, 1f);
                }
            } else {
                rect.set(sideStartX, sideStartY, sideStartX + AndroidUtilities.dp(32), sideStartY + AndroidUtilities.dp(32));
                applyServiceShaderMatrix();
                canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), getThemedPaint(sideButtonPressed ? Theme.key_paint_chatActionBackgroundSelected : Theme.key_paint_chatActionBackground));
                if (hasGradientService()) {
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
                }

                if (drawSideButton == 2) {
                    Drawable goIconDrawable = getThemedDrawable(Theme.key_drawable_goIcon);
                    if (currentMessageObject.isOutOwner()) {
                        setDrawableBounds(goIconDrawable, sideStartX + AndroidUtilities.dp(10), sideStartY + AndroidUtilities.dp(9));
                        canvas.save();
                        canvas.scale(-1, 1, goIconDrawable.getBounds().centerX(), goIconDrawable.getBounds().centerY());
                    } else {
                        setDrawableBounds(goIconDrawable, sideStartX + AndroidUtilities.dp(12), sideStartY + AndroidUtilities.dp(9));
                    }
                    goIconDrawable.draw(canvas);
                    if (currentMessageObject.isOutOwner()) {
                        canvas.restore();
                    }
                } else {

                    Drawable drawable = getThemedDrawable(Theme.key_drawable_shareIcon);
                    setDrawableBounds(drawable, sideStartX + AndroidUtilities.dp(8), sideStartY + AndroidUtilities.dp(9));
                    drawable.draw(canvas);
                }
            }
        }
    }

    public void setTimeAlpha(float value) {
        timeAlpha = value;
    }

    public float getTimeAlpha() {
        return timeAlpha;
    }

    public int getBackgroundDrawableLeft() {
        if (currentMessageObject.isOutOwner()) {
            if (isRoundVideo) {
                return layoutWidth - backgroundWidth - (int) ((1f - getVideoTranscriptionProgress()) * AndroidUtilities.dp(9));
            }
            return layoutWidth - backgroundWidth - (!mediaBackground ? 0 : AndroidUtilities.dp(9));
        } else {
            int r;
            if (isRoundVideo) {
                r = AndroidUtilities.dp((isChat && isAvatarVisible ? 48 : 0) + 3);
                r += (int) (AndroidUtilities.dp(6) * (1f - getVideoTranscriptionProgress()));
            } else {
                r = AndroidUtilities.dp((isChat && isAvatarVisible ? 48 : 0) + (!mediaBackground ? 3 : 9));
            }
            if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
                if (currentPosition.leftSpanOffset != 0) {
                    r += (int) Math.ceil(currentPosition.leftSpanOffset / 1000.0f * getGroupPhotosWidth());
                }
            }
            if (isRoundVideo) {
                if (drawPinnedBottom) {
                    r += (int) (AndroidUtilities.dp(6) * (1f - getVideoTranscriptionProgress()));
                }
            } else if ((!mediaBackground && drawPinnedBottom)) {
                r += AndroidUtilities.dp(6);
            }
            return r;
        }
    }

    public int getBackgroundDrawableRight() {
        int right = backgroundWidth;
        if (isRoundVideo) {
            right -= (int) (getVideoTranscriptionProgress() * AndroidUtilities.dp(3));
            if (drawPinnedBottom && currentMessageObject.isOutOwner()) {
                right -= AndroidUtilities.dp(6) * (1f - getVideoTranscriptionProgress());
            }
            if (drawPinnedBottom && !currentMessageObject.isOutOwner()) {
                right -= AndroidUtilities.dp(6) * (1f - getVideoTranscriptionProgress());
            }
            return getBackgroundDrawableLeft() + right;
        }
        right -= (mediaBackground ? 0 : AndroidUtilities.dp(3));
        if (!mediaBackground && drawPinnedBottom) {
            right -= AndroidUtilities.dp(6);
        }
        return getBackgroundDrawableLeft() + right;
    }

    public int getBackgroundDrawableTop() {
        int additionalTop = 0;
        if (currentPosition != null) {
            if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                additionalTop -= AndroidUtilities.dp(3);
            }
        }
        int top = additionalTop + (drawPinnedTop ? 0 : AndroidUtilities.dp(1));
        if (!mediaBackground) {
            if (drawPinnedTop) {
                top -= AndroidUtilities.dp(1);
            }
        }
        return top;
    }

    public int getBackgroundDrawableBottom() {
        int additionalBottom = 0;
        if (currentPosition != null) {
            if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0) {
                additionalBottom += AndroidUtilities.dp(3);
            }
            if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
                additionalBottom += AndroidUtilities.dp((currentMessageObject.isOutOwner() ? 3 : 4));
            }
        }

        int offsetBottom;
        if (drawPinnedBottom && drawPinnedTop) {
            offsetBottom = 0;
        } else if (drawPinnedBottom) {
            offsetBottom = AndroidUtilities.dp(1);
        } else {
            offsetBottom = AndroidUtilities.dp(2);
        }
        int top = getBackgroundDrawableTop();
        int bottom = top + layoutHeight - offsetBottom + additionalBottom;
        if (!mediaBackground) {
            if (drawPinnedTop) {
                bottom += AndroidUtilities.dp(1);
            }
            if (drawPinnedBottom) {
                bottom += AndroidUtilities.dp(1);
            }
        }
        return bottom;
    }

    public void drawBackground(Canvas canvas, int left, int top, int right, int bottom, boolean pinnedTop, boolean pinnedBottom, boolean selected, int keyboardHeight) {
        if (currentMessageObject.isOutOwner()) {
            if (!mediaBackground && !pinnedBottom) {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(selected ? Theme.key_drawable_msgOutSelected : Theme.key_drawable_msgOut);
            } else {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(selected ? Theme.key_drawable_msgOutMediaSelected : Theme.key_drawable_msgOutMedia);
            }
        } else {
            if (!mediaBackground && !pinnedBottom) {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(selected ? Theme.key_drawable_msgInSelected : Theme.key_drawable_msgIn);
            } else {
                currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(selected ? Theme.key_drawable_msgInMediaSelected : Theme.key_drawable_msgInMedia);
            }
        }

        int w = parentWidth;
        int h = parentHeight;
        if (h == 0) {
            w = getParentWidth();
            h = AndroidUtilities.displaySize.y;
            if (getParent() instanceof View) {
                View view = (View) getParent();
                w = view.getMeasuredWidth();
                h = view.getMeasuredHeight();
            }
        }

        if (currentBackgroundDrawable != null) {
            currentBackgroundDrawable.setTop(keyboardHeight, w, h, (int) parentViewTopOffset, blurredViewTopOffset, blurredViewBottomOffset, pinnedTop, pinnedBottom);
            Drawable currentBackgroundShadowDrawable = currentBackgroundDrawable.getShadowDrawable();
            if (currentBackgroundShadowDrawable != null) {
                currentBackgroundShadowDrawable.setAlpha((int) (getAlpha() * 255));
                currentBackgroundShadowDrawable.setBounds(left, top, right, bottom);
                currentBackgroundShadowDrawable.draw(canvas);
                currentBackgroundShadowDrawable.setAlpha(255);
            }
            currentBackgroundDrawable.setAlpha((int) (getAlpha() * 255));
            currentBackgroundDrawable.setBounds(left, top, right, bottom);
            currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
            currentBackgroundDrawable.setAlpha(255);
        }

        animateCheckboxTranslation();
    }

    public boolean hasNameLayout() {
        return drawNameLayout && nameLayout != null ||
                drawForwardedName && forwardedNameLayout[0] != null && forwardedNameLayout[1] != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) ||
                replyNameLayout != null || drawTopic;
    }

    public boolean isDrawNameLayout() {
        return drawNameLayout && nameLayout != null;
    }

    public boolean isDrawTopic() {
        return drawTopic;
    }

    public float getDrawTopicHeight() {
        return topicButton != null ? topicButton.height() : 0;
    }

    public boolean isAdminLayoutChanged() {
        return !TextUtils.equals(lastPostAuthor, currentMessageObject.messageOwner.post_author);
    }

    public void drawNamesLayout(Canvas canvas, float alpha) {
        long newAnimationTime = SystemClock.elapsedRealtime();
        long dt = newAnimationTime - lastNamesAnimationTime;
        if (dt > 17) {
            dt = 17;
        }
        lastNamesAnimationTime = newAnimationTime;

        if (currentMessageObject.deleted && currentMessagesGroup != null && currentMessagesGroup.messages.size() >= 1) {
            return;
        }

        int restore = Integer.MIN_VALUE;
        if (alpha != 1f) {
            rect.set(0, 0, getMaxNameWidth(), getMeasuredHeight());
            restore = canvas.saveLayerAlpha(rect, (int) (255 * alpha), Canvas.ALL_SAVE_FLAG);
        }

        float replyForwardAlpha = 1f;
        if (isRoundVideo && !hasLinkPreview) {
            replyForwardAlpha *= 1f - getVideoTranscriptionProgress();
            if (transitionParams.animatePlayingRound) {
                if (isPlayingRound) {
                    replyForwardAlpha *= (1f - transitionParams.animateChangeProgress);
                } else {
                    replyForwardAlpha *= transitionParams.animateChangeProgress;
                }
            } else if (isPlayingRound) {
                replyForwardAlpha = 0;
            }
        }
        if (drawNameLayout && nameLayout != null) {
            canvas.save();

            int oldAlpha;

            if (currentMessageObject.shouldDrawWithoutBackground()) {
                Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_stickerNameText));
                if (currentMessageObject.isOutOwner()) {
                    nameX = AndroidUtilities.dp(28);
                } else {
                    nameX = backgroundDrawableLeft + transitionParams.deltaLeft + backgroundDrawableRight + AndroidUtilities.dp(22);
                }
                nameY = layoutHeight - AndroidUtilities.dp(38);
                float alphaProgress = currentMessageObject.isOut() && (checkBoxVisible || checkBoxAnimationInProgress) ? (1.0f - checkBoxAnimationProgress) : 1.0f;

                rect.set((int) nameX - AndroidUtilities.dp(12), (int) nameY - AndroidUtilities.dp(5), (int) nameX + AndroidUtilities.dp(12) + nameWidth, (int) nameY + AndroidUtilities.dp(22));
                oldAlpha = getThemedPaint(Theme.key_paint_chatActionBackground).getAlpha();
                getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha((int) (alphaProgress * oldAlpha * replyForwardAlpha));
                applyServiceShaderMatrix();
                canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), getThemedPaint(Theme.key_paint_chatActionBackground));
                if (hasGradientService()) {
                    int oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                    Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * timeAlpha * replyForwardAlpha));
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
                    Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
                }

                if (viaSpan1 != null || viaSpan2 != null) {
                    int color = getThemedColor(Theme.key_chat_stickerViaBotNameText);
                    color = (getThemedColor(Theme.key_chat_stickerViaBotNameText) & 0x00ffffff) | ((int) (Color.alpha(color) * alphaProgress) << 24);
                    if (viaSpan1 != null) {
                        viaSpan1.setColor(color);
                    }
                    if (viaSpan2 != null) {
                        viaSpan2.setColor(color);
                    }
                }
                nameX -= nameOffsetX;
                getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha(oldAlpha);
            } else {
                if (mediaBackground || currentMessageObject.isOutOwner()) {
                    nameX = backgroundDrawableLeft + transitionParams.deltaLeft + AndroidUtilities.dp(11) - nameOffsetX + getExtraTextX();
                } else {
                    nameX = backgroundDrawableLeft + transitionParams.deltaLeft + AndroidUtilities.dp(!mediaBackground && drawPinnedBottom ? 11 : 17) - nameOffsetX + getExtraTextX();
                }
                if (currentUser != null) {
                    if (currentBackgroundDrawable != null && currentBackgroundDrawable.hasGradient()) {
                        Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
                    } else {
                        Theme.chat_namePaint.setColor(getThemedColor(AvatarDrawable.getNameColorNameForId(currentUser.id)));
                    }
                } else if (currentChat != null) {
                    if (currentMessageObject.isOutOwner() && ChatObject.isChannel(currentChat)) {
                        if (currentBackgroundDrawable != null && currentBackgroundDrawable.hasGradient()) {
                            Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
                        } else {
                            Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_outForwardedNameText));
                        }
                    } else if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
                        Theme.chat_namePaint.setColor(Theme.changeColorAccent(getThemedColor(AvatarDrawable.getNameColorNameForId(5))));
                    } else if (currentMessageObject.isOutOwner()) {
                        Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_outForwardedNameText));
                    } else {
                        Theme.chat_namePaint.setColor(getThemedColor(AvatarDrawable.getNameColorNameForId(currentChat.id)));
                    }
                } else {
                    Theme.chat_namePaint.setColor(getThemedColor(AvatarDrawable.getNameColorNameForId(0)));
                }
                nameY = AndroidUtilities.dp(drawPinnedTop ? 9 : 10);
                if (viaSpan1 != null || viaSpan2 != null) {
                    int color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outViaBotNameText : Theme.key_chat_inViaBotNameText);
                    if (viaSpan1 != null) {
                        viaSpan1.setColor(color);
                    }
                    if (viaSpan2 != null) {
                        viaSpan2.setColor(color);
                    }
                }
            }
            if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                nameX += currentMessagesGroup.transitionParams.offsetLeft;
                nameY += currentMessagesGroup.transitionParams.offsetTop - getTranslationY();
            }
            nameX += animationOffsetX;
            nameY += transitionParams.deltaTop;
            float nx;
            if (transitionParams.animateSign) {
                nx = transitionParams.animateNameX + (nameX - transitionParams.animateNameX) * transitionParams.animateChangeProgress;
            } else {
                nx = nameX;
            }
            canvas.translate(nx, nameY);
            nameLayout.draw(canvas);
            canvas.restore();
            if (adminLayout != null) {
                int color;
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    color = getThemedColor(Theme.key_chat_stickerReplyNameText);
                } else if (currentMessageObject.isOutOwner()) {
                    color = getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outAdminSelectedText : Theme.key_chat_outAdminText);
                } else {
                    color = getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inAdminSelectedText : Theme.key_chat_inAdminText);
                }
                Theme.chat_adminPaint.setColor(color);
                canvas.save();
                float ax;
                if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
                    int dWidth = getGroupPhotosWidth();
                    int firstLineWidth = 0;
                    for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                        MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                        if (position.minY == 0) {
                            firstLineWidth += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
                        } else {
                            break;
                        }
                    }
                    if (!mediaBackground && currentMessageObject.isOutOwner()) {
                        ax = backgroundDrawableLeft + firstLineWidth - AndroidUtilities.dp(17) - adminLayout.getLineWidth(0);
                    } else {
                        ax = backgroundDrawableLeft + firstLineWidth - AndroidUtilities.dp(11) - adminLayout.getLineWidth(0);
                    }
                    ax -= getExtraTextX() + AndroidUtilities.dp(8);
                    if (!currentMessageObject.isOutOwner()) {
                        ax -= AndroidUtilities.dp(48);
                    }
                } else {
                    if (currentMessageObject.shouldDrawWithoutBackground()) {
                        if (currentMessageObject.isOutOwner()) {
                            ax = AndroidUtilities.dp(28) + nameWidth - adminLayout.getLineWidth(0);
                        } else {
                            ax = backgroundDrawableLeft + transitionParams.deltaLeft + backgroundDrawableRight + AndroidUtilities.dp(22) + nameWidth - adminLayout.getLineWidth(0);
                        }
                    } else if (!mediaBackground && currentMessageObject.isOutOwner()) {
                        ax = backgroundDrawableLeft + backgroundDrawableRight - AndroidUtilities.dp(17) - adminLayout.getLineWidth(0);
                    } else {
                        ax = backgroundDrawableLeft + backgroundDrawableRight - AndroidUtilities.dp(11) - adminLayout.getLineWidth(0);
                    }
                }
                ax += transitionParams.deltaRight;
                canvas.translate(ax, nameY + AndroidUtilities.dp(0.5f));
                if (transitionParams.animateSign) {
                    Theme.chat_adminPaint.setAlpha((int) (Color.alpha(color) * transitionParams.animateChangeProgress));
                }
                adminLayout.draw(canvas);
                canvas.restore();
            }
        }

        boolean drawForwardedNameLocal = drawForwardedName;
        boolean hasReply = replyNameLayout != null;
        StaticLayout[] forwardedNameLayoutLocal = forwardedNameLayout;
        float animatingAlpha = 1f;
        int forwardedNameWidthLocal = forwardedNameWidth;
        if (transitionParams.animateForwardedLayout) {
            if (!currentMessageObject.needDrawForwarded()) {
                drawForwardedNameLocal = true;
                forwardedNameLayoutLocal = transitionParams.animatingForwardedNameLayout;
                animatingAlpha = 1f - transitionParams.animateChangeProgress;
                forwardedNameWidthLocal = transitionParams.animateForwardNameWidth;
            } else {
                animatingAlpha = transitionParams.animateChangeProgress;
            }
        }

        float forwardNameXLocal;
        boolean needDrawReplyBackground = true;
        if (drawForwardedNameLocal && forwardedNameLayoutLocal[0] != null && forwardedNameLayoutLocal[1] != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
            if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO || currentMessageObject.isAnyKindOfSticker()) {
                Theme.chat_forwardNamePaint.setColor(getThemedColor(Theme.key_chat_stickerReplyNameText));
                if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
                    if (currentMessageObject.isOutOwner()) {
                        if (currentMessageObject.needDrawForwarded()) {
                            forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(11) + getExtraTextX();
                            forwardNameXLocal += transitionParams.deltaLeft;
                        } else {
                            forwardNameXLocal = transitionParams.animateForwardNameX;
                        }
                        int width = Math.max(forwardedNameWidthLocal + AndroidUtilities.dp(14), hasReply ? Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14) : 0);
                        forwardNameXLocal -= Math.max(0, forwardNameXLocal + width - AndroidUtilities.displaySize.x);
                    } else {
                        if (currentMessageObject.needDrawForwarded()) {
                            forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground || drawPinnedBottom ? 11 : 17) + getExtraTextX();
                        } else {
                            forwardNameXLocal = transitionParams.animateForwardNameX;
                        }
                    }
                    forwardNameXLocal -= AndroidUtilities.dp(7);
                } else if (currentMessageObject.needDrawForwarded()) {
                    if (currentMessageObject.isOutOwner()) {
                        forwardNameXLocal = forwardNameX = AndroidUtilities.dp(23);
                    } else {
                        forwardNameXLocal = forwardNameX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(17);
                    }
                } else {
                    forwardNameXLocal = transitionParams.animateForwardNameX;
                }
                if (!currentMessageObject.isVoiceTranscriptionOpen() && (currentMessageObject.isOutOwner() && currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO && transitionParams.animatePlayingRound || isPlayingRound)) {
                    forwardNameXLocal -= AndroidUtilities.dp(78) * (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress));
                }
                forwardNameY = AndroidUtilities.dp(12) + (drawTopic && topicButton != null ? topicButton.height() + AndroidUtilities.dp(14) : 0);
                forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;

                int backWidth = forwardedNameWidthLocal + AndroidUtilities.dp(14);
                if (hasReply) {
                    needDrawReplyBackground = false;
                    int replyBackWidth = Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14);
                    rect.set((int) forwardNameXLocal - AndroidUtilities.dp(7), forwardNameY - AndroidUtilities.dp(6), (int) forwardNameXLocal - AndroidUtilities.dp(7) + Math.max(backWidth, replyBackWidth), forwardNameY + forwardHeight + AndroidUtilities.dp(6) + AndroidUtilities.dp(41));
                } else {
                    rect.set((int) forwardNameXLocal - AndroidUtilities.dp(7), forwardNameY - AndroidUtilities.dp(6), (int) forwardNameXLocal - AndroidUtilities.dp(7) + backWidth, forwardNameY + forwardHeight + AndroidUtilities.dp(6));
                }
                applyServiceShaderMatrix();
                int oldAlpha1 = -1, oldAlpha2 = -1;
                if (animatingAlpha != 1f || replyForwardAlpha != 1f) {
                    oldAlpha1 = getThemedPaint(Theme.key_paint_chatActionBackground).getAlpha();
                    getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha((int) (oldAlpha1 * animatingAlpha * replyForwardAlpha));
                }
                canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), getThemedPaint(Theme.key_paint_chatActionBackground));
                if (hasGradientService()) {
                    if (animatingAlpha != 1f || replyForwardAlpha != 1f) {
                        oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                        Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * animatingAlpha * replyForwardAlpha));
                    }
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
                }
                if (oldAlpha1 >= 0) {
                    getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha(oldAlpha1);
                }
                if (oldAlpha2 >= 0) {
                    Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
                }
            } else {
                forwardNameY = AndroidUtilities.dp(10) + (drawNameLayout ? AndroidUtilities.dp(5) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawTopic && topicButton != null ? topicButton.height() + AndroidUtilities.dp(7 + (currentMessageObject.type != MessageObject.TYPE_TEXT ? 3 : 0)) : 0);
                forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_forwardNamePaint.setColor(getThemedColor(hasPsaHint ? Theme.key_chat_outPsaNameText : Theme.key_chat_outForwardedNameText));
                    if (currentMessageObject.needDrawForwarded()) {
                        forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(11) + getExtraTextX();
                        forwardNameXLocal += transitionParams.deltaLeft;
                    } else {
                        forwardNameXLocal = transitionParams.animateForwardNameX;
                    }
                } else {
                    Theme.chat_forwardNamePaint.setColor(getThemedColor(hasPsaHint ? Theme.key_chat_inPsaNameText : Theme.key_chat_inForwardedNameText));
                    if (currentMessageObject.needDrawForwarded()) {
                        forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground || drawPinnedBottom ? 11 : 17) + getExtraTextX();
                    } else {
                        forwardNameXLocal = transitionParams.animateForwardNameX;
                    }
                }
            }
            boolean clipContent = false;
            if (transitionParams.animateForwardedLayout) {
                if (currentBackgroundDrawable != null && currentMessagesGroup == null && currentMessageObject.type != MessageObject.TYPE_ROUND_VIDEO && !currentMessageObject.isAnyKindOfSticker()) {
                    Rect r = currentBackgroundDrawable.getBounds();
                    canvas.save();
                    if (currentMessageObject.isOutOwner() && !mediaBackground && !pinnedBottom) {
                        canvas.clipRect(
                                r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                                r.right - AndroidUtilities.dp(10), r.bottom - AndroidUtilities.dp(4)
                        );
                    } else {
                        canvas.clipRect(
                                r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
                                r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
                        );
                    }
                    clipContent = true;
                }
            }

            for (int a = 0; a < 2; a++) {
                canvas.save();
                canvas.translate(forwardNameXLocal - forwardNameOffsetX[a], forwardNameY + (forwardHeight / 2f + 2) * a);
                if (animatingAlpha != 1f || replyForwardAlpha != 1f) {
                    int oldAlpha = forwardedNameLayoutLocal[a].getPaint().getAlpha();
                    forwardedNameLayoutLocal[a].getPaint().setAlpha((int) (oldAlpha * animatingAlpha * replyForwardAlpha));
                    forwardedNameLayoutLocal[a].draw(canvas);
                    forwardedNameLayoutLocal[a].getPaint().setAlpha(oldAlpha);
                } else {
                    forwardedNameLayoutLocal[a].draw(canvas);
                }
                canvas.restore();
            }
            if (clipContent) {
                canvas.restore();
            }

            if (hasPsaHint) {
                if (psaButtonVisible || psaButtonProgress > 0) {
                    Drawable drawable = Theme.chat_psaHelpDrawable[currentMessageObject.isOutOwner() ? 1 : 0];
                    int cx = psaHelpX + drawable.getIntrinsicWidth() / 2;
                    int cy = psaHelpY + drawable.getIntrinsicHeight() / 2;
                    float scale = psaButtonVisible && psaButtonProgress < 1 ? AnimationProperties.overshootInterpolator.getInterpolation(psaButtonProgress) : psaButtonProgress;
                    int w = (int) (drawable.getIntrinsicWidth() * scale);
                    int h = (int) (drawable.getIntrinsicHeight() * scale);
                    drawable.setBounds(cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2);
                    drawable.draw(canvas);

                    if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null && selectorDrawableMaskType[0] == 3) {
                        canvas.save();
                        canvas.scale(psaButtonProgress, psaButtonProgress, selectorDrawable[0].getBounds().centerX(), selectorDrawable[0].getBounds().centerY());
                        selectorDrawable[0].draw(canvas);
                        canvas.restore();
                    }
                }
                if (psaButtonVisible && psaButtonProgress < 1.0f) {
                    psaButtonProgress += dt / 180.0f;
                    invalidate();
                    if (psaButtonProgress > 1.0f) {
                        psaButtonProgress = 1.0f;
                        setInvalidatesParent(false);
                    }
                } else if (!psaButtonVisible && psaButtonProgress > 0.0f) {
                    psaButtonProgress -= dt / 180.0f;
                    invalidate();
                    if (psaButtonProgress < 0.0f) {
                        psaButtonProgress = 0.0f;
                        setInvalidatesParent(false);
                    }
                }
            }
        }

        if (drawTopic && topicButton != null && (animatingAlpha > 0 && replyForwardAlpha > 0) && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
            float x, y;
            if (currentMessageObject.shouldDrawWithoutBackground() && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
                if (currentMessageObject.isOutOwner()) {
                    x = AndroidUtilities.dp(23);
                    if (isPlayingRound) {
                        x -= (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
                    }
                } else if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                    x = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(4);
                } else {
                    x = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(17);
                }
                y = AndroidUtilities.dp(12);
                x -= AndroidUtilities.dp(8);
            } else {
                if (currentMessageObject.isOutOwner()) {
                    x = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
                } else {
                    if (mediaBackground) {
                        x = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
                    } else {
                        x = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
                    }
                }
                x -= AndroidUtilities.dp(2.33f);
                y = AndroidUtilities.dp(12) + (drawNameLayout && nameLayout != null ? AndroidUtilities.dp(6) + (int) Theme.chat_namePaint.getTextSize() : 0);
            }
            if (transitionParams.animateBackgroundBoundsInner) {
                x += transitionParams.deltaLeft;
            }
            topicButton.draw(canvas, x, y, animatingAlpha * replyForwardAlpha);
        }

        if (hasReply) {
            float replyStartX = this.replyStartX;
            float replyStartY = this.replyStartY;
            if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                replyStartX += currentMessagesGroup.transitionParams.offsetLeft;
            }
            if (transitionParams.animateBackgroundBoundsInner) {
                if (isRoundVideo) {
                    replyStartX += (currentMessageObject.isOutOwner() ? 0 : transitionParams.deltaLeft) + transitionParams.deltaRight;
                } else {
                    replyStartX += transitionParams.deltaLeft;
                }
                replyStartY = this.replyStartY * transitionParams.animateChangeProgress + transitionParams.animateFromReplyY * (1f - transitionParams.animateChangeProgress);
            }
            final boolean loading = currentMessageObject != null && delegate != null && delegate.isProgressLoading(this, ChatActivity.PROGRESS_REPLY);
            if (replyPressedFloat == null) {
                replyPressedFloat = new AnimatedFloat(this);
            }
            float replyPressedT = replyPressedFloat.set(replySelectorPressed || loading ? 1f : 0f);

            int rippleColor = getThemedColor(Theme.key_listSelector);
            if (currentMessageObject.shouldDrawWithoutBackground()) {
                Theme.chat_replyLinePaint.setColor(getThemedColor(Theme.key_chat_stickerReplyLine));
                int oldAlpha = Theme.chat_replyLinePaint.getAlpha();
                Theme.chat_replyLinePaint.setAlpha((int) (oldAlpha * timeAlpha * replyForwardAlpha));
                rippleColor = ColorUtils.setAlphaComponent(Theme.chat_replyLinePaint.getColor(), Color.alpha(rippleColor));
                Theme.chat_replyNamePaint.setColor(getThemedColor(Theme.key_chat_stickerReplyNameText));
                oldAlpha = Theme.chat_replyNamePaint.getAlpha();
                Theme.chat_replyNamePaint.setAlpha((int) (oldAlpha * timeAlpha * replyForwardAlpha));
                Theme.chat_replyTextPaint.setColor(getThemedColor(Theme.key_chat_stickerReplyMessageText));
                oldAlpha = Theme.chat_replyTextPaint.getAlpha();
                Theme.chat_replyTextPaint.setAlpha((int) (oldAlpha * timeAlpha * replyForwardAlpha));
                if (needDrawReplyBackground) {
                    int backWidth = Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14);
                    rect.set((int) replyStartX - AndroidUtilities.dp(7), replyStartY - AndroidUtilities.dp(6), (int) replyStartX - AndroidUtilities.dp(7) + backWidth, replyStartY + AndroidUtilities.dp(6) + replyHeight);
                    applyServiceShaderMatrix();
                    oldAlpha = getThemedPaint(Theme.key_paint_chatActionBackground).getAlpha();
                    getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha((int) (oldAlpha * timeAlpha * replyForwardAlpha));
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), getThemedPaint(Theme.key_paint_chatActionBackground));
                    getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha(oldAlpha);
                    if (hasGradientService()) {
                        oldAlpha = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                        Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha * timeAlpha * replyForwardAlpha));
                        canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
                        Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha);
                    }
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_replyLinePaint.setColor(getThemedColor(Theme.key_chat_outReplyLine));
                    Theme.chat_replyNamePaint.setColor(getThemedColor(Theme.key_chat_outReplyNameText));
                    rippleColor = ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_outReplyLine), 0x1e);
                    if (currentMessageObject.hasValidReplyMessageObject() && (currentMessageObject.replyMessageObject.type == MessageObject.TYPE_TEXT || !TextUtils.isEmpty(currentMessageObject.replyMessageObject.caption)) && !(MessageObject.getMedia(currentMessageObject.replyMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaGame || MessageObject.getMedia(currentMessageObject.replyMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaInvoice)) {
                        Theme.chat_replyTextPaint.setColor(getThemedColor(Theme.key_chat_outReplyMessageText));
                    } else {
                        int color = getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outReplyMediaMessageSelectedText : Theme.key_chat_outReplyMediaMessageText);
                        Theme.chat_replyTextPaint.setColor(ColorUtils.blendARGB(color, Theme.adaptHue(color, Theme.chat_replyNamePaint.getColor()), replyPressedT));
                    }
                } else {
                    if (currentReplyUserId == 0) {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(Theme.key_chat_inReplyLine));
                        Theme.chat_replyNamePaint.setColor(getThemedColor(Theme.key_chat_inReplyNameText));
                        rippleColor = ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_inReplyLine), 0x1e);
                    } else {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(AvatarDrawable.getNameColorNameForId(currentReplyUserId)));
                        Theme.chat_replyLinePaint.setAlpha((int) (Theme.chat_replyLinePaint.getAlpha() * .9f));
                        Theme.chat_replyNamePaint.setColor(getThemedColor(AvatarDrawable.getNameColorNameForId(currentReplyUserId)));
                        rippleColor = ColorUtils.setAlphaComponent(getThemedColor(AvatarDrawable.getNameColorNameForId(currentReplyUserId)), 0x1e);
                    }
                    if (currentMessageObject.hasValidReplyMessageObject() && (currentMessageObject.replyMessageObject.type == MessageObject.TYPE_TEXT || !TextUtils.isEmpty(currentMessageObject.replyMessageObject.caption)) && !(MessageObject.getMedia(currentMessageObject.replyMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaGame || MessageObject.getMedia(currentMessageObject.replyMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaInvoice)) {
                        Theme.chat_replyTextPaint.setColor(getThemedColor(Theme.key_chat_inReplyMessageText));
                    } else {
                        int color = getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inReplyMediaMessageSelectedText : Theme.key_chat_inReplyMediaMessageText);
                        Theme.chat_replyTextPaint.setColor(ColorUtils.blendARGB(color, Theme.adaptHue(color, Theme.chat_replyNamePaint.getColor()), replyPressedT));
                    }
                }
            }
            int offset = (int) Math.min(AndroidUtilities.dp(10), (replyHeight - AndroidUtilities.dp(35)) / 1.5f + AndroidUtilities.dp(10));
            forwardNameX = replyStartX - replyTextOffset + offset + (needReplyImage ? offset - AndroidUtilities.dp(1) + replyHeight : 0);
            if ((currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) && !(enterTransitionInProgress && !currentMessageObject.isVoice())) {
                int restoreToCount = -1;
                if (getAlpha() * replyForwardAlpha != 1f) {
                    AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
                    restoreToCount = canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha() * replyForwardAlpha), Canvas.ALL_SAVE_FLAG);
                }

                float leftRad, rightRad, bottomRad = Math.min(6.75f, SharedConfig.bubbleRadius);
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    leftRad = rightRad = bottomRad = 9;
                    replySelectorRect.set(
                        (int) (replyStartX - AndroidUtilities.dp(7)),
                        (int) (replyStartY - AndroidUtilities.dp(7)),
                        (int) (replyStartX + Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(7)),
                        (int) (replyStartY + replyHeight + AndroidUtilities.dp(7))
                    );
                } else {
                    if (drawTopic || drawNameLayout || (drawForwardedName && forwardedNameLayout[0] != null)) {
                        leftRad = bottomRad;
                    } else if (currentMessageObject.isOutOwner() || !drawPinnedTop) {
                        leftRad = SharedConfig.bubbleRadius * .75f;
                    } else {
                        leftRad = Math.min(6, SharedConfig.bubbleRadius);
                    }
                    if (drawTopic || drawNameLayout || (drawForwardedName && forwardedNameLayout[0] != null)) {
                        rightRad = bottomRad;
                    } else if (!currentMessageObject.isOutOwner() || !drawPinnedTop) {
                        rightRad = SharedConfig.bubbleRadius * .75f;
                    } else {
                        rightRad = Math.min(6, SharedConfig.bubbleRadius) / 3f;
                    }
                    replySelectorRect.set(
                        (int) (getCurrentBackgroundLeft() + AndroidUtilities.dp(5 + (!currentMessageObject.isOutOwner() && !mediaBackground && !drawPinnedBottom ? 6 : 0)) + getExtraTextX()),
                        (int) (replyStartY - AndroidUtilities.dp(drawNameLayout ? 4 : (4 + (!mediaBackground && drawPinnedTop ? 2 : 0)) - (drawForwardedName && forwardedNameLayout[0] != null ? 2 : 0))),
                        (int) ((currentMessagesGroup != null ? replyStartX + Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(10) : getBackgroundDrawableRight()) - AndroidUtilities.dp(5 + (currentMessageObject.isOutOwner() && !mediaBackground && !drawPinnedBottom ? 6 : 0)) - getExtraTextX()),
                        (int) (replyStartY + replyHeight + AndroidUtilities.dp(4))
                    );
                }
                if (replySelector == null) {
                    replySelector = Theme.createRadSelectorDrawable(replySelectorColor = rippleColor, 0, 0);
                    replySelector.setCallback(this);
                }
                replySelector.setBounds(replySelectorRect);
                if (leftRad != replySelectorRadLeft || rightRad != replySelectorRadRight) {
                    Theme.setMaskDrawableRad(replySelector, replySelectorRadLeft = leftRad, replySelectorRadRight = rightRad, bottomRad, bottomRad);
                }
                if (rippleColor != replySelectorColor) {
                    Theme.setSelectorDrawableColor(replySelector, replySelectorColor = rippleColor, true);
                }
                if (loading) {
                    if (replyLoadingDrawable == null) {
                        replyLoadingDrawable = new LoadingDrawable();
                        replyLoadingDrawable.setAppearByGradient(true);
                        replyLoadingDrawable.setGradientScale(3.5f);
                        replyLoadingDrawable.setSpeed(.5f);
                    }

                    int a = Color.alpha(rippleColor);
                    replyLoadingDrawable.setColors(
                        ColorUtils.setAlphaComponent(rippleColor, MathUtils.clamp(a / 2, 0, 0xFF)),
                        ColorUtils.setAlphaComponent(rippleColor, MathUtils.clamp(a * 2, 0, 0xFF)),
                        ColorUtils.setAlphaComponent(rippleColor, MathUtils.clamp(a / 2, 0, 0xFF)),
                        ColorUtils.setAlphaComponent(rippleColor, 0xFF)
                    );

                    replyLoadingDrawable.setBounds(replySelectorRect);
                    replyLoadingDrawable.setRadiiDp(leftRad, rightRad, bottomRad, bottomRad);
                    replyLoadingDrawable.strokePaint.setStrokeWidth(AndroidUtilities.dp(1));

                    replyLoadingDrawable.draw(canvas);
                } else if (replyLoadingDrawable != null) {
                    replyLoadingDrawable.reset();
                }
                replySelector.draw(canvas);

                AndroidUtilities.rectTmp.set(replyStartX, replyStartY, replyStartX + AndroidUtilities.dp(3), replyStartY + replyHeight);
                if (replyRoundRectPath == null) {
                    replyRoundRectPath = new Path();
                } else {
                    replyRoundRectPath.rewind();
                }
                if (replyRoundRectRadii == null) {
                    replyRoundRectRadii = new float[8];
                    replyRoundRectRadii[0] = replyRoundRectRadii[1] = replyRoundRectRadii[6] = replyRoundRectRadii[7] = AndroidUtilities.dp(2); // left
                    replyRoundRectRadii[2] = replyRoundRectRadii[3] = replyRoundRectRadii[4] = replyRoundRectRadii[5] = AndroidUtilities.dp(1); // right
                }
                replyRoundRectPath.addRoundRect(AndroidUtilities.rectTmp, replyRoundRectRadii, Path.Direction.CW);
                int wasAlpha = Theme.chat_replyLinePaint.getAlpha();
                if (loading) {
                    Theme.chat_replyLinePaint.setAlpha((int) (wasAlpha * .3f));
                    canvas.drawPath(replyRoundRectPath, Theme.chat_replyLinePaint);
                    Theme.chat_replyLinePaint.setAlpha(wasAlpha);

                    replyRoundRectPath.rewind();
                    replyLoadingT += 1000f / AndroidUtilities.screenRefreshRate;
                    if (replyLoadingSegment == null) {
                        replyLoadingSegment = new float[2];
                    }

                    float x = (float) Math.pow(replyLoadingT / 120f / 4f, .85f) * 4f;
                    final float from = MathUtils.clamp(.5f * ((Math.max(x, .5f) + 1.5f) % 3.5f), 0, 1);
                    final float to   = MathUtils.clamp(.5f * (((x + 1.5f) % 3.5f) - 1.5f), 0, 1);

                    AndroidUtilities.rectTmp.set(
                        replyStartX,
                        replyStartY + replyHeight * (1f - CubicBezierInterpolator.EASE_IN.getInterpolation(from)),
                        replyStartX + AndroidUtilities.dp(3),
                        replyStartY + replyHeight * (1f - CubicBezierInterpolator.EASE_OUT.getInterpolation(to))
                    );
                    replyRoundRectPath.addRoundRect(AndroidUtilities.rectTmp, replyRoundRectRadii, Path.Direction.CW);
                    canvas.drawPath(replyRoundRectPath, Theme.chat_replyLinePaint);

                    invalidate();
                } else {
                    replyLoadingT = 0;
                    canvas.drawPath(replyRoundRectPath, Theme.chat_replyLinePaint);
                }
                Theme.chat_replyLinePaint.setAlpha(wasAlpha);
                if (needReplyImage) {
                    replyImageReceiver.setAlpha(replyForwardAlpha);
                    replyImageReceiver.setImageCoords(replyStartX + offset, replyStartY, replyHeight, replyHeight);
                    replyImageReceiver.draw(canvas);

                    if (currentMessageObject != null && currentMessageObject.hasValidReplyMessageObject() && currentMessageObject.replyMessageObject.hasMediaSpoilers()) {
                        int[] rad = replyImageReceiver.getRoundRadius();
                        mediaSpoilerRadii[0] = mediaSpoilerRadii[1] = rad[0];
                        mediaSpoilerRadii[2] = mediaSpoilerRadii[3] = rad[1];
                        mediaSpoilerRadii[4] = mediaSpoilerRadii[5] = rad[2];
                        mediaSpoilerRadii[6] = mediaSpoilerRadii[7] = rad[3];

                        mediaSpoilerPath.rewind();
                        AndroidUtilities.rectTmp.set(replyImageReceiver.getImageX(), replyImageReceiver.getImageY(), replyImageReceiver.getImageX2(), replyImageReceiver.getImageY2());
                        mediaSpoilerPath.addRoundRect(AndroidUtilities.rectTmp, mediaSpoilerRadii, Path.Direction.CW);

                        canvas.save();
                        canvas.clipPath(mediaSpoilerPath);

                        int sColor = Color.WHITE;
                        mediaSpoilerEffect.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f * replyImageReceiver.getAlpha())));
                        mediaSpoilerEffect.setBounds((int) replyImageReceiver.getImageX(), (int) replyImageReceiver.getImageY(), (int) replyImageReceiver.getImageX2(), (int) replyImageReceiver.getImageY2());
                        mediaSpoilerEffect.draw(canvas);
                        canvas.restore();

                        invalidate();
                    }
                }

                if (replyNameLayout != null) {
                    canvas.save();
                    canvas.translate(replyStartX - replyNameOffset + offset + (needReplyImage ? offset - AndroidUtilities.dp(1) + replyHeight : 0), replyStartY);
                    replyNameLayout.draw(canvas);
                    canvas.restore();
                }
                int spoilersColor;
                if (currentMessageObject != null && currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount)) {
                    spoilersColor = getThemedColor(Theme.key_chat_outTimeText);
                } else {
                    spoilersColor = Theme.chat_replyTextPaint.getColor();
                }
                if (transitionParams.animateReplyTextLayout != null && transitionParams.animateChangeProgress < 1) {
                    canvas.save();
                    canvas.clipRect(replySelectorRect);

                    canvas.save();
                    canvas.translate(forwardNameX + replyTextOffset - transitionParams.animateReplyTextOffset, replyStartY + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5));
                    int wasAlpha2 = Theme.chat_replyTextPaint.getAlpha();
                    Theme.chat_replyTextPaint.setAlpha((int) (wasAlpha2 * (1f - transitionParams.animateChangeProgress)));
                    SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, transitionParams.animateReplyTextLayout, replySpoilers, canvas, false);
                    AnimatedEmojiSpan.drawAnimatedEmojis(canvas, transitionParams.animateReplyTextLayout, transitionParams.animateOutAnimateEmojiReply, 0, replySpoilers, 0, 0, 0, alpha, Theme.chat_animatedEmojiTextColorFilter);
                    Theme.chat_replyTextPaint.setAlpha(wasAlpha2);
                    canvas.restore();
                }
                if (replyTextLayout != null) {
                    canvas.save();
                    canvas.translate(forwardNameX, replyStartY + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5));
                    int wasAlpha2 = Theme.chat_replyTextPaint.getAlpha();
                    Theme.chat_replyTextPaint.setAlpha((int) (wasAlpha2 * (transitionParams.animateReplyTextLayout != null ? transitionParams.animateChangeProgress : 1)));
                    SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, replyTextLayout, replySpoilers, canvas, false);
                    AnimatedEmojiSpan.drawAnimatedEmojis(canvas, replyTextLayout, animatedEmojiReplyStack, 0, replySpoilers, 0, 0, 0, alpha, Theme.chat_animatedEmojiTextColorFilter);
                    Theme.chat_replyTextPaint.setAlpha(wasAlpha2);
                    canvas.restore();
                }
                if (transitionParams.animateReplyTextLayout != null && transitionParams.animateChangeProgress < 1) {
                    canvas.restore();
                }

                if (restoreToCount >= 0) {
                    canvas.restoreToCount(restoreToCount);
                }
            }
        }
        if (restore != Integer.MIN_VALUE) {
            canvas.restoreToCount(restore);
        }
    }

    public boolean hasCaptionLayout() {
        return captionLayout != null;
    }

    public boolean hasCommentLayout() {
        return drawCommentButton;
    }


    public StaticLayout getCaptionLayout() {
        return captionLayout;
    }

    public void setDrawSelectionBackground(boolean value) {
        if (drawSelectionBackground != value) {
            drawSelectionBackground = value;
            invalidate();
        }
    }

    public boolean isDrawingSelectionBackground() {
        return drawSelectionBackground || isHighlightedAnimated || isHighlighted;
    }

    public float getHighlightAlpha() {
        if (!drawSelectionBackground && isHighlightedAnimated) {
            return highlightProgress >= 300 ? 1.0f : highlightProgress / 300.0f;
        }
        return 1.0f;
    }

    public void setCheckBoxVisible(boolean visible, boolean animated) {
        if (visible) {
            if (checkBox == null) {
                checkBox = new CheckBoxBase(this, 21, resourcesProvider);
                if (attachedToWindow) {
                    checkBox.onAttachedToWindow();
                }
            } else {
                checkBox.setResourcesProvider(resourcesProvider);
            }
        }
        if (visible && ((currentMessagesGroup != null && currentMessagesGroup.messages.size() > 1) || (groupedMessagesToSet != null && groupedMessagesToSet.messages.size() > 1))) {
            if (mediaCheckBox == null) {
                mediaCheckBox = new CheckBoxBase(this, 21, resourcesProvider);
                mediaCheckBox.setUseDefaultCheck(true);
                if (attachedToWindow) {
                    mediaCheckBox.onAttachedToWindow();
                }
            } else {
                mediaCheckBox.setResourcesProvider(resourcesProvider);
            }
        }
        if (checkBoxVisible == visible) {
            if (animated != checkBoxAnimationInProgress && !animated) {
                checkBoxAnimationProgress = visible ? 1.0f : 0.0f;
                invalidate();
            }
            return;
        }
        checkBoxAnimationInProgress = animated;
        checkBoxVisible = visible;
        if (animated) {
            lastCheckBoxAnimationTime = SystemClock.elapsedRealtime();
        } else {
            checkBoxAnimationProgress = visible ? 1.0f : 0.0f;
        }
        invalidate();
    }

    public void setChecked(boolean checked, boolean allChecked, boolean animated) {
        if (checkBox != null) {
            checkBox.setChecked(allChecked, animated);
        }
        if (mediaCheckBox != null) {
            mediaCheckBox.setChecked(checked, animated);
        }
        backgroundDrawable.setSelected(allChecked, animated);
    }

    public void setLastTouchCoords(float x, float y) {
        lastTouchX = x;
        lastTouchY = y;
        backgroundDrawable.setTouchCoords(lastTouchX + getTranslationX(), lastTouchY);
    }

    public MessageBackgroundDrawable getBackgroundDrawable() {
        return backgroundDrawable;
    }

    public Theme.MessageDrawable getCurrentBackgroundDrawable(boolean update) {
        if (update) {
            boolean forceMediaByGroup = currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0 && currentMessagesGroup.isDocuments && !drawPinnedBottom;
            if (currentMessageObject.isOutOwner()) {
                if (!mediaBackground && !drawPinnedBottom && !forceMediaByGroup) {
                    currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOut);
                } else {
                    currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgOutMedia);
                }
            } else {
                if (!mediaBackground && !drawPinnedBottom && !forceMediaByGroup) {
                    currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgIn);
                } else {
                    currentBackgroundDrawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgInMedia);
                }
            }
        }
        currentBackgroundDrawable.getBackgroundDrawable();
        return currentBackgroundDrawable;
    }

    private boolean shouldDrawCaptionLayout() {
        return !currentMessageObject.preview && (currentPosition == null || (currentMessagesGroup != null && currentMessagesGroup.isDocuments && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0)) && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && currentMessageObject.isVoice());
    }

    public void drawCaptionLayout(Canvas canvas, boolean selectionOnly, float alpha) {
        if (animatedEmojiStack != null && (captionLayout != null || transitionParams.animateOutCaptionLayout != null)) {
            animatedEmojiStack.clearPositions();
        }
        if (transitionParams.animateReplaceCaptionLayout && transitionParams.animateChangeProgress != 1f) {
            drawCaptionLayout(canvas, transitionParams.animateOutCaptionLayout, selectionOnly, alpha * (1f - transitionParams.animateChangeProgress));
            drawCaptionLayout(canvas, captionLayout, selectionOnly, alpha * transitionParams.animateChangeProgress);
        } else {
            drawCaptionLayout(canvas, captionLayout, selectionOnly, alpha);
        }

        if (!selectionOnly) {
            drawAnimatedEmojiCaption(canvas, alpha);
        }

        if (currentMessageObject != null && currentMessageObject.messageOwner != null && currentMessageObject.isVoiceTranscriptionOpen() && !currentMessageObject.messageOwner.voiceTranscriptionFinal && TranscribeButton.isTranscribing(currentMessageObject)) {
            invalidate();
        }

        if (isRoundVideo) {
            reactionsLayoutInBubble.drawServiceShaderBackground = 1f - getVideoTranscriptionProgress();
        }

        if (!selectionOnly && (currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) {
            if (reactionsLayoutInBubble.drawServiceShaderBackground > 0) {
                applyServiceShaderMatrix();
            }
            if (getAlpha() != 1f) {
                AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
                canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha()), Canvas.ALL_SAVE_FLAG);
            }
            if (reactionsLayoutInBubble.drawServiceShaderBackground > 0 || !transitionParams.animateBackgroundBoundsInner || currentPosition != null || isRoundVideo) {
                reactionsLayoutInBubble.draw(canvas, transitionParams.animateChange ? transitionParams.animateChangeProgress : 1f, null);
            } else {
                canvas.save();
                canvas.clipRect(0, 0, getMeasuredWidth(), getBackgroundDrawableBottom() + transitionParams.deltaBottom);
                reactionsLayoutInBubble.draw(canvas, transitionParams.animateChange ? transitionParams.animateChangeProgress : 1f, null);
                canvas.restore();
            }
            if (getAlpha() != 1f) {
                canvas.restore();
            }
        }
    }

    private void drawCaptionLayout(Canvas canvas, StaticLayout captionLayout, boolean selectionOnly, float alpha) {
        if (currentBackgroundDrawable != null && drawCommentButton && timeLayout != null) {
            int x;
            float y = layoutHeight + transitionParams.deltaBottom - AndroidUtilities.dp(18) - timeLayout.getHeight();
            if (currentMessagesGroup != null) {
                y += currentMessagesGroup.transitionParams.offsetBottom;
                if (currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                    y -= getTranslationY();
                }
            }
            if (mediaBackground) {
                x = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
            } else {
                x = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
            }
            int endX = x - getExtraTextX();
            if (currentMessagesGroup != null && !currentMessageObject.isMusic() && !currentMessageObject.isDocument()) {
                int dWidth = getGroupPhotosWidth();
                if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
                    endX += Math.ceil(currentPosition.pw / 1000.0f * dWidth);
                } else {
                    int firstLineWidth = 0;
                    for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
                        MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
                        if (position.minY == 0) {
                            firstLineWidth += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
                        } else {
                            break;
                        }
                    }
                    endX += firstLineWidth - AndroidUtilities.dp(9);
                }
            } else {
                endX += backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(9));
            }

            int h;
            int h2;
            if (pinnedBottom) {
                h = 2;
                h2 = 3;
            } else if (pinnedTop) {
                h = 4;
                h2 = 1;
            } else {
                h = 3;
                h2 = 0;
            }

            int buttonX = getCurrentBackgroundLeft() + AndroidUtilities.dp(currentMessageObject.isOutOwner() || mediaBackground || drawPinnedBottom ? 2 : 8);
            float buttonY = layoutHeight - AndroidUtilities.dp(45.1f - h2);
            if (currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0 && !currentMessagesGroup.hasSibling) {
                endX += AndroidUtilities.dp(14);
                buttonX -= AndroidUtilities.dp(10);
            }
            commentButtonRect.set(
                buttonX - AndroidUtilities.dp((currentMessageObject == null || !currentMessageObject.isOut()) && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL || pollInstantViewTouchesBottom) ? 6 : 0),
                (int) buttonY,
                endX - AndroidUtilities.dp(14),
                layoutHeight - AndroidUtilities.dp(h)
            );
            if (selectorDrawable[1] != null && selectorDrawableMaskType[1] == 2) {
                int count = canvas.getSaveCount();
                selectorDrawable[1].setBounds(commentButtonRect);
                selectorDrawable[1].draw(canvas);
                canvas.restoreToCount(count);
            }
            if (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && currentPosition.minX == 0 && currentPosition.maxX == 0) {
                if (getAlpha() != 1f) {
                    AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
                    canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha()), Canvas.ALL_SAVE_FLAG);
                }
                Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_inPreviewInstantText));
                boolean drawnAvatars = false;
                int avatarsOffset = 2;
                if (commentAvatarImages != null) {
                    int toAdd = AndroidUtilities.dp(17);
                    int ax = x + getExtraTextX();
                    for (int a = commentAvatarImages.length - 1; a >= 0; a--) {
                        if (!commentAvatarImagesVisible[a] || !commentAvatarImages[a].hasImageSet()) {
                            continue;
                        }
                        commentAvatarImages[a].setImageX(ax + toAdd * a);
                        commentAvatarImages[a].setImageY(y - AndroidUtilities.dp(4) + (pinnedBottom ? AndroidUtilities.dp(2) : 0));
                        if (a != commentAvatarImages.length - 1) {
                            canvas.drawCircle(commentAvatarImages[a].getCenterX(), commentAvatarImages[a].getCenterY(), AndroidUtilities.dp(13), currentBackgroundDrawable.getPaint());
                        }
                        commentAvatarImages[a].draw(canvas);
                        drawnAvatars = true;
                        if (a != 0) {
                            avatarsOffset += 17;
                        }
                    }
                }
                if (getAlpha() != 1f) {
                    canvas.restore();
                }
                if (!mediaBackground || captionLayout != null || (!reactionsLayoutInBubble.isEmpty && !reactionsLayoutInBubble.isSmall)) {
                    if (isDrawSelectionBackground()) {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outVoiceSeekbarSelected : Theme.key_chat_inVoiceSeekbarSelected));
                    } else {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outVoiceSeekbar : Theme.key_chat_inVoiceSeekbar));
                    }
                    float ly = layoutHeight - AndroidUtilities.dp(45.1f - h2);
                    ly += transitionParams.deltaBottom;
                    if (currentMessagesGroup != null) {
                        ly += currentMessagesGroup.transitionParams.offsetBottom;
                        if (currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                            ly -= getTranslationY();
                        }
                    } else {
                        int backgroundWidth = (int) (this.backgroundWidth - transitionParams.deltaLeft + transitionParams.deltaRight);
                        endX = x + backgroundWidth - AndroidUtilities.dp(12);
                    }
                    Theme.chat_replyLinePaint.setAlpha((int) (Theme.chat_replyLinePaint.getAlpha() * ChatMessageCell.this.getAlpha()));
                    canvas.drawLine(x, ly, endX - AndroidUtilities.dp(14), ly, Theme.chat_replyLinePaint);
                }
                if (commentLayout != null && drawSideButton != 3) {
                    Theme.chat_commentTextPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewInstantText : Theme.key_chat_inPreviewInstantText));
                    commentX = x + AndroidUtilities.dp(33 + avatarsOffset);
                    if (drawCommentNumber) {
                        commentX += commentNumberWidth + AndroidUtilities.dp(4);
                    }
                    int prevAlpha = Theme.chat_commentTextPaint.getAlpha();
                    if (transitionParams.animateComments) {
                        if (transitionParams.animateCommentsLayout != null) {
                            canvas.save();
                            Theme.chat_commentTextPaint.setAlpha((int) (prevAlpha * (1.0 - transitionParams.animateChangeProgress)));
                            float cx = transitionParams.animateCommentX + (commentX - transitionParams.animateCommentX) * transitionParams.animateChangeProgress;
                            canvas.translate(cx, y - AndroidUtilities.dp(0.1f) + (pinnedBottom ? AndroidUtilities.dp(2) : 0));
                            transitionParams.animateCommentsLayout.draw(canvas);
                            canvas.restore();
                        }
                    }
                    canvas.save();
                    canvas.translate(x + AndroidUtilities.dp(33 + avatarsOffset), y - AndroidUtilities.dp(0.1f) + (pinnedBottom ? AndroidUtilities.dp(2) : 0));
                    if (!currentMessageObject.isSent()) {
                        Theme.chat_commentTextPaint.setAlpha(127);
                        Theme.chat_commentArrowDrawable.setAlpha(127);
                        Theme.chat_commentDrawable.setAlpha(127);
                    } else {
                        Theme.chat_commentArrowDrawable.setAlpha(255);
                        Theme.chat_commentDrawable.setAlpha(255);
                    }
                    if (drawCommentNumber || transitionParams.animateComments && transitionParams.animateDrawCommentNumber) {
                        if (drawCommentNumber && transitionParams.animateComments) {
                            if (transitionParams.animateDrawCommentNumber) {
                                Theme.chat_commentTextPaint.setAlpha(prevAlpha);
                            } else {
                                Theme.chat_commentTextPaint.setAlpha((int) (prevAlpha * transitionParams.animateChangeProgress));
                            }
                        }
                        Theme.chat_commentTextPaint.setAlpha((int) (Theme.chat_commentTextPaint.getAlpha() * ChatMessageCell.this.getAlpha()));
                        commentNumberLayout.draw(canvas);
                        if (drawCommentNumber) {
                            canvas.translate(commentNumberWidth + AndroidUtilities.dp(4), 0);
                        }
                    }
                    if (transitionParams.animateComments && transitionParams.animateCommentsLayout != null) {
                        Theme.chat_commentTextPaint.setAlpha((int) (prevAlpha * transitionParams.animateChangeProgress));
                    } else {
                        Theme.chat_commentTextPaint.setAlpha((int) (prevAlpha * alpha));
                    }
                    Theme.chat_commentTextPaint.setAlpha((int) (Theme.chat_commentTextPaint.getAlpha() * ChatMessageCell.this.getAlpha()));
                    commentLayout.draw(canvas);
                    canvas.restore();
                    commentUnreadX = x + commentWidth + AndroidUtilities.dp(33 + avatarsOffset) + AndroidUtilities.dp(9);
                    if (drawCommentNumber) {
                        commentUnreadX += commentNumberWidth + AndroidUtilities.dp(4);
                    }
                    TLRPC.MessageReplies replies = null;
                    if (currentMessagesGroup != null && !currentMessagesGroup.messages.isEmpty()) {
                        MessageObject messageObject = currentMessagesGroup.messages.get(0);
                        if (messageObject.hasReplies()) {
                            replies = messageObject.messageOwner.replies;
                        }
                    } else {
                        if (currentMessageObject.hasReplies()) {
                            replies = currentMessageObject.messageOwner.replies;
                        }
                    }
                    if (commentDrawUnread = (replies != null && replies.read_max_id != 0 && replies.read_max_id < replies.max_id)) {
                        int color = getThemedColor(Theme.key_chat_inInstant);
                        Theme.chat_docBackPaint.setColor(color);
                        int unreadX;
                        if (transitionParams.animateComments) {
                            if (!transitionParams.animateCommentDrawUnread) {
                                Theme.chat_docBackPaint.setAlpha((int) (Color.alpha(color) * transitionParams.animateChangeProgress));
                            }
                            unreadX = (int) (transitionParams.animateCommentUnreadX + (commentUnreadX - transitionParams.animateCommentUnreadX) * transitionParams.animateChangeProgress);
                        } else {
                            unreadX = commentUnreadX;
                        }
                        canvas.drawCircle(unreadX, y + AndroidUtilities.dp(8) + (pinnedBottom ? AndroidUtilities.dp(2) : 0), AndroidUtilities.dp(2.5f), Theme.chat_docBackPaint);
                    }
                }
                if (!drawnAvatars) {
                    setDrawableBounds(Theme.chat_commentDrawable, x, y - AndroidUtilities.dp(4) + (pinnedBottom ? AndroidUtilities.dp(2) : 0));
                    if (alpha != 1f) {
                        Theme.chat_commentDrawable.setAlpha((int) (255 * alpha));
                        Theme.chat_commentDrawable.draw(canvas);
                        Theme.chat_commentDrawable.setAlpha(255);
                    } else {
                        Theme.chat_commentDrawable.draw(canvas);
                    }
                }

                commentArrowX = endX - AndroidUtilities.dp(44);
                int commentX;
                if (transitionParams.animateComments) {
                    commentX = (int) (transitionParams.animateCommentArrowX + (commentArrowX - transitionParams.animateCommentArrowX) * transitionParams.animateChangeProgress);
                } else {
                    commentX = commentArrowX;
                }
                float commentY = y - AndroidUtilities.dp(4) + (pinnedBottom ? AndroidUtilities.dp(2) : 0);
                boolean drawProgress = delegate.shouldDrawThreadProgress(this);
                long newTime = SystemClock.elapsedRealtime();
                long dt = (newTime - commentProgressLastUpadteTime);
                commentProgressLastUpadteTime = newTime;
                if (dt > 17) {
                    dt = 17;
                }
                if (drawProgress) {
                    if (commentProgressAlpha < 1.0f) {
                        commentProgressAlpha += dt / 180.0f;
                        if (commentProgressAlpha > 1.0f) {
                            commentProgressAlpha = 1.0f;
                        }
                    }
                } else {
                    if (commentProgressAlpha > 0.0f) {
                        commentProgressAlpha -= dt / 180.0f;
                        if (commentProgressAlpha < 0.0f) {
                            commentProgressAlpha = 0.0f;
                        }
                    }
                }
                if ((drawProgress || commentProgressAlpha > 0.0f) && commentProgress != null) {
                    commentProgress.setColor(getThemedColor(Theme.key_chat_inInstant));
                    commentProgress.setAlpha(commentProgressAlpha);
                    commentProgress.draw(canvas, commentX + AndroidUtilities.dp(11), commentY + AndroidUtilities.dp(12), commentProgressAlpha);
                    invalidate();
                }
                if (!drawProgress || commentProgressAlpha < 1.0f) {
                    int aw = Theme.chat_commentArrowDrawable.getIntrinsicWidth();
                    int ah = Theme.chat_commentArrowDrawable.getIntrinsicHeight();
                    float acx = commentX + aw / 2;
                    float acy = commentY + ah / 2;
                    Theme.chat_commentArrowDrawable.setBounds((int) (acx - aw / 2 * (1.0f - commentProgressAlpha)), (int) (acy - ah / 2 * (1.0f - commentProgressAlpha)), (int) (acx + aw / 2 * (1.0f - commentProgressAlpha)), (int) (acy + ah / 2 * (1.0f - commentProgressAlpha)));
                    Theme.chat_commentArrowDrawable.setAlpha((int) (255 * (1.0f - commentProgressAlpha) * alpha));
                    Theme.chat_commentArrowDrawable.draw(canvas);
                }
            }
        }

        if (captionLayout == null || selectionOnly && links.isEmpty() || (currentMessageObject.deleted && currentPosition != null) || alpha == 0) {
            return;
        }
        if (currentMessageObject.isOutOwner()) {
            Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
            Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
        } else {
            Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
            Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
        }
        canvas.save();
        float renderingAlpha = alpha;
        if (currentMessagesGroup != null) {
            renderingAlpha = currentMessagesGroup.transitionParams.captionEnterProgress * alpha;
        }
        if (renderingAlpha == 0) {
            return;
        }

        float captionY = this.captionY;
        float captionX = this.captionX;

        if (transitionParams.animateBackgroundBoundsInner) {
            if (transitionParams.transformGroupToSingleMessage) {
                captionY -= getTranslationY();
                captionX += transitionParams.deltaLeft;
            } else if (transitionParams.moveCaption) {
                captionX = this.captionX * transitionParams.animateChangeProgress + transitionParams.captionFromX * (1f - transitionParams.animateChangeProgress);
                captionY = this.captionY * transitionParams.animateChangeProgress + transitionParams.captionFromY * (1f - transitionParams.animateChangeProgress);
            } else if ((!currentMessageObject.isVoice() && !currentMessageObject.isRoundVideo()) || !TextUtils.isEmpty(currentMessageObject.caption)) {
                captionX += transitionParams.deltaLeft;
            }
        }
        
        if (isRoundVideo && transitionParams.animateDrawBackground) {
            captionY += (1f - getVideoTranscriptionProgress()) * AndroidUtilities.roundMessageSize;
        }

        int restore = Integer.MIN_VALUE;
        if (renderingAlpha != 1.0f) {
            rect.set(captionX, captionY, captionX + captionLayout.getWidth(), captionY + captionLayout.getHeight());
            restore = canvas.saveLayerAlpha(rect, (int) (255 * renderingAlpha), Canvas.ALL_SAVE_FLAG);
        }
        if (isRoundVideo && transitionParams.animateDrawBackground) {
            if (backgroundCacheParams != null) {
                Path path = backgroundCacheParams.getPath();
                if (path != null && !path.isEmpty()) {
                    canvas.translate(0, transitionYOffsetForDrawables);
                    canvas.clipPath(path);
                    canvas.translate(0, -transitionYOffsetForDrawables);
                }
            }
        } else if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null && currentMessagesGroup == null) {
            int bottomoffset = (drawCommentButton && commentButtonRect != null ? commentButtonRect.height() : 0) + (reactionsLayoutInBubble != null && !reactionsLayoutInBubble.isSmall ? reactionsLayoutInBubble.height : 0);
            if (currentMessageObject.isOutOwner() && !mediaBackground && !pinnedBottom) {
                canvas.clipRect(
                        getBackgroundDrawableLeft() + transitionParams.deltaLeft + AndroidUtilities.dp(4), getBackgroundDrawableTop() + transitionParams.deltaTop + AndroidUtilities.dp(4),
                        getBackgroundDrawableRight() + transitionParams.deltaRight - AndroidUtilities.dp(10), getBackgroundDrawableBottom() + transitionParams.deltaBottom - AndroidUtilities.dp(4) - bottomoffset
                );
            } else {
                canvas.clipRect(
                        getBackgroundDrawableLeft() + transitionParams.deltaLeft + AndroidUtilities.dp(4), getBackgroundDrawableTop() + transitionParams.deltaTop + AndroidUtilities.dp(4),
                        getBackgroundDrawableRight() + transitionParams.deltaRight - AndroidUtilities.dp(4), getBackgroundDrawableBottom() + transitionParams.deltaBottom - AndroidUtilities.dp(4) - bottomoffset
                );
            }
        }
        canvas.translate(captionX, captionY);
        boolean translating = MessagesController.getInstance(currentAccount).getTranslateController().isTranslating(getMessageObject(), getCurrentMessagesGroup());
        if (true) {
            if (translationLoadingFloat == null) {
                translationLoadingFloat = new AnimatedFloat(((View) getParent()), 350, CubicBezierInterpolator.EASE_OUT_QUINT);
            }
            float translationLoading = translationLoadingFloat.set(translating ? 1 : 0);
            if (translationLoading > 0) {
                if (translationLoadingDrawable == null) {
                    translationLoadingDrawable = new LoadingDrawable();
                    translationLoadingDrawable.setAppearByGradient(true);
                    if (translationLoadingPath == null) {
                        translationLoadingPath = new LinkPath(true);
                    }
                    translationLoadingDrawable.usePath(translationLoadingPath);
                    translationLoadingDrawable.setRadiiDp(5);
                }

                if (translationLoadingDrawableLayout != captionLayout) {
                    translationLoadingDrawableLayout = captionLayout;
                    translationLoadingPath.setCurrentLayout(captionLayout, 0, 0);
                    captionLayout.getSelectionPath(0, captionLayout.getText().length(), translationLoadingPath);
                    translationLoadingDrawable.updateBounds();
                }

                if (translating && translationLoadingDrawable.isDisappearing() || translationLoadingDrawable.isDisappeared()) {
                    translationLoadingDrawable.reset();
                    translationLoadingDrawable.resetDisappear();
                } else if (!translating && !translationLoadingDrawable.isDisappearing() && !translationLoadingDrawable.isDisappeared()) {
                    translationLoadingDrawable.disappear();
                }

                int color = getThemedColor(currentMessageObject != null && currentMessageObject.isOutOwner() ? Theme.key_chat_messageLinkOut : Theme.key_chat_messageLinkIn);
                translationLoadingDrawable.setColors(
                        Theme.multAlpha(color, .05f),
                        Theme.multAlpha(color, .15f),
                        Theme.multAlpha(color, .1f),
                        Theme.multAlpha(color, .3f)
                );
                translationLoadingDrawable.setAlpha((int) (0xFF * alpha * translationLoading));
                translationLoadingDrawable.draw(canvas);
                invalidate();
            }
        }

        if (links.draw(canvas)) {
            invalidate();
        }
        drawProgressLoadingLink(canvas, -1);
        if (!urlPathSelection.isEmpty()) {
            for (int b = 0; b < urlPathSelection.size(); b++) {
                canvas.drawPath(urlPathSelection.get(b), Theme.chat_textSearchSelectionPaint);
            }
        }
        if (highlightPath != null) {
            float t = (System.currentTimeMillis() - highlightPathStart) / 850f;
            if (t > 1) {
                highlightPath = null;
            } else {
                int wasAlpha = Theme.chat_textSearchSelectionPaint.getAlpha();
                Theme.chat_textSearchSelectionPaint.setAlpha((int) (wasAlpha * .8f * (4 * t * (1 - t))));
                canvas.save();
                float s = .4f + .6f * AndroidUtilities.overshootInterpolator.getInterpolation(Math.min(1, t * 4f));
                canvas.scale(s, s, highlightPath.centerX, highlightPath.centerY);
                canvas.drawPath(highlightPath, Theme.chat_textSearchSelectionPaint);
                canvas.restore();
                Theme.chat_textSearchSelectionPaint.setAlpha(wasAlpha);
            }
            invalidate();
        }
        if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
            Theme.chat_timePaint.setColor(
                ColorUtils.blendARGB(
                    getThemedColor(Theme.key_chat_serviceText),
                    getThemedColor(isDrawSelectionBackground() ?
                        (currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_inTimeSelectedText) :
                        (currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeText : Theme.key_chat_inTimeText)
                    ),
                    getVideoTranscriptionProgress()
                )
            );
        }
        if (!selectionOnly) {
            try {
                if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
                    getDelegate().getTextSelectionHelper().drawCaption(currentMessageObject.isOutOwner(), captionLayout, canvas);
                }
                float top = parentBoundsTop - getY() - captionY;
                float bottom = parentBoundsBottom - getY() - captionY;

                Emoji.emojiDrawingYOffset = -transitionYOffsetForDrawables;

                int spoilersColor = currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount) ? getThemedColor(Theme.key_chat_outTimeText) : captionLayout.getPaint().getColor();
                SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, 0, captionPatchedSpoilersLayout, captionLayout, captionSpoilers, canvas, currentMessagesGroup != null);

                Emoji.emojiDrawingYOffset = 0;
            } catch (Exception e) {
                FileLog.e(e);
            }
        }
        if (restore != Integer.MIN_VALUE) {
            canvas.restoreToCount(restore);
        }
        canvas.restore();
    }

    public void drawProgressLoadingLink(Canvas canvas, int blockNum) {
        updateProgressLoadingLink();
        if (progressLoadingLinkDrawables == null || progressLoadingLinkDrawables.isEmpty()) {
            return;
        }
        int color = getThemedColor(currentMessageObject != null && currentMessageObject.isOutOwner() ? Theme.key_chat_outLinkSelectBackground : Theme.key_chat_linkSelectBackground);
        for (int i = 0; i < progressLoadingLinkDrawables.size(); ++i) {
            LoadingDrawableLocation location = progressLoadingLinkDrawables.get(i);
            if (location.blockNum == blockNum) {
                LoadingDrawable drawable = location.drawable;
                drawable.setColors(
                    Theme.multAlpha(color, .85f),
                    Theme.multAlpha(color, 2f),
                    Theme.multAlpha(color, 3.5f),
                    Theme.multAlpha(color, 6f)
                );
                drawable.draw(canvas);
                invalidate();
                if (drawable.isDisappeared()) {
                    progressLoadingLinkDrawables.remove(i);
                    i--;
                }
            }
        }
    }

    public void updateProgressLoadingLink() {
        if (delegate == null) {
            return;
        }
        if (!delegate.isProgressLoading(this, ChatActivity.PROGRESS_LINK)) {
            progressLoadingLink = null;
            if (progressLoadingLinkDrawables != null && !progressLoadingLinkDrawables.isEmpty()) {
                for (int i = 0; i < progressLoadingLinkDrawables.size(); ++i) {
                    LoadingDrawableLocation location = progressLoadingLinkDrawables.get(i);
                    if (!location.drawable.isDisappearing()) {
                        location.drawable.disappear();
                    }
                }
            }
            return;
        }

        CharacterStyle link = delegate.getProgressLoadingLink(this);
        if (link == progressLoadingLink) {
            return;
        }
        progressLoadingLink = link;
        if (progressLoadingLinkCurrentDrawable != null) {
            progressLoadingLinkCurrentDrawable.disappear();
            progressLoadingLinkCurrentDrawable = null;
        }
        progressLoadingLinkCurrentDrawable = new LoadingDrawable();
        progressLoadingLinkCurrentDrawable.setAppearByGradient(true);
        LinkPath path = new LinkPath(true);
        progressLoadingLinkCurrentDrawable.usePath(path);
        progressLoadingLinkCurrentDrawable.setRadiiDp(5);
        LoadingDrawableLocation location = new LoadingDrawableLocation();
        location.drawable = progressLoadingLinkCurrentDrawable;
        location.blockNum = -3;
        if (progressLoadingLinkDrawables == null) {
            progressLoadingLinkDrawables = new ArrayList<>();
        }
        progressLoadingLinkDrawables.add(location);
        if (progressLoadingLink != null) {
            final int count = Math.max(0, currentMessageObject != null && currentMessageObject.textLayoutBlocks != null ? currentMessageObject.textLayoutBlocks.size() : 0);
            for (int i = -2; i < count; ++i) {
                float yOffset = 0;
                Layout layout;
                if (i == -2) {
                    layout = descriptionLayout;
                } else if (i == -1) {
                    layout = captionLayout;
                } else {
                    layout = currentMessageObject.textLayoutBlocks.get(i).textLayout;
                    yOffset = currentMessageObject.textLayoutBlocks.get(i).textYOffset;
                }

                if (layout != null && layout.getText() instanceof Spanned) {
                    Spanned spanned = (Spanned) layout.getText();
                    CharacterStyle[] spans = spanned.getSpans(0, spanned.length(), CharacterStyle.class);
                    if (spans != null) {
                        for (int j = 0; j < spans.length; ++j) {
                            if (spans[j] == progressLoadingLink) {
                                location.blockNum = i;
                                break;
                            }
                        }
                    }

                    if (location.blockNum == i) {
                        path.rewind();
                        int start = spanned.getSpanStart(progressLoadingLink);
                        int end = spanned.getSpanEnd(progressLoadingLink);
                        path.setCurrentLayout(layout, start, yOffset);
                        layout.getSelectionPath(start, end, path);
                        progressLoadingLinkCurrentDrawable.updateBounds();
                        return;
                    }
                }
            }
        }
    }

    public boolean needDrawTime() {
        return !forceNotDrawTime;
    }

    public boolean shouldDrawTimeOnMedia() {
        if (overideShouldDrawTimeOnMedia != 0) {
            return overideShouldDrawTimeOnMedia == 1;
        }
        return mediaBackground && captionLayout == null && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall || currentMessageObject.isAnyKindOfSticker() || currentMessageObject.isRoundVideo())/* || isMedia && drawCommentButton && !isRepliesChat*/;
    }

    //绘制时间以及未读已读
    public void drawTime(Canvas canvas, float alpha, boolean fromParent) {
        if (BuildVars.IS_CHAT_AIR || !drawFromPinchToZoom && delegate != null && delegate.getPinchToZoomHelper() != null && delegate.getPinchToZoomHelper().isInOverlayModeFor(this) && shouldDrawTimeOnMedia()) {
            return;
        }
        for (int i = 0; i < 2; i++) {
            float currentAlpha = alpha;
            if (i == 0 && isDrawSelectionBackground() && currentSelectedBackgroundAlpha == 1f && !shouldDrawTimeOnMedia()) {
                continue;
            } else if (i == 1 && ((!isDrawSelectionBackground() && currentSelectedBackgroundAlpha == 0) || shouldDrawTimeOnMedia())) {
                break;
            }
            boolean drawSelectionBackground = i == 1;
            if (i == 1) {
                currentAlpha *= currentSelectedBackgroundAlpha;
            } else if (!shouldDrawTimeOnMedia()) {
                currentAlpha *= (1f - currentSelectedBackgroundAlpha);
            }
            if (transitionParams.animateShouldDrawTimeOnMedia && transitionParams.animateChangeProgress != 1f) {
                //针对媒体的时间绘制
                if (shouldDrawTimeOnMedia()) {
                    overideShouldDrawTimeOnMedia = 1;
                    drawTimeInternal(canvas, currentAlpha * transitionParams.animateChangeProgress, fromParent, this.timeX, timeLayout, timeWidth, drawSelectionBackground);
                    overideShouldDrawTimeOnMedia = 2;
                    drawTimeInternal(canvas, currentAlpha * (1f - transitionParams.animateChangeProgress), fromParent, transitionParams.animateFromTimeX, transitionParams.animateTimeLayout, transitionParams.animateTimeWidth, drawSelectionBackground);
                } else {
                    overideShouldDrawTimeOnMedia = 2;
                    drawTimeInternal(canvas, currentAlpha * transitionParams.animateChangeProgress, fromParent, this.timeX, timeLayout, timeWidth, drawSelectionBackground);
                    overideShouldDrawTimeOnMedia = 1;
                    drawTimeInternal(canvas, currentAlpha * (1f - transitionParams.animateChangeProgress), fromParent, transitionParams.animateFromTimeX, transitionParams.animateTimeLayout, transitionParams.animateTimeWidth, drawSelectionBackground);
                }
                overideShouldDrawTimeOnMedia = 0;
            } else {
                //普通情况下的时间绘制
                float timeX;
                float timeWidth;
                if (transitionParams.shouldAnimateTimeX) {
                    timeX = this.timeX * transitionParams.animateChangeProgress + transitionParams.animateFromTimeX * (1f - transitionParams.animateChangeProgress);
                    timeWidth = this.timeWidth * transitionParams.animateChangeProgress + transitionParams.animateTimeWidth * (1f - transitionParams.animateChangeProgress);
                } else {
                    timeX = this.timeX + transitionParams.deltaRight;
                    timeWidth = this.timeWidth;
                }
                drawTimeInternal(canvas, currentAlpha, fromParent, timeX, timeLayout, timeWidth, drawSelectionBackground);
            }
        }

        //与动画有关的时间绘制
        if (transitionParams.animateBackgroundBoundsInner) {
            drawOverlays(canvas);
        }
    }

    //绘制时间以及未读已读
    private void drawTimeInternal(Canvas canvas, float alpha, boolean fromParent, float timeX, StaticLayout timeLayout, float timeWidth, boolean drawSelectionBackground) {
        if ((!drawTime || groupPhotoInvisible) && shouldDrawTimeOnMedia() || timeLayout == null || (currentMessageObject.deleted && currentPosition != null) || currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
            return;
        }
        //根据不同情况绘制时间画笔配置
        if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
            Theme.chat_timePaint.setColor(
                ColorUtils.blendARGB(
                    getThemedColor(Theme.key_chat_serviceText),
                    getThemedColor(isDrawSelectionBackground() ?
                            (currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_inTimeSelectedText) :
                            (currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeText : Theme.key_chat_inTimeText)
                    ),
                    getVideoTranscriptionProgress()
                )
            );
        } else {
            if (shouldDrawTimeOnMedia()) {
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_serviceText));
                } else {
                    Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_mediaTimeText));
                }
            } else {
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_timePaint.setColor(getThemedColor(drawSelectionBackground ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_outTimeText));
                } else {
                    Theme.chat_timePaint.setColor(getThemedColor(drawSelectionBackground ? Theme.key_chat_inTimeSelectedText : Theme.key_chat_inTimeText));
                }
            }
        }
        if (getTransitionParams().animateDrawingTimeAlpha) {
            alpha *= getTransitionParams().animateChangeProgress;
        }
        if (alpha != 1f) {
            Theme.chat_timePaint.setAlpha((int) (Theme.chat_timePaint.getAlpha() * alpha));
        }
        canvas.save();
        if (drawPinnedBottom && !shouldDrawTimeOnMedia()) {
            canvas.translate(0, AndroidUtilities.dp(2));
        }
        boolean bigRadius = false;
        float layoutHeight = this.layoutHeight;
        if (transitionParams.animateBackgroundBoundsInner) {
            layoutHeight += transitionParams.deltaBottom;
        }
        float timeTitleTimeX = timeX;
        if (transitionParams.shouldAnimateTimeX) {
            timeTitleTimeX = transitionParams.animateFromTimeX * (1f - transitionParams.animateChangeProgress) + this.timeX * transitionParams.animateChangeProgress;
        }
        if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
            layoutHeight -= getTranslationY();
            timeX += currentMessagesGroup.transitionParams.offsetRight;
            timeTitleTimeX += currentMessagesGroup.transitionParams.offsetRight;
        }
        if (drawPinnedBottom && shouldDrawTimeOnMedia()) {
            layoutHeight += AndroidUtilities.dp(1);
        }
        if (transitionParams.animateBackgroundBoundsInner) {
            timeX += animationOffsetX;
            timeTitleTimeX += animationOffsetX;
        }
        if (reactionsLayoutInBubble.isSmall) {
            if (transitionParams.animateBackgroundBoundsInner && transitionParams.deltaRight != 0) {
                timeTitleTimeX += reactionsLayoutInBubble.getCurrentWidth(1f);
            } else {
                timeTitleTimeX += reactionsLayoutInBubble.getCurrentWidth(transitionParams.animateChangeProgress);
            }
        }
        if (transitionParams.animateEditedEnter) {
            timeTitleTimeX -= transitionParams.animateEditedWidthDiff * (1f - transitionParams.animateChangeProgress);
        }

        int timeYOffset;
        if (shouldDrawTimeOnMedia()) {
            //针对媒体的绘制
            timeYOffset = -(drawCommentButton ? AndroidUtilities.dp(41.3f) : 0);
            Paint paint;
            if (currentMessageObject.shouldDrawWithoutBackground()) {
                paint = getThemedPaint(Theme.key_paint_chatActionBackground);
            } else {
                paint = getThemedPaint(Theme.key_paint_chatTimeBackground);
            }
            int oldAlpha = paint.getAlpha();
            float oldAlpha3 = alpha;
            Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha * alpha));
            if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_GEO) {
                float progress = photoImage.isCrossfadingWithOldImage() ? 1 : photoImage.getCurrentAlpha();
                if (!photoImage.hasNotThumb()) {
                    progress = 0;
                }
                alpha = AndroidUtilities.lerp(0.35f, 1f, progress);
            }
            paint.setAlpha((int) (oldAlpha * timeAlpha * alpha));

            int r;
            if (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
                int[] rad = photoImage.getRoundRadius();
                r = Math.min(AndroidUtilities.dp(8), Math.max(rad[2], rad[3]));
                bigRadius = SharedConfig.bubbleRadius >= 10;
            } else {
                r = AndroidUtilities.dp(4);
            }
            float x1 = timeX - AndroidUtilities.dp(bigRadius ? 6 : 4);
            float timeY;
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
                timeY = layoutHeight - (AndroidUtilities.dp(drawPinnedBottom ? 4 : 5) + reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress)) * (1f - getVideoTranscriptionProgress());
            } else {
                timeY = photoImage.getImageY2() + additionalTimeOffsetY;
            }
            float y1 = timeY - AndroidUtilities.dp(23);
            float timeHeight = Math.max(AndroidUtilities.dp(17), Theme.chat_timePaint.getTextSize() + AndroidUtilities.dp(5));
            rect.set(x1, y1, x1 + timeWidth + AndroidUtilities.dp((bigRadius ? 12 : 8) + (currentMessageObject.isOutOwner() ? 20 + (currentMessageObject.type == MessageObject.TYPE_EMOJIS ? 4 : 0) : 0)), y1 + timeHeight);

            applyServiceShaderMatrix();
            canvas.drawRoundRect(rect, r, r, paint);
            if (paint == getThemedPaint(Theme.key_paint_chatActionBackground) && hasGradientService()) {
                int oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * timeAlpha * alpha));
                canvas.drawRoundRect(rect, r, r, Theme.chat_actionBackgroundGradientDarkenPaint);
                Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
            }
            paint.setAlpha(oldAlpha);

            alpha = oldAlpha3;

            float additionalX = -timeLayout.getLineLeft(0);
            if (reactionsLayoutInBubble.isSmall) {
                updateReactionLayoutPosition();
                reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, null);
            }

            if (ChatObject.isChannel(currentChat) && !currentChat.megagroup || (currentMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0 || repliesLayout != null || isPinned) {
                additionalX += this.timeWidth - timeLayout.getLineWidth(0);
                if (reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
                    additionalX -= reactionsLayoutInBubble.width;
                }

                int currentStatus = transitionParams.createStatusDrawableParams();
                if (transitionParams.lastStatusDrawableParams >= 0 && transitionParams.lastStatusDrawableParams != currentStatus && !statusDrawableAnimationInProgress) {
                    createStatusDrawableAnimator(transitionParams.lastStatusDrawableParams, currentStatus, fromParent);
                }
                if (statusDrawableAnimationInProgress) {
                    currentStatus = animateToStatusDrawableParams;
                }

                boolean drawClock = (currentStatus & 4) != 0;
                boolean drawError = (currentStatus & 8) != 0;

                if (statusDrawableAnimationInProgress) {
                    boolean outDrawClock = (animateFromStatusDrawableParams & 4) != 0;
                    boolean outDrawError = (animateFromStatusDrawableParams & 8) != 0;
                    drawClockOrErrorLayout(canvas, outDrawClock, outDrawError, layoutHeight, alpha, timeYOffset, timeX, 1f - statusDrawableProgress, drawSelectionBackground);
                    drawClockOrErrorLayout(canvas, drawClock, drawError, layoutHeight, alpha, timeYOffset, timeX, statusDrawableProgress, drawSelectionBackground);

                    if (!currentMessageObject.isOutOwner()) {
                        if (!outDrawClock && !outDrawError) {
                            drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, 1f - statusDrawableProgress, drawSelectionBackground);
                        }
                        if (!drawClock && !drawError) {
                            drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, statusDrawableProgress, drawSelectionBackground);
                        }
                    }
                } else {
                    if (!currentMessageObject.isOutOwner()) {
                        if (!drawClock && !drawError) {
                            drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, 1f, drawSelectionBackground);
                        }
                    }
                    drawClockOrErrorLayout(canvas, drawClock, drawError, layoutHeight, alpha, timeYOffset, timeX, 1f, drawSelectionBackground);
                }

                if (currentMessageObject.isOutOwner()) {
                    drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, 1f, drawSelectionBackground);
                }

                transitionParams.lastStatusDrawableParams = transitionParams.createStatusDrawableParams();

                if (drawClock && fromParent && getParent() != null) {
                    ((View) getParent()).invalidate();
                }
            }

            canvas.save();
            canvas.translate(drawTimeX = timeTitleTimeX + additionalX, drawTimeY = timeY - AndroidUtilities.dp(7.3f) - timeLayout.getHeight());
            timeLayout.draw(canvas);
            canvas.restore();
            Theme.chat_timePaint.setAlpha(255);
        } else {
            //普通绘制
            if (currentMessageObject.isSponsored()) {
                timeYOffset = -AndroidUtilities.dp(48);
                if (hasNewLineForTime) {
                    timeYOffset -= AndroidUtilities.dp(16);
                }
            } else {
                timeYOffset = -(drawCommentButton ? AndroidUtilities.dp(43) : 0);
            }
            float additionalX = -timeLayout.getLineLeft(0);
            if (reactionsLayoutInBubble.isSmall) {
                updateReactionLayoutPosition();
                reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, null);
            }
            if (ChatObject.isChannel(currentChat) && !currentChat.megagroup || (currentMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0 || (repliesLayout != null || transitionParams.animateReplies) || (isPinned || transitionParams.animatePinned)) {
                additionalX += timeWidth - timeLayout.getLineWidth(0);
                if (reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
                    additionalX -= reactionsLayoutInBubble.width;
                }

                int currentStatus = transitionParams.createStatusDrawableParams();
                if (transitionParams.lastStatusDrawableParams >= 0 && transitionParams.lastStatusDrawableParams != currentStatus && !statusDrawableAnimationInProgress) {
                    createStatusDrawableAnimator(transitionParams.lastStatusDrawableParams, currentStatus, fromParent);
                }
                if (statusDrawableAnimationInProgress) {
                    currentStatus = animateToStatusDrawableParams;
                }

                boolean drawClock = (currentStatus & 4) != 0;
                boolean drawError = (currentStatus & 8) != 0;

                if (statusDrawableAnimationInProgress) {
                    boolean outDrawClock = (animateFromStatusDrawableParams & 4) != 0;
                    boolean outDrawError = (animateFromStatusDrawableParams & 8) != 0;
                    drawClockOrErrorLayout(canvas, outDrawClock, outDrawError, layoutHeight, alpha, timeYOffset, timeX, 1f - statusDrawableProgress, drawSelectionBackground);
                    drawClockOrErrorLayout(canvas, drawClock, drawError, layoutHeight, alpha, timeYOffset, timeX, statusDrawableProgress, drawSelectionBackground);

                    if (!currentMessageObject.isOutOwner()) {
                        if (!outDrawClock && !outDrawError) {
                            drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, 1f - statusDrawableProgress, drawSelectionBackground);
                        }
                        if (!drawClock && !drawError) {
                            drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, statusDrawableProgress, drawSelectionBackground);
                        }
                    }
                } else {
                    if (!currentMessageObject.isOutOwner()) {
                        if (!drawClock && !drawError) {
                            drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, 1f, drawSelectionBackground);
                        }
                    }
                    drawClockOrErrorLayout(canvas, drawClock, drawError, layoutHeight, alpha, timeYOffset, timeX, 1f, drawSelectionBackground);
                }

                if (currentMessageObject.isOutOwner()) {
                    drawViewsAndRepliesLayout(canvas, layoutHeight, alpha, timeYOffset, timeX, 1f, drawSelectionBackground);
                }
                //重新配置已读未读错误消息状态
                transitionParams.lastStatusDrawableParams = transitionParams.createStatusDrawableParams();

                if (drawClock && fromParent && getParent() != null) {
                    ((View) getParent()).invalidate();
                }
            }

            canvas.save();
            if (transitionParams.animateEditedEnter && transitionParams.animateChangeProgress != 1f) {
                if (transitionParams.animateEditedLayout != null) {
                    canvas.translate(timeTitleTimeX + additionalX, layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
                    int oldAlpha = Theme.chat_timePaint.getAlpha();
                    Theme.chat_timePaint.setAlpha((int) (oldAlpha * transitionParams.animateChangeProgress));
                    transitionParams.animateEditedLayout.draw(canvas);
                    Theme.chat_timePaint.setAlpha(oldAlpha);
                    transitionParams.animateTimeLayout.draw(canvas);
                } else {
                    int oldAlpha = Theme.chat_timePaint.getAlpha();
                    canvas.save();
                    canvas.translate(transitionParams.animateFromTimeX + additionalX, layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
                    Theme.chat_timePaint.setAlpha((int) (oldAlpha * (1f - transitionParams.animateChangeProgress)));
                    transitionParams.animateTimeLayout.draw(canvas);
                    canvas.restore();

                    canvas.translate(timeTitleTimeX + additionalX, layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
                    Theme.chat_timePaint.setAlpha((int) (oldAlpha * (transitionParams.animateChangeProgress)));
                    timeLayout.draw(canvas);
                    Theme.chat_timePaint.setAlpha(oldAlpha);
                }
            } else {
                //核心绘制时间
                canvas.translate(drawTimeX = timeTitleTimeX + additionalX, drawTimeY = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
                timeLayout.draw(canvas);
            }
            canvas.restore();
        }

        //绘制自己已读未读状态
        if (currentMessageObject.isOutOwner()) {
            int currentStatus = transitionParams.createStatusDrawableParams();
            if (transitionParams.lastStatusDrawableParams >= 0 && transitionParams.lastStatusDrawableParams != currentStatus && !statusDrawableAnimationInProgress) {
                createStatusDrawableAnimator(transitionParams.lastStatusDrawableParams, currentStatus, fromParent);
            }
            if (statusDrawableAnimationInProgress) {
                currentStatus = animateToStatusDrawableParams;
            }
            boolean drawCheck1 = (currentStatus & 1) != 0;
            boolean drawCheck2 = (currentStatus & 2) != 0;
            boolean drawClock = (currentStatus & 4) != 0;
            boolean drawError = (currentStatus & 8) != 0;
            boolean needRestore = false;
            if (transitionYOffsetForDrawables != 0) {
                needRestore = true;
                canvas.save();
                canvas.translate(0, transitionYOffsetForDrawables);
            }
            if (statusDrawableAnimationInProgress) {
                boolean outDrawCheck1 = (animateFromStatusDrawableParams & 1) != 0;
                boolean outDrawCheck2 = (animateFromStatusDrawableParams & 2) != 0;
                boolean outDrawClock = (animateFromStatusDrawableParams & 4) != 0;
                boolean outDrawError = (animateFromStatusDrawableParams & 8) != 0;
                if (!outDrawClock && outDrawCheck2 && drawCheck2 && !outDrawCheck1 && drawCheck1) {
                    drawStatusDrawable(canvas, drawCheck1, drawCheck2, drawClock, drawError, alpha, bigRadius, timeYOffset, layoutHeight, statusDrawableProgress, true, drawSelectionBackground);
                } else {
                    drawStatusDrawable(canvas, outDrawCheck1, outDrawCheck2, outDrawClock, outDrawError, alpha, bigRadius, timeYOffset, layoutHeight, 1f - statusDrawableProgress, false, drawSelectionBackground);
                    drawStatusDrawable(canvas, drawCheck1, drawCheck2, drawClock, drawError, alpha, bigRadius, timeYOffset, layoutHeight, statusDrawableProgress, false, drawSelectionBackground);
                }
            } else {
                //绘制已读未读错误状态
                drawStatusDrawable(canvas, drawCheck1, drawCheck2, drawClock, drawError, alpha, bigRadius, timeYOffset, layoutHeight, 1, false, drawSelectionBackground);
            }
            if (needRestore) {
                canvas.restore();
            }
            transitionParams.lastStatusDrawableParams = transitionParams.createStatusDrawableParams();
            if (fromParent && drawClock && getParent() != null) {
                ((View) getParent()).invalidate();
            }
        }
        canvas.restore();

        //多媒体预览相关未锁内容绘制
        if (unlockLayout != null) {
            if (unlockX == 0 || unlockY == 0) {
                calculateUnlockXY();
            }

            unlockSpoilerPath.rewind();
            AndroidUtilities.rectTmp.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2());
            int[] photoRadius = photoImage.getRoundRadius();
            unlockSpoilerRadii[0] = unlockSpoilerRadii[1] = photoRadius[0];
            unlockSpoilerRadii[2] = unlockSpoilerRadii[3] = photoRadius[1];
            unlockSpoilerRadii[4] = unlockSpoilerRadii[5] = photoRadius[2];
            unlockSpoilerRadii[6] = unlockSpoilerRadii[7] = photoRadius[3];
            unlockSpoilerPath.addRoundRect(AndroidUtilities.rectTmp, unlockSpoilerRadii, Path.Direction.CW);

            canvas.save();
            canvas.clipPath(unlockSpoilerPath);
            unlockSpoilerPath.rewind();

            AndroidUtilities.rectTmp.set(unlockX - AndroidUtilities.dp(12), unlockY - AndroidUtilities.dp(8), unlockX + Theme.chat_msgUnlockDrawable.getIntrinsicWidth() + AndroidUtilities.dp(14) + unlockLayout.getWidth() + AndroidUtilities.dp(12), unlockY + unlockLayout.getHeight() + AndroidUtilities.dp(8));
            unlockSpoilerPath.addRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(32), AndroidUtilities.dp(32), Path.Direction.CW);
            canvas.clipPath(unlockSpoilerPath, Region.Op.DIFFERENCE);

            int sColor = Color.WHITE;
            unlockSpoilerEffect.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f)));
            unlockSpoilerEffect.setBounds((int) photoImage.getImageX(), (int) photoImage.getImageY(), (int) photoImage.getImageX2(), (int) photoImage.getImageY2());
            unlockSpoilerEffect.draw(canvas);
            invalidate();
            canvas.restore();

            canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int)(unlockAlpha * 0xFF), Canvas.ALL_SAVE_FLAG);
            int wasAlpha = Theme.chat_timeBackgroundPaint.getAlpha();
            Theme.chat_timeBackgroundPaint.setAlpha((int) (wasAlpha * 0.7f));
            canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(32), AndroidUtilities.dp(32), Theme.chat_timeBackgroundPaint);
            Theme.chat_timeBackgroundPaint.setAlpha(wasAlpha);
            canvas.translate(unlockX + AndroidUtilities.dp(4), unlockY);
            Theme.chat_msgUnlockDrawable.setBounds(0, 0, Theme.chat_msgUnlockDrawable.getIntrinsicWidth(), Theme.chat_msgUnlockDrawable.getIntrinsicHeight());
            Theme.chat_msgUnlockDrawable.draw(canvas);
            canvas.translate(AndroidUtilities.dp(6) + Theme.chat_msgUnlockDrawable.getIntrinsicWidth(), 0);
            unlockLayout.draw(canvas);
            canvas.restore();

            if (videoInfoLayout != null && photoImage.getVisible() && imageBackgroundSideColor == 0) {
                float rad;
                if (SharedConfig.bubbleRadius > 2) {
                    rad = AndroidUtilities.dp(SharedConfig.bubbleRadius - 2);
                    bigRadius = SharedConfig.bubbleRadius >= 10;
                } else {
                    rad = AndroidUtilities.dp(SharedConfig.bubbleRadius);
                }

                int x = (int) (photoImage.getImageX() + AndroidUtilities.dp(9));
                int y = (int) (photoImage.getImageY() + AndroidUtilities.dp(6));
                rect.set(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + durationWidth + AndroidUtilities.dp(4) + AndroidUtilities.dp(bigRadius ? 2 : 0), y + videoInfoLayout.getHeight() + AndroidUtilities.dp(1.5f));
                canvas.drawRoundRect(rect, rad, rad, getThemedPaint(Theme.key_paint_chatTimeBackground));

                canvas.save();
                canvas.translate(x + (bigRadius ? 2 : 0), y);
                videoInfoLayout.draw(canvas);
                canvas.restore();
            }
        }
    }

    private void createStatusDrawableAnimator(int lastStatusDrawableParams, int currentStatus, boolean fromParent) {
        boolean drawCheck1 = (currentStatus & 1) != 0;
        boolean drawCheck2 = (currentStatus & 2) != 0;

        boolean outDrawCheck1 = (lastStatusDrawableParams & 1) != 0;
        boolean outDrawCheck2 = (lastStatusDrawableParams & 2) != 0;
        boolean outDrawClock = (lastStatusDrawableParams & 4) != 0;

        boolean moveCheckTransition = !outDrawClock && outDrawCheck2 && drawCheck2 && !outDrawCheck1 && drawCheck1;

        if (transitionParams.messageEntering && !moveCheckTransition) {
            return;
        }
        statusDrawableProgress = 0f;
        statusDrawableAnimator = ValueAnimator.ofFloat(0, 1f);
        if (moveCheckTransition) {
            statusDrawableAnimator.setDuration(220);
        } else {
            statusDrawableAnimator.setDuration(150);
        }
        statusDrawableAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
        animateFromStatusDrawableParams = lastStatusDrawableParams;
        animateToStatusDrawableParams = currentStatus;
        statusDrawableAnimator.addUpdateListener(valueAnimator -> {
            statusDrawableProgress = (float) valueAnimator.getAnimatedValue();
            invalidate();
            if (fromParent && getParent() != null) {
                ((View) getParent()).invalidate();
            }
        });
        statusDrawableAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                int currentStatus = transitionParams.createStatusDrawableParams();
                if (animateToStatusDrawableParams != currentStatus) {
                    createStatusDrawableAnimator(animateToStatusDrawableParams, currentStatus, fromParent);
                } else {
                    statusDrawableAnimationInProgress = false;
                    transitionParams.lastStatusDrawableParams = animateToStatusDrawableParams;
                }
            }
        });
        statusDrawableAnimationInProgress = true;
        statusDrawableAnimator.start();

    }

    private void drawClockOrErrorLayout(Canvas canvas, boolean drawTime, boolean drawError, float layoutHeight, float alpha, float timeYOffset, float timeX, float progress, boolean drawSelectionBackground) {
        boolean useScale = progress != 1f;
        float scale = 0.5f + 0.5f * progress;
        alpha *= progress;
        if (drawTime) {
            if (!currentMessageObject.isOutOwner()) {
                MsgClockDrawable clockDrawable = Theme.chat_msgClockDrawable;
                int clockColor;
                if (shouldDrawTimeOnMedia()) {
                    clockColor = getThemedColor(Theme.key_chat_mediaSentClock);
                } else {
                    clockColor = getThemedColor(drawSelectionBackground ? Theme.key_chat_outSentClockSelected : Theme.key_chat_mediaSentClock);
                }
                clockDrawable.setColor(clockColor);
                float timeY;
                if (shouldDrawTimeOnMedia()) {
                    timeY = photoImage.getImageY2() + additionalTimeOffsetY - AndroidUtilities.dp(9.0f);
                } else {
                    timeY = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9.5f : 8.5f) + timeYOffset;
                    if (isRoundVideo) {
                        timeY -= (AndroidUtilities.dp(drawPinnedBottom ? 4 : 5) + reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress)) * (1f - getVideoTranscriptionProgress());
                    }
                }
                setDrawableBounds(clockDrawable, timeX + (currentMessageObject.scheduled ? 0 : AndroidUtilities.dp(11)), timeY - clockDrawable.getIntrinsicHeight());
                clockDrawable.setAlpha((int) (255 * alpha));
                if (useScale) {
                    canvas.save();
                    canvas.scale(scale, scale, clockDrawable.getBounds().centerX(), clockDrawable.getBounds().centerY());
                }
                clockDrawable.draw(canvas);
                clockDrawable.setAlpha(255);
                invalidate();
                if (useScale) {
                    canvas.restore();
                }
            }
        } else if (drawError) {
            if (!currentMessageObject.isOutOwner()) {
                float x = timeX + (currentMessageObject.scheduled ? 0 : AndroidUtilities.dp(11));
                float y;
                if (shouldDrawTimeOnMedia()) {
                    y = photoImage.getImageY2() + additionalTimeOffsetY - AndroidUtilities.dp(21.5f);
                } else {
                    y = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 21.5f : 20.5f) + timeYOffset;
                    if (isRoundVideo) {
                        y -= reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress) * (1f - getVideoTranscriptionProgress());
                    }
                }
                rect.set(x, y, x + AndroidUtilities.dp(14), y + AndroidUtilities.dp(14));
                int oldAlpha = Theme.chat_msgErrorPaint.getAlpha();
                Theme.chat_msgErrorPaint.setAlpha((int) (255 * alpha));
                if (useScale) {
                    canvas.save();
                    canvas.scale(scale, scale, rect.centerX(), rect.centerY());
                }
                canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), Theme.chat_msgErrorPaint);
                Theme.chat_msgErrorPaint.setAlpha(oldAlpha);
                Drawable errorDrawable = getThemedDrawable(Theme.key_drawable_msgError);
                setDrawableBounds(errorDrawable, x + AndroidUtilities.dp(6), y + AndroidUtilities.dp(2));
                errorDrawable.setAlpha((int) (255 * alpha));
                errorDrawable.draw(canvas);
                errorDrawable.setAlpha(255);
                if (useScale) {
                    canvas.restore();
                }
            }
        }
    }

    private void drawViewsAndRepliesLayout(Canvas canvas, float layoutHeight, float alpha, float timeYOffset, float timeX, float progress, boolean drawSelectionBackground) {
        boolean useScale = progress != 1f;
        float scale = 0.5f + 0.5f * progress;
        alpha *= progress;

        float offsetX = reactionsLayoutInBubble.isSmall ? reactionsLayoutInBubble.getCurrentWidth(1f) : 0;
        int timeAlpha = Theme.chat_timePaint.getAlpha();
        float timeY;
        if (shouldDrawTimeOnMedia() && documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND) {
            timeY = photoImage.getImageY2() + additionalTimeOffsetY - AndroidUtilities.dp(7.3f) - timeLayout.getHeight();
        } else {
            timeY = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset;
            if (isRoundVideo) {
                timeY -= (AndroidUtilities.dp(drawPinnedBottom ? 4 : 5) + reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress)) * (1f - getVideoTranscriptionProgress());
            }
        }
        if (repliesLayout != null || transitionParams.animateReplies) {
            float repliesX = (transitionParams.shouldAnimateTimeX ? this.timeX : timeX) + offsetX;
            boolean inAnimation = transitionParams.animateReplies && transitionParams.animateRepliesLayout == null && repliesLayout != null;
            boolean outAnimation = transitionParams.animateReplies && transitionParams.animateRepliesLayout != null && repliesLayout == null;
            boolean replaceAnimation = transitionParams.animateReplies && transitionParams.animateRepliesLayout != null && repliesLayout != null;
            if (!(isRoundVideo && transitionParams.animateDrawBackground)) {
                if (transitionParams.shouldAnimateTimeX && !inAnimation) {
                    if (outAnimation) {
                        repliesX = transitionParams.animateFromTimeXReplies;
                    } else {
                        repliesX = transitionParams.animateFromTimeXReplies * (1f - transitionParams.animateChangeProgress) + repliesX * transitionParams.animateChangeProgress;
                    }
                } else {
                    repliesX += transitionParams.deltaRight;
                }
            }
            if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                repliesX += currentMessagesGroup.transitionParams.offsetRight;
            }
            if (transitionParams.animateBackgroundBoundsInner) {
                repliesX += animationOffsetX;
            }
            Drawable repliesDrawable;
            float w;
            if (shouldDrawTimeOnMedia()) {
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    repliesDrawable = getThemedDrawable(Theme.key_drawable_msgStickerReplies);
                } else {
                    repliesDrawable = Theme.chat_msgMediaRepliesDrawable;
                }
            } else {
                if (!currentMessageObject.isOutOwner()) {
                    repliesDrawable = drawSelectionBackground ? Theme.chat_msgInRepliesSelectedDrawable : Theme.chat_msgInRepliesDrawable;
                } else {
                    repliesDrawable = getThemedDrawable(drawSelectionBackground ? Theme.key_drawable_msgOutRepliesSelected : Theme.key_drawable_msgOutReplies);
                }
            }
            w = setDrawableBounds(repliesDrawable, repliesX, timeY, Theme.chat_timePaint.getTextSize());
            float repliesAlpha = alpha;
            if (inAnimation) {
                repliesAlpha *= transitionParams.animateChangeProgress;
            } else if (outAnimation) {
                repliesAlpha *= (1f - transitionParams.animateChangeProgress);
            }
            repliesDrawable.setAlpha((int) (255 * repliesAlpha));
            if (useScale) {
                canvas.save();
                float cx = repliesX + (w + AndroidUtilities.dp(3) + repliesTextWidth) / 2f;
                canvas.scale(scale, scale, cx, repliesDrawable.getBounds().centerY());
            }
            repliesDrawable.draw(canvas);
            repliesDrawable.setAlpha(255);

            if (transitionParams.animateReplies) {
                if (replaceAnimation) {
                    canvas.save();
                    Theme.chat_timePaint.setAlpha((int) (timeAlpha * (1.0 - transitionParams.animateChangeProgress)));
                    canvas.translate(repliesX + w + AndroidUtilities.dp(3), timeY);
                    transitionParams.animateRepliesLayout.draw(canvas);
                    canvas.restore();
                }
                Theme.chat_timePaint.setAlpha((int) (timeAlpha * repliesAlpha));
            }
            canvas.save();
            canvas.translate(repliesX + w + AndroidUtilities.dp(3), timeY);
            if (repliesLayout != null) {
                repliesLayout.draw(canvas);
            } else if (transitionParams.animateRepliesLayout != null) {
                transitionParams.animateRepliesLayout.draw(canvas);
            }
            canvas.restore();
            if (repliesLayout != null) {
                offsetX += w + repliesTextWidth + AndroidUtilities.dp(10);
            }

            if (useScale) {
                canvas.restore();
            }

            if (transitionParams.animateReplies) {
                Theme.chat_timePaint.setAlpha(timeAlpha);
            }
            transitionParams.lastTimeXReplies = repliesX;
        }
        if (viewsLayout != null) {
            float viewsX = (transitionParams.shouldAnimateTimeX ? this.timeX : timeX) + offsetX;
            if (!(isRoundVideo && transitionParams.animateDrawBackground)) {
                if (transitionParams.shouldAnimateTimeX) {
                    viewsX = transitionParams.animateFromTimeXViews * (1f - transitionParams.animateChangeProgress) + viewsX * transitionParams.animateChangeProgress;
                } else {
                    viewsX += transitionParams.deltaRight;
                }
            }
            if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                viewsX += currentMessagesGroup.transitionParams.offsetRight;
            }
            if (transitionParams.animateBackgroundBoundsInner) {
                viewsX += animationOffsetX;
            }
            Drawable viewsDrawable;
            if (shouldDrawTimeOnMedia()) {
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    viewsDrawable = getThemedDrawable(Theme.key_drawable_msgStickerViews);
                } else {
                    viewsDrawable = Theme.chat_msgMediaViewsDrawable;
                }
            } else {
                if (!currentMessageObject.isOutOwner()) {
                    viewsDrawable = drawSelectionBackground ? Theme.chat_msgInViewsSelectedDrawable : Theme.chat_msgInViewsDrawable;
                } else {
                    viewsDrawable = getThemedDrawable(drawSelectionBackground ? Theme.key_drawable_msgOutViewsSelected : Theme.key_drawable_msgOutViews);
                }
            }
            float y = timeY;
            float w = setDrawableBounds(viewsDrawable, viewsX, y + AndroidUtilities.dp(1.5f), Theme.chat_timePaint.getTextSize() - AndroidUtilities.dp(2));
            if (useScale) {
                canvas.save();
                float cx = viewsX + (viewsDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3) + viewsTextWidth) / 2f;
                canvas.scale(scale, scale, cx, viewsDrawable.getBounds().centerY());
            }
            viewsDrawable.setAlpha((int) (255 * alpha));
            viewsDrawable.draw(canvas);
            viewsDrawable.setAlpha(255);

            if (transitionParams.animateViewsLayout != null) {
                canvas.save();
                Theme.chat_timePaint.setAlpha((int) (timeAlpha * (1.0 - transitionParams.animateChangeProgress)));
                canvas.translate(viewsX + w + AndroidUtilities.dp(3), y);
                transitionParams.animateViewsLayout.draw(canvas);
                canvas.restore();
                Theme.chat_timePaint.setAlpha((int) (timeAlpha * transitionParams.animateChangeProgress));
            }

            canvas.save();
            canvas.translate(viewsX + w + AndroidUtilities.dp(3), y);
            viewsLayout.draw(canvas);
            canvas.restore();
            if (useScale) {
                canvas.restore();
            }

            offsetX += viewsTextWidth + w + AndroidUtilities.dp(10);

            if (transitionParams.animateViewsLayout != null) {
                Theme.chat_timePaint.setAlpha(timeAlpha);
            }
            transitionParams.lastTimeXViews = viewsX;
        }
        if (isPinned || transitionParams.animatePinned) {
            float pinnedX = (transitionParams.shouldAnimateTimeX ? this.timeX : timeX) + offsetX;
            boolean inAnimation = transitionParams.animatePinned && isPinned;
            boolean outAnimation = transitionParams.animatePinned && !isPinned;
            if (!isRoundVideo) {
                if (transitionParams.shouldAnimateTimeX && !inAnimation) {
                    if (outAnimation) {
                        pinnedX = transitionParams.animateFromTimeXPinned;
                    } else {
                        pinnedX = transitionParams.animateFromTimeXPinned * (1f - transitionParams.animateChangeProgress) + pinnedX * transitionParams.animateChangeProgress;
                    }
                } else {
                    pinnedX += transitionParams.deltaRight;
                }
            }
            if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
                pinnedX += currentMessagesGroup.transitionParams.offsetRight;
            }
            if (transitionParams.animateBackgroundBoundsInner) {
                pinnedX += animationOffsetX;
            }

            Drawable pinnedDrawable;
            if (shouldDrawTimeOnMedia()) {
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    pinnedDrawable = getThemedDrawable(Theme.key_drawable_msgStickerPinned);
                } else {
                    pinnedDrawable = Theme.chat_msgMediaPinnedDrawable;
                }
            } else {
                if (!currentMessageObject.isOutOwner()) {
                    pinnedDrawable = drawSelectionBackground ? Theme.chat_msgInPinnedSelectedDrawable : Theme.chat_msgInPinnedDrawable;
                } else {
                    pinnedDrawable = getThemedDrawable(drawSelectionBackground ? Theme.key_drawable_msgOutPinnedSelected : Theme.key_drawable_msgOutPinned);
                }
            }
            float w;
            if (transitionParams.animatePinned) {
                if (isPinned) {
                    pinnedDrawable.setAlpha((int) (255 * alpha * transitionParams.animateChangeProgress));
                    w = setDrawableBounds(pinnedDrawable, pinnedX, timeY, Theme.chat_timePaint.getTextSize() + AndroidUtilities.dp(1));
                } else {
                    pinnedDrawable.setAlpha((int) (255 * alpha * (1.0f - transitionParams.animateChangeProgress)));
                    w = setDrawableBounds(pinnedDrawable, pinnedX, timeY, Theme.chat_timePaint.getTextSize() + AndroidUtilities.dp(1));
                }
            } else {
                pinnedDrawable.setAlpha((int) (255 * alpha));
                w = setDrawableBounds(pinnedDrawable, pinnedX, timeY, Theme.chat_timePaint.getTextSize() + AndroidUtilities.dp(1));
            }
            if (useScale) {
                canvas.save();
                float cx = pinnedX + w / 2f;
                canvas.scale(scale, scale, cx, pinnedDrawable.getBounds().centerY());
            }
            pinnedDrawable.draw(canvas);
            pinnedDrawable.setAlpha(255);

            if (useScale) {
                canvas.restore();
            }
            transitionParams.lastTimeXPinned = pinnedX;
        }
    }

    //绘制已读未读消息状态
    private void drawStatusDrawable(Canvas canvas, boolean drawCheck1, boolean drawCheck2, boolean drawClock, boolean drawError, float alpha, boolean bigRadius, float timeYOffset, float layoutHeight, float progress, boolean moveCheck, boolean drawSelectionBackground) {
        final boolean useScale = progress != 1f && !moveCheck;
        float scale = 0.5f + 0.5f * progress;
        if (useScale) {
            alpha = alpha * progress;
        }
        float timeY;
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
            timeY = layoutHeight - (AndroidUtilities.dp(drawPinnedBottom ? 4 : 5) + reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress)) * (1f - getVideoTranscriptionProgress());
        } else {
            timeY = photoImage.getImageY2() + additionalTimeOffsetY;
        }
        timeY -= AndroidUtilities.dp(8.5f);
        if (drawClock) {
            MsgClockDrawable drawable = Theme.chat_msgClockDrawable;
            int color;
            if (shouldDrawTimeOnMedia()) {
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    color = getThemedColor(Theme.key_chat_serviceText);
                    setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 24 : 22) - drawable.getIntrinsicWidth(), timeY - drawable.getIntrinsicHeight() + timeYOffset);
                    drawable.setAlpha((int) (255 * timeAlpha * alpha));
                } else {
                    color = getThemedColor(Theme.key_chat_mediaSentClock);
                    setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 24 : 22) - drawable.getIntrinsicWidth(), timeY - drawable.getIntrinsicHeight() + timeYOffset);
                    drawable.setAlpha((int) (255 * alpha));
                }
            } else {
                color = getThemedColor(Theme.key_chat_outSentClock);
                setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - drawable.getIntrinsicHeight() + timeYOffset);
                drawable.setAlpha((int) (255 * alpha));
            }
            drawable.setColor(color);

            if (useScale) {
                canvas.save();
                canvas.scale(scale, scale, drawable.getBounds().centerX(), drawable.getBounds().centerY());
            }
            drawable.draw(canvas);
            drawable.setAlpha(255);
            if (useScale) {
                canvas.restore();
            }
            invalidate();
        }
        //绘制已发送
        if (drawCheck2) {
            if (shouldDrawTimeOnMedia()) {
                Drawable drawable;
                if (moveCheck) {
                    canvas.save();
                }
                if (currentMessageObject.shouldDrawWithoutBackground()) {
                    drawable = getThemedDrawable(Theme.key_drawable_msgStickerCheck);
                    if (drawCheck1) {
                        if (moveCheck) {
                            canvas.translate(AndroidUtilities.dp(4.8f) * (1f - progress), 0);
                        }
                        setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 28.3f : 26.3f) - drawable.getIntrinsicWidth(), timeY - drawable.getIntrinsicHeight() + timeYOffset);
                    } else {
                        setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - drawable.getIntrinsicWidth(), timeY - drawable.getIntrinsicHeight() + timeYOffset);
                    }
                    drawable.setAlpha((int) (255 * timeAlpha * alpha));
                } else {
                    if (drawCheck1) {
                        if (moveCheck) {
                            canvas.translate(AndroidUtilities.dp(4.8f) * (1f - progress), 0);
                        }
                        setDrawableBounds(Theme.chat_msgMediaCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 28.3f : 26.3f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicWidth(), timeY - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight() + timeYOffset);
                    } else {
                        setDrawableBounds(Theme.chat_msgMediaCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicWidth(), timeY - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight() + timeYOffset);
                    }
                    Theme.chat_msgMediaCheckDrawable.setAlpha((int) (255 * timeAlpha * alpha));
                    drawable = Theme.chat_msgMediaCheckDrawable;
                }
                if (useScale) {
                    canvas.save();
                    canvas.scale(scale, scale, drawable.getBounds().centerX(), drawable.getBounds().centerY());
                }
                drawable.draw(canvas);
                if (useScale) {
                    canvas.restore();
                }
                if (moveCheck) {
                    canvas.restore();
                }
                drawable.setAlpha(255);
            } else {
                Drawable drawable;
                if (moveCheck) {
                    canvas.save();
                }
                if (drawCheck1) {
                    if (moveCheck) {
                        canvas.translate(AndroidUtilities.dp(4) * (1f - progress), 0);
                    }
                    drawable = getThemedDrawable(drawSelectionBackground ? Theme.key_drawable_msgOutCheckReadSelected : Theme.key_drawable_msgOutCheckRead);
                    setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(22.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9 : 8) - drawable.getIntrinsicHeight() + timeYOffset);
                } else {
                    drawable = getThemedDrawable(drawSelectionBackground ? Theme.key_drawable_msgOutCheckSelected : Theme.key_drawable_msgOutCheck);
                    setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9 : 8) - drawable.getIntrinsicHeight() + timeYOffset);
                }
                drawable.setAlpha((int) (255 * alpha));
                if (useScale) {
                    canvas.save();
                    canvas.scale(scale, scale, drawable.getBounds().centerX(), drawable.getBounds().centerY());
                }
                drawable.draw(canvas);
                if (useScale) {
                    canvas.restore();
                }
                if (moveCheck) {
                    canvas.restore();
                }
                drawable.setAlpha(255);
            }
        }
        //绘制已读
        if (drawCheck1) {
            if (shouldDrawTimeOnMedia()) {
                Drawable drawable = currentMessageObject.shouldDrawWithoutBackground() ? getThemedDrawable(Theme.key_drawable_msgStickerHalfCheck) : Theme.chat_msgMediaHalfCheckDrawable;
                setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - drawable.getIntrinsicWidth(), timeY - drawable.getIntrinsicHeight() + timeYOffset);
                drawable.setAlpha((int) (255 * timeAlpha * alpha));
                if (useScale || moveCheck) {
                    canvas.save();
                    canvas.scale(scale, scale, drawable.getBounds().centerX(), drawable.getBounds().centerY());
                }
                drawable.draw(canvas);
                if (useScale || moveCheck) {
                    canvas.restore();
                }
                drawable.setAlpha(255);
            } else {
                Drawable drawable = getThemedDrawable(drawSelectionBackground ? Theme.key_drawable_msgOutHalfCheckSelected : Theme.key_drawable_msgOutHalfCheck);
                setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9 : 8) - drawable.getIntrinsicHeight() + timeYOffset);
                drawable.setAlpha((int) (255 * alpha));
                if (useScale || moveCheck) {
                    canvas.save();
                    canvas.scale(scale, scale, drawable.getBounds().centerX(), drawable.getBounds().centerY());
                }
                drawable.draw(canvas);
                if (useScale || moveCheck) {
                    canvas.restore();
                }
                drawable.setAlpha(255);
            }
        }

        //绘制发送错误
        if (drawError) {
            int x;
            float y;
            if (shouldDrawTimeOnMedia()) {
                x = layoutWidth - AndroidUtilities.dp(34.5f);
                y = layoutHeight - AndroidUtilities.dp(26.5f) + timeYOffset;
            } else {
                x = layoutWidth - AndroidUtilities.dp(32);
                y = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 22 : 21) + timeYOffset;
            }
            rect.set(x, y, x + AndroidUtilities.dp(14), y + AndroidUtilities.dp(14));
            int oldAlpha = Theme.chat_msgErrorPaint.getAlpha();
            Theme.chat_msgErrorPaint.setAlpha((int) (oldAlpha * alpha));
            canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), Theme.chat_msgErrorPaint);
            Theme.chat_msgErrorPaint.setAlpha(oldAlpha);
            setDrawableBounds(Theme.chat_msgErrorDrawable, x + AndroidUtilities.dp(6), y + AndroidUtilities.dp(2));
            Theme.chat_msgErrorDrawable.setAlpha((int) (255 * alpha));
            if (useScale) {
                canvas.save();
                canvas.scale(scale, scale, Theme.chat_msgErrorDrawable.getBounds().centerX(), Theme.chat_msgErrorDrawable.getBounds().centerY());
            }
            Theme.chat_msgErrorDrawable.draw(canvas);
            Theme.chat_msgErrorDrawable.setAlpha(255);
            if (useScale) {
                canvas.restore();
            }
        }
    }

    public void drawOverlays(Canvas canvas) {
        if (!drawFromPinchToZoom && delegate != null && delegate.getPinchToZoomHelper() != null && delegate.getPinchToZoomHelper().isInOverlayModeFor(this)) {
            return;
        }
        long newAnimationTime = SystemClock.elapsedRealtime();
        long animationDt = newAnimationTime - lastAnimationTime;
        if (animationDt > 17) {
            animationDt = 17;
        }
        lastAnimationTime = newAnimationTime;

        if (currentMessageObject.hadAnimationNotReadyLoading && photoImage.getVisible() && !currentMessageObject.needDrawBluredPreview() && (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF)) {
            AnimatedFileDrawable animation = photoImage.getAnimation();
            if (animation != null && animation.hasBitmap()) {
                currentMessageObject.hadAnimationNotReadyLoading = false;
                updateButtonState(false, true, false);
            }
        }

        if (hasGamePreview) {

        } else if (currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_PHOTO || currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
            if (photoImage.getVisible()) {
                if (!currentMessageObject.needDrawBluredPreview()) {
                    if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
                        int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha();
                        if (drawMediaCheckBox) {
                            Theme.chat_msgMediaMenuDrawable.setAlpha((int) (oldAlpha * controlsAlpha * (1.0f - checkBoxAnimationProgress)));
                        } else {
                            Theme.chat_msgMediaMenuDrawable.setAlpha((int) (oldAlpha * controlsAlpha));
                        }
                        setDrawableBounds(Theme.chat_msgMediaMenuDrawable, otherX = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(14)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8.1f)));
                        Theme.chat_msgMediaMenuDrawable.draw(canvas);
                        Theme.chat_msgMediaMenuDrawable.setAlpha(oldAlpha);
                    }
                }

                boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
                if (animatingNoSoundPlaying != playing) {
                    animatingNoSoundPlaying = playing;
                    animatingNoSound = playing ? 1 : 2;
                    animatingNoSoundProgress = playing ? 1.0f : 0.0f;
                }

                boolean fullWidth = true;
                if (currentPosition != null) {
                    int mask = MessageObject.POSITION_FLAG_LEFT | MessageObject.POSITION_FLAG_RIGHT;
                    fullWidth = (currentPosition.flags & mask) == mask;
                }

                if ((documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) && (buttonState == 1 || buttonState == 2 || buttonState == 0 || buttonState == 3 || buttonState == -1 || currentMessageObject.needDrawBluredPreview())) {
                    if (autoPlayingMedia) {
                        updatePlayingMessageProgress();
                    }

                    if ((infoLayout != null || loadingProgressLayout != null) && (!forceNotDrawTime || autoPlayingMedia || drawVideoImageButton || animatingLoadingProgressProgress != 0 || (fullWidth && docTitleLayout != null) || (loadingProgressLayout != null && currentPosition != null && (buttonState == 1 || (buttonState == 3 && miniButtonState == 1))))) {
                        boolean drawLoadingProgress;
                        float alpha = 0;
                        boolean drawDocTitleLayout;
                        float loadingProgressAlpha = 1f;
                        if (!fullWidth) {
                            drawLoadingProgress = true;
                            drawDocTitleLayout = false;
                            loadingProgressAlpha = animatingLoadingProgressProgress;
                        } else {
                            drawLoadingProgress = (buttonState == 1 || miniButtonState == 1 || animatingLoadingProgressProgress != 0) && !currentMessageObject.isSecretMedia() &&
                                    (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT);
                            if (currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
                                alpha = currentMessageObject.needDrawBluredPreview() && docTitleLayout == null ? 0 : animatingDrawVideoImageButtonProgress;
                            }
                            drawDocTitleLayout = alpha > 0 && docTitleLayout != null;
                            if (!drawDocTitleLayout && (drawLoadingProgress || infoLayout == null)) {
                                loadingProgressAlpha = animatingLoadingProgressProgress;
                            }
                        }

                        boolean bigRadius = false;
                        if (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
                            bigRadius = SharedConfig.bubbleRadius >= 10;
                        }
                        Theme.chat_infoPaint.setColor(getThemedColor(Theme.key_chat_mediaInfoText));
                        int x1 = (int) (photoImage.getImageX() + AndroidUtilities.dp(4));
                        int y1 = (int) (photoImage.getImageY() + AndroidUtilities.dp(4));

                        int imageW;
                        int infoW;
                        if (autoPlayingMedia && (!playing || animatingNoSound != 0)) {
                            imageW = (int) ((Theme.chat_msgNoSoundDrawable.getIntrinsicWidth() + AndroidUtilities.dp(4)) * animatingNoSoundProgress);
                        } else {
                            imageW = 0;
                        }
                        if (drawLoadingProgress && loadingProgressLayout != null) {
                            imageW = 0;
                            infoW = (int) loadingProgressLayout.getLineWidth(0);
//                            infoW = loadingProgressLayout.getCurrentWidth();
                        } else {
                            infoW = infoWidth;
                        }

                        int w = (int) Math.ceil(infoW + AndroidUtilities.dp(bigRadius ? 12 : 8) + imageW + (Math.max(infoW + (infoWidth == infoW ? imageW : 0), docTitleWidth) + (canStreamVideo ? AndroidUtilities.dp(32) : 0) - infoW - imageW) * alpha);

                        if (alpha != 0 && docTitleLayout == null) {
                            alpha = 0;
                        }

                        canvas.save();
                        canvas.scale(loadingProgressAlpha, loadingProgressAlpha, x1, y1);
                        int oldAlpha = getThemedPaint(Theme.key_paint_chatTimeBackground).getAlpha();
                        getThemedPaint(Theme.key_paint_chatTimeBackground).setAlpha((int) (oldAlpha * controlsAlpha * loadingProgressAlpha));
                        if (drawDocTitleLayout || (drawLoadingProgress && loadingProgressLayout != null) || (!drawLoadingProgress && infoLayout != null)) {
                            rect.set(x1, y1, x1 + w, y1 + AndroidUtilities.dp(16.5f + 15.5f * alpha));
                            int[] rad = photoImage.getRoundRadius();
                            int r = Math.min(AndroidUtilities.dp(8), Math.max(rad[0], rad[1]));
                            canvas.drawRoundRect(rect, r, r, getThemedPaint(Theme.key_paint_chatTimeBackground));
                        }

                        Theme.chat_infoPaint.setAlpha((int) (255 * controlsAlpha * loadingProgressAlpha));

                        canvas.translate(noSoundCenterX = (int) (photoImage.getImageX() + AndroidUtilities.dp((bigRadius ? 10 : 8) + (canStreamVideo ? 30 * alpha : 0))), photoImage.getImageY() + AndroidUtilities.dp(5.5f + 0.2f * alpha));
                        if (infoLayout != null && (!drawLoadingProgress || drawDocTitleLayout)) {
                            infoLayout.draw(canvas);
                        }
                        if (imageW != 0 && (!drawLoadingProgress || drawDocTitleLayout)) {
                            canvas.save();
                            Theme.chat_msgNoSoundDrawable.setAlpha((int) (255 * animatingNoSoundProgress * animatingNoSoundProgress * controlsAlpha));
                            int size = AndroidUtilities.dp(14 * animatingNoSoundProgress);
                            int y = (AndroidUtilities.dp(14) - size) / 2;
                            int offset = infoWidth + AndroidUtilities.dp(4);
                            canvas.translate(offset, 0);
                            Theme.chat_msgNoSoundDrawable.setBounds(0, y, size, y + size);
                            Theme.chat_msgNoSoundDrawable.draw(canvas);
                            noSoundCenterX += offset + size / 2;
                            canvas.restore();
                        }
                        if (drawLoadingProgress && loadingProgressLayout != null) {
                            canvas.save();
                            if (drawDocTitleLayout) {
                                Theme.chat_infoPaint.setAlpha((int) (255 * controlsAlpha * alpha));
                                canvas.translate(0, AndroidUtilities.dp(14.3f * alpha));
                            }
//                            loadingProgressLayout.copyStylesFrom(Theme.chat_infoPaint);
                            loadingProgressLayout.draw(canvas);
                            canvas.restore();
                        } else if (drawDocTitleLayout) {
                            Theme.chat_infoPaint.setAlpha((int) (255 * controlsAlpha * alpha));
                            canvas.translate(0, AndroidUtilities.dp(14.3f * alpha));
                            docTitleLayout.draw(canvas);
                        }
                        canvas.restore();
                        Theme.chat_infoPaint.setAlpha(255);
                        getThemedPaint(Theme.key_paint_chatTimeBackground).setAlpha(oldAlpha);
                    }
                }
                if (animatingDrawVideoImageButton == 1) {
                    animatingDrawVideoImageButtonProgress -= animationDt / 160.0f;
                    if (animatingDrawVideoImageButtonProgress <= 0) {
                        animatingDrawVideoImageButtonProgress = 0;
                        animatingDrawVideoImageButton = 0;
                    }
                    invalidate();
                } else if (animatingDrawVideoImageButton == 2) {
                    animatingDrawVideoImageButtonProgress += animationDt / 160.0f;
                    if (animatingDrawVideoImageButtonProgress >= 1) {
                        animatingDrawVideoImageButtonProgress = 1;
                        animatingDrawVideoImageButton = 0;
                    }
                    invalidate();
                }
                if (animatingNoSound == 1) {
                    animatingNoSoundProgress -= animationDt / 180.0f;
                    if (animatingNoSoundProgress <= 0.0f) {
                        animatingNoSoundProgress = 0.0f;
                        animatingNoSound = 0;
                    }
                    invalidate();
                } else if (animatingNoSound == 2) {
                    animatingNoSoundProgress += animationDt / 180.0f;
                    if (animatingNoSoundProgress >= 1.0f) {
                        animatingNoSoundProgress = 1.0f;
                        animatingNoSound = 0;
                    }
                    invalidate();
                }

                float animatingToLoadingProgress = (buttonState == 1 || miniButtonState == 1) && loadingProgressLayout != null ? 1f : 0f;
                if (animatingToLoadingProgress == 0f && infoLayout != null && fullWidth) {
                    animatingLoadingProgressProgress = 0f;
                }
                if (animatingLoadingProgressProgress < animatingToLoadingProgress) {
                    animatingLoadingProgressProgress += animationDt / 160.0f;
                    if (animatingLoadingProgressProgress > animatingToLoadingProgress) {
                        animatingLoadingProgressProgress = animatingToLoadingProgress;
                    }
                    invalidate();
                } else if (animatingLoadingProgressProgress != animatingToLoadingProgress) {
                    animatingLoadingProgressProgress -= animationDt / 160.0f;
                    if (animatingLoadingProgressProgress < animatingToLoadingProgress) {
                        animatingLoadingProgressProgress = animatingToLoadingProgress;
                    }
                    invalidate();
                }
            }
        } else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
            if (docTitleLayout != null) {
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_locationTitlePaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
                    Theme.chat_locationAddressPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outVenueInfoSelectedText : Theme.key_chat_outVenueInfoText));
                } else {
                    Theme.chat_locationTitlePaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
                    Theme.chat_locationAddressPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inVenueInfoSelectedText : Theme.key_chat_inVenueInfoText));
                }

                if (MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaGeoLive) {
                    int cy = (int) (photoImage.getImageY2() + AndroidUtilities.dp(30));
                    if (!locationExpired || transitionParams.animateLocationIsExpired) {
                        forceNotDrawTime = true;
                        float progress;
                        String text;
                        StaticLayout docTitleLayout = this.docTitleLayout;
                        StaticLayout infoLayout = this.infoLayout;
                        float alpha = 1f;
                        if (transitionParams.animateLocationIsExpired) {
                            progress = transitionParams.lastDrawLocationExpireProgress;
                            text = transitionParams.lastDrawLocationExpireText;
                            docTitleLayout = transitionParams.lastDrawDocTitleLayout;
                            infoLayout = transitionParams.lastDrawInfoLayout;
                            alpha = 1f - transitionParams.animateChangeProgress;
                        } else {
                            progress = 1.0f - Math.abs(ConnectionsManager.getInstance(currentAccount).getCurrentTime() - currentMessageObject.messageOwner.date) / (float) MessageObject.getMedia(currentMessageObject.messageOwner).period;
                            text = LocaleController.formatLocationLeftTime(Math.abs(MessageObject.getMedia(currentMessageObject.messageOwner).period - (ConnectionsManager.getInstance(currentAccount).getCurrentTime() - currentMessageObject.messageOwner.date)));
                        }

                        rect.set(photoImage.getImageX2() - AndroidUtilities.dp(43), cy - AndroidUtilities.dp(15), photoImage.getImageX2() - AndroidUtilities.dp(13), cy + AndroidUtilities.dp(15));
                        if (currentMessageObject.isOutOwner()) {
                            Theme.chat_radialProgress2Paint.setColor(getThemedColor(Theme.key_chat_outInstant));
                            Theme.chat_livePaint.setColor(getThemedColor(Theme.key_chat_outInstant));
                        } else {
                            Theme.chat_radialProgress2Paint.setColor(getThemedColor(Theme.key_chat_inInstant));
                            Theme.chat_livePaint.setColor(getThemedColor(Theme.key_chat_inInstant));
                        }

                        int docTitleAlpha = Theme.chat_locationTitlePaint.getAlpha();
                        int infoAlpha = Theme.chat_locationAddressPaint.getAlpha();
                        int liveAplha = Theme.chat_livePaint.getAlpha();
                        if (alpha != 1f) {
                            Theme.chat_locationTitlePaint.setAlpha((int) (docTitleAlpha * alpha));
                            Theme.chat_locationAddressPaint.setAlpha((int) (infoAlpha * alpha));
                            Theme.chat_livePaint.setAlpha((int) (liveAplha * alpha));
                            canvas.save();
                            canvas.translate(0, -AndroidUtilities.dp(50) * transitionParams.animateChangeProgress);
                        }

                        Theme.chat_radialProgress2Paint.setAlpha((int) (50 * alpha));
                        canvas.drawCircle(rect.centerX(), rect.centerY(), AndroidUtilities.dp(15), Theme.chat_radialProgress2Paint);
                        Theme.chat_radialProgress2Paint.setAlpha((int) (255 * alpha));
                        canvas.drawArc(rect, -90, -360 * progress, false, Theme.chat_radialProgress2Paint);

                        float w = Theme.chat_livePaint.measureText(text);
                        canvas.drawText(text, rect.centerX() - w / 2, cy + AndroidUtilities.dp(4), Theme.chat_livePaint);

                        if (docTitleLayout != null && infoLayout != null) {
                            canvas.save();
                            canvas.translate(photoImage.getImageX() + AndroidUtilities.dp(10), photoImage.getImageY2() + AndroidUtilities.dp(10));
                            docTitleLayout.draw(canvas);
                            canvas.translate(0, AndroidUtilities.dp(23));
                            infoLayout.draw(canvas);
                            canvas.restore();
                        }

                        if (alpha != 1f) {
                            Theme.chat_locationTitlePaint.setAlpha(docTitleAlpha);
                            Theme.chat_locationAddressPaint.setAlpha(infoAlpha);
                            Theme.chat_livePaint.setAlpha(liveAplha);
                            canvas.restore();
                        }

                        transitionParams.lastDrawLocationExpireProgress = progress;
                        transitionParams.lastDrawLocationExpireText = text;
                        transitionParams.lastDrawDocTitleLayout = docTitleLayout;
                        transitionParams.lastDrawInfoLayout = infoLayout;
                    } else {
                        transitionParams.lastDrawLocationExpireText = null;
                        transitionParams.lastDrawDocTitleLayout = null;
                        transitionParams.lastDrawInfoLayout = null;
                    }

                    float progress = photoImage.isCrossfadingWithOldImage() ? 1 : photoImage.getCurrentAlpha();
                    if (progress > 0 && (photoImage.hasNotThumb() || photoImage.isCrossfadingWithOldImage())) {
                        int cx = (int) (photoImage.getImageX() + photoImage.getImageWidth() / 2 - AndroidUtilities.dp(31));
                        cy = (int) (photoImage.getImageY() + photoImage.getImageHeight() / 2 - AndroidUtilities.dp(38) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(progress)));

                        setDrawableBounds(Theme.chat_msgAvatarLiveLocationDrawable, cx, cy);
                        Theme.chat_msgAvatarLiveLocationDrawable.setAlpha((int) (255 * Math.min(1, progress * 5)));
                        Theme.chat_msgAvatarLiveLocationDrawable.draw(canvas);

                        locationImageReceiver.setImageCoords(cx + AndroidUtilities.dp(5.0f), cy + AndroidUtilities.dp(5.0f), AndroidUtilities.dp(52), AndroidUtilities.dp(52));
                        locationImageReceiver.setAlpha(Math.min(1, progress * 5));
                        locationImageReceiver.draw(canvas);
                    }
                } else {
                    canvas.save();
                    canvas.translate(photoImage.getImageX() + AndroidUtilities.dp(6), photoImage.getImageY2() + AndroidUtilities.dp(8));
                    docTitleLayout.draw(canvas);
                    if (infoLayout != null) {
                        canvas.translate(0, AndroidUtilities.dp(21));
                        infoLayout.draw(canvas);
                    }
                    canvas.restore();
                }
            }
        } else if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
            if (currentMessageObject.isOutOwner()) {
                Theme.chat_audioTitlePaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
                Theme.chat_contactPhonePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_outTimeText));
            } else {
                Theme.chat_audioTitlePaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
                Theme.chat_contactPhonePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inTimeSelectedText : Theme.key_chat_inTimeText));
            }
            forceNotDrawTime = true;
            int x;
            if (currentMessageObject.isOutOwner()) {
                x = layoutWidth - backgroundWidth + AndroidUtilities.dp(16);
            } else {
                if (isChat && !isThreadPost && currentMessageObject.needDrawAvatar()) {
                    x = AndroidUtilities.dp(74);
                } else {
                    x = AndroidUtilities.dp(25);
                }
            }
            otherX = x;
            if (titleLayout != null) {
                canvas.save();
                canvas.translate(x, AndroidUtilities.dp(12) + namesOffset);
                titleLayout.draw(canvas);
                canvas.restore();
            }
            if (docTitleLayout != null) {
                canvas.save();
                canvas.translate(x + AndroidUtilities.dp(19), AndroidUtilities.dp(37) + namesOffset);
                docTitleLayout.draw(canvas);
                canvas.restore();
            }
            Drawable icon;
            Drawable phone;
            int idx = currentMessageObject.isVideoCall() ? 1 : 0;
            if (currentMessageObject.isOutOwner()) {
                icon = Theme.chat_msgCallUpGreenDrawable;
                if (currentMessageObject.isVideoCall()) {
                    phone = getThemedDrawable(isDrawSelectionBackground() ? Theme.key_drawable_msgOutCallVideoSelected : Theme.key_drawable_msgOutCallVideo);
                } else {
                    phone = getThemedDrawable(isDrawSelectionBackground() ? Theme.key_drawable_msgOutCallAudioSelected : Theme.key_drawable_msgOutCallAudio);
                }
            } else {
                TLRPC.PhoneCallDiscardReason reason = currentMessageObject.messageOwner.action.reason;
                if (reason instanceof TLRPC.TL_phoneCallDiscardReasonMissed || reason instanceof TLRPC.TL_phoneCallDiscardReasonBusy) {
                    icon = Theme.chat_msgCallDownRedDrawable;
                } else {
                    icon = Theme.chat_msgCallDownGreenDrawable;
                }
                phone = isDrawSelectionBackground() ? Theme.chat_msgInCallSelectedDrawable[idx] : Theme.chat_msgInCallDrawable[idx];
            }
            setDrawableBounds(icon, x - AndroidUtilities.dp(1), AndroidUtilities.dp(37) + namesOffset);
            icon.draw(canvas);

            if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null && selectorDrawableMaskType[0] == 4) {
                selectorDrawable[0].draw(canvas);
            }

            if (!pinnedBottom && !pinnedTop) {
                otherY = AndroidUtilities.dp(18.5f);
            } else if (pinnedBottom && pinnedTop) {
                otherY = AndroidUtilities.dp(18);
            } else if (!pinnedBottom) {
                otherY = AndroidUtilities.dp(17);
            } else {
                otherY = AndroidUtilities.dp(19);
            }
            setDrawableBounds(phone, x + AndroidUtilities.dp(idx == 0 ? 201 : 200), otherY);
            phone.draw(canvas);
        } else if (currentMessageObject.type == MessageObject.TYPE_POLL) {
            long newTime = System.currentTimeMillis();
            long dt = newTime - voteLastUpdateTime;
            if (dt > 17) {
                dt = 17;
            }
            voteLastUpdateTime = newTime;

            int color1;
            int color2;
            if (currentMessageObject.isOutOwner()) {
                color1 = getThemedColor(Theme.key_chat_messageTextOut);
                color2 = getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_outTimeText);
            } else {
                color1 = getThemedColor(Theme.key_chat_messageTextIn);
                color2 = getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inTimeSelectedText : Theme.key_chat_inTimeText);
            }
            Theme.chat_audioTitlePaint.setColor(color1);
            Theme.chat_audioPerformerPaint.setColor(color1);
            Theme.chat_instantViewPaint.setColor(color1);
            Theme.chat_timePaint.setColor(color2);
            Theme.chat_livePaint.setColor(color2);
            Theme.chat_locationAddressPaint.setColor(color2);

            canvas.save();
            if (transitionParams.animateForwardedLayout) {
                float y = namesOffset * transitionParams.animateChangeProgress + transitionParams.animateForwardedNamesOffset * (1f - transitionParams.animateChangeProgress);
                if (currentMessageObject.needDrawForwarded()) {
                    y -= namesOffset;
                }
                canvas.translate(0, y);
            }
            int x;
            if (currentMessageObject.isOutOwner()) {
                x = layoutWidth - backgroundWidth + AndroidUtilities.dp(11);
            } else {
                if (isChat && !isThreadPost && currentMessageObject.needDrawAvatar()) {
                    x = AndroidUtilities.dp(68);
                } else {
                    x = AndroidUtilities.dp(20);
                }
            }
            if (titleLayout != null) {
                canvas.save();
                canvas.translate(x + getExtraTextX(), AndroidUtilities.dp(15) + namesOffset);
                titleLayout.draw(canvas);
                canvas.restore();
            }
            int y = (titleLayout != null ? titleLayout.getHeight() : 0) + AndroidUtilities.dp(20) + namesOffset;
            if (docTitleLayout != null) {
                canvas.save();
                canvas.translate(x + docTitleOffsetX + getExtraTextX(), y);
                docTitleLayout.draw(canvas);
                canvas.restore();

                TLRPC.TL_messageMediaPoll media = (TLRPC.TL_messageMediaPoll) MessageObject.getMedia(currentMessageObject.messageOwner);
                if (lastPoll.quiz && (pollVoted || pollClosed) && !TextUtils.isEmpty(media.results.solution)) {
                    Drawable drawable = getThemedDrawable(currentMessageObject.isOutOwner() ? Theme.key_drawable_chat_pollHintDrawableOut : Theme.key_drawable_chat_pollHintDrawableIn);
                    if (pollVoteInProgress) {
                        drawable.setAlpha((int) (255 * pollAnimationProgress));
                    } else {
                        drawable.setAlpha(255);
                    }
                    if (docTitleOffsetX < 0 || docTitleOffsetX == 0 && docTitleLayout.getLineLeft(0) == 0) {
                        pollHintX = currentBackgroundDrawable.getBounds().right - drawable.getIntrinsicWidth() - AndroidUtilities.dp(currentMessageObject.isOutOwner() ? 17 : 11);
                    } else {
                        pollHintX = getCurrentBackgroundLeft() + AndroidUtilities.dp(11);
                    }
                    pollHintY = y - AndroidUtilities.dp(6);
                    int cx = pollHintX + drawable.getIntrinsicWidth() / 2;
                    int cy = pollHintY + drawable.getIntrinsicHeight() / 2;
                    float scale = hintButtonVisible && hintButtonProgress < 1 ? AnimationProperties.overshootInterpolator.getInterpolation(hintButtonProgress) : hintButtonProgress;
                    int w = (int) (drawable.getIntrinsicWidth() * scale);
                    int h = (int) (drawable.getIntrinsicHeight() * scale);
                    drawable.setBounds(cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2);
                    drawable.draw(canvas);
                } else {
                    pollHintX = -1;
                }

                if (pollAvatarImages != null && !isBot) {
                    int toAdd;
                    int ax;
                    int lineLeft = (int) Math.ceil(docTitleLayout.getLineLeft(0));
                    if (docTitleOffsetX != 0 || lineLeft != 0) {
                        toAdd = -AndroidUtilities.dp(13);
                        if (docTitleOffsetX != 0) {
                            ax = x + docTitleOffsetX - AndroidUtilities.dp(7 + 16) - getExtraTextX();
                        } else {
                            ax = x + lineLeft - AndroidUtilities.dp(7 + 16) - getExtraTextX();
                        }
                    } else {
                        toAdd = AndroidUtilities.dp(13);
                        ax = x + (int) Math.ceil(docTitleLayout.getLineWidth(0)) + AndroidUtilities.dp(7) + getExtraTextX();
                    }
                    for (int a = pollAvatarImages.length - 1; a >= 0; a--) {
                        if (!pollAvatarImagesVisible[a] || !pollAvatarImages[a].hasImageSet()) {
                            continue;
                        }
                        pollAvatarImages[a].setImageX(ax + toAdd * a);
                        pollAvatarImages[a].setImageY(y - AndroidUtilities.dp(1));
                        if (a != pollAvatarImages.length - 1) {
                            canvas.drawCircle(pollAvatarImages[a].getCenterX(), pollAvatarImages[a].getCenterY(), AndroidUtilities.dp(9), currentBackgroundDrawable.getPaint());
                        }
                        if (animatePollAvatars && animatePollAnswerAlpha) {
                            float alpha = Math.min(pollUnvoteInProgress ? (1.0f - pollAnimationProgress) / 0.3f : pollAnimationProgress, 1.0f);
                            pollAvatarImages[a].setAlpha(alpha);
                        }
                        pollAvatarImages[a].draw(canvas);
                    }
                }
            }
            if ((!pollClosed && !pollVoted || pollVoteInProgress) && lastPoll.quiz && lastPoll.close_period != 0) {
                long currentTime = ConnectionsManager.getInstance(currentAccount).getCurrentTimeMillis();
                long time = Math.max(0, ((long) lastPoll.close_date) * 1000 - currentTime);
                if (closeTimeText == null || lastPollCloseTime != time) {
                    closeTimeText = AndroidUtilities.formatDurationNoHours((int) Math.ceil(time / 1000.0f), false);
                    closeTimeWidth = (int) Math.ceil(Theme.chat_timePaint.measureText(closeTimeText));
                    lastPollCloseTime = time;
                }
                if (time <= 0 && !pollClosed) {
                    if (currentMessageObject.pollLastCheckTime + 1000 < SystemClock.elapsedRealtime()) {
                        currentMessageObject.pollLastCheckTime = 0;
                    }
                    delegate.needReloadPolls();
                }
                int tx = currentBackgroundDrawable.getBounds().right - closeTimeWidth - AndroidUtilities.dp(currentMessageObject.isOutOwner() ? 40 : 34);
                if (time <= 5000) {
                    Theme.chat_timePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPollWrongAnswer : Theme.key_chat_inPollWrongAnswer));
                }
                if (animatePollAnswer) {
                    Theme.chat_timePaint.setAlpha((int) (255 * (1.0f - pollAnimationProgress)));
                }
                canvas.drawText(closeTimeText, tx, y + AndroidUtilities.dp(11), Theme.chat_timePaint);
                Theme.chat_pollTimerPaint.setColor(Theme.chat_timePaint.getColor());
                tx += closeTimeWidth + AndroidUtilities.dp(13);
                int rad = AndroidUtilities.dp(5.1f);
                int ty = y + AndroidUtilities.dp(6);
                if (time <= 60000) {
                    rect.set(tx - rad, ty - rad, tx + rad, ty + rad);
                    float radProgress = -360 * (time / (Math.min(60, lastPoll.close_period) * 1000.0f));
                    canvas.drawArc(rect, -90, radProgress, false, Theme.chat_pollTimerPaint);
                    timerParticles.draw(canvas, Theme.chat_pollTimerPaint, rect, radProgress, pollVoteInProgress ? (1.0f - pollAnimationProgress) : 1.0f);
                } else {
                    canvas.drawCircle(tx, ty, rad, Theme.chat_pollTimerPaint);
                }
                if (time > 60000 || timerTransitionProgress != 0.0f) {
                    Theme.chat_pollTimerPaint.setAlpha((int) (255 * timerTransitionProgress));
                    canvas.drawLine(tx - AndroidUtilities.dp(2.1f) * timerTransitionProgress, ty - AndroidUtilities.dp(7.5f), tx + AndroidUtilities.dp(2.1f) * timerTransitionProgress, ty - AndroidUtilities.dp(7.5f), Theme.chat_pollTimerPaint);
                    canvas.drawLine(tx, ty - AndroidUtilities.dp(3) * timerTransitionProgress, tx, ty, Theme.chat_pollTimerPaint);
                    if (time <= 60000) {
                        timerTransitionProgress -= dt / 180.0f;
                        if (timerTransitionProgress < 0) {
                            timerTransitionProgress = 0;
                        }
                    }
                }
                invalidate();
            }
            if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null && (selectorDrawableMaskType[0] == 1 || selectorDrawableMaskType[0] == 3)) {
                if (selectorDrawableMaskType[0] == 3) {
                    canvas.save();
                    canvas.scale(hintButtonProgress, hintButtonProgress, selectorDrawable[0].getBounds().centerX(), selectorDrawable[0].getBounds().centerY());
                }
                selectorDrawable[0].draw(canvas);
                if (selectorDrawableMaskType[0] == 3) {
                    canvas.restore();
                }
            }
            int lastVoteY = 0;
            for (int a = 0, N = pollButtons.size(); a < N; a++) {
                PollButton button = pollButtons.get(a);
                button.x = x;
                canvas.save();
                canvas.translate(x + AndroidUtilities.dp(35), button.y + namesOffset);
                button.title.draw(canvas);
                int alpha = (int) (animatePollAnswerAlpha ? 255 * Math.min((pollUnvoteInProgress ? 1.0f - pollAnimationProgress : pollAnimationProgress) / 0.3f, 1.0f) : 255);
                if (pollVoted || pollClosed || animatePollAnswerAlpha) {
                    if (lastPoll.quiz && pollVoted && button.chosen) {
                        String key;
                        if (button.correct) {
                            key = currentMessageObject.isOutOwner() ? Theme.key_chat_outPollCorrectAnswer : Theme.key_chat_inPollCorrectAnswer;
                        } else {
                            key = currentMessageObject.isOutOwner() ? Theme.key_chat_outPollWrongAnswer : Theme.key_chat_inPollWrongAnswer;
                        }
                        if (!currentBackgroundDrawable.hasGradient() || Theme.hasThemeKey(key)) {
                            Theme.chat_docBackPaint.setColor(getThemedColor(key));
                        } else {
                            Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outAudioSeekbarFill : Theme.key_chat_inAudioSeekbarFill));
                        }
                    } else {
                        Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outAudioSeekbarFill : Theme.key_chat_inAudioSeekbarFill));
                    }
                    if (animatePollAnswerAlpha) {
                        float oldAlpha = Theme.chat_instantViewPaint.getAlpha() / 255.0f;
                        Theme.chat_instantViewPaint.setAlpha((int) (alpha * oldAlpha));
                        oldAlpha = Theme.chat_docBackPaint.getAlpha() / 255.0f;
                        Theme.chat_docBackPaint.setAlpha((int) (alpha * oldAlpha));
                    }

                    int currentPercent = (int) Math.ceil(button.prevPercent + (button.percent - button.prevPercent) * pollAnimationProgress);
                    String text = String.format("%d%%", currentPercent);
                    int width = (int) Math.ceil(Theme.chat_instantViewPaint.measureText(text));
                    canvas.drawText(text, -AndroidUtilities.dp(6.5f) - width, AndroidUtilities.dp(14), Theme.chat_instantViewPaint);

                    width = backgroundWidth - AndroidUtilities.dp(76);
                    float currentPercentProgress = button.prevPercentProgress + (button.percentProgress - button.prevPercentProgress) * pollAnimationProgress;
                    rect.set(0, button.height + AndroidUtilities.dp(6), width * currentPercentProgress, button.height + AndroidUtilities.dp(11));
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), Theme.chat_docBackPaint);

                    if (button.chosen || button.prevChosen || lastPoll.quiz && button.correct && (pollVoted || pollClosed)) {
                        float cx = rect.left - AndroidUtilities.dp(13.5f);
                        float cy = rect.centerY();
                        canvas.drawCircle(cx, cy, AndroidUtilities.dp(7), Theme.chat_docBackPaint);
                        Drawable drawable;
                        if (lastPoll.quiz && button.chosen && !button.correct) {
                            drawable = Theme.chat_pollCrossDrawable[currentMessageObject.isOutOwner() ? 1 : 0];
                        } else {
                            drawable = Theme.chat_pollCheckDrawable[currentMessageObject.isOutOwner() ? 1 : 0];
                        }
                        drawable.setAlpha(alpha);
                        setDrawableBounds(drawable, cx - drawable.getIntrinsicWidth() / 2, cy - drawable.getIntrinsicHeight() / 2);
                        drawable.draw(canvas);
                    }
                }

                if (!pollVoted && !pollClosed || animatePollAnswerAlpha) {
                    if (isDrawSelectionBackground()) {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outVoiceSeekbarSelected : Theme.key_chat_inVoiceSeekbarSelected));
                    } else {
                        Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outVoiceSeekbar : Theme.key_chat_inVoiceSeekbar));
                    }
                    if (animatePollAnswerAlpha) {
                        float oldAlpha = Theme.chat_replyLinePaint.getAlpha() / 255.0f;
                        Theme.chat_replyLinePaint.setAlpha((int) ((255 - alpha) * oldAlpha));
                    }
                    canvas.drawLine(-AndroidUtilities.dp(2), button.height + AndroidUtilities.dp(13), backgroundWidth - AndroidUtilities.dp(58), button.height + AndroidUtilities.dp(13), Theme.chat_replyLinePaint);
                    if (pollVoteInProgress && a == pollVoteInProgressNum) {
                        Theme.chat_instantViewRectPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outAudioSeekbarFill : Theme.key_chat_inAudioSeekbarFill));
                        if (animatePollAnswerAlpha) {
                            float oldAlpha = Theme.chat_instantViewRectPaint.getAlpha() / 255.0f;
                            Theme.chat_instantViewRectPaint.setAlpha((int) ((255 - alpha) * oldAlpha));
                        }
                        rect.set(-AndroidUtilities.dp(22) - AndroidUtilities.dp(8.5f), AndroidUtilities.dp(9) - AndroidUtilities.dp(8.5f), -AndroidUtilities.dp(23) + AndroidUtilities.dp(8.5f), AndroidUtilities.dp(9) + AndroidUtilities.dp(8.5f));
                        canvas.drawArc(rect, voteRadOffset, voteCurrentCircleLength, false, Theme.chat_instantViewRectPaint);
                    } else {
                        if (currentMessageObject.isOutOwner()) {
                            Theme.chat_instantViewRectPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outMenuSelected : Theme.key_chat_outMenu));
                        } else {
                            Theme.chat_instantViewRectPaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inMenuSelected : Theme.key_chat_inMenu));
                        }
                        if (animatePollAnswerAlpha) {
                            float oldAlpha = Theme.chat_instantViewRectPaint.getAlpha() / 255.0f;
                            Theme.chat_instantViewRectPaint.setAlpha((int) ((255 - alpha) * oldAlpha));
                        }
                        canvas.drawCircle(-AndroidUtilities.dp(22), AndroidUtilities.dp(9), AndroidUtilities.dp(8.5f), Theme.chat_instantViewRectPaint);
                        if (lastPoll.multiple_choice) {
                            int size = AndroidUtilities.dp(8.5f);
                            String key = Theme.key_checkboxCheck;
                            if (currentMessageObject.isOutOwner()) {
                                if (getThemedColor(key) == 0xffffffff) {
                                    key = Theme.key_chat_outBubble;
                                }
                            }
                            pollCheckBox[a].setColor(null, currentMessageObject.isOutOwner() ? Theme.key_chat_outAudioSeekbarFill : Theme.key_chat_inAudioSeekbarFill, key);
                            pollCheckBox[a].setBounds(-AndroidUtilities.dp(22) - size / 2, AndroidUtilities.dp(9) - size / 2, size, size);
                            pollCheckBox[a].draw(canvas);
                        }
                    }
                }
                canvas.restore();
                if (a == N - 1) {
                    lastVoteY = button.y + namesOffset + button.height;
                }
            }
            if (drawInstantView) {
                int textX = getCurrentBackgroundLeft() + AndroidUtilities.dp(currentMessageObject.isOutOwner() || mediaBackground || drawPinnedBottom ? 2 : 8);
                int instantY = lastVoteY + AndroidUtilities.dp(13);
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_outPreviewInstantText));
                } else {
                    Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_inPreviewInstantText));
                }

                instantButtonRect.set(textX, instantY, textX + instantWidth, instantY + AndroidUtilities.dp(44));
                if (selectorDrawable[0] != null && selectorDrawableMaskType[0] == 2) {
                    selectorDrawable[0].setBounds(textX - AndroidUtilities.dp(pollInstantViewTouchesBottom ? 6 : 0), instantY, textX + instantWidth, instantY + AndroidUtilities.dp(44));
                    selectorDrawable[0].draw(canvas);
                }
                if (instantViewLayout != null) {
                    canvas.save();
                    canvas.translate(textX + instantTextX, instantY + AndroidUtilities.dp(14.5f));
                    instantViewLayout.draw(canvas);
                    canvas.restore();
                }
            } else if (infoLayout != null) {
                if (lastPoll.public_voters || lastPoll.multiple_choice) {
                    lastVoteY += AndroidUtilities.dp(6);
                }
                canvas.save();
                canvas.translate(x + infoX, lastVoteY + AndroidUtilities.dp(22));
                infoLayout.draw(canvas);
                canvas.restore();
            }
            updatePollAnimations(dt);
            canvas.restore();
        } else if (currentMessageObject.type == MessageObject.TYPE_CONTACT) {
            if (currentMessageObject.isOutOwner()) {
                Theme.chat_contactNamePaint.setColor(getThemedColor(Theme.key_chat_outContactNameText));
                Theme.chat_contactPhonePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outContactPhoneSelectedText : Theme.key_chat_outContactPhoneText));
            } else {
                Theme.chat_contactNamePaint.setColor(getThemedColor(Theme.key_chat_inContactNameText));
                Theme.chat_contactPhonePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inContactPhoneSelectedText : Theme.key_chat_inContactPhoneText));
            }
            if (titleLayout != null) {
                canvas.save();
                canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(16) + namesOffset);
                titleLayout.draw(canvas);
                canvas.restore();
            }
            if (docTitleLayout != null) {
                canvas.save();
                canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(39) + namesOffset);
                docTitleLayout.draw(canvas);
                canvas.restore();
            }

            Drawable menuDrawable;
            if (currentMessageObject.isOutOwner()) {
                menuDrawable = getThemedDrawable(isDrawSelectionBackground() ? Theme.key_drawable_msgOutMenuSelected : Theme.key_drawable_msgOutMenu);
            } else {
                menuDrawable = isDrawSelectionBackground() ? Theme.chat_msgInMenuSelectedDrawable : Theme.chat_msgInMenuDrawable;
            }
            setDrawableBounds(menuDrawable, otherX = (int) (photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(48)), otherY = (int) (photoImage.getImageY() - AndroidUtilities.dp(2)));
            menuDrawable.draw(canvas);

            if (drawInstantView) {
                int textX = (int) (photoImage.getImageX() - AndroidUtilities.dp(2));
                int instantY = layoutHeight - AndroidUtilities.dp(36 + 30);
                if (!reactionsLayoutInBubble.isEmpty && !reactionsLayoutInBubble.isSmall) {
                    instantY -= reactionsLayoutInBubble.totalHeight;
                }
                if (drawCommentButton) {
                    instantY -= AndroidUtilities.dp(shouldDrawTimeOnMedia() ? 39.3f : 41);
                }
                Paint backPaint = Theme.chat_instantViewRectPaint;
                if (currentMessageObject.isOutOwner()) {
                    Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_outPreviewInstantText));
                    backPaint.setColor(getThemedColor(Theme.key_chat_outPreviewInstantText));
                } else {
                    Theme.chat_instantViewPaint.setColor(getThemedColor(Theme.key_chat_inPreviewInstantText));
                    backPaint.setColor(getThemedColor(Theme.key_chat_inPreviewInstantText));
                }

                instantButtonRect.set(textX, instantY, textX + instantWidth, instantY + AndroidUtilities.dp(36));
                if (Build.VERSION.SDK_INT >= 21) {
                    selectorDrawableMaskType[0] = 0;
                    selectorDrawable[0].setBounds(textX, instantY, textX + instantWidth, instantY + AndroidUtilities.dp(36));
                    selectorDrawable[0].draw(canvas);
                }
                canvas.drawRoundRect(instantButtonRect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), backPaint);
                if (instantViewLayout != null) {
                    canvas.save();
                    canvas.translate(textX + instantTextX, instantY + AndroidUtilities.dp(10.5f));
                    instantViewLayout.draw(canvas);
                    canvas.restore();
                }
            }
        }

        if (drawImageButton && photoImage.getVisible()) {
            if (controlsAlpha != 1.0f) {
                radialProgress.setOverrideAlpha(controlsAlpha);
            }
            if (photoImage.hasImageSet()) {
                radialProgress.setBackgroundDrawable(null);
            } else {
                radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable);
            }
            boolean restore = false;
            boolean on = false;
            if (currentMessageObject != null && currentMessageObject.isRoundVideo() && !currentMessageObject.mediaExists) {
                radialProgress.setProgressRect(
                    photoImage.getImageX() + (photoImage.getImageWidth() - radialProgress.getRadius()) / 2f,
                    photoImage.getImageY() + (photoImage.getImageHeight() - radialProgress.getRadius()) / 2f,
                    photoImage.getImageX() + (photoImage.getImageWidth() + radialProgress.getRadius()) / 2f,
                    photoImage.getImageY() + (photoImage.getImageHeight() + radialProgress.getRadius()) / 2f
                );
            } else if (currentMessageObject != null && currentMessageObject.isRoundVideo()) {
                radialProgress.setProgressRect(
                    photoImage.getImageX(),
                    photoImage.getImageY(),
                    photoImage.getImageX() + photoImage.getImageWidth(),
                    photoImage.getImageY() + photoImage.getImageHeight()
                );
                canvas.saveLayerAlpha(radialProgress.getProgressRect(), (int) (255 * getVideoTranscriptionProgress()), Canvas.ALL_SAVE_FLAG);
                float scale = photoImage.getImageHeight() / (radialProgress.getRadius() * 2);
                canvas.scale(scale, scale, radialProgress.getProgressRect().centerX(), radialProgress.getProgressRect().centerY());
                restore = true;
            }
            if ((!isRoundVideo || !hasLinkPreview) && (!currentMessageObject.needDrawBluredPreview() || !MediaController.getInstance().isPlayingMessage(currentMessageObject)) && !(currentMessageObject.hasMediaSpoilers() && (!currentMessageObject.isMediaSpoilersRevealed || !currentMessageObject.revealingMediaSpoilers) && SharedConfig.isAutoplayVideo() && currentMessagesGroup == null && (radialProgress.getIcon() == MediaActionDrawable.ICON_PLAY || radialProgress.getIcon() == MediaActionDrawable.ICON_NONE))) {
                if (isRoundVideo && !on) {
                    radialProgress.overrideCircleAlpha = .25f + .75f * (1f - getVideoTranscriptionProgress());
                }
                if ((!SharedConfig.isAutoplayVideo() || currentMessagesGroup != null) && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed && radialProgress.getIcon() == MediaActionDrawable.ICON_PLAY) {
                    canvas.saveLayerAlpha(radialProgress.getProgressRect(), (int) (mediaSpoilerRevealProgress * 0xFF), Canvas.ALL_SAVE_FLAG);
                }
                radialProgress.draw(canvas);
                if ((!SharedConfig.isAutoplayVideo() || currentMessagesGroup != null) && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed && radialProgress.getIcon() == MediaActionDrawable.ICON_PLAY) {
                    canvas.restore();
                }
                if (isRoundVideo && !on) {
                    radialProgress.overrideCircleAlpha = 1f;
                }
            }
            if (restore) {
                canvas.restore();
            }
        }
        if (buttonState == -1 && currentMessageObject.needDrawBluredPreview() && !MediaController.getInstance().isPlayingMessage(currentMessageObject) && photoImage.getVisible() && currentMessageObject.messageOwner.destroyTime != 0) {
            if (!currentMessageObject.isOutOwner()) {
                long msTime = System.currentTimeMillis() + ConnectionsManager.getInstance(currentAccount).getTimeDifference() * 1000;
                float progress = Math.max(0, (long) currentMessageObject.messageOwner.destroyTime * 1000 - msTime) / (currentMessageObject.messageOwner.ttl * 1000.0f);
                Theme.chat_deleteProgressPaint.setAlpha((int) (255 * controlsAlpha));
                canvas.drawArc(deleteProgressRect, -90, -360 * progress, true, Theme.chat_deleteProgressPaint);
                if (progress != 0) {
                    int offset = AndroidUtilities.dp(2);
                    invalidate((int) deleteProgressRect.left - offset, (int) deleteProgressRect.top - offset, (int) deleteProgressRect.right + offset * 2, (int) deleteProgressRect.bottom + offset * 2);
                }
            }
            updateSecretTimeText(currentMessageObject);
        }
        if ((drawVideoImageButton || animatingDrawVideoImageButton != 0) && photoImage.getVisible()) {
            if (controlsAlpha != 1.0f) {
                videoRadialProgress.setOverrideAlpha(controlsAlpha);
            }
            videoRadialProgress.draw(canvas);
        }
        if (drawMediaCheckBox) {
            if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT && !drawPhotoImage) {
                int size = AndroidUtilities.dp(20);
                mediaCheckBox.setBackgroundType(radialProgress.getMiniIcon() != MediaActionDrawable.ICON_NONE ? 12 : 13);
                mediaCheckBox.setBounds(buttonX + AndroidUtilities.dp(28), buttonY + AndroidUtilities.dp(28), size, size);
                mediaCheckBox.setColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outTimeText : Theme.key_chat_inTimeText, currentMessageObject.isOutOwner() ? Theme.key_chat_outLoader : Theme.key_chat_inLoader, currentMessageObject.isOutOwner() ? Theme.key_chat_outBubble : Theme.key_chat_inBubble);
                mediaCheckBox.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable);
            } else {
                int size = AndroidUtilities.dp(21);
                mediaCheckBox.setBackgroundType(0);
                mediaCheckBox.setBounds((int) photoImage.getImageX2() - AndroidUtilities.dp(21 + 4), (int) photoImage.getImageY() + AndroidUtilities.dp(4), size, size);
                mediaCheckBox.setColor(null, null, currentMessageObject.isOutOwner() ? Theme.key_chat_outBubbleSelected : Theme.key_chat_inBubbleSelected);
                mediaCheckBox.setBackgroundDrawable(null);
            }
            mediaCheckBox.draw(canvas);
        }

        if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
            float x1, y1;
            boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
            if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
                float offsetX = 0f;
                if (currentMessageObject.isOutOwner()) {
                    float offsetSize = (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.2f;
                    offsetX = isPlayingRound ? offsetSize : 0;
                    if (transitionParams.animatePlayingRound) {
                        offsetX = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * offsetSize;
                    }
                }

                x1 = backgroundDrawableLeft + transitionParams.deltaLeft + (!currentMessageObject.isOutOwner() && !drawPinnedBottom && drawBackground ? AndroidUtilities.dp(6) : 0) + AndroidUtilities.dp(8) + roundPlayingDrawableProgress + offsetX;
                y1 = layoutHeight - AndroidUtilities.dp(28 - (drawPinnedBottom ? 2 : 0));
                if (!reactionsLayoutInBubble.isEmpty) {
                    y1 -= reactionsLayoutInBubble.totalHeight;
                }
                transitionParams.lastDrawRoundVideoDotY = y1;
                if (transitionParams.animateRoundVideoDotY) {
                    y1 = transitionParams.animateFromRoundVideoDotY * (1f - transitionParams.animateChangeProgress) + y1 * transitionParams.animateChangeProgress;
                }

                int timeAudioX = this.timeAudioX;
                if (!hasLinkPreview) {
                    if (currentMessageObject.isOutOwner()) {
                        timeAudioX = (getWidth() - ((transitionParams.animateBackgroundBoundsInner ? (int) (backgroundWidth - transitionParams.deltaLeft + transitionParams.deltaRight) : backgroundWidth)) - (!drawPinnedBottom && mediaBackground ? AndroidUtilities.dp(8) : 0)) + AndroidUtilities.dp(67);
                    }
                    x1 = AndroidUtilities.lerp(x1, timeAudioX - AndroidUtilities.dp(4), getVideoTranscriptionProgress());
                    y1 = AndroidUtilities.lerp(y1, AndroidUtilities.dp(44) + namesOffset + mediaOffsetY - AndroidUtilities.dp(1.7f), getVideoTranscriptionProgress());
                }

                rect.set(x1, y1, x1 + timeWidthAudio + AndroidUtilities.dp(8 + 12 + 2), y1 + AndroidUtilities.dp(17));

                int oldAlpha = getThemedPaint(Theme.key_paint_chatActionBackground).getAlpha();
                getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha((int) (oldAlpha * timeAlpha * (1f - getVideoTranscriptionProgress())));
                applyServiceShaderMatrix();
                canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), getThemedPaint(Theme.key_paint_chatActionBackground));
                if (hasGradientService()) {
                    int oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
                    Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * timeAlpha * (1f - getVideoTranscriptionProgress())));
                    canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
                    Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
                }
                getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha(oldAlpha);

                boolean showPlayingDrawable = playing || !currentMessageObject.isContentUnread();

                if (showPlayingDrawable && roundPlayingDrawableProgress != 1f) {
                    roundPlayingDrawableProgress += 16f / 150f;
                    if (roundPlayingDrawableProgress > 1f) {
                        roundPlayingDrawableProgress = 1f;
                    } else {
                        invalidate();
                    }
                } else if (!showPlayingDrawable && roundPlayingDrawableProgress != 0) {
                    roundPlayingDrawableProgress -= 16f / 150f;
                    if (roundPlayingDrawableProgress < 0f) {
                        roundPlayingDrawableProgress = 0f;
                    } else {
                        invalidate();
                    }
                }
                if (showPlayingDrawable) {
                    if (playing && !MediaController.getInstance().isMessagePaused()) {
                        roundVideoPlayingDrawable.start();
                    } else {
                        roundVideoPlayingDrawable.stop();
                    }
                }
                if (roundPlayingDrawableProgress < 1f) {
                    float cx = x1 + timeWidthAudio + AndroidUtilities.dp(12);
                    float cy = y1 + AndroidUtilities.dp(8.3f);
                    canvas.save();
                    canvas.scale((1f - roundPlayingDrawableProgress), (1f - roundPlayingDrawableProgress), cx, cy);
                    Theme.chat_docBackPaint.setColor(Theme.chat_timePaint.getColor());
                    Theme.chat_docBackPaint.setAlpha((int) (255 * timeAlpha * (1f - roundPlayingDrawableProgress)));
                    canvas.drawCircle(cx, cy, AndroidUtilities.dp(3), Theme.chat_docBackPaint);
                    canvas.restore();
                }
                if (roundPlayingDrawableProgress > 0f) {
                    setDrawableBounds(roundVideoPlayingDrawable, x1 + timeWidthAudio + AndroidUtilities.dp(6), y1 + AndroidUtilities.dp(2.3f));
                    canvas.save();
                    canvas.scale(roundPlayingDrawableProgress, roundPlayingDrawableProgress, roundVideoPlayingDrawable.getBounds().centerX(), roundVideoPlayingDrawable.getBounds().centerY());
                    if (!hasLinkPreview) {
                        roundVideoPlayingDrawable.timeColor = Theme.chat_timePaint.getColor();
                        roundVideoPlayingDrawable.colorProgress = getVideoTranscriptionProgress();
                    } else {
                        roundVideoPlayingDrawable.colorProgress = 0;
                    }
                    roundVideoPlayingDrawable.setAlpha((int) (255 * roundPlayingDrawableProgress * (1f - getVideoTranscriptionProgress())));
                    roundVideoPlayingDrawable.draw(canvas);
                    canvas.restore();
                }
                x1 += AndroidUtilities.dp(4);
                y1 += AndroidUtilities.dp(1.7f);
            } else {
                x1 = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() || drawPinnedBottom ? 12 : 18);
                y1 = layoutHeight - AndroidUtilities.dp(6.3f - (drawPinnedBottom ? 2 : 0)) - timeLayout.getHeight();
            }

            if (durationLayout != null) {
                Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha));
                canvas.save();
                canvas.translate(x1, y1);
                durationLayout.draw(canvas);
                canvas.restore();
                Theme.chat_timePaint.setAlpha(255);
            }
        }
    }

    @Override
    public int getObserverTag() {
        return TAG;
    }

    public MessageObject getMessageObject() {
        return messageObjectToSet != null ? messageObjectToSet : currentMessageObject;
    }

    public TLRPC.Document getStreamingMedia() {
        return documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF ? documentAttach : null;
    }

    public boolean drawPinnedBottom() {
        if (currentMessagesGroup != null && currentMessagesGroup.isDocuments) {
            if (currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0) {
                return pinnedBottom;
            }
            return true;
        }
        return pinnedBottom;
    }

    public float getVideoTranscriptionProgress() {
        if (transitionParams == null || currentMessageObject == null || !currentMessageObject.isRoundVideo()) {
            return 1;
        }
        if (transitionParams.animateDrawBackground) {
            if (drawBackground) {
                return transitionParams.animateChangeProgress;
            } else {
                return 1f - transitionParams.animateChangeProgress;
            }
        }
        return drawBackground ? 1 : 0;
    }

    public boolean drawPinnedTop() {
        if (currentMessagesGroup != null && currentMessagesGroup.isDocuments) {
            if (currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0) {
                return pinnedTop;
            }
            return true;
        }
        return pinnedTop;
    }

    public boolean isPinnedBottom() {
        return pinnedBottom;
    }

    public boolean isPinnedTop() {
        return pinnedTop;
    }

    public MessageObject.GroupedMessages getCurrentMessagesGroup() {
        return currentMessagesGroup;
    }

    public MessageObject.GroupedMessagePosition getCurrentPosition() {
        return currentPosition;
    }

    public int getLayoutHeight() {
        return layoutHeight;
    }

    @Override
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        if (delegate != null && delegate.onAccessibilityAction(action, arguments)) {
            return false;
        }
        if (action == AccessibilityNodeInfo.ACTION_CLICK) {
            int icon = getIconForCurrentState();
            if (icon != MediaActionDrawable.ICON_NONE && icon != MediaActionDrawable.ICON_FILE) {
                didPressButton(true, false);
            } else if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
                delegate.didPressOther(this, otherX, otherY);
            } else {
                didClickedImage();
            }
            return true;
        } else if (action == R.id.acc_action_small_button) {
            didPressMiniButton(true);
        } else if (action == R.id.acc_action_msg_options) {
            if (delegate != null) {
                if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
                    delegate.didLongPress(this, 0, 0);
                } else {
                    delegate.didPressOther(this, otherX, otherY);
                }
            }
        } else if (action == R.id.acc_action_open_forwarded_origin) {
            if (delegate != null) {
                if (currentForwardChannel != null) {
                    delegate.didPressChannelAvatar(ChatMessageCell.this, currentForwardChannel, currentMessageObject.messageOwner.fwd_from.channel_post, lastTouchX, lastTouchY);
                } else if (currentForwardUser != null) {
                    delegate.didPressUserAvatar(ChatMessageCell.this, currentForwardUser, lastTouchX, lastTouchY);
                } else if (currentForwardName != null) {
                    delegate.didPressHiddenForward(ChatMessageCell.this);
                }
            }
        }
        if (currentMessageObject.isVoice() || currentMessageObject.isRoundVideo() || currentMessageObject.isMusic() && MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
            if (seekBarAccessibilityDelegate.performAccessibilityActionInternal(action, arguments)) {
                return true;
            }
        }
        return super.performAccessibilityAction(action, arguments);
    }

    public void setAnimationRunning(boolean animationRunning, boolean willRemoved) {
        this.animationRunning = animationRunning;
        if (animationRunning) {
            this.willRemoved = willRemoved;
        } else {
            this.willRemoved = false;
        }
        if (getParent() == null && attachedToWindow) {
            onDetachedFromWindow();
        }
    }

    @Override
    public boolean onHoverEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) {
            for (int i = 0; i < accessibilityVirtualViewBounds.size(); i++) {
                Rect rect = accessibilityVirtualViewBounds.valueAt(i);
                if (rect.contains(x, y)) {
                    int id = accessibilityVirtualViewBounds.keyAt(i);
                    if (id != currentFocusedVirtualView) {
                        currentFocusedVirtualView = id;
                        sendAccessibilityEventForVirtualView(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
                    }
                    return true;
                }
            }
        } else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
            currentFocusedVirtualView = 0;
        }
        return super.onHoverEvent(event);
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfo(info);
    }

    @Override
    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
        return new MessageAccessibilityNodeProvider();
    }

    private void sendAccessibilityEventForVirtualView(int viewId, int eventType) {
        sendAccessibilityEventForVirtualView(viewId, eventType, null);
    }

    private void sendAccessibilityEventForVirtualView(int viewId, int eventType, String text) {
        AccessibilityManager am = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
        if (am.isTouchExplorationEnabled()) {
            AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
            event.setPackageName(getContext().getPackageName());
            event.setSource(ChatMessageCell.this, viewId);
            if (text != null) {
                event.getText().add(text);
            }
            if (getParent() != null) {
                getParent().requestSendAccessibilityEvent(ChatMessageCell.this, event);
            }
        }
    }

    public static Point getMessageSize(int imageW, int imageH) {
        return getMessageSize(imageW, imageH, 0, 0);
    }

    private static Point getMessageSize(int imageW, int imageH, int photoWidth, int photoHeight) {
        if (photoHeight == 0 || photoWidth == 0) {
            if (AndroidUtilities.isTablet()) {
                photoWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
            } else {
                if (imageW >= imageH) {
                    photoWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(64);
                } else {
                    photoWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f);
                }
            }

            photoHeight = photoWidth + AndroidUtilities.dp(100);

            if (photoWidth > AndroidUtilities.getPhotoSize()) {
                photoWidth = AndroidUtilities.getPhotoSize();
            }
            if (photoHeight > AndroidUtilities.getPhotoSize()) {
                photoHeight = AndroidUtilities.getPhotoSize();
            }
        }

        float scale = (float) imageW / (float) photoWidth;
        int w = (int) (imageW / scale);
        int h = (int) (imageH / scale);
        if (w == 0) {
            w = AndroidUtilities.dp(150);
        }
        if (h == 0) {
            h = AndroidUtilities.dp(150);
        }
        if (h > photoHeight) {
            float scale2 = h;
            h = photoHeight;
            scale2 /= h;
            w = (int) (w / scale2);
        } else if (h < AndroidUtilities.dp(120)) {
            h = AndroidUtilities.dp(120);
            float hScale = (float) imageH / h;
            if (imageW / hScale < photoWidth) {
                w = (int) (imageW / hScale);
            }
        }
        return new Point(w, h);
    }

    public StaticLayout getDescriptionlayout() {
        return descriptionLayout;
    }

    public void setSelectedBackgroundProgress(float value) {
        selectedBackgroundProgress = value;
        invalidate();
    }

    public int computeHeight(MessageObject object, MessageObject.GroupedMessages groupedMessages) {
        photoImage.setIgnoreImageSet(true);
        avatarImage.setIgnoreImageSet(true);
        replyImageReceiver.setIgnoreImageSet(true);
        locationImageReceiver.setIgnoreImageSet(true);

        if (groupedMessages != null && groupedMessages.messages.size() != 1) {
            int h = 0;
            for (int i = 0; i < groupedMessages.messages.size(); i++) {
                MessageObject o = groupedMessages.messages.get(i);
                MessageObject.GroupedMessagePosition position = groupedMessages.positions.get(o);
                if (position != null && (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
                    setMessageContent(o, groupedMessages, false, false);
                    h += totalHeight + keyboardHeight;
                }
            }
            return h;
        }

        setMessageContent(object, groupedMessages, false, false);
        photoImage.setIgnoreImageSet(false);
        avatarImage.setIgnoreImageSet(false);
        replyImageReceiver.setIgnoreImageSet(false);
        locationImageReceiver.setIgnoreImageSet(false);
        return totalHeight + keyboardHeight;
    }

    public void shakeView() {
        Keyframe kf0 = Keyframe.ofFloat(0f, 0);
        Keyframe kf1 = Keyframe.ofFloat(0.2f, 3);
        Keyframe kf2 = Keyframe.ofFloat(0.4f, -3);
        Keyframe kf3 = Keyframe.ofFloat(0.6f, 3);
        Keyframe kf4 = Keyframe.ofFloat(0.8f, -3);
        Keyframe kf5 = Keyframe.ofFloat(1f, 0);
        PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(View.ROTATION, kf0, kf1, kf2, kf3, kf4, kf5);

        Keyframe kfs0 = Keyframe.ofFloat(0f, 1.0f);
        Keyframe kfs1 = Keyframe.ofFloat(0.5f, 0.97f);
        Keyframe kfs2 = Keyframe.ofFloat(1.0f, 1.0f);
        PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofKeyframe(View.SCALE_X, kfs0, kfs1, kfs2);
        PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofKeyframe(View.SCALE_Y, kfs0, kfs1, kfs2);

        shakeAnimation = new AnimatorSet();
        shakeAnimation.playTogether(
                ObjectAnimator.ofPropertyValuesHolder(this, pvhRotation),
                ObjectAnimator.ofPropertyValuesHolder(this, pvhScaleX),
                ObjectAnimator.ofPropertyValuesHolder(this, pvhScaleY));
        shakeAnimation.setDuration(500);
        shakeAnimation.start();
    }

    private void cancelShakeAnimation() {
        if (shakeAnimation != null) {
            shakeAnimation.cancel();
            shakeAnimation = null;

            setScaleX(1.0f);
            setScaleY(1.0f);
            setRotation(0);
        }
    }

    private float slidingOffsetX;
    private float animationOffsetX;

    public Property<ChatMessageCell, Float> ANIMATION_OFFSET_X = new Property<ChatMessageCell, Float>(Float.class, "animationOffsetX") {
        @Override
        public Float get(ChatMessageCell object) {
            return object.animationOffsetX;
        }

        @Override
        public void set(ChatMessageCell object, Float value) {
            object.setAnimationOffsetX(value);
        }
    };

    public void setSlidingOffset(float offsetX) {
        if (slidingOffsetX != offsetX) {
            slidingOffsetX = offsetX;
            updateTranslation();
        }
    }

    public void setAnimationOffsetX(float offsetX) {
        if (animationOffsetX != offsetX) {
            animationOffsetX = offsetX;
            updateTranslation();
        }
    }

    private void updateTranslation() {
        if (currentMessageObject == null) {
            return;
        }
        int checkBoxOffset = !currentMessageObject.isOutOwner() ? checkBoxTranslation : 0;
        setTranslationX(slidingOffsetX + animationOffsetX + checkBoxOffset);
    }

    public float getNonAnimationTranslationX(boolean update) {
        if (currentMessageObject != null && !currentMessageObject.isOutOwner()) {
            if (update && (checkBoxVisible || checkBoxAnimationInProgress)) {
                Interpolator interpolator = checkBoxVisible ? CubicBezierInterpolator.EASE_OUT : CubicBezierInterpolator.EASE_IN;
                checkBoxTranslation = (int) Math.ceil(interpolator.getInterpolation(checkBoxAnimationProgress) * AndroidUtilities.dp(35));
            }
            return slidingOffsetX + checkBoxTranslation;
        } else {
            return slidingOffsetX;
        }
    }

    public float getSlidingOffsetX() {
        return slidingOffsetX;
    }

    public boolean willRemovedAfterAnimation() {
        return willRemoved;
    }

    public float getAnimationOffsetX() {
        return animationOffsetX;
    }

    @Override
    public void setTranslationX(float translationX) {
        super.setTranslationX(translationX);
    }

    public SeekBar getSeekBar() {
        return seekBar;
    }

    public SeekBarWaveform getSeekBarWaveform() {
        return seekBarWaveform;
    }

    private class MessageAccessibilityNodeProvider extends AccessibilityNodeProvider {

        public static final int PROFILE = 5000;
        public static final int LINK_IDS_START = 2000;
        public static final int LINK_CAPTION_IDS_START = 3000;
        public static final int BOT_BUTTONS_START = 1000;
        public static final int POLL_BUTTONS_START = 500;
        public static final int INSTANT_VIEW = 499;
        public static final int SHARE = 498;
        public static final int REPLY = 497;
        public static final int COMMENT = 496;
        public static final int POLL_HINT = 495;
        public static final int FORWARD = 494;
        public static final int TRANSCRIBE = 493;
        private Path linkPath = new Path();
        private RectF rectF = new RectF();
        private Rect rect = new Rect();

        private class ProfileSpan extends ClickableSpan {
            private TLRPC.User user;

            public ProfileSpan(TLRPC.User user) {
                this.user = user;
            }

            @Override
            public void onClick(@NonNull View view) {
                if (delegate != null) {
                    delegate.didPressUserAvatar(ChatMessageCell.this, user, 0, 0);
                }
            }
        }

        @Override
        public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
            int[] pos = {0, 0};
            getLocationOnScreen(pos);
            if (virtualViewId == HOST_VIEW_ID) {
                AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(ChatMessageCell.this);
                onInitializeAccessibilityNodeInfo(info);
                final boolean unread = currentMessageObject != null && currentMessageObject.isOut() && !currentMessageObject.scheduled && currentMessageObject.isUnread();
                final boolean contentUnread = currentMessageObject != null && currentMessageObject.isContentUnread();
                final long fileSize = currentMessageObject != null ? currentMessageObject.loadedFileSize : 0;
                if (accessibilityText == null || accessibilityTextUnread != unread || accessibilityTextContentUnread != contentUnread || accessibilityTextFileSize != fileSize) {
                    SpannableStringBuilder sb = new SpannableStringBuilder();
                    if (isChat && currentUser != null && !currentMessageObject.isOut()) {
                        sb.append(UserObject.getUserName(currentUser));
                        sb.setSpan(new ProfileSpan(currentUser), 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        sb.append('\n');
                    }
                    if (drawForwardedName) {
                        for (int a = 0; a < 2; a++) {
                            if (forwardedNameLayout[a] != null) {
                                sb.append(forwardedNameLayout[a].getText());
                                sb.append(a == 0 ? " " : "\n");
                            }
                        }
                    }
                    if (documentAttach != null && documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                        String fileName = FileLoader.getAttachFileName(documentAttach);
                        if (fileName.indexOf('.') != -1) {
                            sb.append(LocaleController.formatString(R.string.AccDescrDocumentType, fileName.substring(fileName.lastIndexOf('.') + 1).toUpperCase(Locale.ROOT)));
                        }
                    }
                    if (!TextUtils.isEmpty(currentMessageObject.messageText)) {
                        sb.append(currentMessageObject.messageText);
                    }
                    if (documentAttach != null && (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO)) {
                        if (buttonState == 1 && loadingProgressLayout != null) {
                            sb.append("\n");
                            final boolean sending = currentMessageObject.isSending();
                            final String key = sending ? "AccDescrUploadProgress" : "AccDescrDownloadProgress";
                            final int resId = sending ? R.string.AccDescrUploadProgress : R.string.AccDescrDownloadProgress;
                            sb.append(LocaleController.formatString(key, resId, AndroidUtilities.formatFileSize(currentMessageObject.loadedFileSize), AndroidUtilities.formatFileSize(lastLoadingSizeTotal)));
                        }
                    }
                    if (currentMessageObject.isMusic()) {
                        sb.append("\n");
                        sb.append(LocaleController.formatString("AccDescrMusicInfo", R.string.AccDescrMusicInfo, currentMessageObject.getMusicAuthor(), currentMessageObject.getMusicTitle()));
                        sb.append(", ");
                        sb.append(LocaleController.formatDuration(currentMessageObject.getDuration()));
                    } else if (currentMessageObject.isVoice() || isRoundVideo) {
                        sb.append(", ");
                        sb.append(LocaleController.formatDuration(currentMessageObject.getDuration()));
                        sb.append(", ");
                        if (currentMessageObject.isContentUnread()) {
                            sb.append(LocaleController.getString("AccDescrMsgNotPlayed", R.string.AccDescrMsgNotPlayed));
                        } else {
                            sb.append(LocaleController.getString("AccDescrMsgPlayed", R.string.AccDescrMsgPlayed));
                        }
                    }
                    if (lastPoll != null) {
                        sb.append(", ");
                        sb.append(lastPoll.question);
                        sb.append(", ");
                        String title;
                        if (pollClosed) {
                            title = LocaleController.getString("FinalResults", R.string.FinalResults);
                        } else {
                            if (lastPoll.quiz) {
                                if (lastPoll.public_voters) {
                                    title = LocaleController.getString("QuizPoll", R.string.QuizPoll);
                                } else {
                                    title = LocaleController.getString("AnonymousQuizPoll", R.string.AnonymousQuizPoll);
                                }
                            } else if (lastPoll.public_voters) {
                                title = LocaleController.getString("PublicPoll", R.string.PublicPoll);
                            } else {
                                title = LocaleController.getString("AnonymousPoll", R.string.AnonymousPoll);
                            }
                        }
                        sb.append(title);
                    }
                    if (documentAttach != null) {
                        if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
                            sb.append(", ");
                            sb.append(LocaleController.formatDuration(currentMessageObject.getDuration()));
                        }
                        if (buttonState == 0 || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                            sb.append(", ");
                            sb.append(AndroidUtilities.formatFileSize(documentAttach.size));
                        }
                    }
                    if (currentMessageObject.isVoiceTranscriptionOpen()) {
                        sb.append("\n");
                        sb.append(currentMessageObject.getVoiceTranscription());
                    } else {
                        if (MessageObject.getMedia(currentMessageObject.messageOwner) != null && !TextUtils.isEmpty(currentMessageObject.caption)) {
                            sb.append("\n");
                            sb.append(currentMessageObject.caption);
                        }
                    }
                    if (currentMessageObject.isOut()) {
                        if (currentMessageObject.isSent()) {
                            sb.append("\n");
                            if (currentMessageObject.scheduled) {
                                sb.append(LocaleController.formatString("AccDescrScheduledDate", R.string.AccDescrScheduledDate, currentTimeString));
                            } else {
                                sb.append(LocaleController.formatString("AccDescrSentDate", R.string.AccDescrSentDate, LocaleController.getString("TodayAt", R.string.TodayAt) + " " + currentTimeString));
                                sb.append(", ");
                                sb.append(currentMessageObject.isUnread() ? LocaleController.getString("AccDescrMsgUnread", R.string.AccDescrMsgUnread) : LocaleController.getString("AccDescrMsgRead", R.string.AccDescrMsgRead));
                            }
                        } else if (currentMessageObject.isSending()) {
                            sb.append("\n");
                            sb.append(LocaleController.getString("AccDescrMsgSending", R.string.AccDescrMsgSending));
                            final float sendingProgress = radialProgress.getProgress();
                            if (sendingProgress > 0f) {
                                sb.append(Integer.toString(Math.round(sendingProgress * 100))).append("%");
                            }
                        } else if (currentMessageObject.isSendError()) {
                            sb.append("\n");
                            sb.append(LocaleController.getString("AccDescrMsgSendingError", R.string.AccDescrMsgSendingError));
                        }
                    } else {
                        sb.append("\n");
                        sb.append(LocaleController.formatString("AccDescrReceivedDate", R.string.AccDescrReceivedDate, LocaleController.getString("TodayAt", R.string.TodayAt) + " " + currentTimeString));
                    }
                    if (getRepliesCount() > 0 && !hasCommentLayout()) {
                        sb.append("\n");
                        sb.append(LocaleController.formatPluralString("AccDescrNumberOfReplies", getRepliesCount()));
                    }
                    if (currentMessageObject.messageOwner.reactions != null && currentMessageObject.messageOwner.reactions.results != null) {
                        if (currentMessageObject.messageOwner.reactions.results.size() == 1) {
                            TLRPC.ReactionCount reaction = currentMessageObject.messageOwner.reactions.results.get(0);
                            String emoticon = reaction.reaction instanceof TLRPC.TL_reactionEmoji ? ((TLRPC.TL_reactionEmoji) reaction.reaction).emoticon : "";
                            if (reaction.count == 1) {
                                sb.append("\n");
                                boolean isMe = false;
                                String userName = "";
                                if (currentMessageObject.messageOwner.reactions.recent_reactions != null && currentMessageObject.messageOwner.reactions.recent_reactions.size() == 1) {
                                    TLRPC.MessagePeerReaction recentReaction = currentMessageObject.messageOwner.reactions.recent_reactions.get(0);
                                    if (recentReaction != null) {
                                        TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(MessageObject.getPeerId(recentReaction.peer_id));
                                        isMe = UserObject.isUserSelf(user);
                                        if (user != null) {
                                            userName = UserObject.getFirstName(user);
                                        }
                                    }
                                }
                                if (isMe) {
                                    sb.append(LocaleController.formatString("AccDescrYouReactedWith", R.string.AccDescrYouReactedWith, emoticon));
                                } else {
                                    sb.append(LocaleController.formatString("AccDescrReactedWith", R.string.AccDescrReactedWith, userName, emoticon));
                                }
                            } else if (reaction.count > 1) {
                                sb.append("\n");
                                sb.append(LocaleController.formatPluralString("AccDescrNumberOfPeopleReactions", reaction.count, emoticon));
                            }
                        } else {
                            sb.append(LocaleController.getString("Reactions", R.string.Reactions)).append((": "));
                            final int count = currentMessageObject.messageOwner.reactions.results.size();
                            for (int i = 0; i < count; ++i) {
                                TLRPC.ReactionCount reactionCount = currentMessageObject.messageOwner.reactions.results.get(i);
                                String emoticon = reactionCount.reaction instanceof TLRPC.TL_reactionEmoji ? ((TLRPC.TL_reactionEmoji) reactionCount.reaction).emoticon : "";
                                if (reactionCount != null) {
                                    sb.append(emoticon).append(" ").append(reactionCount.count + "");
                                    if (i + 1 < count) {
                                        sb.append(", ");
                                    }
                                }
                            }
                            sb.append("\n");
                        }
                    }
                    if ((currentMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
                        sb.append("\n");
                        sb.append(LocaleController.formatPluralString("AccDescrNumberOfViews", currentMessageObject.messageOwner.views));
                    }
                    sb.append("\n");

                    CharacterStyle[] links = sb.getSpans(0, sb.length(), ClickableSpan.class);

                    for (CharacterStyle link : links) {
                        int start = sb.getSpanStart(link);
                        int end = sb.getSpanEnd(link);
                        sb.removeSpan(link);

                        ClickableSpan underlineSpan = new ClickableSpan() {
                            @Override
                            public void onClick(View view) {
                                if (link instanceof ProfileSpan) {
                                    ((ProfileSpan) link).onClick(view);
                                } else if (delegate != null) {
                                    delegate.didPressUrl(ChatMessageCell.this, link, false);
                                }
                            }
                        };
                        sb.setSpan(underlineSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                    accessibilityText = sb;
                    accessibilityTextUnread = unread;
                    accessibilityTextContentUnread = contentUnread;
                    accessibilityTextFileSize = fileSize;
                }

                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                    info.setContentDescription(accessibilityText.toString());
                } else {
                    info.setText(accessibilityText);
                }

                info.setEnabled(true);
                if (Build.VERSION.SDK_INT >= 19) {
                    AccessibilityNodeInfo.CollectionItemInfo itemInfo = info.getCollectionItemInfo();
                    if (itemInfo != null) {
                        info.setCollectionItemInfo(AccessibilityNodeInfo.CollectionItemInfo.obtain(itemInfo.getRowIndex(), 1, 0, 1, false));
                    }
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    info.addAction(new AccessibilityNodeInfo.AccessibilityAction(R.id.acc_action_msg_options, LocaleController.getString("AccActionMessageOptions", R.string.AccActionMessageOptions)));
                    int icon = getIconForCurrentState();
                    CharSequence actionLabel = null;
                    switch (icon) {
                        case MediaActionDrawable.ICON_PLAY:
                            actionLabel = LocaleController.getString("AccActionPlay", R.string.AccActionPlay);
                            break;
                        case MediaActionDrawable.ICON_PAUSE:
                            actionLabel = LocaleController.getString("AccActionPause", R.string.AccActionPause);
                            break;
                        case MediaActionDrawable.ICON_FILE:
                            actionLabel = LocaleController.getString("AccActionOpenFile", R.string.AccActionOpenFile);
                            break;
                        case MediaActionDrawable.ICON_DOWNLOAD:
                            actionLabel = LocaleController.getString("AccActionDownload", R.string.AccActionDownload);
                            break;
                        case MediaActionDrawable.ICON_CANCEL:
                            actionLabel = LocaleController.getString("AccActionCancelDownload", R.string.AccActionCancelDownload);
                            break;
                        default:
                            if (currentMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
                                actionLabel = LocaleController.getString("CallAgain", R.string.CallAgain);
                            }
                    }
                    info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, actionLabel));
                    info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_LONG_CLICK, LocaleController.getString("AccActionEnterSelectionMode", R.string.AccActionEnterSelectionMode)));
                    int smallIcon = getMiniIconForCurrentState();
                    if (smallIcon == MediaActionDrawable.ICON_DOWNLOAD) {
                        info.addAction(new AccessibilityNodeInfo.AccessibilityAction(R.id.acc_action_small_button, LocaleController.getString("AccActionDownload", R.string.AccActionDownload)));
                    }
                } else {
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                }

                if ((currentMessageObject.isVoice() || currentMessageObject.isRoundVideo() || currentMessageObject.isMusic()) && MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
                    seekBarAccessibilityDelegate.onInitializeAccessibilityNodeInfoInternal(info);
                }

                if (useTranscribeButton && transcribeButton != null) {
                    info.addChild(ChatMessageCell.this, TRANSCRIBE);
                }

                int i;
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                    if (isChat && currentUser != null && !currentMessageObject.isOut()) {
                        info.addChild(ChatMessageCell.this, PROFILE);
                    }
                    if (currentMessageObject.messageText instanceof Spannable) {
                        Spannable buffer = (Spannable) currentMessageObject.messageText;
                        CharacterStyle[] links = buffer.getSpans(0, buffer.length(), ClickableSpan.class);
                        i = 0;
                        for (CharacterStyle link : links) {
                            info.addChild(ChatMessageCell.this, LINK_IDS_START + i);
                            i++;
                        }
                    }
                    if (currentMessageObject.caption instanceof Spannable && captionLayout != null) {
                        Spannable buffer = (Spannable) currentMessageObject.caption;
                        CharacterStyle[] links = buffer.getSpans(0, buffer.length(), ClickableSpan.class);
                        i = 0;
                        for (CharacterStyle link : links) {
                            info.addChild(ChatMessageCell.this, LINK_CAPTION_IDS_START + i);
                            i++;
                        }
                    }
                }
                i = 0;
                for (BotButton button : botButtons) {
                    info.addChild(ChatMessageCell.this, BOT_BUTTONS_START + i);
                    i++;
                }
                if (hintButtonVisible && pollHintX != -1 && currentMessageObject.isPoll()) {
                    info.addChild(ChatMessageCell.this, POLL_HINT);
                }
                i = 0;
                for (PollButton button : pollButtons) {
                    info.addChild(ChatMessageCell.this, POLL_BUTTONS_START + i);
                    i++;
                }
                if (drawInstantView && !instantButtonRect.isEmpty()) {
                    info.addChild(ChatMessageCell.this, INSTANT_VIEW);
                }
                if (commentLayout != null) {
                    info.addChild(ChatMessageCell.this, COMMENT);
                }
                if (drawSideButton == 1 || drawSideButton == 2) {
                    info.addChild(ChatMessageCell.this, SHARE);
                }
                if (replyNameLayout != null) {
                    info.addChild(ChatMessageCell.this, REPLY);
                }
                if (forwardedNameLayout[0] != null && forwardedNameLayout[1] != null) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        info.addAction(new AccessibilityNodeInfo.AccessibilityAction(R.id.acc_action_open_forwarded_origin, LocaleController.getString("AccActionOpenForwardedOrigin", R.string.AccActionOpenForwardedOrigin)));
                    } else {
                        info.addChild(ChatMessageCell.this, FORWARD);
                    }
                }
                if (drawSelectionBackground || getBackground() != null) {
                    info.setSelected(true);
                }
                return info;
            } else {
                AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
                info.setSource(ChatMessageCell.this, virtualViewId);
                info.setParent(ChatMessageCell.this);
                info.setPackageName(getContext().getPackageName());
                if (virtualViewId == PROFILE) {
                    if (currentUser == null) {
                        return null;
                    }
                    String content = UserObject.getUserName(currentUser);
                    info.setText(content);
                    rect.set((int) nameX, (int) nameY, (int) (nameX + nameWidth), (int) (nameY + (nameLayout != null ? nameLayout.getHeight() : 10)));
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClassName("android.widget.TextView");
                    info.setEnabled(true);
                    info.setClickable(true);
                    info.setLongClickable(true);
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                } else if (virtualViewId >= LINK_CAPTION_IDS_START) {
                    if (!(currentMessageObject.caption instanceof Spannable) || captionLayout == null) {
                        return null;
                    }
                    Spannable buffer = (Spannable) currentMessageObject.caption;
                    ClickableSpan link = getLinkById(virtualViewId, true);
                    if (link == null) {
                        return null;
                    }
                    int[] linkPos = getRealSpanStartAndEnd(buffer, link);
                    String content = buffer.subSequence(linkPos[0], linkPos[1]).toString();
                    info.setText(content);
                    int length = captionLayout.getText().length();

                    captionLayout.getSelectionPath(linkPos[0], linkPos[1], linkPath);
                    linkPath.computeBounds(rectF, true);
                    rect.set((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom);
                    rect.offset((int) captionX, (int) captionY);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);

                    info.setClassName("android.widget.TextView");
                    info.setEnabled(true);
                    info.setClickable(true);
                    info.setLongClickable(true);
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                } else if (virtualViewId >= LINK_IDS_START) {
                    if (!(currentMessageObject.messageText instanceof Spannable)) {
                        return null;
                    }
                    Spannable buffer = (Spannable) currentMessageObject.messageText;
                    ClickableSpan link = getLinkById(virtualViewId, false);
                    if (link == null) {
                        return null;
                    }
                    int[] linkPos = getRealSpanStartAndEnd(buffer, link);
                    String content = buffer.subSequence(linkPos[0], linkPos[1]).toString();
                    info.setText(content);
                    for (MessageObject.TextLayoutBlock block : currentMessageObject.textLayoutBlocks) {
                        int length = block.textLayout.getText().length();
                        if (block.charactersOffset <= linkPos[0] && block.charactersOffset + length >= linkPos[1]) {
                            block.textLayout.getSelectionPath(linkPos[0] - block.charactersOffset, linkPos[1] - block.charactersOffset, linkPath);
                            linkPath.computeBounds(rectF, true);
                            rect.set((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom);
                            rect.offset(0, (int) block.textYOffset);
                            rect.offset(textX, textY);
                            info.setBoundsInParent(rect);
                            if (accessibilityVirtualViewBounds.get(virtualViewId) == null) {
                                accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                            }
                            rect.offset(pos[0], pos[1]);
                            info.setBoundsInScreen(rect);
                            break;
                        }
                    }

                    info.setClassName("android.widget.TextView");
                    info.setEnabled(true);
                    info.setClickable(true);
                    info.setLongClickable(true);
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                } else if (virtualViewId >= BOT_BUTTONS_START) {
                    int buttonIndex = virtualViewId - BOT_BUTTONS_START;
                    if (buttonIndex >= botButtons.size()) {
                        return null;
                    }
                    BotButton button = botButtons.get(buttonIndex);
                    info.setText(button.title.getText());
                    info.setClassName("android.widget.Button");
                    info.setEnabled(true);
                    info.setClickable(true);
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);

                    rect.set(button.x, button.y, button.x + button.width, button.y + button.height);
                    int addX;
                    if (currentMessageObject.isOutOwner()) {
                        addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
                    } else {
                        addX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground ? 1 : 7);
                    }
                    rect.offset(addX, layoutHeight);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                } else if (virtualViewId >= POLL_BUTTONS_START) {
                    int buttonIndex = virtualViewId - POLL_BUTTONS_START;
                    if (buttonIndex >= pollButtons.size()) {
                        return null;
                    }
                    PollButton button = pollButtons.get(buttonIndex);
                    StringBuilder sb = new StringBuilder(button.title.getText());
                    if (!pollVoted) {
                        info.setClassName("android.widget.Button");
                    } else {
                        info.setSelected(button.chosen);
                        sb.append(", ").append(button.percent).append("%");
                        if (lastPoll != null && lastPoll.quiz && (button.chosen || button.correct)) {
                            sb.append(", ").append(button.correct ? LocaleController.getString("AccDescrQuizCorrectAnswer", R.string.AccDescrQuizCorrectAnswer) : LocaleController.getString("AccDescrQuizIncorrectAnswer", R.string.AccDescrQuizIncorrectAnswer));
                        }
                    }
                    info.setText(sb);
                    info.setEnabled(true);
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);

                    final int y = button.y + namesOffset;
                    final int w = backgroundWidth - AndroidUtilities.dp(76);
                    rect.set(button.x, y, button.x + w, y + button.height);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);

                    info.setClickable(true);
                } else if (virtualViewId == POLL_HINT) {
                    info.setClassName("android.widget.Button");
                    info.setEnabled(true);
                    info.setText(LocaleController.getString("AccDescrQuizExplanation", R.string.AccDescrQuizExplanation));
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    rect.set(pollHintX - AndroidUtilities.dp(8), pollHintY - AndroidUtilities.dp(8), pollHintX + AndroidUtilities.dp(32), pollHintY + AndroidUtilities.dp(32));
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                } else if (virtualViewId == INSTANT_VIEW) {
                    info.setClassName("android.widget.Button");
                    info.setEnabled(true);
                    if (instantViewLayout != null) {
                        info.setText(instantViewLayout.getText());
                    }
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    instantButtonRect.round(rect);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                } else if (virtualViewId == SHARE) {
                    info.setClassName("android.widget.ImageButton");
                    info.setEnabled(true);
                    if (isOpenChatByShare(currentMessageObject)) {
                        info.setContentDescription(LocaleController.getString("AccDescrOpenChat", R.string.AccDescrOpenChat));
                    } else {
                        info.setContentDescription(LocaleController.getString("ShareFile", R.string.ShareFile));
                    }
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    rect.set((int) sideStartX, (int) sideStartY, (int) sideStartX + AndroidUtilities.dp(40), (int) sideStartY + AndroidUtilities.dp(32));
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                } else if (virtualViewId == REPLY) {
                    info.setEnabled(true);
                    StringBuilder sb = new StringBuilder();
                    sb.append(LocaleController.getString("Reply", R.string.Reply));
                    sb.append(", ");
                    if (replyNameLayout != null) {
                        sb.append(replyNameLayout.getText());
                        sb.append(", ");
                    }
                    if (replyTextLayout != null) {
                        sb.append(replyTextLayout.getText());
                    }
                    info.setContentDescription(sb.toString());
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);

                    rect.set(replyStartX, replyStartY, replyStartX + Math.max(replyNameWidth, replyTextWidth), replyStartY + (int) replyHeight);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                } else if (virtualViewId == FORWARD) {
                    info.setEnabled(true);
                    StringBuilder sb = new StringBuilder();
                    if (forwardedNameLayout[0] != null && forwardedNameLayout[1] != null) {
                        for (int a = 0; a < 2; a++) {
                            sb.append(forwardedNameLayout[a].getText());
                            sb.append(a == 0 ? " " : "\n");
                        }
                    }
                    info.setContentDescription(sb.toString());
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);

                    int x = (int) Math.min(forwardNameX - forwardNameOffsetX[0], forwardNameX - forwardNameOffsetX[1]);
                    rect.set(x, forwardNameY, x + forwardedNameWidth, forwardNameY + forwardHeight);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                } else if (virtualViewId == COMMENT) {
                    info.setClassName("android.widget.Button");
                    info.setEnabled(true);
                    int commentCount = getRepliesCount();
                    String comment = null;
                    if (currentMessageObject != null && !currentMessageObject.shouldDrawWithoutBackground() && !currentMessageObject.isAnimatedEmoji()) {
                        if (isRepliesChat) {
                            comment = LocaleController.getString("ViewInChat", R.string.ViewInChat);
                        } else {
                            comment = commentCount == 0 ? LocaleController.getString("LeaveAComment", R.string.LeaveAComment) : LocaleController.formatPluralString("CommentsCount", commentCount);
                        }
                    } else if (!isRepliesChat && commentCount > 0) {
                        comment = LocaleController.formatShortNumber(commentCount, null);
                    }
                    if (comment != null) {
                        info.setText(comment);
                    }
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    rect.set(commentButtonRect);
                    info.setBoundsInParent(rect);
                    if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
                        accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
                    }
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                } else if (virtualViewId == TRANSCRIBE) {
                    info.setClassName("android.widget.Button");
                    info.setEnabled(true);
                    info.setText(currentMessageObject.isVoiceTranscriptionOpen() ? LocaleController.getString("AccActionCloseTranscription", R.string.AccActionCloseTranscription) : LocaleController.getString("AccActionOpenTranscription", R.string.AccActionOpenTranscription));
                    info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                    if (transcribeButton != null) {
                        rect.set((int) transcribeX, (int) transcribeY, (int) (transcribeX + transcribeButton.width()), (int) (transcribeY + transcribeButton.height()));
                    }
                    info.setBoundsInParent(rect);
                    rect.offset(pos[0], pos[1]);
                    info.setBoundsInScreen(rect);
                    info.setClickable(true);
                }
                info.setFocusable(true);
                info.setVisibleToUser(true);
                return info;
            }
        }

        @Override
        public boolean performAction(int virtualViewId, int action, Bundle arguments) {
            if (virtualViewId == HOST_VIEW_ID) {
                performAccessibilityAction(action, arguments);
            } else {
                if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) {
                    sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
                } else if (action == AccessibilityNodeInfo.ACTION_CLICK) {
                    if (virtualViewId == PROFILE) {
                        if (delegate != null) {
                            delegate.didPressUserAvatar(ChatMessageCell.this, currentUser, 0, 0);
                        }
                    } else if (virtualViewId >= LINK_CAPTION_IDS_START) {
                        ClickableSpan link = getLinkById(virtualViewId, true);
                        if (link != null) {
                            delegate.didPressUrl(ChatMessageCell.this, link, false);
                            sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
                        }
                    } else if (virtualViewId >= LINK_IDS_START) {
                        ClickableSpan link = getLinkById(virtualViewId, false);
                        if (link != null) {
                            delegate.didPressUrl(ChatMessageCell.this, link, false);
                            sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
                        }
                    } else if (virtualViewId >= BOT_BUTTONS_START) {
                        int buttonIndex = virtualViewId - BOT_BUTTONS_START;
                        if (buttonIndex >= botButtons.size()) {
                            return false;
                        }
                        BotButton button = botButtons.get(buttonIndex);
                        if (delegate != null) {
                            if (button.button != null) {
                                delegate.didPressBotButton(ChatMessageCell.this, button.button);
                            }
                        }
                        sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
                    } else if (virtualViewId >= POLL_BUTTONS_START) {
                        int buttonIndex = virtualViewId - POLL_BUTTONS_START;
                        if (buttonIndex >= pollButtons.size()) {
                            return false;
                        }
                        PollButton button = pollButtons.get(buttonIndex);
                        if (delegate != null) {
                            ArrayList<TLRPC.TL_pollAnswer> answers = new ArrayList<>();
                            answers.add(button.answer);
                            delegate.didPressVoteButtons(ChatMessageCell.this, answers, -1, 0, 0);
                        }
                        sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
                    } else if (virtualViewId == POLL_HINT) {
                        if (delegate != null) {
                            delegate.didPressHint(ChatMessageCell.this, 0);
                        }
                    } else if (virtualViewId == INSTANT_VIEW) {
                        if (delegate != null) {
                            delegate.didPressInstantButton(ChatMessageCell.this, drawInstantViewType);
                        }
                    } else if (virtualViewId == SHARE) {
                        if (delegate != null) {
                            delegate.didPressSideButton(ChatMessageCell.this);
                        }
                    } else if (virtualViewId == REPLY) {
                        if (delegate != null && (!isThreadChat || currentMessageObject.getReplyTopMsgId() != 0) && currentMessageObject.hasValidReplyMessageObject()) {
                            delegate.didPressReplyMessage(ChatMessageCell.this, currentMessageObject.getReplyMsgId());
                        }
                    } else if (virtualViewId == FORWARD) {
                        if (delegate != null) {
                            if (currentForwardChannel != null) {
                                delegate.didPressChannelAvatar(ChatMessageCell.this, currentForwardChannel, currentMessageObject.messageOwner.fwd_from.channel_post, lastTouchX, lastTouchY);
                            } else if (currentForwardUser != null) {
                                delegate.didPressUserAvatar(ChatMessageCell.this, currentForwardUser, lastTouchX, lastTouchY);
                            } else if (currentForwardName != null) {
                                delegate.didPressHiddenForward(ChatMessageCell.this);
                            }
                        }
                    } else if (virtualViewId == COMMENT) {
                        if (delegate != null) {
                            if (isRepliesChat) {
                                delegate.didPressSideButton(ChatMessageCell.this);
                            } else {
                                delegate.didPressCommentButton(ChatMessageCell.this);
                            }
                        }
                    } else if (virtualViewId == TRANSCRIBE && transcribeButton != null) {
                        transcribeButton.onTap();
                    }
                } else if (action == AccessibilityNodeInfo.ACTION_LONG_CLICK) {
                    ClickableSpan link = getLinkById(virtualViewId, virtualViewId >= LINK_CAPTION_IDS_START);
                    if (link != null) {
                        delegate.didPressUrl(ChatMessageCell.this, link, true);
                        sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
                    }
                }
            }
            return true;
        }

        private ClickableSpan getLinkById(int id, boolean caption) {
            if (id == PROFILE) {
                return null;
            }
            if (caption) {
                id -= LINK_CAPTION_IDS_START;
                if (!(currentMessageObject.caption instanceof Spannable) || id < 0) {
                    return null;
                }
                Spannable buffer = (Spannable) currentMessageObject.caption;
                ClickableSpan[] links = buffer.getSpans(0, buffer.length(), ClickableSpan.class);
                if (links.length <= id) {
                    return null;
                }
                return links[id];
            } else {
                id -= LINK_IDS_START;
                if (!(currentMessageObject.messageText instanceof Spannable) || id < 0) {
                    return null;
                }
                Spannable buffer = (Spannable) currentMessageObject.messageText;
                ClickableSpan[] links = buffer.getSpans(0, buffer.length(), ClickableSpan.class);
                if (links.length <= id) {
                    return null;
                }
                return links[id];
            }
        }
    }

    public void setImageCoords(float x, float y, float w, float h) {
        photoImage.setImageCoords(x, y, w, h);
        if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
            videoButtonX = (int) (photoImage.getImageX() + AndroidUtilities.dp(8));
            videoButtonY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8));
            videoRadialProgress.setProgressRect(videoButtonX, videoButtonY, videoButtonX + AndroidUtilities.dp(24), videoButtonY + AndroidUtilities.dp(24));

            buttonX = (int) (x + (photoImage.getImageWidth() - AndroidUtilities.dp(48)) / 2.0f);
            buttonY = (int) (photoImage.getImageY() + (photoImage.getImageHeight() - AndroidUtilities.dp(48)) / 2);
            radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48));
        }
    }

    @Override
    public float getAlpha() {
        if (ALPHA_PROPERTY_WORKAROUND) {
            return alphaInternal;
        }
        return super.getAlpha();
    }

    @Override
    public void setAlpha(float alpha) {
        if ((alpha == 1f) != (getAlpha() == 1)) {
            invalidate();
        }
        if (ALPHA_PROPERTY_WORKAROUND) {
            alphaInternal = alpha;
            invalidate();
        } else {
            super.setAlpha(alpha);
        }
        if ((currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) && !(enterTransitionInProgress && !currentMessageObject.isVoice()) && replyNameLayout != null && replyTextLayout != null || // Reply layout
                (currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) { // Reactions
            invalidate();
        }
    }

    public int getCurrentBackgroundLeft() {
        if (currentBackgroundDrawable == null) {
            return 0;
        }
        int left = currentBackgroundDrawable.getBounds().left;
        if (!currentMessageObject.isOutOwner() && transitionParams.changePinnedBottomProgress != 1 && (isRoundVideo || !mediaBackground) && !drawPinnedBottom) {
            if (isRoundVideo) {
                left -= AndroidUtilities.dp(6) * (getVideoTranscriptionProgress());
            } else {
                left -= AndroidUtilities.dp(6);
            }
        }
        return left;
    }

    public int getCurrentBackgroundRight() {
        if (currentBackgroundDrawable == null) {
            return getWidth();
        }
        int right = currentBackgroundDrawable.getBounds().right;
        if (currentMessageObject.isOutOwner() && transitionParams.changePinnedBottomProgress != 1 && (isRoundVideo || !mediaBackground) && !drawPinnedBottom) {
            if (isRoundVideo) {
                right += AndroidUtilities.dp(6) * (getVideoTranscriptionProgress());
            } else {
                right += AndroidUtilities.dp(6);
            }
        }
        return right;
    }

    public TransitionParams getTransitionParams() {
        return transitionParams;
    }

    public int getTopMediaOffset() {
        if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_MUSIC) {
            return mediaOffsetY + namesOffset;
        }
        return 0;
    }

    public int getTextX() {
        return textX;
    }

    public int getTextY() {
        return textY;
    }

    public boolean isPlayingRound() {
        return isRoundVideo && isPlayingRound;
    }

    public int getParentWidth() {
        MessageObject object = currentMessageObject == null ? messageObjectToSet : currentMessageObject;
        if (object != null && object.preview && parentWidth > 0) {
            return parentWidth;
        }
        return AndroidUtilities.displaySize.x;
    }

    public class TransitionParams {

        public float lastDrawingImageX, lastDrawingImageY, lastDrawingImageW, lastDrawingImageH;
        public float lastDrawingCaptionX, lastDrawingCaptionY;
        public boolean animateChange;
        public int animateFromRepliesTextWidth;
        public boolean messageEntering;
        public boolean animateLocationIsExpired;
        public boolean lastLocatinIsExpired;
        public String lastDrawLocationExpireText;
        public float lastDrawLocationExpireProgress;
        public StaticLayout lastDrawDocTitleLayout;
        public StaticLayout lastDrawInfoLayout;
        public boolean updatePhotoImageX;
        public boolean animateRoundVideoDotY;
        public float lastDrawRoundVideoDotY;
        public float animateFromRoundVideoDotY;
        public boolean animateReplyY;
        public float lastDrawReplyY;
        public float animateFromReplyY;

        private boolean lastIsPinned;
        private boolean animatePinned;
        public float lastTimeXPinned;
        public float animateFromTimeXPinned;

        private int lastRepliesCount;
        private boolean animateReplies;
        private StaticLayout lastRepliesLayout;
        private StaticLayout animateRepliesLayout;
        private float animateFromTimeXReplies;
        private float lastTimeXReplies;

        private float animateFromTimeXViews;
        private float lastTimeXViews;

        private int lastCommentsCount;
        private int lastTotalCommentWidth;
        private int lastCommentArrowX;
        private int lastCommentUnreadX;
        private boolean lastCommentDrawUnread;
        private float lastCommentX;
        private boolean lastDrawCommentNumber;
        private StaticLayout lastCommentLayout;
        private boolean animateComments;
        private StaticLayout animateCommentsLayout;
        private float animateCommentX;
        private int animateTotalCommentWidth;
        private int animateCommentArrowX;
        private int animateCommentUnreadX;
        private boolean animateCommentDrawUnread;
        private boolean animateDrawCommentNumber;

        private boolean animateSign;
        private float animateNameX;
        private String lastSignMessage;

        public boolean imageChangeBoundsTransition;
        public float deltaLeft;
        public float deltaRight;
        public float deltaBottom;
        public float deltaTop;

        // in animation, describe to what values deltaLeft and deltaRight moves to
        public float toDeltaLeft, toDeltaRight;

        public float animateToImageX, animateToImageY, animateToImageW, animateToImageH;
        public float captionFromX, captionFromY;
        private boolean moveCaption;

        public int[] imageRoundRadius = new int[4];
        public float captionEnterProgress = 1f;

        public boolean wasDraw;
        public boolean animateBackgroundBoundsInner;
        public boolean animateBackgroundWidth;
        public boolean ignoreAlpha;
        public boolean drawPinnedBottomBackground;
        public float changePinnedBottomProgress = 1f;
        public int[] animateToRadius;
        public boolean animateRadius;
        public boolean transformGroupToSingleMessage;
        public Rect lastDrawingBackgroundRect = new Rect();

        boolean animateMessageText;
        private ArrayList<MessageObject.TextLayoutBlock> animateOutTextBlocks;
        private ArrayList<MessageObject.TextLayoutBlock> lastDrawingTextBlocks;

        private float animateOutTextXOffset;
        private AnimatedEmojiSpan.EmojiGroupedSpans animateOutAnimateEmoji;

        private StaticLayout animateReplyTextLayout;
        private AnimatedEmojiSpan.EmojiGroupedSpans animateOutAnimateEmojiReply;

        private boolean animateEditedEnter;
        private StaticLayout animateEditedLayout;
        private StaticLayout animateTimeLayout;
        private int animateTimeWidth;
        private int lastTimeWidth;
        private int animateEditedWidthDiff;
        private boolean lastDrawingEdited;

        boolean animateReplaceCaptionLayout;
        private StaticLayout animateOutCaptionLayout;
        private StaticLayout lastDrawingCaptionLayout;
        public boolean lastDrawTime;
        public int lastTimeX;
        public int animateFromTimeX;
        public boolean shouldAnimateTimeX;
        public int lastBackgroundLeft, lastBackgroundRight;
        public boolean lastDrawBackground;
        public boolean animateDrawBackground;
        public boolean lastUseTranscribeButton;
        public boolean animateUseTranscribeButton;

        public boolean animateDrawingTimeAlpha;

        public float animateChangeProgress = 1f;
        private ArrayList<BotButton> lastDrawBotButtons = new ArrayList<>();
        private ArrayList<BotButton> transitionBotButtons = new ArrayList<>();

        private float lastButtonX;
        private float lastButtonY;
        private float animateFromButtonX;
        private float animateFromButtonY;
        private boolean animateButton;

        public int lastStatusDrawableParams = -1;

        private int lastViewsCount;
        private StaticLayout lastViewsLayout;
        private StaticLayout animateViewsLayout;

        private boolean lastShouldDrawTimeOnMedia;
        private boolean animateShouldDrawTimeOnMedia;
        private boolean lastShouldDrawMenuDrawable;
        private boolean animateShouldDrawMenuDrawable;
        private StaticLayout lastTimeLayout;
        private boolean lastIsPlayingRound;
        public boolean animatePlayingRound;
        public boolean animateText;

        public float lastDrawingTextY;
        public float lastDrawingTextX;

        public float animateFromTextY;
        public float lastTextXOffset;

        public int lastTopOffset;
        public boolean animateForwardedLayout;
        public int animateForwardedNamesOffset;
        public int lastForwardedNamesOffset;
        public boolean lastDrawnForwardedName;
        public StaticLayout[] lastDrawnForwardedNameLayout = new StaticLayout[2];
        public StaticLayout[] animatingForwardedNameLayout = new StaticLayout[2];
        float animateForwardNameX;
        float lastForwardNameX;
        int animateForwardNameWidth;
        int lastForwardNameWidth;
        boolean animateBotButtonsChanged;
        public StaticLayout lastDrawnReplyTextLayout;

        public int lastReplyTextXOffset;
        public float animateReplyTextOffset;

        public void recordDrawingState() {
            wasDraw = true;
            lastDrawingImageX = photoImage.getImageX();
            lastDrawingImageY = photoImage.getImageY();
            lastDrawingImageW = photoImage.getImageWidth();
            lastDrawingImageH = photoImage.getImageHeight();
            int[] r = photoImage.getRoundRadius();
            System.arraycopy(r, 0, imageRoundRadius, 0, 4);
            if (currentBackgroundDrawable != null) {
                lastDrawingBackgroundRect.set(currentBackgroundDrawable.getBounds());
            }
            lastDrawingTextBlocks = currentMessageObject.textLayoutBlocks;
            lastDrawingEdited = edited;

            lastDrawingCaptionX = captionX;
            lastDrawingCaptionY = captionY;

            lastDrawingCaptionLayout = captionLayout;
            lastDrawBotButtons.clear();
            if (!botButtons.isEmpty()) {
                lastDrawBotButtons.addAll(botButtons);
            }

            if (commentLayout != null) {
                lastCommentsCount = getRepliesCount();
                lastTotalCommentWidth = totalCommentWidth;
                lastCommentLayout = commentLayout;
                lastCommentArrowX = commentArrowX;
                lastCommentUnreadX = commentUnreadX;
                lastCommentDrawUnread = commentDrawUnread;
                lastCommentX = commentX;
                lastDrawCommentNumber = drawCommentNumber;
            }

            lastRepliesCount = getRepliesCount();
            this.lastViewsCount = getMessageObject().messageOwner.views;
            lastRepliesLayout = repliesLayout;
            lastViewsLayout = viewsLayout;

            lastIsPinned = isPinned;

            lastSignMessage = lastPostAuthor;

            lastDrawBackground = drawBackground;
            lastUseTranscribeButton = useTranscribeButton;

            lastButtonX = buttonX;
            lastButtonY = buttonY;

            lastDrawTime = !forceNotDrawTime;
            lastTimeX = timeX;
            lastTimeLayout = timeLayout;
            lastTimeWidth = timeWidth;

            lastShouldDrawTimeOnMedia = shouldDrawTimeOnMedia();
            lastTopOffset = getTopMediaOffset();
            lastShouldDrawMenuDrawable = shouldDrawMenuDrawable();

            lastLocatinIsExpired = locationExpired;
            lastIsPlayingRound = isPlayingRound;

            lastDrawingTextY = textY;
            lastDrawingTextX = textX;

            lastDrawnForwardedNameLayout[0] = forwardedNameLayout[0];
            lastDrawnForwardedNameLayout[1] = forwardedNameLayout[1];
            lastDrawnForwardedName = currentMessageObject.needDrawForwarded();
            lastForwardNameX = forwardNameX;
            lastForwardedNamesOffset = namesOffset;
            lastForwardNameWidth = forwardedNameWidth;
            lastBackgroundLeft = getCurrentBackgroundLeft();
            lastBackgroundRight = currentBackgroundDrawable.getBounds().right;
            lastTextXOffset = currentMessageObject.textXOffset;

            lastDrawnReplyTextLayout = replyTextLayout;
            lastReplyTextXOffset = replyTextOffset;

            reactionsLayoutInBubble.recordDrawingState();
            if (replyNameLayout != null) {
                lastDrawReplyY = replyStartY;
            } else {
                lastDrawReplyY = 0;
            }
        }

        public void recordDrawingStatePreview() {
            lastDrawnForwardedNameLayout[0] = forwardedNameLayout[0];
            lastDrawnForwardedNameLayout[1] = forwardedNameLayout[1];
            lastDrawnForwardedName = currentMessageObject.needDrawForwarded();
            lastForwardNameX = forwardNameX;
            lastForwardedNamesOffset = namesOffset;
            lastForwardNameWidth = forwardedNameWidth;
        }

        public boolean animateChange() {
            if (!wasDraw) {
                return false;
            }
            boolean changed = false;

            animateMessageText = false;
            if (currentMessageObject.textLayoutBlocks != lastDrawingTextBlocks) {
                boolean sameText = true;
                if (currentMessageObject.textLayoutBlocks != null && lastDrawingTextBlocks != null && currentMessageObject.textLayoutBlocks.size() == lastDrawingTextBlocks.size()) {
                    for (int i = 0; i < lastDrawingTextBlocks.size(); i++) {
                        String newText = currentMessageObject.textLayoutBlocks.get(i).textLayout == null ? null : currentMessageObject.textLayoutBlocks.get(i).textLayout.getText().toString();
                        String oldText = lastDrawingTextBlocks.get(i).textLayout == null ? null : lastDrawingTextBlocks.get(i).textLayout.getText().toString();
                        if ((newText == null && oldText != null) || (newText != null && oldText == null) || !newText.equals(oldText)) {
                            sameText = false;
                            break;
                        } else {
                            if (animatedEmojiStack != null) {
                                animatedEmojiStack.replaceLayout(currentMessageObject.textLayoutBlocks.get(i).textLayout, lastDrawingTextBlocks.get(i).textLayout);
                            }
                        }
                    }
                } else {
                    sameText = false;
                }
                if (!sameText) {
                    animateMessageText = true;
                    animateOutTextBlocks = lastDrawingTextBlocks;
                    animateOutTextXOffset = lastTextXOffset;
                    animateOutAnimateEmoji = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animateOutAnimateEmoji, lastDrawingTextBlocks, true);
                    animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, currentMessageObject.textLayoutBlocks);
                    changed = true;
                } else {
                    animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, currentMessageObject.textLayoutBlocks);
                }
            }
            if (replyTextLayout != lastDrawnReplyTextLayout) {
                animateReplyTextLayout = lastDrawnReplyTextLayout;
                animateReplyTextOffset = lastReplyTextXOffset;
                animateOutAnimateEmojiReply = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, false, animateOutAnimateEmojiReply, true, lastDrawnReplyTextLayout);
                changed = true;
            }
            if (edited && !lastDrawingEdited && timeLayout != null) {
                String editedStr = LocaleController.getString("EditedMessage", R.string.EditedMessage);
                CharSequence text = timeLayout.getText();
                int i = text.toString().indexOf(editedStr);
                if (i >= 0) {
                    if (i == 0) {
                        animateEditedLayout = new StaticLayout(editedStr, Theme.chat_timePaint, timeTextWidth + AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
                        spannableStringBuilder.append(editedStr);
                        spannableStringBuilder.append(text.subSequence(editedStr.length(), text.length()));
                        spannableStringBuilder.setSpan(new EmptyStubSpan(), 0, editedStr.length(), 0);
                        animateTimeLayout = new StaticLayout(spannableStringBuilder, Theme.chat_timePaint, timeTextWidth + AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                        animateEditedWidthDiff = timeWidth - lastTimeWidth;
                    } else {
                        animateEditedWidthDiff = 0;
                        animateEditedLayout = null;
                        animateTimeLayout = lastTimeLayout;
                    }
                    animateEditedEnter = true;
                    animateTimeWidth = lastTimeWidth;
                    animateFromTimeX = lastTimeX;
                    shouldAnimateTimeX = true;
                    changed = true;
                }
                accessibilityText = null;
            } else if (!edited && lastDrawingEdited && timeLayout != null) {
                animateTimeLayout = lastTimeLayout;
                animateEditedWidthDiff = timeWidth - lastTimeWidth;
                animateEditedEnter = true;
                animateTimeWidth = lastTimeWidth;
                animateFromTimeX = lastTimeX;
                shouldAnimateTimeX = true;
                changed = true;
            }

            animateDrawBackground = false;
            if (drawBackground != lastDrawBackground) {
                animateDrawBackground = true;
                changed = true;
            }

            animateUseTranscribeButton = false;
            if (useTranscribeButton != lastUseTranscribeButton) {
                animateUseTranscribeButton = true;
                changed = true;
            }

            if (captionLayout != lastDrawingCaptionLayout) {
                String oldCaption = lastDrawingCaptionLayout == null ? null : lastDrawingCaptionLayout.getText().toString();
                String currentCaption = captionLayout == null ? null : captionLayout.getText().toString();
                if ((currentCaption == null) != (oldCaption == null) || (oldCaption != null && !oldCaption.equals(currentCaption))) {
                    animateReplaceCaptionLayout = true;
                    animateOutCaptionLayout = lastDrawingCaptionLayout;
                    animateOutAnimateEmoji = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, null, animateOutCaptionLayout);
                    animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, captionLayout);
                    changed = true;
                } else {
                    updateCaptionLayout();
                    if (lastDrawingCaptionX != captionX || lastDrawingCaptionY != captionY) {
                        moveCaption = true;
                        captionFromX = lastDrawingCaptionX;
                        captionFromY = lastDrawingCaptionY;
                        changed = true;
                    }
                }
            } else if (captionLayout != null && lastDrawingCaptionLayout != null) {
                updateCaptionLayout();
                if (lastDrawingCaptionX != captionX || lastDrawingCaptionY != captionY) {
                    moveCaption = true;
                    captionFromX = lastDrawingCaptionX;
                    captionFromY = lastDrawingCaptionY;
                    changed = true;
                }
            }
            if (!lastDrawBotButtons.isEmpty() || !botButtons.isEmpty()) {
                if (lastDrawBotButtons.size() != botButtons.size()) {
                    animateBotButtonsChanged = true;
                }
                if (!animateBotButtonsChanged) {
                    for (int i = 0; i < botButtons.size(); i++) {
                        BotButton button1 = botButtons.get(i);
                        BotButton button2 = lastDrawBotButtons.get(i);
                        if (button1.x != button2.x || button1.width != button2.width || button1.title != button2.title) {
                            animateBotButtonsChanged = true;
                            break;
                        }
                    }
                }
                if (animateBotButtonsChanged) {
                    transitionBotButtons.addAll(lastDrawBotButtons);
                }
            }

            if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
                if (buttonX != lastButtonX || buttonY != lastButtonY) {
                    animateFromButtonX = lastButtonX;
                    animateFromButtonY = lastButtonY;
                    animateButton = true;
                    changed = true;
                }
            }

            boolean timeDrawablesIsChanged = false;

            if (lastIsPinned != isPinned) {
                animatePinned = true;
                changed = true;
                timeDrawablesIsChanged = true;
                accessibilityText = null;
            }

            if ((lastRepliesLayout != null || repliesLayout != null) && lastRepliesCount != getRepliesCount()) {
                animateRepliesLayout = lastRepliesLayout;
                animateReplies = true;
                changed = true;
                timeDrawablesIsChanged = true;
                accessibilityText = null;
            }

            if (lastViewsLayout != null && this.lastViewsCount != getMessageObject().messageOwner.views) {
                animateViewsLayout = lastViewsLayout;
                changed = true;
                timeDrawablesIsChanged = true;
                accessibilityText = null;
            }

            if (commentLayout != null && lastCommentsCount != getRepliesCount()) {
                if (lastCommentLayout != null && !TextUtils.equals(lastCommentLayout.getText(), commentLayout.getText())) {
                    animateCommentsLayout = lastCommentLayout;
                } else {
                    animateCommentsLayout = null;
                }
                animateTotalCommentWidth = lastTotalCommentWidth;
                animateCommentX = lastCommentX;
                animateCommentArrowX = lastCommentArrowX;
                animateCommentUnreadX = lastCommentUnreadX;
                animateCommentDrawUnread = lastCommentDrawUnread;
                animateDrawCommentNumber = lastDrawCommentNumber;
                animateComments = true;
                changed = true;
            }

            if (!TextUtils.equals(lastSignMessage, lastPostAuthor)) {
                animateSign = true;
                animateNameX = nameX;
                changed = true;
            }

            if (lastDrawTime == forceNotDrawTime) {
                animateDrawingTimeAlpha = true;
                animateViewsLayout = null;
                changed = true;
            } else if (lastShouldDrawTimeOnMedia != shouldDrawTimeOnMedia()) {
                animateEditedEnter = false;
                animateShouldDrawTimeOnMedia = true;
                animateFromTimeX = lastTimeX;
                animateTimeLayout = lastTimeLayout;
                animateTimeWidth = lastTimeWidth;
                changed = true;
            } else if (timeDrawablesIsChanged || Math.abs(timeX - lastTimeX) > 1) {
                shouldAnimateTimeX = true;
                animateTimeWidth = lastTimeWidth;
                animateFromTimeX = lastTimeX;
                animateFromTimeXViews = lastTimeXViews;
                animateFromTimeXReplies = lastTimeXReplies;
                animateFromTimeXPinned = lastTimeXPinned;
            }

            if (lastShouldDrawMenuDrawable != shouldDrawMenuDrawable()) {
                animateShouldDrawMenuDrawable = true;
            }

            if (lastLocatinIsExpired != locationExpired) {
                animateLocationIsExpired = true;
            }

            if (lastIsPlayingRound != isPlayingRound) {
                animatePlayingRound = true;
                changed = true;
            }

            if (lastDrawingTextY != textY) {
                animateText = true;
                animateFromTextY = lastDrawingTextY;
                changed = true;
            }

            if (currentMessageObject != null) {
                if (lastDrawnForwardedName != currentMessageObject.needDrawForwarded()) {
                    animateForwardedLayout = true;
                    animatingForwardedNameLayout[0] = lastDrawnForwardedNameLayout[0];
                    animatingForwardedNameLayout[1] = lastDrawnForwardedNameLayout[1];
                    animateForwardNameX = lastForwardNameX;
                    animateForwardedNamesOffset = lastForwardedNamesOffset;
                    animateForwardNameWidth = lastForwardNameWidth;
                    changed = true;
                }
            }
            updateReactionLayoutPosition();
            if (reactionsLayoutInBubble.animateChange()) {
                changed = true;
            }
            if (currentMessageObject.isRoundVideo()) {
                float y1 = layoutHeight - AndroidUtilities.dp(28 - (drawPinnedBottom ? 2 : 0));
                if (!reactionsLayoutInBubble.isEmpty) {
                    y1 -= reactionsLayoutInBubble.totalHeight;
                }
                if (y1 != lastDrawRoundVideoDotY) {
                    animateRoundVideoDotY = true;
                    animateFromRoundVideoDotY = lastDrawRoundVideoDotY;
                    changed = true;
                }
            }

            if (replyNameLayout != null && replyStartX != lastDrawReplyY && lastDrawReplyY != 0) {
                animateReplyY = true;
                animateFromReplyY = lastDrawReplyY;
                changed = true;
            }

            return changed;
        }

        public void onDetach() {
            wasDraw = false;
        }

        public void resetAnimation() {
            animateChange = false;
            animatePinned = false;
            animateBackgroundBoundsInner = false;
            animateBackgroundWidth = false;
            deltaLeft = 0;
            deltaRight = 0;
            deltaBottom = 0;
            deltaTop = 0;
            toDeltaLeft = 0;
            toDeltaRight = 0;
            if (imageChangeBoundsTransition && animateToImageW != 0 && animateToImageH != 0) {
                photoImage.setImageCoords(animateToImageX, animateToImageY, animateToImageW, animateToImageH);
            }
            if (animateRadius) {
                photoImage.setRoundRadius(animateToRadius);
            }
            animateToImageX = 0;
            animateToImageY = 0;
            animateToImageW = 0;
            animateToImageH = 0;
            imageChangeBoundsTransition = false;
            changePinnedBottomProgress = 1f;
            captionEnterProgress = 1f;
            animateRadius = false;
            animateChangeProgress = 1f;
            animateMessageText = false;
            animateOutTextBlocks = null;
            animateEditedLayout = null;
            animateTimeLayout = null;
            animateEditedEnter = false;
            animateReplaceCaptionLayout = false;
            transformGroupToSingleMessage = false;
            animateOutCaptionLayout = null;
            AnimatedEmojiSpan.release(ChatMessageCell.this, animateOutAnimateEmoji);
            animateOutAnimateEmoji = null;
            moveCaption = false;
            animateDrawingTimeAlpha = false;
            transitionBotButtons.clear();
            animateButton = false;

            animateReplies = false;
            animateRepliesLayout = null;

            animateComments = false;
            animateCommentsLayout = null;
            animateViewsLayout = null;
            animateShouldDrawTimeOnMedia = false;
            animateShouldDrawMenuDrawable = false;
            shouldAnimateTimeX = false;
            animateDrawBackground = false;
            animateSign = false;
            animateDrawingTimeAlpha = false;
            animateLocationIsExpired = false;
            animatePlayingRound = false;
            animateText = false;
            animateForwardedLayout = false;
            animatingForwardedNameLayout[0] = null;
            animatingForwardedNameLayout[1] = null;
            animateRoundVideoDotY = false;
            animateReplyY = false;
            reactionsLayoutInBubble.resetAnimation();
        }

        public boolean supportChangeAnimation() {
            return true;
        }

        public int createStatusDrawableParams() {
            if (currentMessageObject.isOutOwner()) {
                boolean drawCheck1 = false;
                boolean drawCheck2 = false;
                boolean drawClock = false;
                boolean drawError = false;

                if (currentMessageObject.isSending() || currentMessageObject.isEditing()) {
                    drawCheck2 = false;
                    drawClock = true;
                    drawError = false;
                } else if (currentMessageObject.isSendError()) {
                    drawCheck2 = false;
                    drawClock = false;
                    drawError = true;
                } else if (currentMessageObject.isSent()) {
                    if (!currentMessageObject.scheduled && !currentMessageObject.isUnread()) {
                        drawCheck1 = true;
                    } else {
                        drawCheck1 = false;
                    }
                    drawCheck2 = true;
                    drawClock = false;
                    drawError = false;
                }
                return (drawCheck1 ? 1 : 0) | (drawCheck2 ? 2 : 0) | (drawClock ? 4 : 0) | (drawError ? 8 : 0);
            } else {
                boolean drawClock = currentMessageObject.isSending() || currentMessageObject.isEditing();
                boolean drawError = currentMessageObject.isSendError();

                return (drawClock ? 4 : 0) | (drawError ? 8 : 0);
            }
        }
    }

    private int getThemedColor(String key) {
        Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
        return color != null ? color : Theme.getColor(key);
    }

    private Drawable getThemedDrawable(String key) {
        Drawable drawable = resourcesProvider != null ? resourcesProvider.getDrawable(key) : null;
        return drawable != null ? drawable : Theme.getThemeDrawable(key);
    }

    private Paint getThemedPaint(String paintKey) {
        Paint paint = resourcesProvider != null ? resourcesProvider.getPaint(paintKey) : null;
        return paint != null ? paint : Theme.getThemePaint(paintKey);
    }

    private boolean hasGradientService() {
        return resourcesProvider != null ? resourcesProvider.hasGradientService() : Theme.hasGradientService();
    }

}
