package com.kongzue.dialogx.dialogs;

import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Space;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import com.kongzue.dialogx.DialogX;
import com.kongzue.dialogx.R;
import com.kongzue.dialogx.interfaces.BaseDialog;
import com.kongzue.dialogx.interfaces.BaseOnDialogClickCallback;
import com.kongzue.dialogx.interfaces.BlurViewType;
import com.kongzue.dialogx.interfaces.DialogConvertViewInterface;
import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
import com.kongzue.dialogx.interfaces.DialogXAnimInterface;
import com.kongzue.dialogx.interfaces.DialogXRunnable;
import com.kongzue.dialogx.interfaces.DialogXStyle;
import com.kongzue.dialogx.interfaces.OnBackPressedListener;
import com.kongzue.dialogx.interfaces.OnBackgroundMaskClickListener;
import com.kongzue.dialogx.interfaces.OnBindView;
import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialogx.interfaces.OnInputDialogButtonClickListener;
import com.kongzue.dialogx.interfaces.OnMenuButtonClickListener;
import com.kongzue.dialogx.interfaces.ScrollController;
import com.kongzue.dialogx.util.InputInfo;
import com.kongzue.dialogx.util.TextInfo;
import com.kongzue.dialogx.util.views.DialogScrollView;
import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
import com.kongzue.dialogx.util.views.MaxRelativeLayout;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;

/**
 * @author: Kongzue
 * @github: https://github.com/kongzue/
 * @homepage: http://kongzue.com/
 * @mail: myzcxhh@live.cn
 * @createTime: 2020/9/21 17:08
 */
public class MessageDialog extends BaseDialog {

    public static int overrideEnterDuration = -1;
    public static int overrideExitDuration = -1;
    public static int overrideEnterAnimRes = 0;
    public static int overrideExitAnimRes = 0;
    public static BOOLEAN overrideCancelable;
    protected boolean bkgInterceptTouch = true;
    protected OnBindView<MessageDialog> onBindView;
    protected MessageDialog me = this;
    protected BOOLEAN privateCancelable;
    protected int customEnterAnimResId;
    protected int customExitAnimResId;
    protected DialogXAnimInterface<MessageDialog> dialogXAnimImpl;
    protected OnBackPressedListener<MessageDialog> onBackPressedListener;
    protected BUTTON_SELECT_RESULT buttonSelectResult = BUTTON_SELECT_RESULT.NONE;

    protected DialogLifecycleCallback<MessageDialog> dialogLifecycleCallback;
    protected OnBackgroundMaskClickListener<MessageDialog> onBackgroundMaskClickListener;

    protected MessageDialog() {
        super();
    }

    protected CharSequence title;
    protected CharSequence message;
    protected CharSequence okText;
    protected CharSequence cancelText;
    protected CharSequence otherText;
    protected String inputText;
    protected String inputHintText;
    protected Integer maskColor = null;
    protected float backgroundRadius = DialogX.defaultMessageDialogBackgroundRadius;
    protected Drawable titleIcon;

    protected TextInfo titleTextInfo;
    protected TextInfo messageTextInfo;
    protected TextInfo okTextInfo;
    protected TextInfo cancelTextInfo;
    protected TextInfo otherTextInfo;
    protected InputInfo inputInfo;

    protected BaseOnDialogClickCallback okButtonClickListener;
    protected BaseOnDialogClickCallback cancelButtonClickListener;
    protected BaseOnDialogClickCallback otherButtonClickListener;

    protected int buttonOrientation;

    public static MessageDialog build() {
        return new MessageDialog();
    }

    public static MessageDialog build(DialogXStyle style) {
        return new MessageDialog().setStyle(style);
    }

    public static MessageDialog build(OnBindView<MessageDialog> onBindView) {
        return new MessageDialog().setCustomView(onBindView);
    }

    public MessageDialog(CharSequence message) {
        this.message = message;
    }

    public MessageDialog(CharSequence title, CharSequence message) {
        this.title = title;
        this.message = message;
    }

    public MessageDialog(CharSequence title, CharSequence message, CharSequence okText) {
        this.title = title;
        this.message = message;
        this.okText = okText;
    }

    public MessageDialog(int titleResId, int messageResId, int okTextResId) {
        this.title = getString(titleResId);
        this.message = getString(messageResId);
        this.okText = getString(okTextResId);
    }

    public MessageDialog(int titleResId, int messageResId) {
        this.title = getString(titleResId);
        this.message = getString(messageResId);
    }

