content: package com.mxt.anitrend.base.custom.sheet;
  
  import android.app.Dialog;
  import android.os.Bundle;
  import android.view.View;
  
  import androidx.annotation.NonNull;
  import androidx.annotation.Nullable;
  import androidx.annotation.StringRes;
  import androidx.appcompat.widget.AppCompatImageView;
  import androidx.coordinatorlayout.widget.CoordinatorLayout;
  
  import com.google.android.material.bottomsheet.BottomSheetBehavior;
  import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
  import com.miguelcatalan.materialsearchview.MaterialSearchView;
  import com.mxt.anitrend.R;
  import com.mxt.anitrend.base.custom.view.text.SingleLineTextView;
  import com.mxt.anitrend.base.custom.viewmodel.ViewModelBase;
  import com.mxt.anitrend.base.interfaces.event.BottomSheetChoice;
  import com.mxt.anitrend.base.interfaces.event.BottomSheetListener;
  import com.mxt.anitrend.base.interfaces.event.ResponseCallback;
  import com.mxt.anitrend.presenter.base.BasePresenter;
  import com.mxt.anitrend.util.CompatUtil;
  import com.mxt.anitrend.util.KeyUtil;
  
  import org.greenrobot.eventbus.EventBus;
  
  import butterknife.BindView;
  import butterknife.Unbinder;
  import timber.log.Timber;
  
  /**
   * Created by max on 2017/11/02.
   * Custom bottom sheet base implementation
   */
  
  public abstract class BottomSheetBase<T> extends BottomSheetDialogFragment implements BottomSheetListener, ResponseCallback {
  
      public String TAG;
  
      protected Unbinder unbinder;
  
      protected @BindView(R.id.toolbar_title) SingleLineTextView toolbarTitle;
      protected @BindView(R.id.toolbar_state) AppCompatImageView toolbarState;
      protected @BindView(R.id.toolbar_search) AppCompatImageView toolbarSearch;
      protected @BindView(R.id.search_view) MaterialSearchView searchView;
  
      protected ViewModelBase<T> viewModel;
      protected BottomSheetChoice bottomSheetChoice;
  
      protected @StringRes int mTitle, mText, mPositive, mNegative;
      protected String searchQuery;
  
      protected BasePresenter presenter;
      protected BottomSheetBehavior bottomSheetBehavior;
      protected BottomSheetBehavior.BottomSheetCallback bottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() {
          @Override
          public void onStateChanged(@NonNull View bottomSheet, @BottomSheetBehavior.State int newState) {
              if(isAlive()) {
                  try {
                      switch (newState) {
                          case BottomSheetBehavior.STATE_HIDDEN:
                              dismiss();
                              break;
                          case BottomSheetBehavior.STATE_COLLAPSED:
                              onStateCollapsed();
                              break;
                          case BottomSheetBehavior.STATE_EXPANDED:
                              onStateExpanded();
                              break;
                      }
                  } catch (Exception e) {
                      Timber.e(e);
                  }
              }
          }
  
          @Override
          public void onSlide(@NonNull View bottomSheet, float slideOffset) {
  
          }
      };
  
      /**
       * Set up your custom bottom sheet and check for arguments if any
       */
      @Override
      public void onCreate(@Nullable Bundle savedInstanceState) {
          TAG = this.toString();
          super.onCreate(savedInstanceState);
          if(getArguments() != null) {
              mTitle = getArguments().getInt(KeyUtil.arg_title);
              mText = getArguments().getInt(KeyUtil.arg_text);
              mPositive = getArguments().getInt(KeyUtil.arg_positive_text);
              mNegative = getArguments().getInt(KeyUtil.arg_negative_text);
          }
          presenter = new BasePresenter(getContext());
      }
  
      /**
       * Setup your view un-binder here as well as inflating other views as needed
       * into your view stub
       */
      @Override @NonNull
      public Dialog onCreateDialog(Bundle savedInstanceState) {
          return super.onCreateDialog(savedInstanceState);
      }
  
      @Override
      public void onStart() {
          super.onStart();
          toolbarTitle.setText(mTitle);
          if(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
              toolbarState.setImageDrawable(CompatUtil.INSTANCE.getTintedDrawable(getContext(), R.drawable.ic_keyboard_arrow_down_grey_600_24dp));
          else
              toolbarState.setImageDrawable(CompatUtil.INSTANCE.getTintedDrawable(getContext(), R.drawable.ic_close_grey_600_24dp));
          toolbarState.setOnClickListener(view -> {
              switch (bottomSheetBehavior.getState()) {
                  case BottomSheetBehavior.STATE_EXPANDED:
                      bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                      break;
                  default:
                      bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                      break;
              }
          });
          toolbarSearch.setImageDrawable(CompatUtil.INSTANCE.getTintedDrawable(getContext(), R.drawable.ic_search_grey_600_24dp));
          toolbarSearch.setOnClickListener(view -> searchView.showSearch(true));
          searchView.setCursorDrawable(R.drawable.material_search_cursor);
      }
  
      @Override
      public void onStop() {
          if(EventBus.getDefault().isRegistered(this))
              EventBus.getDefault().unregister(this);
          super.onStop();
      }
  
      @Override
      public void onPause() {
          super.onPause();
      }
  
      @Override
      public void onResume() {
          super.onResume();
      }
  
      public void setBottomSheetChoice(BottomSheetChoice bottomSheetChoice) {
          this.bottomSheetChoice = bottomSheetChoice;
      }
  
      protected boolean isAlive() {
          return isVisible() && !isDetached() || !isRemoving();
      }
  
      protected void createBottomSheetBehavior(View contentView) {
          CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
          CoordinatorLayout.Behavior coordinatorBehavior = layoutParams.getBehavior();
  
          if (coordinatorBehavior instanceof BottomSheetBehavior) {
              bottomSheetBehavior = (BottomSheetBehavior) coordinatorBehavior;
              bottomSheetBehavior.setPeekHeight(CompatUtil.INSTANCE.dipToPx(KeyUtil.PEEK_HEIGHT));
              bottomSheetBehavior.setBottomSheetCallback(bottomSheetCallback);
          }
      }
  
      public boolean closeDialog() {
          if(bottomSheetBehavior.getState() != BottomSheetBehavior.STATE_HIDDEN) {
              bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
              return true;
          }
          return false;
      }
  
      /**
       * Remove dialog.
       */
      @Override
      public void onDestroyView() {
          super.onDestroyView();
          if(unbinder != null)
              unbinder.unbind();
          bottomSheetCallback = null;
      }
  
      @Override
      public void onStateCollapsed() {
          toolbarState.setImageDrawable(CompatUtil.INSTANCE.getTintedDrawable(getContext(), R.drawable.ic_close_grey_600_24dp));
      }
  
      @Override
      public void onStateExpanded() {
          toolbarState.setImageDrawable(CompatUtil.INSTANCE.getTintedDrawable(getContext(), R.drawable.ic_keyboard_arrow_down_grey_600_24dp));
      }
  
      /**
       * Builder class for bottom sheet
       */
      public abstract static class BottomSheetBuilder {
  
          protected Bundle bundle;
  
          public BottomSheetBuilder() {
              bundle = new Bundle();
          }
  
          public abstract BottomSheetBase build();
  
          public BottomSheetBase buildWithCallback(BottomSheetChoice bottomSheetChoice) {
              BottomSheetBase bottomSheetBase = build();
              bottomSheetBase.setBottomSheetChoice(bottomSheetChoice);
              return bottomSheetBase;
          }
  
          public BottomSheetBuilder setTitle(@StringRes int title) {
              bundle.putInt(KeyUtil.arg_title, title);
              return this;
          }
  
          public BottomSheetBuilder setPositiveText(@StringRes int positiveText) {
              bundle.putInt(KeyUtil.arg_positive_text, positiveText);
              return this;
          }
  
          public BottomSheetBuilder setNegativeText(@StringRes int negativeText) {
              bundle.putInt(KeyUtil.arg_negative_text, negativeText);
              return this;
          }
      }
  
      @Override
      public void showError(String error) {
          Timber.tag(TAG).e(error);
      }
  
      @Override
      public void showEmpty(String message) {
          Timber.tag(TAG).d(message);
      }
  }
  