package net.nightwhistler.pageturner.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ExpandableListView;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.github.rtyley.android.sherlock.roboguice.activity.RoboSherlockFragmentActivity;
import com.google.inject.Inject;
import com.limecreativelabs.sherlocksupport.ActionBarDrawerToggleCompat;
import jedi.option.Option;
import net.nightwhistler.pageturner.Configuration;
import net.nightwhistler.pageturner.PageTurner;
import net.nightwhistler.pageturner.R;
import net.nightwhistler.pageturner.view.NavigationCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import roboguice.RoboGuice;
import roboguice.inject.InjectView;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Superclass for all PageTurner activity classes.
*/
public abstract class PageTurnerActivity extends RoboSherlockFragmentActivity {
@InjectView(R.id.drawer_layout)
private DrawerLayout mDrawer;
@InjectView(R.id.left_drawer)
private ExpandableListView mDrawerOptions;
private ActionBarDrawerToggleCompat mToggle;
private NavigationAdapter adapter;
private CharSequence originalTitle;
private boolean drawerIsOpen;
@Inject
private Configuration config;
private static Logger LOG = LoggerFactory.getLogger("PageTurnerActivity");
@Override
protected final void onCreate(Bundle savedInstanceState) {
Configuration config = RoboGuice.getInjector(this).getInstance(Configuration.class);
PageTurner.changeLanguageSetting(this, config);
setTheme( getTheme(config) );
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState);
setContentView(getMainLayoutResource());
// set a custom shadow that overlays the main content when the drawer opens
mDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
// enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
initDrawerItems( mDrawerOptions );
mToggle = new ActionBarDrawerToggleCompat(this, mDrawer, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
PageTurnerActivity.this.onDrawerClosed(view);
}
public void onDrawerOpened(View drawerView) {
PageTurnerActivity.this.onDrawerOpened(drawerView);
}
};
mToggle.setDrawerIndicatorEnabled(true);
mDrawer.setDrawerListener(mToggle);
onCreatePageTurnerActivity(savedInstanceState);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
if ( action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK && isDrawerOpen() ) {
closeNavigationDrawer();
return true;
}
return super.dispatchKeyEvent(event);
}
protected void closeNavigationDrawer() {
mDrawer.closeDrawers();
}
protected NavigationAdapter getAdapter() {
return this.adapter;
}
protected void initDrawerItems( ExpandableListView expandableListView ) {
if ( expandableListView != null ) {
this.adapter = new NavigationAdapter( this, getMenuItems(config), this::createExpandableListView, 0);
setClickListeners( expandableListView, this.adapter );
}
}
private ExpandableListView createExpandableListView( List<NavigationCallback> items, int level ) {
ExpandableListView e = new ExpandableListView(this) {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/*
* Adjust height
*/
heightMeasureSpec = MeasureSpec.makeMeasureSpec(10000, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
setClickListeners(e, new NavigationAdapter(this, items, this::createExpandableListView, level ));
return e;
}
private void setClickListeners( ExpandableListView expandableListView, NavigationAdapter adapter ) {
expandableListView.setAdapter( adapter );
expandableListView.setOnGroupClickListener(
(e, v, groupId, l) -> this.onGroupClick(adapter, groupId) );
expandableListView.setOnChildClickListener(
(e, v, groupId, childId, l) -> this.onChildClick(adapter, groupId, childId));
expandableListView.setOnItemLongClickListener(
(av, v, position, id) -> this.onItemLongClick(adapter, position, id));
expandableListView.setGroupIndicator(null);
}
protected abstract int getMainLayoutResource();
protected void onCreatePageTurnerActivity( Bundle savedInstanceState ) {
}
protected void beforeLaunchActivity() {
}
protected int getTheme( Configuration config ) {
return config.getTheme();
}
protected List<NavigationCallback> getMenuItems( Configuration config ) {
List result = new ArrayList<>();
if ( new File(config.getLastOpenedFile()).exists() ) {
String nowReading = getString( R.string.now_reading, config.getLastReadTitle() );
result.add( navigate(nowReading, ReadingActivity.class));
}
result.add( navigate(getString(R.string.open_library), LibraryActivity.class) );
result.add( navigate(getString(R.string.download), CatalogActivity.class));
result.add( new NavigationCallback(getString(R.string.prefs)).setOnClick(this::startPreferences));
return result;
}
protected void startPreferences() {
Intent intent = new Intent(this, PageTurnerPrefsActivity.class);
beforeLaunchActivity();
startActivity(intent);
}
protected NavigationCallback navigate( String title, Class<? extends PageTurnerActivity> classToStart ) {
return new NavigationCallback( title ).setOnClick(
() -> launchActivity(classToStart));
}
public void onDrawerClosed(View view) {
this.drawerIsOpen = false;
getSupportActionBar().setTitle(originalTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
this.drawerIsOpen = true;
this.originalTitle = getSupportActionBar().getTitle();
getSupportActionBar().setTitle(R.string.app_name);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
protected boolean isDrawerOpen() {
return drawerIsOpen;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
initDrawerItems( mDrawerOptions );
return super.onPrepareOptionsMenu(menu);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setSupportProgressBarIndeterminate(true);
setSupportProgressBarIndeterminateVisibility(false);
mToggle.syncState();
}
public void launchActivity(Class<? extends PageTurnerActivity> activityClass) {
Intent intent = new Intent(this, activityClass);
beforeLaunchActivity();
config.setLastActivity( activityClass );
startActivity(intent);
finish();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// I think there's a bug in mToggle.onOptionsItemSelected, because it always returns false.
// The item id testing is a fix.
if (mToggle.onOptionsItemSelected(item) || item.getItemId() == android.R.id.home) {
return true;
}
return super.onOptionsItemSelected(item);
}
protected boolean onGroupClick(NavigationAdapter adapter, int groupId ) {
LOG.debug( "Got onGroupClick for group " + groupId + " on level " + adapter.getLevel() );
Option<Boolean> group =adapter.findGroup(groupId).map(g -> {
if (g.hasChildren()) {
return false; //Let the superclass handle it and expand the group
} else {
g.onClick();
closeNavigationDrawer();
return true;
}
});
return group.getOrElse( false );
}
protected boolean onChildClick(NavigationAdapter adapter, int groupId, int childId) {
LOG.debug("Got onChildClick event for group " + groupId + " and child " + childId
+ " on level " + adapter.getLevel() );
Option<NavigationCallback> childItem = adapter.findChild(groupId, childId);
childItem.forEach(item -> {
if ( ! item.hasChildren() ) {
item.onClick();
closeNavigationDrawer();
}
});
return false;
}
protected boolean onItemLongClick(NavigationAdapter adapter, int position, long id) {
LOG.debug("Got long click on position" + position + " on level " + adapter.getLevel() );
if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
int groupPosition = ExpandableListView.getPackedPositionGroup(id);
int childPosition = getAdapter().getIndexForChildId( groupPosition,
ExpandableListView.getPackedPositionChild(id) );
Option<NavigationCallback> childItem = adapter.findChild(groupPosition, childPosition);
LOG.debug("Long-click on " + groupPosition + ", " + childPosition );
LOG.debug("Child-item: " + childItem );
childItem.match(
NavigationCallback::onLongClick,
() -> LOG.error( "Could not get child-item for " + position + " and id " + id )
);
closeNavigationDrawer();
return true;
}
return false;
}
}