package com.etiennelawlor.loop.ui;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.etiennelawlor.loop.R;
import com.etiennelawlor.loop.adapters.SuggestionsAdapter;
import com.etiennelawlor.loop.bus.RxBus;
import com.etiennelawlor.loop.bus.events.FilterClickedEvent;
import com.etiennelawlor.loop.bus.events.HideSearchSuggestionsEvent;
import com.etiennelawlor.loop.bus.events.LeftDrawableClickedEvent;
import com.etiennelawlor.loop.bus.events.SearchPerformedEvent;
import com.etiennelawlor.loop.bus.events.ShowSearchSuggestionsEvent;
import com.etiennelawlor.loop.realm.RealmUtility;
import com.etiennelawlor.loop.utilities.DisplayUtility;
import com.etiennelawlor.loop.utilities.FontCache;
import com.etiennelawlor.loop.utilities.TrestleUtility;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnFocusChange;
import butterknife.OnTextChanged;
import de.hdodenhof.circleimageview.CircleImageView;
/**
* Created by etiennelawlor on 10/6/15.
*/
public class MaterialSearchView extends FrameLayout implements
SuggestionsAdapter.OnItemClickListener,
SuggestionsAdapter.OnItemLongClickListener,
SuggestionsAdapter.OnSearchSuggestionCompleteClickListener {
// region Constants
public static final int REQUEST_VOICE = 1001;
public static final int MENU = 0;
public static final int BACK = 1;
public static final int SEARCH = 2;
public static final int AVATAR = 3;
// endregion
// region Member Variables
private boolean areSearchSuggestionsVisible;
private DividerItemDecoration dividerItemDecoration;
private int leftDrawableType;
private String hintText;
private int marginTop;
private int marginBottom;
private int marginLeft;
private int marginRight;
private String voicePrompt;
private Typeface font;
private SuggestionsAdapter suggestionsAdapter = new SuggestionsAdapter();
private boolean isSearchEditTextFocused = false;
@BindView(R.id.search_et)
EditText searchEditText;
@BindView(R.id.microphone_iv)
ImageView microphoneImageView;
@BindView(R.id.clear_iv)
ImageView clearImageView;
@BindView(R.id.filter_iv)
ImageView filterImageView;
@BindView(R.id.cv)
CardView cardView;
@BindView(R.id.left_drawable_iv)
ImageView leftDrawableImageView;
@BindView(R.id.left_drawable_riv)
CircleImageView leftDrawableRoundedImageView;
@BindView(R.id.divider_v)
View dividerView;
@BindView(R.id.bg_cover_fl)
FrameLayout backgroundCoverFrameLayout;
@BindView(R.id.rv)
RecyclerView recyclerView;
// endregion
// region Listeners
@OnClick(R.id.bg_cover_fl)
public void backgroundCoverFrameLayoutClicked() {
if (areSearchSuggestionsVisible) {
hideSearchSuggestions();
}
}
@OnClick(R.id.microphone_iv)
public void microphoneImageViewClicked() {
if (isVoiceAvailable()) {
hideSearchSuggestions();
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// intent.putExtra(RecognizerIntent.EXTRA_PROMPT, voicePrompt);
// intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
// intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
Bundle bundle = new Bundle();
bundle.putString(RecognizerIntent.EXTRA_PROMPT, voicePrompt);
bundle.putString(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
bundle.putInt(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
intent.putExtras(bundle);
((Activity) ((ContextWrapper) microphoneImageView.getContext()).getBaseContext()).startActivityForResult(intent, REQUEST_VOICE);
} else {
Toast.makeText(getContext(), "Voice Search is unavailable", Toast.LENGTH_SHORT).show();
}
}
@OnClick(R.id.left_drawable_iv)
public void leftDrawableImageViewClicked() {
if (areSearchSuggestionsVisible) {
hideSearchSuggestions();
} else {
LeftDrawableClickedEvent.Type type = null;
switch (leftDrawableType) {
case 0:
type = LeftDrawableClickedEvent.Type.MENU;
break;
case 1:
type = LeftDrawableClickedEvent.Type.BACK;
break;
case 2:
type = LeftDrawableClickedEvent.Type.SEARCH;
searchEditText.requestFocus();
default:
break;
}
RxBus.getInstance().send(new LeftDrawableClickedEvent(type));
}
}
@OnClick(R.id.clear_iv)
public void clearImageViewClicked() {
setQuery("");
}
@OnTextChanged(R.id.search_et)
public void onSearchEditTextTextChanged(CharSequence text) {
if (text.length() > 0) {
microphoneImageView.setVisibility(View.GONE);
clearImageView.setVisibility(View.VISIBLE);
} else {
clearImageView.setVisibility(View.GONE);
microphoneImageView.setVisibility(View.VISIBLE);
}
if (isSearchEditTextFocused) {
suggestionsAdapter.setCurrentQuery(text.toString());
RxBus.getInstance().send(new ShowSearchSuggestionsEvent(text.toString()));
}
filterImageView.setVisibility(View.GONE);
}
@OnClick(R.id.search_et)
public void searchEditTextClicked() {
searchEditText.requestFocus();
}
@OnFocusChange(R.id.search_et)
public void onSearchEditTextFocusChanged(boolean focused) {
isSearchEditTextFocused = focused;
if (isSearchEditTextFocused) {
if (!areSearchSuggestionsVisible) {
showSearchSuggestions();
}
DisplayUtility.showKeyboard(getContext(), searchEditText);
} else {
DisplayUtility.hideKeyboard(getContext(), searchEditText);
}
}
private OnClickListener filterImageViewOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
RxBus.getInstance().send(new FilterClickedEvent());
}
};
// endregion
// region Constructors
public MaterialSearchView(Context context) {
super(context);
init(null);
}
public MaterialSearchView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public MaterialSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
// endregion
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
if (event != null) {
int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (areSearchSuggestionsVisible) {
hideSearchSuggestions();
}
}
}
return true;
}
// region SuggestionsAdapter.OnItemClickListener Methods
@Override
public void onItemClick(int position, View view) {
TextView suggestionTextView = (TextView) view.findViewById(R.id.suggestion_tv);
String suggestion = suggestionTextView.getText().toString();
hideSearchSuggestions();
RxBus.getInstance().send(new SearchPerformedEvent(suggestion));
}
// endregion
// region SuggestionsAdapter.OnItemLongClickListener Methods
@Override
public void onItemLongClick(int position, View view) {
TextView suggestionTextView = (TextView) view.findViewById(R.id.suggestion_tv);
final String suggestion = suggestionTextView.getText().toString();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext(), R.style.DialogTheme);
alertDialogBuilder.setMessage(TrestleUtility.getFormattedText("Remove from search history?", font));
alertDialogBuilder.setPositiveButton(
getContext().getString(android.R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
RealmUtility.deleteQuery(suggestion);
RxBus.getInstance().send(new ShowSearchSuggestionsEvent(getQuery()));
dialog.dismiss();
}
});
alertDialogBuilder.setNegativeButton(
getContext().getString(android.R.string.cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alertDialog = alertDialogBuilder.show();
Button btnPositive = alertDialog.getButton(Dialog.BUTTON_POSITIVE);
btnPositive.setTypeface(font);
Button btnNegative = alertDialog.getButton(Dialog.BUTTON_NEGATIVE);
btnNegative.setTypeface(font);
}
// endregion
// region SuggestionsAdapter.OnSearchSuggestionCompleteClickListener Methods
@Override
public void onSearchSuggestionCompleteClickListener(int position, TextView textView) {
searchEditText.setText(textView.getText().toString());
int textLength = searchEditText.getText().length();
searchEditText.setSelection(textLength, textLength);
}
// endregion
// region Helper Methods
private void init(AttributeSet attrs) {
if (!isInEditMode()) {
LayoutInflater.from(getContext()).inflate((R.layout.material_search_view), this, true);
ButterKnife.bind(this);
font = FontCache.getTypeface("Ubuntu-Medium.ttf", getContext());
if (attrs != null) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.MaterialSearchView, 0, 0);
try {
leftDrawableType = a.getInteger(R.styleable.MaterialSearchView_leftDrawableType, 1);
hintText = a.getString(R.styleable.MaterialSearchView_hintText);
voicePrompt = a.getString(R.styleable.MaterialSearchView_voicePrompt);
marginTop = a.getDimensionPixelSize(R.styleable.MaterialSearchView_layout_marginTop, 0);
marginBottom = a.getDimensionPixelSize(R.styleable.MaterialSearchView_layout_marginBottom, 0);
marginLeft = a.getDimensionPixelSize(R.styleable.MaterialSearchView_layout_marginLeft, 0);
marginRight = a.getDimensionPixelSize(R.styleable.MaterialSearchView_layout_marginRight, 0);
} finally {
a.recycle();
}
}
setUpLeftDrawable(false);
setUpCardView();
setUpHintText();
setUpListeners();
}
}
private void setUpCardView() {
LayoutParams params = new LayoutParams(
cardView.getLayoutParams());
params.topMargin = marginTop;
params.bottomMargin = marginBottom;
params.leftMargin = marginLeft;
params.rightMargin = marginRight;
cardView.setLayoutParams(params);
}
private void setUpListeners() {
searchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
hideSearchSuggestions();
RxBus.getInstance().send(new SearchPerformedEvent(getQuery()));
return true;
} else {
return false;
}
}
});
}
private void setUpLeftDrawable(boolean showingSearchSuggestions) {
if (showingSearchSuggestions) {
leftDrawableImageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_arrow_back_dark));
leftDrawableRoundedImageView.setVisibility(View.GONE);
leftDrawableImageView.setVisibility(View.VISIBLE);
} else {
switch (leftDrawableType) {
case MENU:
leftDrawableImageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_menu_dark));
break;
case BACK:
leftDrawableImageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_arrow_back_dark));
break;
case SEARCH:
leftDrawableImageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_search));
break;
case AVATAR:
break;
default:
break;
}
if (leftDrawableType == AVATAR) {
leftDrawableImageView.setVisibility(View.GONE);
leftDrawableRoundedImageView.setVisibility(View.VISIBLE);
} else {
leftDrawableRoundedImageView.setVisibility(View.GONE);
leftDrawableImageView.setVisibility(View.VISIBLE);
}
}
}
public void setLeftDrawableType(int type) {
leftDrawableType = type;
}
private void setUpHintText() {
if (searchEditText != null)
searchEditText.setHint(hintText);
}
private void showSearchSuggestions() {
RxBus.getInstance().send(new ShowSearchSuggestionsEvent(getQuery()));
suggestionsAdapter.setOnItemClickListener(this);
suggestionsAdapter.setOnItemLongClickListener(this);
suggestionsAdapter.setOnSearchSuggestionCompleteClickListener(this);
CustomLinearLayoutManager layoutManager = new CustomLinearLayoutManager(getContext());
// LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
dividerItemDecoration = new DividerItemDecoration(ContextCompat.getDrawable(getContext(), R.drawable.divider));
recyclerView.addItemDecoration(dividerItemDecoration);
// recyclerView.setItemAnimator(new SlideInUpAnimator());
recyclerView.setAdapter(suggestionsAdapter);
if (!(suggestionsAdapter.isEmpty())) {
recyclerView.setVisibility(View.VISIBLE);
dividerView.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.GONE);
dividerView.setVisibility(View.GONE);
}
backgroundCoverFrameLayout.setVisibility(View.VISIBLE);
setUpLeftDrawable(true);
areSearchSuggestionsVisible = true;
}
private void hideSearchSuggestions() {
dividerView.setVisibility(View.GONE);
backgroundCoverFrameLayout.setVisibility(View.GONE);
setUpLeftDrawable(false);
recyclerView.setVisibility(View.GONE);
recyclerView.removeItemDecoration(dividerItemDecoration);
searchEditText.clearFocus();
areSearchSuggestionsVisible = false;
RxBus.getInstance().send(new HideSearchSuggestionsEvent());
}
private boolean isVoiceAvailable() {
PackageManager pm = getContext().getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
return (activities.size() != 0);
}
public void setQuery(String query) {
searchEditText.setText(query);
suggestionsAdapter.setCurrentQuery(query);
if (!TextUtils.isEmpty(query))
filterImageView.setVisibility(View.VISIBLE);
}
public String getQuery() {
return searchEditText.getText().toString();
}
public void setHint(String hint) {
searchEditText.setHint(hint);
}
public void addSuggestions(List<String> suggestions) {
suggestionsAdapter.clear();
suggestionsAdapter.addAll(suggestions);
if (!(suggestionsAdapter.isEmpty())) {
recyclerView.setVisibility(View.VISIBLE);
dividerView.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.GONE);
dividerView.setVisibility(View.GONE);
}
backgroundCoverFrameLayout.setVisibility(View.VISIBLE);
}
public void enableFilter() {
filterImageView.setOnClickListener(filterImageViewOnClickListener);
filterImageView.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ripple));
filterImageView.setImageResource(R.drawable.ic_filter_list_active);
}
public void disableFilter() {
filterImageView.setOnClickListener(null);
filterImageView.setBackgroundDrawable(null);
filterImageView.setImageResource(R.drawable.ic_filter_list_inactive);
}
// public void setAvatar(Retailer retailer){
//// mLeftDrawableRoundedImageView.bind(retailer);
// mLeftDrawableImageView.setVisibility(View.GONE);
// mLeftDrawableRoundedImageView.setVisibility(View.VISIBLE);
// }
// endregion
}