    public static MessageDialog show(CharSequence title, CharSequence message, CharSequence okText) {
        MessageDialog messageDialog = new MessageDialog(title, message, okText);
        messageDialog.show();
        return messageDialog;
    }

    public static MessageDialog show(int titleResId, int messageResId, int okTextResId) {
        MessageDialog messageDialog = new MessageDialog(titleResId, messageResId, okTextResId);
        messageDialog.show();
        return messageDialog;
    }

    public static MessageDialog show(CharSequence title, CharSequence message) {
        MessageDialog messageDialog = new MessageDialog(title, message);
        messageDialog.show();
        return messageDialog;
    }

    public static MessageDialog show(int titleResId, int messageResId) {
        MessageDialog messageDialog = new MessageDialog(titleResId, messageResId);
        messageDialog.show();
        return messageDialog;
    }

    public MessageDialog(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText) {
        this.title = title;
        this.message = message;
        this.okText = okText;
        this.cancelText = cancelText;
    }

    public MessageDialog(int titleResId, int messageResId, int okTextResId, int cancelTextResId) {
        this.title = getString(titleResId);
        this.message = getString(messageResId);
        this.okText = getString(okTextResId);
        this.cancelText = getString(cancelTextResId);
    }

    public static MessageDialog show(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText) {
        MessageDialog messageDialog = new MessageDialog(title, message, okText, cancelText);
        messageDialog.show();
        return messageDialog;
    }

    public static MessageDialog show(int titleResId, int messageResId, int okTextResId, int cancelTextResId) {
        MessageDialog messageDialog = new MessageDialog(titleResId, messageResId, okTextResId, cancelTextResId);
        messageDialog.show();
        return messageDialog;
    }

    public MessageDialog(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, CharSequence otherText) {
        this.title = title;
        this.message = message;
        this.okText = okText;
        this.cancelText = cancelText;
        this.otherText = otherText;
    }

    public MessageDialog(int titleResId, int messageResId, int okTextResId, int cancelTextResId, int otherTextResId) {
        this.title = getString(titleResId);
        this.message = getString(messageResId);
        this.okText = getString(okTextResId);
        this.cancelText = getString(cancelTextResId);
        this.otherText = getString(otherTextResId);
    }

    public static MessageDialog show(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, CharSequence otherText) {
        MessageDialog messageDialog = new MessageDialog(title, message, okText, cancelText, otherText);
        messageDialog.show();
        return messageDialog;
    }

    public static MessageDialog show(int titleResId, int messageResId, int okTextResId, int cancelTextResId, int otherTextResId) {
        MessageDialog messageDialog = new MessageDialog(titleResId, messageResId, okTextResId, cancelTextResId, otherTextResId);
        messageDialog.show();
        return messageDialog;
    }

    protected DialogImpl dialogImpl;

    public MessageDialog show() {
        if (isHide && getDialogView() != null && isShow) {
            if (hideWithExitAnim && getDialogImpl() != null) {
                getDialogView().setVisibility(View.VISIBLE);
                getDialogImpl().getDialogXAnimImpl().doShowAnim(me, getDialogImpl().bkg);
            } else {
                getDialogView().setVisibility(View.VISIBLE);
            }
            return this;
        }
        super.beforeShow();
        if (getDialogView() == null) {
            int layoutId = getCustomDialogLayoutResId(isLightTheme()) != 0 ? getCustomDialogLayoutResId(isLightTheme()) : style.layout(isLightTheme());
            layoutId = layoutId == 0 ? (isLightTheme() ? R.layout.layout_dialogx_material : R.layout.layout_dialogx_material_dark) : layoutId;

            View dialogView = createView(layoutId);
            dialogImpl = new DialogImpl(dialogView);
            if (dialogView != null) dialogView.setTag(me);
            show(dialogView);
        } else {
            show(getDialogView());
        }
        return this;
    }

    public void show(Activity activity) {
        super.beforeShow();
        if (getDialogView() == null) {
            int layoutId = getCustomDialogLayoutResId(isLightTheme()) != 0 ? getCustomDialogLayoutResId(isLightTheme()) : style.layout(isLightTheme());
            layoutId = layoutId == 0 ? (isLightTheme() ? R.layout.layout_dialogx_material : R.layout.layout_dialogx_material_dark) : layoutId;

            View dialogView = createView(layoutId);
            dialogImpl = new DialogImpl(dialogView);
            if (dialogView != null) dialogView.setTag(me);
            show(activity, dialogView);
        } else {
            show(activity, getDialogView());
        }
    }

