package yuku.alkitab.base.widget;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.widget.SwitchCompat;
import android.text.SpannableStringBuilder;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.PopupMenu;
import android.widget.Spinner;
import android.widget.TextView;
import yuku.afw.V;
import yuku.afw.storage.Preferences;
import yuku.afw.widget.EasyAdapter;
import yuku.alkitab.base.App;
import yuku.alkitab.base.IsiActivity;
import yuku.alkitab.base.S;
import yuku.alkitab.base.ac.AboutActivity;
import yuku.alkitab.base.ac.DevotionActivity;
import yuku.alkitab.base.ac.ReadingPlanActivity;
import yuku.alkitab.base.ac.SettingsActivity;
import yuku.alkitab.base.ac.SongViewActivity;
import yuku.alkitab.base.config.AppConfig;
import yuku.alkitab.base.storage.Prefkey;
import yuku.alkitab.base.util.CurrentReading;
import yuku.alkitab.base.util.SongBookUtil;
import yuku.alkitab.debug.R;
import java.util.ArrayList;
import java.util.List;
public abstract class LeftDrawer extends NestedScrollView {
// mandatory
TextView bBible;
TextView bDevotion;
TextView bReadingPlan;
TextView bSongs;
View bSettings;
View bHelp;
// for launching other activities
final Activity activity;
// for closing drawer
DrawerLayout drawerLayout;
public LeftDrawer(final Context context, final AttributeSet attrs) {
super(context, attrs);
activity = isInEditMode() ? null : (Activity) context;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
setClickable(true);
for (int i = 0, len = getChildCount(); i < len; i++) {
getChildAt(i).setDuplicateParentStateEnabled(false);
}
bBible = V.get(this, R.id.bBible);
bDevotion = V.get(this, R.id.bDevotion);
bReadingPlan = V.get(this, R.id.bReadingPlan);
bSongs = V.get(this, R.id.bSongs);
bSettings = V.get(this, R.id.bSettings);
bHelp = V.get(this, R.id.bHelp);
final int selectedTextColor = ResourcesCompat.getColor(getResources(), R.color.accent, getContext().getTheme());
if (this instanceof Text) bBible.setTextColor(selectedTextColor);
if (this instanceof Devotion) bDevotion.setTextColor(selectedTextColor);
if (this instanceof ReadingPlan) bReadingPlan.setTextColor(selectedTextColor);
if (this instanceof Songs) bSongs.setTextColor(selectedTextColor);
// hide and show according to app config
if (!isInEditMode()) {
bSongs.setVisibility(AppConfig.get().menuSongs ? VISIBLE : GONE);
bDevotion.setVisibility(AppConfig.get().menuDevotion ? VISIBLE : GONE);
}
bBible.setOnClickListener(v -> {
bBible_click();
closeDrawer();
});
bDevotion.setOnClickListener(v -> {
bDevotion_click();
closeDrawer();
});
bReadingPlan.setOnClickListener(v -> {
bReadingPlan_click();
closeDrawer();
});
bSongs.setOnClickListener(v -> {
bSongs_click();
closeDrawer();
});
bSettings.setOnClickListener(v -> {
bSettings_click();
closeDrawer();
});
bHelp.setOnClickListener(v -> {
bHelp_click();
closeDrawer();
});
}
@Override
public boolean onDragEvent(final DragEvent event) {
if (event.getAction() == DragEvent.ACTION_DRAG_STARTED) {
App.trackEvent("pin_drag_started");
if (event.getClipDescription().hasMimeType(VerseItem.PROGRESS_MARK_DRAG_MIME_TYPE)) {
return true; // Just to that the progress pin is not dropped to the verses
}
}
return false;
}
public void toggleDrawer() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
drawerLayout.openDrawer(GravityCompat.START);
}
}
public void closeDrawer() {
drawerLayout.closeDrawer(GravityCompat.START);
}
void bHelp_click() {
activity.startActivity(AboutActivity.createIntent());
}
void bSettings_click() {
activity.startActivity(SettingsActivity.createIntent());
}
/**
* When the current activity is not {@link yuku.alkitab.base.IsiActivity},
* this clears all activity on this stack,
* starts {@link yuku.alkitab.base.IsiActivity} on the background,
* and then starts {@link yuku.alkitab.base.ac.ReadingPlanActivity}.
*/
void bReadingPlan_click() {
if (getContext() instanceof IsiActivity) {
activity.startActivity(ReadingPlanActivity.createIntent());
} else {
final Intent baseIntent = IsiActivity.createIntent();
baseIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
baseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final Intent intent = ReadingPlanActivity.createIntent();
activity.startActivities(new Intent[]{baseIntent, intent});
}
}
/**
* When the current activity is not {@link yuku.alkitab.base.IsiActivity},
* this clears all activity on this stack,
* starts {@link yuku.alkitab.base.IsiActivity} on the background,
* and then starts {@link yuku.alkitab.base.ac.SongViewActivity}.
*/
void bSongs_click() {
if (getContext() instanceof IsiActivity) {
activity.startActivity(SongViewActivity.createIntent());
} else {
final Intent baseIntent = IsiActivity.createIntent();
baseIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
baseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final Intent intent = SongViewActivity.createIntent();
activity.startActivities(new Intent[]{baseIntent, intent});
}
}
/**
* When the current activity is not {@link yuku.alkitab.base.IsiActivity},
* this clears all activity on this stack,
* starts {@link yuku.alkitab.base.IsiActivity} on the background,
* and then starts {@link yuku.alkitab.base.ac.DevotionActivity}.
*/
void bDevotion_click() {
if (getContext() instanceof IsiActivity) {
activity.startActivity(DevotionActivity.createIntent());
} else {
final Intent baseIntent = IsiActivity.createIntent();
baseIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
baseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final Intent intent = DevotionActivity.createIntent();
activity.startActivities(new Intent[]{baseIntent, intent});
}
}
/**
* This clears all activity on this stack and starts {@link yuku.alkitab.base.IsiActivity}.
*/
void bBible_click() {
final Intent intent = IsiActivity.createIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
}
public static class Text extends LeftDrawer {
public interface Listener {
void bMarkers_click();
void bDisplay_click();
void cFullScreen_checkedChange(boolean isChecked);
void cNightMode_checkedChange(boolean isChecked);
void cSplitVersion_checkedChange(final SwitchCompat cSplitVersion, boolean isChecked);
void bProgressMarkList_click();
void bProgress_click(int preset_id);
void bCurrentReadingClose_click();
void bCurrentReadingReference_click();
}
public interface Handle {
void setFullScreen(boolean fullScreen);
void setSplitVersion(boolean splitVersion);
}
View bMarkers;
View bDisplay;
SwitchCompat cFullScreen;
SwitchCompat cNightMode;
SwitchCompat cSplitVersion;
View bProgressMarkList;
View bProgress1;
View bProgress2;
View bProgress3;
View bProgress4;
View bProgress5;
View panelCurrentReadingHeader;
View bCurrentReadingClose;
TextView bCurrentReadingReference;
Listener listener;
Handle handle = new Handle() {
@Override
public void setFullScreen(final boolean fullScreen) {
cFullScreen.setOnCheckedChangeListener(null);
cFullScreen.setChecked(fullScreen);
cFullScreen.setOnCheckedChangeListener(cFullScreen_checkedChange);
}
@Override
public void setSplitVersion(final boolean splitVersion) {
cSplitVersion.setOnCheckedChangeListener(null);
cSplitVersion.setChecked(splitVersion);
cSplitVersion.setOnCheckedChangeListener(cSplitVersion_checkedChange);
}
};
public Text(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public Handle getHandle() {
return handle;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
bMarkers = V.get(this, R.id.bMarkers);
bDisplay = V.get(this, R.id.bDisplay);
cFullScreen = V.get(this, R.id.cFullScreen);
cNightMode = V.get(this, R.id.cNightMode);
cSplitVersion = V.get(this, R.id.cSplitVersion);
bProgressMarkList = V.get(this, R.id.bProgressMarkList);
bProgress1 = V.get(this, R.id.bProgress1);
bProgress2 = V.get(this, R.id.bProgress2);
bProgress3 = V.get(this, R.id.bProgress3);
bProgress4 = V.get(this, R.id.bProgress4);
bProgress5 = V.get(this, R.id.bProgress5);
panelCurrentReadingHeader = V.get(this, R.id.panelCurrentReadingHeader);
bCurrentReadingClose = V.get(this, R.id.bCurrentReadingClose);
bCurrentReadingReference = V.get(this, R.id.bCurrentReadingReference);
cNightMode.setChecked(!isInEditMode() && Preferences.getBoolean(Prefkey.is_night_mode, false));
bProgressMarkList.setOnClickListener(v -> listener.bProgressMarkList_click());
final View[] views = new View[]{bProgress1, bProgress2, bProgress3, bProgress4, bProgress5};
for (int i = 0; i < views.length; i++) {
final View b = views[i];
final int preset_id = i;
b.setOnClickListener(v -> {
listener.bProgress_click(preset_id);
closeDrawer();
});
b.setOnLongClickListener(v -> {
final ClipData dragData = new ClipData("progress_mark", new String[]{VerseItem.PROGRESS_MARK_DRAG_MIME_TYPE}, new ClipData.Item("" + preset_id));
b.setPressed(false);
final DragShadowBuilder dragShadowBuilder = new DragShadowBuilder(b);
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
closeDrawer();
v.startDrag(dragData, dragShadowBuilder, null, 0);
return true;
});
}
bMarkers.setOnClickListener(v -> {
listener.bMarkers_click();
closeDrawer();
});
bDisplay.setOnClickListener(v -> {
listener.bDisplay_click();
closeDrawer();
});
cFullScreen.setOnCheckedChangeListener(cFullScreen_checkedChange);
cNightMode.setOnCheckedChangeListener(cNightMode_checkedChange);
cSplitVersion.setOnCheckedChangeListener(cSplitVersion_checkedChange);
bCurrentReadingClose.setOnClickListener(v -> listener.bCurrentReadingClose_click());
bCurrentReadingReference.setOnClickListener(v -> listener.bCurrentReadingReference_click());
displayCurrentReading();
// The following is not in onAttachedFromWindow, because we need to listen to
// ACTION_ACTIVE_VERSION_CHANGED as early as possible, so we do not end up with
// a verse reference from a version that was not actually selected during app startup.
final IntentFilter filter = new IntentFilter();
filter.addAction(CurrentReading.ACTION_CURRENT_READING_CHANGED);
filter.addAction(IsiActivity.ACTION_ACTIVE_VERSION_CHANGED);
App.getLbm().registerReceiver(currentReadingChangeReceiver, filter);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
App.getLbm().unregisterReceiver(currentReadingChangeReceiver);
}
final BroadcastReceiver currentReadingChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
displayCurrentReading();
}
};
void displayCurrentReading() {
if (isInEditMode()) return;
final int[] aris = CurrentReading.get();
if (aris == null) {
panelCurrentReadingHeader.setVisibility(GONE);
bCurrentReadingReference.setVisibility(GONE);
} else {
panelCurrentReadingHeader.setVisibility(VISIBLE);
bCurrentReadingReference.setVisibility(VISIBLE);
bCurrentReadingReference.setText(S.activeVersion.referenceRange(aris[0], aris[1]));
}
}
CompoundButton.OnCheckedChangeListener cFullScreen_checkedChange = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
listener.cFullScreen_checkedChange(isChecked);
}
};
CompoundButton.OnCheckedChangeListener cNightMode_checkedChange = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
listener.cNightMode_checkedChange(isChecked);
}
};
CompoundButton.OnCheckedChangeListener cSplitVersion_checkedChange = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
listener.cSplitVersion_checkedChange(cSplitVersion, isChecked);
closeDrawer();
}
};
public <T extends Activity & Listener> void configure(T listener, DrawerLayout drawerLayout) {
this.listener = listener;
this.drawerLayout = drawerLayout;
}
@Override
void bBible_click() {
closeDrawer();
}
}
public static class Devotion extends LeftDrawer {
DevotionKindAdapter adapter;
public interface Listener {
void bPrev_click();
void bNext_click();
void bReload_click();
void cbKind_itemSelected(DevotionActivity.DevotionKind kind);
}
public interface Handle {
void setDevotionDate(CharSequence date);
void setDevotionKind(DevotionActivity.DevotionKind kind);
}
Spinner cbKind;
TextView tCurrentDate;
View bPrev;
View bNext;
View bReload;
Listener listener;
Handle handle = new Handle() {
@Override
public void setDevotionDate(final CharSequence date) {
tCurrentDate.setText(date);
}
@Override
public void setDevotionKind(final DevotionActivity.DevotionKind kind) {
final AdapterView.OnItemSelectedListener backup = cbKind.getOnItemSelectedListener();
cbKind.setOnItemSelectedListener(null);
cbKind.setSelection(adapter.getPositionForKind(kind));
cbKind.setOnItemSelectedListener(backup);
}
};
public Devotion(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public Handle getHandle() {
return handle;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
cbKind = V.get(this, R.id.cbKind);
tCurrentDate = V.get(this, R.id.tCurrentDate);
bPrev = V.get(this, R.id.bPrev);
bNext = V.get(this, R.id.bNext);
bReload = V.get(this, R.id.bReload);
cbKind.setAdapter(adapter = new DevotionKindAdapter());
cbKind.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(final AdapterView<?> parent, final View view, final int position, final long id) {
listener.cbKind_itemSelected(adapter.getItem(position));
}
@Override
public void onNothingSelected(final AdapterView<?> parent) {
}
});
bPrev.setOnClickListener(v -> listener.bPrev_click());
bNext.setOnClickListener(v -> listener.bNext_click());
bReload.setOnClickListener(v -> {
listener.bReload_click();
closeDrawer();
});
}
public <T extends Activity & Listener> void configure(T listener, DrawerLayout drawerLayout) {
this.listener = listener;
this.drawerLayout = drawerLayout;
}
@Override
void bDevotion_click() {
closeDrawer();
}
class DevotionKindAdapter extends EasyAdapter {
final List<DevotionActivity.DevotionKind> kinds = new ArrayList<>();
{
// gather available devotions based on app config
for (String devotionName : AppConfig.get().devotionNames) {
kinds.add(DevotionActivity.DevotionKind.getByName(devotionName));
}
}
@Override
public View newView(final int position, final ViewGroup parent) {
return LayoutInflater.from(getContext()).inflate(android.R.layout.simple_spinner_item, parent, false);
}
@Override
public DevotionActivity.DevotionKind getItem(final int position) {
return kinds.get(position);
}
@Override
public void bindView(final View view, final int position, final ViewGroup parent) {
final DevotionActivity.DevotionKind kind = getItem(position);
final SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(kind.title);
sb.append("\n");
final int sb_len = sb.length();
sb.append(kind.subtitle);
sb.setSpan(new RelativeSizeSpan(0.7f), sb_len, sb.length(), 0);
((TextView) view).setText(sb);
}
@Override
public View newDropDownView(final int position, final ViewGroup parent) {
final TextView res = (TextView) LayoutInflater.from(getContext()).inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
res.setSingleLine(false);
return res;
}
@Override
public int getCount() {
return kinds.size();
}
public int getPositionForKind(final DevotionActivity.DevotionKind kind) {
return kinds.indexOf(kind);
}
}
}
public static class ReadingPlan extends LeftDrawer {
public interface Listener {
void bRestart_click();
}
public interface Handle {
void setDescription(CharSequence description);
}
NestedScrollView scrollDescription;
TextView tDescription;
View bRestart;
Listener listener;
Handle handle = new Handle() {
@Override
public void setDescription(final CharSequence description) {
if (description == null) {
bRestart.setVisibility(GONE);
scrollDescription.setVisibility(GONE);
tDescription.setText("");
} else {
bRestart.setVisibility(VISIBLE);
scrollDescription.setVisibility(VISIBLE);
tDescription.setText(description);
}
}
};
public ReadingPlan(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public Handle getHandle() {
return handle;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
scrollDescription = V.get(this, R.id.scrollDescription);
tDescription = V.get(this, R.id.tDescription);
bRestart = V.get(this, R.id.bRestart);
bRestart.setOnClickListener(v -> listener.bRestart_click());
}
@Override
void bReadingPlan_click() {
closeDrawer();
}
public <T extends Activity & Listener> void configure(T listener, DrawerLayout drawerLayout) {
this.listener = listener;
this.drawerLayout = drawerLayout;
}
}
public static class Songs extends LeftDrawer {
public interface Listener {
void songKeypadButton_click(View v);
void songBookSelected(String name);
void moreSelected();
}
public interface Handle {
void setOkButtonEnabled(boolean enabled);
void setAButtonEnabled(boolean enabled);
void setBButtonEnabled(boolean enabled);
void setCButtonEnabled(boolean enabled);
void setBookName(CharSequence bookName);
void setCode(String code);
}
Listener listener;
Handle handle = new Handle() {
@Override
public void setOkButtonEnabled(boolean enabled) {
bOk.setEnabled(enabled);
}
@Override
public void setAButtonEnabled(boolean enabled) {
bDigitA.setEnabled(enabled);
}
@Override
public void setBButtonEnabled(boolean enabled) {
bDigitB.setEnabled(enabled);
}
@Override
public void setCButtonEnabled(boolean enabled) {
bDigitC.setEnabled(enabled);
}
@Override
public void setBookName(final CharSequence bookName) {
bChangeBook.setText(bookName);
}
@Override
public void setCode(final String code) {
bChangeCode.setText(code);
}
};
public Songs(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
TextView bChangeBook;
TextView bChangeCode;
Button bOk;
Button bDigitA;
Button bDigitB;
Button bDigitC;
public Handle getHandle() {
return handle;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
bChangeBook = V.get(this, R.id.bChangeBook);
bChangeCode = V.get(this, R.id.bChangeCode);
bOk = V.get(this, R.id.bOk);
bDigitA = V.get(this, R.id.bDigitA);
bDigitB = V.get(this, R.id.bDigitB);
bDigitC = V.get(this, R.id.bDigitC);
bChangeBook.setOnClickListener(v -> {
final PopupMenu popupChangeBook = SongBookUtil.getSongBookPopupMenu(activity, false, true, bChangeBook);
popupChangeBook.setOnMenuItemClickListener(SongBookUtil.getSongBookOnMenuItemClickListener(new SongBookUtil.DefaultOnSongBookSelectedListener() {
@Override
public void onSongBookSelected(final String name) {
listener.songBookSelected(name);
}
@Override
public void onMoreSelected() {
listener.moreSelected();
}
}));
popupChangeBook.show();
});
// all buttons
for (int buttonId : new int[]{
R.id.bDigit0,
R.id.bDigit1,
R.id.bDigit2,
R.id.bDigit3,
R.id.bDigit4,
R.id.bDigit5,
R.id.bDigit6,
R.id.bDigit7,
R.id.bDigit8,
R.id.bDigit9,
R.id.bDigitA,
R.id.bDigitB,
R.id.bDigitC,
R.id.bOk,
R.id.bBackspace,
}) {
V.get(this, buttonId).setOnClickListener(button_click);
}
}
final OnClickListener button_click = v -> {
if (listener != null) {
listener.songKeypadButton_click(v);
}
};
@Override
void bSongs_click() {
closeDrawer();
}
public <T extends Activity & Listener> void configure(T listener, DrawerLayout drawerLayout) {
this.listener = listener;
this.drawerLayout = drawerLayout;
}
}
}