/**
* Copyright (c) 2015 unfoldingWord
* http://creativecommons.org/licenses/MIT/
* See LICENSE file for details.
* Contributors:
* PJ Fechner <pj@actsmedia.com>
*/
package activity.reading;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.github.peejweej.androidsideloading.fragments.TypeChoosingFragment;
import com.github.peejweej.androidsideloading.model.SideLoadInformation;
import com.infteh.comboseekbar.ComboSeekBar;
import org.unfoldingword.mobile.R;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import activity.AnimationParadigm;
import activity.UWBaseActivity;
import activity.readingSelection.BookSelectionActivity;
import activity.readingSelection.VersionSelectionActivity;
import de.greenrobot.event.EventBus;
import eventbusmodels.BiblePagingEvent;
import eventbusmodels.DownloadResult;
import eventbusmodels.StoriesPagingEvent;
import fragments.BitrateFragment;
import fragments.Reading.ReadingFragmentListener;
import fragments.ResourceChoosingFragment;
import fragments.selection.ChapterSelectionFragment;
import fragments.selection.StoryChaptersFragment;
import model.AudioBitrate;
import model.DataFileManager;
import model.DownloadState;
import model.SharingHelper;
import model.daoModels.Book;
import model.daoModels.Project;
import model.daoModels.Version;
import model.parsers.MediaType;
import services.UWBookMediaDownloaderService;
import singletons.UWAudioPlayer;
import view.AudioPlayerViewGroup;
import view.ReadingTabBar;
import view.ReadingToolbarViewBibleModel;
import view.ReadingToolbarViewData;
import view.ReadingToolbarViewStoriesModel;
import view.UWReadingToolbarViewGroup;
import view.UWTabBar;
/**
* Created by PJ Fechner on 5/12/14.
* abstract activity to handle most of the logic involved in the different reading activites.
*/
public abstract class BaseReadingActivity extends UWBaseActivity implements
ReadingFragmentListener,
UWReadingToolbarViewGroup.UWReadingToolbarListener,
UWAudioPlayer.UWAudioPlayerListener,
ResourceChoosingFragment.ResourceChoosingListener
{
private static final String TAG = "ReadingActivity";
private static final String IS_HIDDEN_PARAM = "IS_HIDDEN_PARAM";
private static final String IS_DIGLOT_PARAM = "IS_DIGLOT_PARAM";
public static final String SCROLLED_PAGE = "SCROLLED_PAGE" ;
private static final String VERSION_FRAGMENT_ID = "VERSION_FRAGMENT_ID";
private static final String CHAPTER_SELECTION_FRAGMENT_ID = "CHAPTER_SELECTION_FRAGMENT_ID";
// protected static final String CHECKING_LEVEL_FRAGMENT_ID = "CHECKING_LEVEL_FRAGMENT_ID";
protected FrameLayout readingLayout;
protected FrameLayout secondaryReadingLayout;
protected View errorView;
private ReadingTabBar tabBar;
private UWReadingToolbarViewGroup readingToolbar;
private ViewGroup audioPlayerLayout;
private AudioPlayerViewGroup audioPlayerViewGroup;
private boolean isMini = false;
private boolean isDiglot = false;
private boolean showingAudio = false;
//region Abstract Methods
/**
* @return the current Book being used
*/
abstract protected Book getBook();
/**
* @return The project for the current activity
*/
abstract protected Project getProject();
/**
* @return Version to be shared
*/
abstract protected Version getSharingVersion();
/**
* @return the options for text sizes
*/
abstract protected List<String> getTextSizeOptions();
abstract protected int getCurrentTextSizeIndex();
/**
* should set the text size, chosen by the text slide
* @param index index of the option chosen
*/
abstract protected void setNewTextSize(int index);
/**
* @return View data for the toolbar
*/
abstract protected ReadingToolbarViewData getToolbarViewData();
//endregion
//region Activity Override Methods
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reading);
setupViews();
if(getBook() == null){
gotoVersionSelection(false);
}
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
public void onEventMainThread(DownloadResult event){
downloadEnded(event);
}
public void onEventMainThread(BiblePagingEvent event){
updateToolbar(new ReadingToolbarViewBibleModel(event.mainChapter, event.secondaryChapter));
}
public void onEventMainThread(StoriesPagingEvent event){
updateToolbar(new ReadingToolbarViewStoriesModel(event.mainStoryPage, event.secondaryStoryPage));
}
private void downloadEnded(DownloadResult result){
String resultText = "";
switch (result){
case DOWNLOAD_RESULT_SUCCESS:{
resultText = "Succeeded";
break;
}
case DOWNLOAD_RESULT_CANCELED:{
resultText = "Was Canceled";
break;
}
case DOWNLOAD_RESULT_FAILED:{
resultText = "Failed";
break;
}
}
Toast.makeText(this, "Download " + resultText, Toast.LENGTH_SHORT).show();
Book book = getBook();
book.refresh();
DataFileManager.getStateOfContent(getApplicationContext(), Arrays.asList(book.getVersion()), MediaType.MEDIA_TYPE_AUDIO, new DataFileManager.GetDownloadStateResponse() {
@Override
public void foundDownloadState(DownloadState state) {
audioPlayerViewGroup.handleDownloadState(state);
update();
}
});
}
protected void setupViews(){
audioPlayerLayout = (ViewGroup) (findViewById(R.id.audio_player));
readingLayout = (FrameLayout) findViewById(R.id.reading_fragment_frame);
secondaryReadingLayout = (FrameLayout) findViewById(R.id.secondary_reading_fragment_frame);
errorView = findViewById(R.id.no_version_layout);
ComboSeekBar seekBar = (ComboSeekBar) findViewById(R.id.seek_bar);
List<String> seekBarStep = Arrays.asList("", "", "", "", "", "");
seekBar.setAdapter(seekBarStep);
seekBar.setSelection(getCurrentTextSizeIndex());
seekBar.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setNewTextSize(position);
}
});
}
public void updateToolbar(ReadingToolbarViewData data){
if(readingToolbar != null){
readingToolbar.setViewData(data);
}
else {
readingToolbar = new UWReadingToolbarViewGroup((Toolbar) findViewById(R.id.toolbar), this, data, this);
}
}
/**
* after this method is run all views and data should be updated
*/
protected void update(){
updateToolbar(getToolbarViewData());
setupTabBar();
updateTabBar();
}
protected boolean toggleDiglot(){
isDiglot = !isDiglot;
return isDiglot;
}
@Override
public void backButtonClicked() {
handleBack();
}
@Override
public void chaptersButtonClicked() {
goToChapterActivity();
}
@Override
public void mainVersionButtonClicked() {
gotoVersionSelection(false);
}
@Override
public void secondaryVersionButtonClicked() {
gotoVersionSelection(true);
}
@Override
protected void onResume() {
super.onResume();
if(audioPlayerViewGroup != null){
audioPlayerViewGroup.onResume();
}
update();
if(getBook() == null){
errorView.setVisibility(View.VISIBLE);
findViewById(R.id.tab_bar_view).setVisibility(View.INVISIBLE);
setAudioPlayerVisibility(false);
}
else {
findViewById(R.id.tab_bar_view).setVisibility(View.VISIBLE);
errorView.setVisibility(View.GONE);
registerForListeners();
}
}
private void registerForListeners(){
UWAudioPlayer.getInstance(getApplicationContext()).addListener(this);
}
@Override
protected void onPause() {
super.onPause();
if(audioPlayerViewGroup != null){
audioPlayerViewGroup.onPause();
}
unregisterListeners();
}
private void unregisterListeners(){
UWAudioPlayer.getInstance(getApplicationContext()).removeListener(this);
}
@Override
public void onBackPressed(boolean isSharing) {
if(!isSharing) {
super.onBackPressed(isSharing);
}
}
@Override
protected void handleBack() {
super.handleBack();
UWAudioPlayer.getInstance(getApplicationContext()).reset();
}
@Override
public AnimationParadigm getAnimationParadigm() {
return AnimationParadigm.ANIMATION_LEFT_RIGHT;
}
//endregion
//region userInteraction
public void versionSelectionButtonClicked(View view) {
gotoVersionSelection(false);
}
//endregion
//region setup
private void setupReadingVisibility(boolean visible){
if (visible) {
readingLayout.setVisibility(View.VISIBLE);
setNoVersionSelectedVisibility(false);
}
else{
readingLayout.setVisibility(View.GONE);
setNoVersionSelectedVisibility(true);
}
}
// protected void setTextLargerDisabled(boolean disabled){
//
// findViewById(R.id.larger_text_button).setClickable(!disabled);
// findViewById(R.id.larger_text_button).setEnabled(!disabled);
//
// }
//
// protected void setTextSmallerDisabled(boolean disabled){
//
// findViewById(R.id.smaller_text_button).setClickable(!disabled);
// findViewById(R.id.smaller_text_button).setEnabled(!disabled);
// }
private void setupTabBar(){
ViewGroup baseAudioPlayerLayout = (RelativeLayout) findViewById(R.id.audio_player);
baseAudioPlayerLayout.setVisibility(View.GONE);
int[] images = {R.drawable.audio_normal, R.drawable.video_normal,
R.drawable.font_normal, R.drawable.diglot_normal,
R.drawable.share_normal};
tabBar = new ReadingTabBar(getApplicationContext(), images, (ViewGroup) findViewById(R.id.tab_bar_view), baseAudioPlayerLayout, new UWTabBar.BottomBarListener() {
@Override
public void buttonPressedAtIndex(int index) {
tabBarPressed(index);
}
});
}
@Override
public void paused() {
setAudioButtonState(false);
}
@Override
public void update(long duration, long progress) {
}
@Override
public void started() {
setAudioButtonState(true);
}
private void updateTabBar(){
boolean hasAudioBook = (getBook() != null && getBook().getAudioBook() != null);
tabBar.getButton(0).setEnabled(hasAudioBook);
tabBar.getButton(0).setClickable(hasAudioBook);
tabBar.setImageAtIndex((hasAudioBook) ? R.drawable.audio_normal : R.drawable.audio_disabled, 0);
if(audioPlayerLayout != null && !hasAudioBook){
audioPlayerLayout.setVisibility(View.GONE);
}
if(audioPlayerViewGroup != null) {
Book book = getBook();
if(book != null) {
book.refresh();
DataFileManager.getStateOfContent(getApplicationContext(), book.getVersion(), MediaType.MEDIA_TYPE_TEXT, new DataFileManager.GetDownloadStateResponse() {
@Override
public void foundDownloadState(DownloadState state) {
audioPlayerViewGroup.handleDownloadState(state);
}
});
}
}
boolean hasVideo = false;
tabBar.getButton(1).setEnabled(hasVideo);
tabBar.getButton(1).setClickable(hasVideo);
tabBar.setImageAtIndex((hasVideo) ? R.drawable.video_normal : R.drawable.video_disabled, 1);
setAudioPlayerVisibility(showingAudio);
}
private void setupAudioPlayer(){
audioPlayerViewGroup = new AudioPlayerViewGroup(getApplicationContext(), audioPlayerLayout, new AudioPlayerViewGroup.AudioPlayerViewGroupListener() {
@Override
public void downloadClicked() {
audioPlayerViewGroup.handleDownloadState(DownloadState.DOWNLOAD_STATE_DOWNLOADING);
downloadBookAudio();
}
});
}
private void downloadBookAudio() {
BitrateFragment.newInstance(getBook().getAudioBook().getAudioChapters().get(0).getBitRates(),
"Select Audio Bitrate", new BitrateFragment.BitrateFragmentListener() {
@Override
public void bitrateChosen(DialogFragment fragment, AudioBitrate bitrate) {
Intent downloadIntent = new Intent(getApplicationContext(), UWBookMediaDownloaderService.class);
downloadIntent.putExtra(UWBookMediaDownloaderService.BOOK_ID_PARAM, getBook().getId());
downloadIntent.putExtra(UWBookMediaDownloaderService.IS_VIDEO_PARAM, false);
downloadIntent.putExtra(UWBookMediaDownloaderService.BITRATE_PARAM, bitrate);
getApplicationContext().startService(downloadIntent);
fragment.dismiss();
}
@Override
public void dismissed() {
}
}).show(getSupportFragmentManager(), "BitrateFragment");
}
private BroadcastReceiver createBroadcastReceiver() {
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Download Complete", Toast.LENGTH_SHORT).show();
Book book = getBook();
book.refresh();
DataFileManager.getStateOfContent(context, book.getVersion(), MediaType.MEDIA_TYPE_AUDIO, new DataFileManager.GetDownloadStateResponse() {
@Override
public void foundDownloadState(DownloadState state) {
audioPlayerViewGroup.handleDownloadState(state);
update();
}
});
}
};
}
private void setAudioButtonState(boolean isPlaying){
tabBar.setImageAtIndex((isPlaying) ? R.drawable.audio_active : R.drawable.audio_normal, 0);
}
private void tabBarPressed(int index){
switch (index){
case 0:{
toggleAudioPlayerVisibility();
break;
}
case 1:{
Intent intent = new Intent((android.content.Intent.ACTION_VIEW));
intent.setDataAndType(Uri.parse("https://api.unfoldingword.org/uw/video/beta/01-GEN-br256-640x432.mp4"), "video/avi");
startActivity(intent);
break;
}
case 2:{
toggleTextSizeVisibility();
break;
}
case 3:{
readingToolbar.setHasTwoVersions(toggleDiglot());
break;
}
case 4:{
shareVersion();
break;
}
}
}
private void toggleAudioPlayerVisibility(){
setAudioPlayerVisibility(audioPlayerLayout.getVisibility() != View.VISIBLE);
}
private void setAudioPlayerVisibility(boolean visible){
if(audioPlayerViewGroup == null){
setupAudioPlayer();
}
if(getBook() != null && !getBook().getVersion().hasAudio()){
visible = false;
}
audioPlayerLayout.setVisibility((visible) ? View.VISIBLE : View.GONE);
if(getBook() != null) {
DataFileManager.getStateOfContent(getApplicationContext(), getBook().getVersion(), MediaType.MEDIA_TYPE_AUDIO, new DataFileManager.GetDownloadStateResponse() {
@Override
public void foundDownloadState(DownloadState state) {
audioPlayerViewGroup.handleDownloadState(state);
}
});
}
showingAudio = visible;
}
// @Override
// public void storagePermissionWasGranted() {
// shareVersion();
// }
private void shareVersion(){
if(!verifyOrRequestStoragePermissions()) {
return;
}
Version sharingVersion = getSharingVersion();
if(sharingVersion != null) {
shareVersion(sharingVersion);
}
}
private void shareVersion(Version version){
setLoadingFragmentVisibility(true, "Preparing...", false);
if(version.hasVideo() || (version.hasAudio())){
Version[] versions = {version};
setLoadingFragmentVisibility(false, "", false);
ResourceChoosingFragment.newInstance(versions).show(getSupportFragmentManager(), "ResourceChoosingFragment");
}
else{
Map<Version, List<MediaType>> sharingChoices = new HashMap<>();
sharingChoices.put(version, Arrays.asList(MediaType.MEDIA_TYPE_TEXT));
setLoadingFragmentVisibility(false, "", false);
shareVersion(sharingChoices);
}
}
@Override
public void resourcesChosen(DialogFragment dialogFragment, Map<Version, List<MediaType>> sharingChoices) {
shareVersion(sharingChoices);
dialogFragment.dismiss();
}
private void shareVersion(Map<Version, List<MediaType>> sharingChoices){
setLoadingFragmentVisibility(true, "Preparing Sharable Version", false);
SharingHelper.getShareInformation(getApplicationContext(), sharingChoices, new SharingHelper.SideLoadInformationResponse() {
@Override
public void informationLoaded(SideLoadInformation information) {
TypeChoosingFragment.constructFragment(information)
.show(getSupportFragmentManager(), "TypeChoosingFragment");
setLoadingFragmentVisibility(false, "Preparing Sharable Version", true);
}
});
}
private void toggleTextSizeVisibility(){
View view = findViewById(R.id.reading_text_options);
view.setVisibility((view.getVisibility() == View.VISIBLE) ? View.GONE : View.VISIBLE);
}
//endregion
//region viewChanging
/**
* will show/hide the view needed if there is no chosen version
* @param visible whether the view should be visible
*/
private void setNoVersionSelectedVisibility(boolean visible){
findViewById(R.id.no_version_layout).setVisibility((visible) ? View.VISIBLE : View.GONE);
}
//endregion
//region navigation handling
/**
* will go to version selection
* @param isSecondVersion whether the user is requesting to change the second version of the diglot view
*/
protected void gotoVersionSelection(boolean isSecondVersion){
// if(isTablet()){
//
// FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
//
// VersionSelectionFragment fragment = VersionSelectionFragment.newInstance(projectId, true);
// fragment.show(ft, VERSION_FRAGMENT_ID);
// }
// else {
startActivityForResult(new Intent(this, VersionSelectionActivity.class).putExtra(
VersionSelectionActivity.PROJECT_PARAM, getProject())
.putExtra(VersionSelectionActivity.IS_SECOND_VERSION_PARAM, isSecondVersion), 1);
overridePendingTransition(R.anim.enter_from_bottom, R.anim.enter_center);
// }
UWAudioPlayer.getInstance(getApplicationContext()).reset();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(data != null && data.getExtras() != null && data.getExtras().containsKey(VersionSelectionActivity.MEDIA_TYPE_PARAM)){
MediaType type = (MediaType) data.getExtras().getSerializable(VersionSelectionActivity.MEDIA_TYPE_PARAM);
switch (type){
case MEDIA_TYPE_AUDIO:{
setAudioPlayerVisibility(true);
}
}
}
}
/**
* will go to chapter selection
*/
private void goToChapterActivity(){
if(false){//isTablet()){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
getChapterFragment().show(ft, CHAPTER_SELECTION_FRAGMENT_ID);
}
else {
startActivity(new Intent(getApplicationContext(), BookSelectionActivity.class).putExtra(BookSelectionActivity.PROJECT_PARAM, getProject()));
overridePendingTransition(R.anim.enter_from_bottom, R.anim.enter_center);
}
UWAudioPlayer.getInstance(getApplicationContext()).reset();
}
//endregion
//region helper methods
private DialogFragment getChapterFragment(){
boolean isStories = getProject().getUniqueSlug().contains("obs");
if(isStories){
return StoryChaptersFragment.newInstance(true);
}
else{
return ChapterSelectionFragment.newInstance(true);
}
}
/**
* @return whether current device is a table
*/
private boolean isTablet(){
int screen_density = (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK);
return screen_density == Configuration.SCREENLAYOUT_SIZE_LARGE || screen_density == Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
/**
*
* @param fragmentId id of fragment to be removed
*/
private void removeFragment(String fragmentId){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment previous = getSupportFragmentManager().findFragmentByTag(fragmentId);
if (previous != null) {
ft.remove(previous);
}
ft.addToBackStack(null);
ft.commit();
}
//endregion
//region toolbar actions
@Override
public void rightButtonClicked() {
toggleDiglot();
}
@Override
public void centerButtonClicked() {
goToChapterActivity();
}
//endregion
//region ReadingFragmentListener
@Override
public boolean toggleHidden() {
isMini = readingToolbar.toggleIsMinni();
hideTabs(isMini);
return isMini;
}
private void hideTabs(boolean isHidden){
ViewGroup bottomBar = (ViewGroup) findViewById(R.id.bottom_menu_layout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(bottomBar.getLayoutParams());
if(isHidden){
params.addRule(RelativeLayout.BELOW, R.id.bottom_marker_layout);
}
else{
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
}
bottomBar.setLayoutParams(params);
}
//endregion
}