    public void refreshUI() {
        if (getDialogImpl() == null) return;
        runOnMain(new Runnable() {
            @Override
            public void run() {
                if (dialogImpl != null) dialogImpl.refreshView();
            }
        });
    }

    public class DialogImpl implements DialogConvertViewInterface {

        private List<View> blurViews;

        public DialogXBaseRelativeLayout boxRoot;
        public MaxRelativeLayout bkg;
        public TextView txtDialogTitle;
        public ScrollController scrollView;
        public TextView txtDialogTip;
        public ViewGroup boxList;
        public RelativeLayout boxCustom;
        public EditText txtInput;
        public LinearLayout boxButton;
        public TextView btnSelectOther;
        public View spaceOtherButton;
        public View splitHorizontal;
        public TextView btnSelectNegative;
        public TextView btnSelectPositive;

        public DialogImpl(View convertView) {
            if (convertView == null) return;
            setDialogView(convertView);
            boxRoot = convertView.findViewById(R.id.box_root);
            bkg = convertView.findViewById(R.id.bkg);
            txtDialogTitle = convertView.findViewById(R.id.txt_dialog_title);
            scrollView = convertView.findViewById(R.id.scrollView);
            txtDialogTip = convertView.findViewById(R.id.txt_dialog_tip);
            boxList = convertView.findViewById(R.id.box_list);
            boxCustom = convertView.findViewById(R.id.box_custom);
            txtInput = convertView.findViewById(R.id.txt_input);
            boxButton = convertView.findViewById(R.id.box_button);
            btnSelectOther = convertView.findViewById(R.id.btn_selectOther);
            spaceOtherButton = convertView.findViewById(R.id.space_other_button);
            splitHorizontal = convertView.findViewWithTag("split");
            btnSelectNegative = convertView.findViewById(R.id.btn_selectNegative);
            btnSelectPositive = convertView.findViewById(R.id.btn_selectPositive);

            blurViews = findAllBlurView(convertView);

            init();

            dialogImpl = this;
            refreshView();
        }

        public void init() {
            buttonSelectResult = BUTTON_SELECT_RESULT.NONE;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                getDialogView().setTranslationZ(getThisOrderIndex());
            }

            if (titleTextInfo == null) titleTextInfo = DialogX.titleTextInfo;
            if (messageTextInfo == null) messageTextInfo = DialogX.messageTextInfo;
            if (okTextInfo == null) okTextInfo = DialogX.okButtonTextInfo;
            if (okTextInfo == null) okTextInfo = DialogX.buttonTextInfo;
            if (cancelTextInfo == null) cancelTextInfo = DialogX.buttonTextInfo;
            if (otherTextInfo == null) otherTextInfo = DialogX.buttonTextInfo;
            if (inputInfo == null) inputInfo = DialogX.inputInfo;
            if (backgroundColor == null) backgroundColor = DialogX.backgroundColor;

            txtDialogTitle.getPaint().setFakeBoldText(true);
            btnSelectNegative.getPaint().setFakeBoldText(true);
            btnSelectPositive.getPaint().setFakeBoldText(true);
            btnSelectOther.getPaint().setFakeBoldText(true);

            txtDialogTip.setMovementMethod(LinkMovementMethod.getInstance());

