/FileExtraction/Java_unseen/InsightIM_Tok-Android/app/src/main/java/com/client/tok/ui/chat2/BoardManager.java
package com.client.tok.ui.chat2;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.client.tok.utils.LogUtil;
import com.client.tok.utils.SystemUtils;
import com.client.tok.widget.KeyboardRecordSwitchView;
import com.client.tok.widget.RecorderBtn;

/**
 * board manager:layout on the chat bottom,such as:send msg,file selector,recorder; totally 7
 * 1.button, open layout: file selector(album,camera,file)
 * 2.button, toggle record and keyboard
 * 3.EditText,input message
 * 4.recorder button
 * 5.send button
 * 6.layout include(album,camera,file)
 * 7.keyboard
 */

public class BoardManager implements KeyboardRecordSwitchView.SwitchListener {
    private String TAG = "ChatKeyboard";
    private static final String SHARE_PREFERENCE_NAME = "EmotionKeyboard";
    private static final String SHARE_PREFERENCE_SOFT_INPUT_HEIGHT = "SoftInputHeight";

    private Activity mActivity;
    private SharedPreferences mShareP;

    private View mContentView;
    private KeyboardRecordSwitchView mInputRecordBtSw;
    private View mExtendFileLayout;//file selector layout
    private View mEmotionLayout;
    private EditText mInputEt;
    private RecorderBtn mRecorderView;
    private ImageView mSendIv;

    private BoardManager() {

    }

    public static BoardManager with(Activity activity) {
        BoardManager richMsgKeyboard = new BoardManager();
        richMsgKeyboard.mActivity = activity;
        richMsgKeyboard.mShareP =
            activity.getSharedPreferences(SHARE_PREFERENCE_NAME, Context.MODE_PRIVATE);
        return richMsgKeyboard;
    }

    /**
     * bind view，make the bar's height fixed
     */
    public BoardManager bindToContent(View contentView) {
        mContentView = contentView;
        return this;
    }

