content: package com.alphawallet.app.widget;
  
  import android.app.Activity;
  import android.content.Context;
  import android.content.res.Resources;
  import android.content.res.TypedArray;
  import android.graphics.Typeface;
  import android.os.Handler;
  import android.os.Looper;
  import android.text.InputType;
  import android.text.TextUtils;
  import android.text.method.HideReturnsTransformationMethod;
  import android.text.method.PasswordTransformationMethod;
  import android.util.AttributeSet;
  import android.util.TypedValue;
  import android.view.Gravity;
  import android.view.KeyEvent;
  import android.view.View;
  import android.view.inputmethod.EditorInfo;
  import android.widget.CheckBox;
  import android.widget.EditText;
  import android.widget.LinearLayout;
  import android.widget.TextView;
  
  import androidx.core.content.ContextCompat;
  
  import com.alphawallet.app.R;
  import com.alphawallet.app.util.Utils;
  
  import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent;
  
  public class PasswordInputView extends LinearLayout implements TextView.OnEditorActionListener
  {
      private final Context context;
  
      private final TextView label;
      private final TextView error;
      private final TextView status;
      private final EditText editText;
      private final CheckBox togglePassword;
      private final TextView instruction;
  
      private int labelResId;
      private int lines;
      private String inputType;
      private int minHeight;
      private String imeOptions;
      private String hintTxt;
      private Activity activity;
      private LayoutCallbackListener callbackListener;
      private final Handler handler = new Handler(Looper.getMainLooper());
  
      public PasswordInputView(Context context, AttributeSet attrs) {
          super(context, attrs);
          this.context = context;
          getAttrs(context, attrs);
  
          inflate(context, R.layout.layout_password_input, this);
  
          label = findViewById(R.id.label);
          error = findViewById(R.id.error);
          editText = findViewById(R.id.edit_text);
          status = findViewById(R.id.status_text);
          instruction = findViewById(R.id.instruction);
          togglePassword = findViewById(R.id.toggle_password);
          findViewById(R.id.text_word_count).setVisibility(View.GONE);
  
          setViews();
          setImeOptions();
          setInputType();
          setMinHeight();
          setLines();
      }
  
      public void setLayoutListener(Activity a, LayoutCallbackListener callback)
      {
          activity = a;
          callbackListener = callback;
          getEditText().setOnEditorActionListener(this);
  
          addKeyboardListener(callback);
      }
  
      public EditText getEditText()
      {
          return editText;
      }
  
      private void setViews()
      {
          label.setText(labelResId);
          if (labelResId != R.string.empty) label.setVisibility(View.VISIBLE);
          togglePassword.setOnCheckedChangeListener((buttonView, isChecked) -> {
              if (isChecked) {
                  editText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
              } else {
                  editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
              }
              editText.setSelection(editText.getText().length());
          });
      }
  
      private void getAttrs(Context context, AttributeSet attrs) {
          TypedArray a = context.getTheme().obtainStyledAttributes(
                  attrs,
                  R.styleable.InputView,
                  0, 0
          );
  
          try {
              labelResId = a.getResourceId(R.styleable.InputView_label, R.string.empty);
              lines = a.getInt(R.styleable.InputView_lines, 1);
              inputType = a.getString(R.styleable.InputView_inputType);
              imeOptions = a.getString(R.styleable.InputView_imeOptions);
              minHeight = a.getInteger(R.styleable.InputView_minHeightValue, 0);
              hintTxt = a.getString(R.styleable.InputView_hint);
          } finally {
              a.recycle();
          }
      }
  
      private void setMinHeight() {
          Resources r = getResources();
          if (minHeight > 0)
          {
              int px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, minHeight, r.getDisplayMetrics());
              editText.setMinHeight(px);
          }
      }
  
      private void setInputType() {
          if (inputType != null) {
              switch (inputType) {
                  case "textPassword": {
                      editText.setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
                      togglePassword.setVisibility(View.VISIBLE);
                      editText.setPadding(
                              Utils.dp2px(context, 15),
                              Utils.dp2px(context, 5),
                              Utils.dp2px(context, 50),
                              Utils.dp2px(context, 5)
                      );
                      editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
                      break;
                  }
                  case "number": {
                      editText.setInputType(EditorInfo.TYPE_CLASS_NUMBER);
                      break;
                  }
                  case "textNoSuggestions":{
                      editText.setInputType(editText.getInputType() |
                              EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS |
                              EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE |
                              EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                      break;
                  }
              }
          }
          editText.setTypeface(Typeface.DEFAULT);
          if (!TextUtils.isEmpty(hintTxt)) editText.setHint(hintTxt);
      }
  
      private void setImeOptions() {
          if (imeOptions != null) {
              switch (imeOptions) {
                  case "actionNext": {
                      editText.setImeOptions(EditorInfo.IME_ACTION_NEXT);
                      break;
                  }
                  case "actionDone": {
                      editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
                      editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
                      break;
                  }
              }
          }
      }
  
      private void setLines() {
          if (lines > 1) {
              editText.setGravity(Gravity.TOP);
              editText.setPadding(
                      Utils.dp2px(context, 20),
                      Utils.dp2px(context, 16),
                      Utils.dp2px(context, 20),
                      Utils.dp2px(context, 16)
              );
          }
  
          editText.setMinLines(lines);
      }
  
      public CharSequence getText() {
          return this.editText.getText();
      }
  
      public void setInstruction(int resourceId)
      {
          this.instruction.setText(resourceId);
      }
  
      public void setText(CharSequence text) {
          this.editText.setText(text);
      }
  
      public void setError(int resId) {
          if (resId == R.string.empty) {
              error.setText(resId);
              error.setVisibility(View.GONE);
              editText.setBackgroundResource(R.drawable.background_password_entry);
              label.setTextColor(ContextCompat.getColor(getContext(), R.color.text_secondary));
          } else {
              error.setText(resId);
              error.setVisibility(View.VISIBLE);
              editText.setBackgroundResource(R.drawable.background_password_error);
              label.setTextColor(ContextCompat.getColor(getContext(), R.color.error));
          }
      }
  
      public void setStatus(CharSequence statusTxt)
      {
          if (TextUtils.isEmpty(statusTxt)) {
              status.setVisibility(View.GONE);
          } else {
              status.setText(statusTxt);
              status.setVisibility(View.VISIBLE);
          }
      }
  
      public void setError(CharSequence message) {
          if (message == null) {
              error.setVisibility(View.GONE);
              editText.setBackgroundResource(R.drawable.background_password_entry);
              label.setTextColor(ContextCompat.getColor(getContext(), R.color.text_secondary));
          } else if (message.toString().isEmpty()) {
              error.setText(message);
              error.setVisibility(View.GONE);
              editText.setBackgroundResource(R.drawable.background_password_entry);
              label.setTextColor(ContextCompat.getColor(getContext(), R.color.text_secondary));
          } else {
              error.setText(message);
              error.setVisibility(View.VISIBLE);
              editText.setBackgroundResource(R.drawable.background_password_error);
              label.setTextColor(ContextCompat.getColor(getContext(), R.color.error));
          }
      }
  
      public boolean isErrorState()
      {
          return error.getVisibility() == View.VISIBLE;
      }
  
      private void addKeyboardListener(LayoutCallbackListener callback)
      {
          KeyboardVisibilityEvent.setEventListener(
                  activity, isOpen -> {
                      if (isOpen)
                      {
                          callback.onLayoutShrunk();
                      }
                      else
                      {
                          callback.onLayoutExpand();
                      }
                  });
      }
  
      @Override
      public boolean onEditorAction(TextView view, int i, KeyEvent keyEvent)
      {
          if (isErrorState())
          {
              flashLayout();
          }
          else if (callbackListener != null)
          {
              callbackListener.onInputDoneClick(view);
          }
  
          return true;
      }
  
      private void flashLayout()
      {
          editText.setBackgroundResource(R.drawable.background_password_flash);
          handler.postDelayed(() -> editText.setBackgroundResource(R.drawable.background_password_error), 300);
      }
  }
  
  