            boxRoot.setBkgAlpha(0f);
            boxRoot.setParentDialog(me);
            boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() {
                @Override
                public void onShow() {
                    isShow = true;
                    preShow = false;

                    setLifecycleState(Lifecycle.State.CREATED);

                    onDialogShow();
                    getDialogLifecycleCallback().onShow(me);
                    MessageDialog.this.onShow(me);

                    getDialogXAnimImpl().doShowAnim(me, bkg);

                    if (style.messageDialogBlurSettings() != null && style.messageDialogBlurSettings().blurBackground()) {
                        bkg.post(new Runnable() {
                            @Override
                            public void run() {
                                Integer blurFrontColor = null;
                                Float dialogXRadius = null;
                                if (style.messageDialogBlurSettings() != null) {
                                    blurFrontColor = getColorNullable(getIntStyleAttr(style.messageDialogBlurSettings().blurForwardColorRes(isLightTheme())));
                                    dialogXRadius = getFloatStyleAttr((float) style.messageDialogBlurSettings().blurBackgroundRoundRadiusPx());
                                }

                                if (blurViews != null) {
                                    for (View blurView : blurViews) {
                                        ((BlurViewType) blurView).setOverlayColor(backgroundColor == null ? blurFrontColor : backgroundColor);
                                        ((BlurViewType) blurView).setRadiusPx(dialogXRadius);
                                    }
                                }

                                setLifecycleState(Lifecycle.State.RESUMED);
                            }
                        });
                    }

                    if (autoShowInputKeyboard) {
                        txtInput.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                if (txtInput == null) return;
                                txtInput.requestFocus();
                                txtInput.setFocusableInTouchMode(true);
                                imeShow(txtInput, true);
                                txtInput.setSelection(txtInput.getText().length());
                                if (inputInfo != null && inputInfo.isSelectAllText()) {
                                    txtInput.selectAll();
                                }
                            }
                        }, 300);
                    } else {
                        if (inputInfo != null && inputInfo.isSelectAllText()) {
                            txtInput.clearFocus();
                            txtInput.requestFocus();
                            txtInput.selectAll();
                        }
                    }
                }

                @Override
                public void onDismiss() {
                    isShow = false;
                    getDialogLifecycleCallback().onDismiss(me);
                    MessageDialog.this.onDismiss(me);
                    setLifecycleState(Lifecycle.State.DESTROYED);
                    dialogLifecycleCallback = null;

                    BaseDialog.gc();
                }
            });

            boxRoot.setOnBackPressedListener(new DialogXBaseRelativeLayout.PrivateBackPressedListener() {
                @Override
                public boolean onBackPressed() {
                    if (onBackPressedListener != null) {
                        if (onBackPressedListener.onBackPressed(me)) {
                            dismiss();
                        }
                    } else {
                        if (isCancelable()) {
                            dismiss();
                        }
                    }
                    return true;
                }
            });
            btnSelectPositive.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    buttonSelectResult = BUTTON_SELECT_RESULT.BUTTON_OK;
                    if (txtInput != null) {
                        imeShow(txtInput, false);
                    }
                    haptic(v);
                    if (okButtonClickListener != null) {
                        if (okButtonClickListener instanceof OnInputDialogButtonClickListener) {
                            String s = txtInput == null ? "" : txtInput.getText().toString();
                            if (!((OnInputDialogButtonClickListener) okButtonClickListener).onClick(me, v, s)) {
                                doDismiss(v);
                            }
                        } else if (okButtonClickListener instanceof OnDialogButtonClickListener) {
                            if (!((OnDialogButtonClickListener) okButtonClickListener).onClick(me, v)) {
                                doDismiss(v);
                            }
                        } else if (okButtonClickListener instanceof OnMenuButtonClickListener) {
                            if (!((OnMenuButtonClickListener) okButtonClickListener).onClick(me, v)) {
                                doDismiss(v);
                            }
                        }
                    } else {
                        doDismiss(v);
                    }
                }
            });
            btnSelectNegative.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    buttonSelectResult = BUTTON_SELECT_RESULT.BUTTON_CANCEL;
                    if (txtInput != null) {
                        imeShow(txtInput, false);
                    }
                    haptic(v);
                    if (cancelButtonClickListener != null) {
                        if (cancelButtonClickListener instanceof OnInputDialogButtonClickListener) {
                            String s = txtInput == null ? "" : txtInput.getText().toString();
                            if (!((OnInputDialogButtonClickListener) cancelButtonClickListener).onClick(me, v, s)) {
                                doDismiss(v);
                            }
                        } else if (cancelButtonClickListener instanceof OnMenuButtonClickListener) {
                            if (!((OnMenuButtonClickListener) cancelButtonClickListener).onClick(me, v)) {
                                doDismiss(v);
                            }
                        } else {
                            if (!((OnDialogButtonClickListener) cancelButtonClickListener).onClick(me, v)) {
                                doDismiss(v);
                            }
                        }
                    } else {
                        doDismiss(v);
                    }
                }
            });
            btnSelectOther.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    buttonSelectResult = BUTTON_SELECT_RESULT.BUTTON_OTHER;
                    if (txtInput != null) {
                        imeShow(txtInput, false);
                    }
                    haptic(v);
                    if (otherButtonClickListener != null) {
                        if (otherButtonClickListener instanceof OnInputDialogButtonClickListener) {
                            String s = txtInput == null ? "" : txtInput.getText().toString();
                            if (!((OnInputDialogButtonClickListener) otherButtonClickListener).onClick(me, v, s)) {
                                doDismiss(v);
                            }
                        } else if (otherButtonClickListener instanceof OnMenuButtonClickListener) {
                            if (!((OnMenuButtonClickListener) otherButtonClickListener).onClick(me, v)) {
                                doDismiss(v);
                            }
                        } else {
                            if (!((OnDialogButtonClickListener) otherButtonClickListener).onClick(me, v)) {
                                doDismiss(v);
                            }
                        }
                    } else {
                        doDismiss(v);
                    }
                }
            });

            onDialogInit();
        }

        public void refreshView() {
            if (boxRoot == null || getOwnActivity() == null) {
                return;
            }

            boxRoot.setAutoUnsafePlacePadding(isEnableImmersiveMode());
            // 修改下划线颜色
            if (inputInfo != null && inputInfo.getBottomLineColor() != null) {
                txtInput.getBackground().mutate().setColorFilter(inputInfo.getBottomLineColor(), PorterDuff.Mode.SRC_ATOP);
            }
            // 修改光标颜色
            if (inputInfo != null && inputInfo.getCursorColor() != null) {
                int cursorColor = inputInfo.getCursorColor();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    if (txtInput.getTextCursorDrawable() != null) {
                        txtInput.getTextCursorDrawable().mutate().setColorFilter((new PorterDuffColorFilter(cursorColor, PorterDuff.Mode.SRC_ATOP)));
                    } else {
                        try {
                            @SuppressLint("SoonBlockedPrivateApi") Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
                            field.setAccessible(true);
                            field.set(txtInput, R.drawable.rect_dialogx_defalut_edittxt_cursor);
                            txtInput.getTextCursorDrawable().mutate().setColorFilter((new PorterDuffColorFilter(cursorColor, PorterDuff.Mode.SRC_ATOP)));
                        } catch (Throwable throwable) {
                            log("DialogX: 在对话框" + dialogKey() + "中设置光标颜色时发生错误！");
                            if (DialogX.DEBUGMODE) {
                                throwable.printStackTrace();
                            }
                        }
                    }
                } else {
                    // Thanks for @Jared Rummler https://stackoverflow.com/questions/11554078/set-textcursordrawable-programmatically/57555148#57555148
                    try {
                        Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
                        fCursorDrawableRes.setAccessible(true);
                        int mCursorDrawableRes = fCursorDrawableRes.getInt(txtInput);
                        Field fEditor = TextView.class.getDeclaredField("mEditor");
                        fEditor.setAccessible(true);
                        Object editor = fEditor.get(txtInput);
                        Class<?> clazz = editor.getClass();
                        Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
                        fCursorDrawable.setAccessible(true);
                        Drawable[] drawables = new Drawable[2];
                        drawables[0] = txtInput.getContext().getResources().getDrawable(mCursorDrawableRes);
                        drawables[1] = txtInput.getContext().getResources().getDrawable(mCursorDrawableRes);
                        drawables[0].setColorFilter(cursorColor, PorterDuff.Mode.SRC_IN);
                        drawables[1].setColorFilter(cursorColor, PorterDuff.Mode.SRC_IN);
                        fCursorDrawable.set(editor, drawables);
                    } catch (Throwable throwable) {
                        log("DialogX: 在对话框" + dialogKey() + "中设置光标颜色时发生错误！");
                        if (DialogX.DEBUGMODE) {
                            throwable.printStackTrace();
                        }
                    }
                }
            }

            boxRoot.setRootPadding(screenPaddings[0], screenPaddings[1], screenPaddings[2], screenPaddings[3]);
            if (backgroundColor != null) {
                tintColor(bkg, backgroundColor);
                if (style.tintButtonBackground()) {
                    tintColor(btnSelectOther, backgroundColor);
                    tintColor(btnSelectNegative, backgroundColor);
                    tintColor(btnSelectPositive, backgroundColor);
                }

                if (blurViews != null) {
                    log("#blurViews != null");
                    for (View blurView : blurViews) {
                        log("#blurView: " + blurView);
                        ((BlurViewType) blurView).setOverlayColor(backgroundColor);
                    }
                }
            }

            bkg.setMaxWidth(getMaxWidth());
            bkg.setMaxHeight(getMaxHeight());
            bkg.setMinimumWidth(getMinWidth());
            bkg.setMinimumHeight(getMinHeight());

            View inputBoxView = boxRoot.findViewWithTag("dialogx_editbox");
            if (me instanceof InputDialog) {
                if (inputBoxView != null) {
                    inputBoxView.setVisibility(View.VISIBLE);
                }
                txtInput.setVisibility(View.VISIBLE);
                boxRoot.bindFocusView(txtInput);
            } else {
                if (inputBoxView != null) {
                    inputBoxView.setVisibility(View.GONE);
                }
                txtInput.setVisibility(View.GONE);
            }
            boxRoot.setClickable(true);
            if (maskColor != null) {
                boxRoot.setBackgroundColor(maskColor);
            }
            if (backgroundRadius > -1) {
                // GradientDrawable gradientDrawable = (GradientDrawable) bkg.getBackground();
                // if (gradientDrawable != null) gradientDrawable.setCornerRadius(backgroundRadius);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    bkg.setOutlineProvider(new ViewOutlineProvider() {
                        @Override
                        public void getOutline(View view, Outline outline) {
                            outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), backgroundRadius);
                        }
                    });
                    bkg.setClipToOutline(true);
                }

                if (blurViews != null) {
                    for (View blurView : blurViews) {
                        ((BlurViewType) blurView).setRadiusPx(backgroundRadius);
                    }
                }
            }

            showText(txtDialogTitle, title == null ? DialogX.defaultMessageDialogTitleText : title);
            showText(txtDialogTip, message);
            showText(btnSelectPositive, okText);
            showText(btnSelectNegative, cancelText);
            showText(btnSelectOther, otherText);

            txtInput.setText(inputText);
            txtInput.setHint(inputHintText);
            if (spaceOtherButton != null) {
                if (otherText == null) {
                    spaceOtherButton.setVisibility(View.GONE);
                } else {
                    spaceOtherButton.setVisibility(View.VISIBLE);
                }
            }

            useTextInfo(txtDialogTitle, titleTextInfo);
            useTextInfo(txtDialogTip, messageTextInfo);
            useTextInfo(btnSelectPositive, okTextInfo);
            useTextInfo(btnSelectNegative, cancelTextInfo);
            useTextInfo(btnSelectOther, otherTextInfo);

            if (boxButton != null) {
                boxButton.setVisibility((btnSelectNegative != null && btnSelectNegative.getVisibility() == View.VISIBLE) ||
                        (btnSelectOther != null && btnSelectOther.getVisibility() == View.VISIBLE) ||
                        (btnSelectPositive != null && btnSelectPositive.getVisibility() == View.VISIBLE) ?
                        View.VISIBLE : View.GONE);
            }
            if (titleIcon != null) {
                int size = (int) txtDialogTitle.getTextSize();
                titleIcon.setBounds(0, 0, size, size);
                txtDialogTitle.setCompoundDrawablePadding(dip2px(10));
                txtDialogTitle.setCompoundDrawables(titleIcon, null, null, null);
            }

            if (inputInfo != null) {
                int inputType = inputInfo.getInputType();
                if (inputInfo.getMAX_LENGTH() != -1) {
                    int inputClass = inputType & InputType.TYPE_MASK_CLASS;
                    if (inputClass != InputType.TYPE_CLASS_TEXT &&
                            inputClass != InputType.TYPE_CLASS_NUMBER &&
                            inputClass != InputType.TYPE_CLASS_PHONE &&
                            inputClass != InputType.TYPE_CLASS_DATETIME) {
                        inputType = (inputType & ~InputType.TYPE_MASK_CLASS) | InputType.TYPE_CLASS_TEXT;
                    }
                    txtInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(inputInfo.getMAX_LENGTH())});
                }
                if (inputInfo.isMultipleLines()) {
                    inputType = inputType | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
                }
                txtInput.setInputType(inputType);
                if (inputInfo.getTextInfo() != null) {
                    useTextInfo(txtInput, inputInfo.getTextInfo());
                }
                if (inputInfo.getInputFilters() != null && inputInfo.getInputFilters().length > 0) {
                    txtInput.setFilters(inputInfo.getInputFilters());
                }
            }

            int visibleButtonCount = 0;
            if (!isNull(okText)) {
                visibleButtonCount = visibleButtonCount + 1;
            }
            if (!isNull(cancelText)) {
                visibleButtonCount = visibleButtonCount + 1;
            }
            if (!isNull(otherText)) {
                visibleButtonCount = visibleButtonCount + 1;
            }

            if (splitHorizontal != null) {
                splitHorizontal.setBackgroundColor(getColor(style.splitColorRes(isLightTheme())));
            }

            boxButton.setOrientation(buttonOrientation);
            if (buttonOrientation == LinearLayout.VERTICAL) {