    public BoardManager bindToEditText(EditText editText) {
        mInputEt = editText;
        mInputEt.requestFocus();
        mInputEt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    View curShowLayout = null;
                    if (mEmotionLayout != null && mEmotionLayout.isShown()) {
                        curShowLayout = mEmotionLayout;
                    } else if (mExtendFileLayout != null && mExtendFileLayout.isShown()) {
                        curShowLayout = mExtendFileLayout;
                    }
                    if (curShowLayout != null) {
                        BoardManager.this.lockContentHeight();
                        BoardManager.this.hideExtendLayout(curShowLayout, true);
                        mInputEt.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                unlockContentHeightDelayed();
                            }
                        }, 200L);
                    }
                }
                return false;
            }
        });
        return this;
    }

    public BoardManager bindToEmotionBtn(View emotionBtn) {
        emotionBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mEmotionLayout != null && mEmotionLayout.isShown()) {
                    BoardManager.this.lockContentHeight();
                    BoardManager.this.hideExtendLayout(mEmotionLayout, true);
                    BoardManager.this.unlockContentHeightDelayed();
                } else {
                    if (BoardManager.this.isSoftInputShown()) {
                        BoardManager.this.lockContentHeight();
                        BoardManager.this.showExtendLayout(mEmotionLayout);
                        BoardManager.this.unlockContentHeightDelayed();
                    } else {
                        if (mExtendFileLayout.isShown()) {
                            BoardManager.this.hideExtendLayout(mExtendFileLayout, false);
                        }
                        BoardManager.this.showExtendLayout(mEmotionLayout);
                    }
                }
            }
        });
        return this;
    }

    public BoardManager setEmotionLayout(View emotionLayout) {
        this.mEmotionLayout = emotionLayout;
        return this;
    }

    public BoardManager bindToExtendBtn(View addExtendFileBtn) {
        addExtendFileBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mExtendFileLayout != null && mExtendFileLayout.isShown()) {
                    BoardManager.this.lockContentHeight();
                    BoardManager.this.hideExtendLayout(mExtendFileLayout, true);
                    BoardManager.this.unlockContentHeightDelayed();
                } else {
                    if (BoardManager.this.isSoftInputShown()) {
                        BoardManager.this.lockContentHeight();
                        BoardManager.this.showExtendLayout(mExtendFileLayout);
                        BoardManager.this.unlockContentHeightDelayed();
                    } else {
                        if (mEmotionLayout != null && mEmotionLayout.isShown()) {
                            BoardManager.this.hideExtendLayout(mEmotionLayout, false);
                        }
                        BoardManager.this.showExtendLayout(mExtendFileLayout);
                    }
                }
            }
        });
        return this;
    }

    public BoardManager setExtendFileLayout(View extendLayout) {
        mExtendFileLayout = extendLayout;
        return this;
    }

    public BoardManager setRecordInputBtSw(KeyboardRecordSwitchView inputRecordBtSw) {
        mInputRecordBtSw = inputRecordBtSw;
        mInputRecordBtSw.setSwitchListener(this);
        return this;
    }

    public BoardManager setRecordLayout(RecorderBtn recordBtn) {
        mRecorderView = recordBtn;
        return this;
    }

    public BoardManager setSendBt(ImageView sendBt) {
        mSendIv = sendBt;
        return this;
    }

    private void lockContentHeight() {
        LinearLayout.LayoutParams params =
            (LinearLayout.LayoutParams) mContentView.getLayoutParams();
        params.height = mContentView.getHeight();
        params.weight = 0.0F;
    }

    private void unlockContentHeightDelayed() {
        mInputEt.postDelayed(new Runnable() {
            @Override
            public void run() {
                ((LinearLayout.LayoutParams) mContentView.getLayoutParams()).weight = 1.0F;
            }
        }, 200L);
    }

    private void showSoftInput() {
        SystemUtils.openSoftKeyBoard(mActivity);
    }

    private void hideSoftInput() {
        SystemUtils.hideSoftKeyBoard(mActivity);
    }

    private boolean isSoftInputShown() {
        return getSupportSoftInputHeight() != 0;
    }

    @Override
    public void onKeyboard() {
        showInputLayout();
    }

    @Override
    public void onRecord() {
        showRecordLayout();
    }

    private void hideLayoutWithFixHeight(View layout, boolean isShowSoft) {
        lockContentHeight();
        hideExtendLayout(mExtendFileLayout, isShowSoft);
        unlockContentHeightDelayed();
    }

    private void showLayoutWithFixHeight(View layout) {
        int softInputHeight = getSupportSoftInputHeight();
        if (softInputHeight == 0) {
            softInputHeight = mShareP.getInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, 778);
        }
        LogUtil.i(TAG, "softInputHeight:" + softInputHeight);
        if (layout != null) {
            layout.getLayoutParams().height = softInputHeight;
            layout.setVisibility(View.VISIBLE);
        }
    }

    /**
     * show file selector layout
     * No.2-->toggle button show keyboard
     * No.3-->EditText visible
     * No.4-->record button invisible
     * No.5-->send button visible
     * No.6-->file selector layout show
     * No.7-->keyboard hide
     *
     * @param layout the view should be visible
     */
    private void showExtendLayout(View layout) {
        //No.2
        mInputRecordBtSw.showKeyboard();
        //No.3
        mInputEt.setVisibility(View.VISIBLE);
        //No.4
        mRecorderView.setVisibility(View.GONE);
        //No.5
        mSendIv.setVisibility(View.VISIBLE);
        //No.6
        showLayoutWithFixHeight(layout);
        //No.7
        hideSoftInput();
    }

    /**
     * hide file selector layout
     * No.2-->toggle button show keyboard
     * No.3-->EditText visible
     * No.4-->record button invisible
     * No.5-->send button visible
     * No.6-->file selector layout show
     * No.7-->keyboard is visible by parameter
     *
     * @param layout the view need invisible
     * @param showSoftInput is show keyboard
     */
    private void hideExtendLayout(View layout, boolean showSoftInput) {
        if (layout != null && layout.isShown()) {
            layout.setVisibility(View.GONE);
            if (showSoftInput) {
                showSoftInput();
                mInputRecordBtSw.showRecord();
            } else {
                mInputRecordBtSw.showKeyboard();
            }
        }
    }

    /**
     * No.2 -->toggle button show keyboard
     * No.3 -->EditText invisible
     * No.4 -->record button visible
     * No.5-->send button invisible
     * No.6-->file selector layout invisible
     * No.7-->keyboard is visible by parameter
     */
    private void showRecordLayout() {
        //No.2
        mInputRecordBtSw.showKeyboard();
        //No.3
        mInputEt.setVisibility(View.GONE);
        //No.4
        mRecorderView.setVisibility(View.VISIBLE);
        //No.5
        mSendIv.setVisibility(View.GONE);
        //No.6
        mExtendFileLayout.setVisibility(View.GONE);
        //No.7
        hideSoftInput();
    }

    /**
     * No.2 -->toggle button show record
     * No.3 -->EditText visible
     * No.4 -->record button invisible
     * No.5-->send button visible
     * No.6-->file selector layout invisible
     * No.7-->keyboard is visible
     */
    private void showInputLayout() {
        //No.2
        mInputRecordBtSw.showRecord();
        //No.3
        mInputEt.setVisibility(View.VISIBLE);
        mInputEt.requestFocus();
        mInputEt.setSelection(mInputEt.getText().length());
        //No.4
        mRecorderView.setVisibility(View.GONE);
        //No.5
        mSendIv.setVisibility(View.VISIBLE);
        //No.6 +No.7
        if (mExtendFileLayout.isShown()) {
            lockContentHeight();
            hideExtendLayout(mExtendFileLayout, true);
            unlockContentHeightDelayed();
        } else {
            showSoftInput();
        }
    }

    private int getSupportSoftInputHeight() {
        Rect r = new Rect();
        /**
         * decorView is the top view of the window，we can get decorView by window's getDecorView
         * decorView can get display area(include title bar,but status bar)
         */
        mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
        int screenHeight = mActivity.getWindow().getDecorView().getRootView().getHeight();
        int softInputHeight = screenHeight - r.bottom;

        LogUtil.i(TAG, "ScreenHeight:"
            + screenHeight
            + ",activityBottom:"
            + r.bottom
            + ",softInputHeight:"
            + softInputHeight);
        /**
         * some android ,when keyboard not show,the height always 144,
         * because it include the bottom virtual keystroke bar's height
         * when apk >20,we need minus the height
         */
        if (Build.VERSION.SDK_INT >= 20) {
            // When SDK Level >= 20 (Android L), the softInputHeight will contain the height of softButtonsBar (if has)
            int softBtnBarHeight = getNavigationBarHeight();
            softInputHeight = softInputHeight - getNavigationBarHeight();
            LogUtil.i(TAG,
                "softInputHeight:" + softInputHeight + ",softBtnBarHeight:" + softBtnBarHeight);
        }

        if (softInputHeight < 0) {
            LogUtil.i(TAG, "EmotionKeyboard--Warning: value of softInputHeight is below zero!");
            softInputHeight = 0;
        }
        if (softInputHeight > 0) {
            mShareP.edit().putInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, softInputHeight).apply();
        }
        return softInputHeight;
    }

    /**
     * Height of the bottom virtual keystroke bar
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private int getNavigationBarHeight() {
        Resources resources = mActivity.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        return resources.getDimensionPixelSize(resourceId);
    }

    public BoardManager build() {
        mActivity.getWindow()
            .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        hideSoftInput();
        return this;
    }

    public boolean isRichMsgLayoutShowing() {
        return (mExtendFileLayout != null && mExtendFileLayout.isShown()) || (mEmotionLayout != null
            && mEmotionLayout.isShown());
    }

    public void hideRichMsgLayout() {
        hideExtendLayout(mExtendFileLayout, false);
        hideExtendLayout(mEmotionLayout, false);
    }

    /**
     * when click back should be hide bottom layout first
     */
    public boolean interceptBackPress() {
        if (isRichMsgLayoutShowing()) {
            hideRichMsgLayout();
            return true;
        }
        return false;
    }
}
