package com.madeinhk.english_chinesedictionary;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import com.madeinhk.app.AboutFragment;
import com.madeinhk.english_chinesedictionary.service.ECDictionaryService;
import com.madeinhk.model.AppPreference;
import com.madeinhk.model.ECDictionary;
import com.madeinhk.utils.Analytics;
import java.util.Stack;
import de.greenrobot.event.EventBus;
import static com.madeinhk.english_chinesedictionary.R.id.word;
public class DictionaryActivity extends AppCompatActivity {
private NavigationView mNavigationView;
private Toolbar mToolbar;
private interface PagePos {
int EMPTY = -1;
int DICTIONARY = 0;
int FAVOURITE = 1;
int SETTINGS = 2;
int ABOUT = 3;
}
private static final String TAG = "DictionaryActivity";
public static final String ACTION_VIEW_WORD = "android.intent.action.VIEW_WORD";
public static final String ACTION_SETTINGS = "android.intent.action.SETTINGS";
private static final String KEY_CURRENT_PAGE = "current_page";
private static final String KEY_EXPANDED_SEARCH_VIEW = "expanded_search_view";
private static final int[] ITEM_NAMES = new int[]{R.string.dictionary, R.string.favourites,
R.string.settings, R.string.about};
private DrawerLayout mDrawerLayout;
private int mCurrentPage = PagePos.EMPTY;
private boolean mExpandedSearchView = false;
private String mWord;
private ActionBarDrawerToggle mDrawerToggle;
private boolean mIsVisible;
private static final String EXTRA_FROM_TOAST = "from_toast";
private BackStack mBackStack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBackStack = new BackStack();
setContentView(R.layout.activity_dictionary);
setupToolBar();
setupDrawerLayout();
mNavigationView = (NavigationView) findViewById(R.id.nav_view);
setupDrawerContent(mNavigationView);
ECDictionaryService.start(this);
if (savedInstanceState == null) {
handleIntent(getIntent());
Analytics.trackAppLaunch(this);
} else {
mCurrentPage = savedInstanceState.getInt(KEY_CURRENT_PAGE);
mExpandedSearchView = savedInstanceState.getBoolean(KEY_EXPANDED_SEARCH_VIEW);
selectDrawerItem(mCurrentPage);
}
if (!AppPreference.getShowedTutorial(this)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.see_tut_title);
builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.youtube.com/watch?v=a5nDV2c04Q4"));
startActivity(intent);
}
});
builder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
AppPreference.saveShowedTutorial(DictionaryActivity.this, true);
}
}
@Override
public void onStart() {
super.onStart();
if (getIntent().getBooleanExtra(EXTRA_FROM_TOAST, false)) {
handleIntent(getIntent());
}
mIsVisible = true;
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
mIsVisible = false;
EventBus.getDefault().unregister(this);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_CURRENT_PAGE, mCurrentPage);
outState.putBoolean(KEY_EXPANDED_SEARCH_VIEW, mExpandedSearchView);
}
private void setupToolBar() {
mToolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
private void selectDrawerItem(int pos) {
setTitle(ITEM_NAMES[pos]);
int menuItemId = pagePosToMenuId(pos);
MenuItem menuItem = mNavigationView.getMenu().findItem(menuItemId);
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
}
private int pagePosToMenuId(int pos) {
switch (pos) {
case PagePos.DICTIONARY:
return R.id.nav_dictionary;
case PagePos.FAVOURITE:
return R.id.nav_favourite;
case PagePos.SETTINGS:
return R.id.settings;
case PagePos.ABOUT:
return R.id.nav_about;
}
throw new IllegalArgumentException("Invalid Pos");
}
private void showFragment(Fragment fragment, int page) {
FragmentManager fragmentManager = DictionaryActivity.this.getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fragmentManager
.beginTransaction()
.setCustomAnimations(R.anim.slide_from_bottom_in, R.anim
.slide_from_bottom_out)
.replace(R.id.content, fragment);
Fragment topFragment = fragmentManager.findFragmentById(R.id.content);
if (page == PagePos.FAVOURITE) {
mBackStack.clear();
}
if (mCurrentPage == PagePos.FAVOURITE && page == PagePos.DICTIONARY) {
mBackStack.push(topFragment);
}
transaction.commit();
mCurrentPage = page;
}
private int fragmentToPos(Fragment fragment) {
Class<? extends Fragment> fragmentClass = fragment.getClass();
if (fragmentClass.equals(DictionaryFragment.class)) {
return 0;
} else if (fragmentClass.equals(FavouriteFragment.class)) {
return 1;
} else if (fragmentClass.equals(AboutFragment.class)) {
return 2;
}
throw new IllegalArgumentException("Illegal fragment: " + fragment);
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
Fragment fragment = null;
int position = PagePos.EMPTY;
switch (menuItem.getItemId()) {
case R.id.nav_dictionary:
fragment = DictionaryFragment.newInstance(null);
position = PagePos.DICTIONARY;
break;
case R.id.nav_favourite:
fragment = FavouriteFragment.newInstance();
position = PagePos.FAVOURITE;
break;
case R.id.nav_about:
fragment = new AboutFragment();
position = PagePos.ABOUT;
break;
case R.id.settings:
fragment = new SettingFragment();
position = PagePos.SETTINGS;
}
if (mCurrentPage != position) {
showFragment(fragment, position);
}
return true;
}
});
}
private void setupDrawerLayout() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
mToolbar,
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/**
* Called when a drawer has settled in a completely closed state.
*/
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
/**
* Called when a drawer has settled in a completely open state.
*/
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
if (mIsVisible) {
handleIntent(intent);
}
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.app, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchItem = menu.findItem(R.id.search);
if (!mExpandedSearchView && TextUtils.isEmpty(mWord)) {
mExpandedSearchView = true;
MenuItemCompat.expandActionView(searchItem);
}
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
// FIXME: How to clear search icon focus
MenuItemCompat.collapseActionView(searchItem);
return false;
}
@Override
public boolean onQueryTextChange(String s) {
return false;
}
});
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int i) {
return false;
}
@Override
public boolean onSuggestionClick(int i) {
MenuItemCompat.collapseActionView(searchItem);
return false;
}
});
return true;
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction()) || ("com.google.android.gms.actions" +
".SEARCH_ACTION").equals(intent.getAction())) {
String word = intent.getStringExtra(SearchManager.QUERY);
showWord(word);
} else if (ACTION_VIEW_WORD.equals(intent.getAction())) {
Uri data = intent.getData();
ECDictionary ecDictionary = new ECDictionary(this);
String word = ecDictionary.lookupFromId(data.getLastPathSegment()).mWord;
showWord(word);
} else if (ACTION_SETTINGS.equals(intent.getAction())) {
Fragment fragment = new SettingFragment();
showFragment(fragment, PagePos.SETTINGS);
selectDrawerItem(PagePos.SETTINGS);
} else {
showWord(null);
}
}
private void showWord(String word) {
mWord = word;
if (mCurrentPage != PagePos.DICTIONARY) {
Fragment fragment = DictionaryFragment.newInstance(word);
selectDrawerItem(PagePos.DICTIONARY);
showFragment(fragment, PagePos.DICTIONARY);
} else {
EventBus.getDefault().post(new DictionaryFragment.UpdateWordEvent(word));
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
if (mBackStack.isEmpty()) {
super.onBackPressed();
} else {
Fragment fragment = mBackStack.pop();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content, fragment, null);
ft.commit();
int page = fragmentToPos(fragment);
mCurrentPage = page;
selectDrawerItem(page);
}
}
public void onEvent(LookupWordEvent event) {
String word = event.word;
Fragment fragment = DictionaryFragment.newInstance(word);
showFragment(fragment, PagePos.DICTIONARY);
selectDrawerItem(PagePos.DICTIONARY);
}
public static class LookupWordEvent {
public String word;
public LookupWordEvent(String word) {
this.word = word;
}
}
public static Intent getIntent(Context context, String word) {
Intent intent = new Intent(context, DictionaryActivity.class);
intent.setAction(Intent.ACTION_SEARCH);
intent.putExtra(SearchManager.QUERY, word);
intent.putExtra(EXTRA_FROM_TOAST, true);
return intent;
}
static class BackStack {
Stack<Fragment> mStack;
public BackStack() {
mStack = new Stack<Fragment>();
}
public void clear() {
mStack.clear();
}
public void push(Fragment fragment) {
mStack.push(fragment);
}
public Fragment pop() {
return mStack.pop();
}
public boolean isEmpty() {
return mStack.isEmpty();
}
}
}