package com.mirhoseini.marvel.character.search;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.mirhoseini.marvel.MarvelApplication;
import com.mirhoseini.marvel.R;
import com.mirhoseini.marvel.base.BaseFragment;
import com.mirhoseini.marvel.database.model.CharacterModel;
import com.mirhoseini.utils.Utils;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnEditorAction;
import rx.Observable;
import rx.subjects.PublishSubject;
import timber.log.Timber;
/**
* Created by Mohsen on 20/10/2016.
*/
public class SearchFragment extends BaseFragment implements SearchView {
// injecting dependencies via Dagger
@Inject
Context context;
@Inject
Resources resources;
@Inject
FirebaseAnalytics firebaseAnalytics;
@Inject
SearchPresenter presenter;
// injecting views via ButterKnife
@BindView(R.id.character)
AutoCompleteTextView character;
@BindView(R.id.show)
Button show;
ProgressDialog progressDialog;
PublishSubject<CharacterModel> notifyCharacter = PublishSubject.create();
PublishSubject<String> notifyMessage = PublishSubject.create();
PublishSubject<Boolean> notifyOffline = PublishSubject.create();
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public SearchFragment() {
}
public static SearchFragment newInstance() {
SearchFragment fragment = new SearchFragment();
return fragment;
}
@OnEditorAction(R.id.character)
boolean onEditorAction(EditText v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH || (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
onShowClick(v);
return true;
}
return false;
}
@OnClick(R.id.show)
void onShowClick(View view) {
character.setError(null);
Utils.hideKeyboard(context, character);
String query = character.getText().toString().trim();
if (presenter.isQueryValid(query)) {
logFirebaseAnalyticsSearchEvent(query);
presenter.doSearch(Utils.isConnected(context), query, Utils.getCurrentTimestamp());
} else {
character.setError(resources.getString(R.string.character_error));
character.requestFocus();
}
}
private void logFirebaseAnalyticsSearchEvent(String query) {
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.SEARCH_TERM, query);
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SEARCH, bundle);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
presenter.bind(this);
}
@Override
protected void injectDependencies(MarvelApplication application) {
application
.getSearchSubComponent()
.inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
ButterKnife.bind(this, view);
return view;
}
@Override
public void onResume() {
super.onResume();
presenter.loadCharactersCachedData();
}
@Override
public void setCharactersCachedData(List<CharacterModel> characters) {
character.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, characters));
}
@Override
public void onDetach() {
super.onDetach();
presenter.unbind();
}
@Override
public void showMessage(String message) {
notifyMessage.onNext(message);
}
@Override
public void showOfflineMessage(boolean isCritical) {
notifyOffline.onNext(isCritical);
}
@Override
public void showError(Throwable throwable) {
Timber.e(throwable, "Error!");
showRetryMessage(throwable);
}
@Override
public void showRetryMessage(Throwable throwable) {
Timber.e(throwable, "Retry error!");
Snackbar.make(character, resources.getString(R.string.retry_message), Snackbar.LENGTH_LONG)
.setAction(R.string.retry, this::onShowClick)
.show();
}
@Override
public void showQueryNoResult() {
showMessage(resources.getString(R.string.no_result));
}
@Override
public void showProgress() {
if (null != progressDialog)
progressDialog.dismiss();
progressDialog = new ProgressDialog(getActivity());
progressDialog.setIndeterminate(true);
progressDialog.setTitle(R.string.please_wait);
progressDialog.show();
}
@Override
public void hideProgress() {
if (null != progressDialog)
progressDialog.dismiss();
}
@Override
public void showServiceError(ApiResponseCodeException throwable) {
Timber.e(throwable, "Service Error!");
showRetryMessage(throwable);
}
@Override
public void showQueryError(Throwable throwable) {
Timber.e(throwable, "Query error!");
showRetryMessage(throwable);
}
@Override
public void showCharacter(CharacterModel character) {
logFirebaseAnalyticsSelectEvent(character);
notifyCharacter.onNext(character);
}
private void logFirebaseAnalyticsSelectEvent(CharacterModel character) {
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, character.getId() + "");
bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, character.getName());
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
}
public Observable<CharacterModel> characterObservable() {
return notifyCharacter.asObservable();
}
public Observable<String> messageObservable() {
return notifyMessage.asObservable();
}
public Observable<Boolean> offlineObservable() {
return notifyOffline.asObservable();
}
}