Added Android code
[wl-app.git] / Android / folioreader / src / main / java / com / folioreader / ui / folio / activity / FolioActivity.java
diff --git a/Android/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java b/Android/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java
new file mode 100755 (executable)
index 0000000..aa5f7bf
--- /dev/null
@@ -0,0 +1,656 @@
+/*\r
+* Copyright (C) 2016 Pedro Paulo de Amorim\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+package com.folioreader.ui.folio.activity;\r
+\r
+import android.Manifest;\r
+import android.annotation.TargetApi;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.content.pm.PackageManager;\r
+import android.os.Build;\r
+import android.os.Bundle;\r
+import android.support.annotation.NonNull;\r
+import android.support.v4.app.ActivityCompat;\r
+import android.support.v4.content.ContextCompat;\r
+import android.support.v7.app.AppCompatActivity;\r
+import android.support.v7.widget.Toolbar;\r
+import android.text.Html;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.animation.Animation;\r
+import android.view.animation.AnimationUtils;\r
+import android.widget.ImageButton;\r
+import android.widget.RelativeLayout;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+\r
+import com.folioreader.Config;\r
+import com.folioreader.Constants;\r
+import com.folioreader.R;\r
+import com.folioreader.model.HighlightImpl;\r
+import com.folioreader.model.event.AnchorIdEvent;\r
+import com.folioreader.model.event.BusOwner;\r
+import com.folioreader.model.event.MediaOverlayHighlightStyleEvent;\r
+import com.folioreader.model.event.MediaOverlayPlayPauseEvent;\r
+import com.folioreader.model.event.MediaOverlaySpeedEvent;\r
+import com.folioreader.model.event.WebViewPosition;\r
+import com.folioreader.ui.folio.adapter.FolioPageFragmentAdapter;\r
+import com.folioreader.ui.folio.fragment.FolioPageFragment;\r
+import com.folioreader.ui.folio.presenter.MainMvpView;\r
+import com.folioreader.ui.folio.presenter.MainPresenter;\r
+import com.folioreader.util.AppUtil;\r
+import com.folioreader.util.FileUtil;\r
+import com.folioreader.util.FolioReader;\r
+import com.folioreader.util.UiUtil;\r
+import com.folioreader.view.ConfigBottomSheetDialogFragment;\r
+import com.folioreader.view.DirectionalViewpager;\r
+import com.folioreader.view.ObservableWebView;\r
+import com.folioreader.view.StyleableTextView;\r
+import com.squareup.otto.Bus;\r
+import com.squareup.otto.ThreadEnforcer;\r
+\r
+import org.readium.r2_streamer.model.container.Container;\r
+import org.readium.r2_streamer.model.container.EpubContainer;\r
+import org.readium.r2_streamer.model.publication.EpubPublication;\r
+import org.readium.r2_streamer.model.publication.link.Link;\r
+import org.readium.r2_streamer.server.EpubServer;\r
+import org.readium.r2_streamer.server.EpubServerSingleton;\r
+\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import static com.folioreader.Constants.CHAPTER_SELECTED;\r
+import static com.folioreader.Constants.HIGHLIGHT_SELECTED;\r
+import static com.folioreader.Constants.SELECTED_CHAPTER_POSITION;\r
+import static com.folioreader.Constants.TYPE;\r
+\r
+public class FolioActivity\r
+        extends AppCompatActivity\r
+        implements FolioPageFragment.FolioPageFragmentCallback,\r
+        ObservableWebView.ToolBarListener,\r
+        ConfigBottomSheetDialogFragment.ConfigDialogCallback,\r
+        BusOwner,\r
+        MainMvpView {\r
+\r
+    private static final String TAG = "FolioActivity";\r
+\r
+    public static final String INTENT_EPUB_SOURCE_PATH = "com.folioreader.epub_asset_path";\r
+    public static final String INTENT_EPUB_SOURCE_TYPE = "epub_source_type";\r
+    public static final String INTENT_HIGHLIGHTS_LIST = "highlight_list";\r
+       public static final String PARAM_FILE_NAME = "PARAM_FILE_NAME";\r
+       public static final String PARAM_CURRENT_CHAPTER = "PARAM_CURRENT_CHAPTER";\r
+       public static final String PARAM_CHAPTERS_COUNT = "PARAM_CHAPTERS_COUNT";\r
+\r
+       public enum EpubSourceType {\r
+        RAW,\r
+        ASSETS,\r
+        SD_CARD\r
+    }\r
+\r
+    private boolean isOpen = true;\r
+\r
+    public static final int ACTION_CONTENT_HIGHLIGHT = 77;\r
+    private String bookFileName;\r
+    private static final String HIGHLIGHT_ITEM = "highlight_item";\r
+\r
+    private final Bus BUS = new Bus(ThreadEnforcer.MAIN);\r
+    @Override\r
+    public Bus getBus() {\r
+        return BUS;\r
+    }\r
+\r
+    public boolean mIsActionBarVisible;\r
+    private DirectionalViewpager mFolioPageViewPager;\r
+    private Toolbar mToolbar;\r
+\r
+    private int mChapterPosition;\r
+    private FolioPageFragmentAdapter mFolioPageFragmentAdapter;\r
+    private int mWebViewScrollPosition;\r
+    private ConfigBottomSheetDialogFragment mConfigBottomSheetDialogFragment;\r
+    private TextView title;\r
+\r
+    private List<Link> mSpineReferenceList = new ArrayList<>();\r
+    private EpubServer mEpubServer;\r
+\r
+    private Animation slide_down;\r
+    private Animation slide_up;\r
+    private boolean mIsNightMode;\r
+    private Config mConfig;\r
+    private String mBookId;\r
+    private String mEpubFilePath;\r
+    private EpubSourceType mEpubSourceType;\r
+    int mEpubRawId = 0;\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        setContentView(R.layout.folio_activity);\r
+\r
+        mBookId = getIntent().getStringExtra(FolioReader.INTENT_BOOK_ID);\r
+        mEpubSourceType = (EpubSourceType)\r
+                getIntent().getExtras().getSerializable(FolioActivity.INTENT_EPUB_SOURCE_TYPE);\r
+        if (mEpubSourceType.equals(EpubSourceType.RAW)) {\r
+            mEpubRawId = getIntent().getExtras().getInt(FolioActivity.INTENT_EPUB_SOURCE_PATH);\r
+        } else {\r
+            mEpubFilePath = getIntent().getExtras()\r
+                    .getString(FolioActivity.INTENT_EPUB_SOURCE_PATH);\r
+        }\r
+\r
+        setConfig();\r
+\r
+        if (!mConfig.isShowTts()) {\r
+            findViewById(R.id.btn_speaker).setVisibility(View.GONE);\r
+        }\r
+\r
+        title = (TextView) findViewById(R.id.lbl_center);\r
+        slide_down = AnimationUtils.loadAnimation(getApplicationContext(),\r
+                R.anim.slide_down);\r
+        slide_up = AnimationUtils.loadAnimation(getApplicationContext(),\r
+                R.anim.slide_up);\r
+\r
+        mToolbar = (Toolbar) findViewById(R.id.toolbar);\r
+\r
+        BUS.register(this);\r
+\r
+\r
+        if (ContextCompat.checkSelfPermission(FolioActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {\r
+            ActivityCompat.requestPermissions(FolioActivity.this, Constants.getWriteExternalStoragePerms(), Constants.WRITE_EXTERNAL_STORAGE_REQUEST);\r
+        } else {\r
+            setupBook();\r
+        }\r
+\r
+        initAudioView();\r
+\r
+        findViewById(R.id.btn_drawer).setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                Intent intent = new Intent(FolioActivity.this, ContentHighlightActivity.class);\r
+                intent.putExtra(CHAPTER_SELECTED, mSpineReferenceList.get(mChapterPosition).href);\r
+                intent.putExtra(FolioReader.INTENT_BOOK_ID, mBookId);\r
+                intent.putExtra(Constants.BOOK_TITLE, bookFileName);\r
+                startActivityForResult(intent, ACTION_CONTENT_HIGHLIGHT);\r
+                overridePendingTransition(R.anim.slide_in_up, R.anim.slide_out_up);\r
+            }\r
+        });\r
+\r
+        // speaker = (ImageView) findViewById(R.id.btn_speaker);\r
+        findViewById(R.id.btn_speaker).setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                if (isOpen) {\r
+                    audioContainer.startAnimation(slide_up);\r
+                    audioContainer.setVisibility(View.VISIBLE);\r
+                    shade.setVisibility(View.VISIBLE);\r
+                } else {\r
+                    audioContainer.startAnimation(slide_down);\r
+                    audioContainer.setVisibility(View.INVISIBLE);\r
+                    shade.setVisibility(View.GONE);\r
+                }\r
+                isOpen = !isOpen;\r
+            }\r
+        });\r
+\r
+        mIsNightMode = mConfig.isNightMode();\r
+        if (mIsNightMode) {\r
+            audioContainer.setBackgroundColor(ContextCompat.getColor(FolioActivity.this, R.color.night));\r
+        }\r
+        ToolbarUtils.updateToolbarColors(this, mToolbar, mConfig, mIsNightMode);\r
+    }\r
+\r
+    private void initBook(String mEpubFileName, int mEpubRawId, String mEpubFilePath, EpubSourceType mEpubSourceType) {\r
+        try {\r
+            int portNumber = getIntent().getIntExtra(Config.INTENT_PORT, Constants.PORT_NUMBER);\r
+            mEpubServer = EpubServerSingleton.getEpubServerInstance(portNumber);\r
+            mEpubServer.start();\r
+            String path = FileUtil.saveEpubFileAndLoadLazyBook(FolioActivity.this, mEpubSourceType, mEpubFilePath,\r
+                    mEpubRawId, mEpubFileName);\r
+            addEpub(path);\r
+\r
+            String urlString = Constants.LOCALHOST + bookFileName + "/manifest";\r
+            new MainPresenter(this).parseManifest(urlString);\r
+\r
+        } catch (IOException e) {\r
+            Log.e(TAG, "initBook failed", e);\r
+        }\r
+    }\r
+\r
+    private void addEpub(String path) throws IOException {\r
+        Container epubContainer = new EpubContainer(path);\r
+        mEpubServer.addEpub(epubContainer, "/" + bookFileName);\r
+        getEpubResource();\r
+    }\r
+\r
+    private void getEpubResource() {\r
+    }\r
+\r
+    @Override\r
+    protected void onPostCreate(Bundle savedInstanceState) {\r
+        super.onPostCreate(savedInstanceState);\r
+        configDrawerLayoutButtons();\r
+    }\r
+\r
+    @Override\r
+    public void onBackPressed() {\r
+        saveBookState();\r
+           Intent data = new Intent();\r
+           data.putExtra(PARAM_FILE_NAME, bookFileName);\r
+           data.putExtra(PARAM_CURRENT_CHAPTER,mFolioPageViewPager.getCurrentItem() + 1);\r
+           data.putExtra(PARAM_CHAPTERS_COUNT, mFolioPageViewPager.getExpectedAdapterCount());\r
+           setResult(RESULT_OK, data);\r
+        finish();\r
+    }\r
+\r
+    @Override\r
+    public void onOrientationChange(int orentation) {\r
+        if (orentation == 0) {\r
+            mFolioPageViewPager.setDirection(DirectionalViewpager.Direction.VERTICAL);\r
+            mFolioPageFragmentAdapter =\r
+                    new FolioPageFragmentAdapter(getSupportFragmentManager(),\r
+                            mSpineReferenceList, bookFileName, mBookId);\r
+            mFolioPageViewPager.setAdapter(mFolioPageFragmentAdapter);\r
+            mFolioPageViewPager.setOffscreenPageLimit(1);\r
+            mFolioPageViewPager.setCurrentItem(mChapterPosition);\r
+\r
+        } else {\r
+            mFolioPageViewPager.setDirection(DirectionalViewpager.Direction.HORIZONTAL);\r
+            mFolioPageFragmentAdapter =\r
+                    new FolioPageFragmentAdapter(getSupportFragmentManager(),\r
+                            mSpineReferenceList, bookFileName, mBookId);\r
+            mFolioPageViewPager.setAdapter(mFolioPageFragmentAdapter);\r
+            mFolioPageViewPager.setCurrentItem(mChapterPosition);\r
+        }\r
+    }\r
+\r
+    private void configFolio() {\r
+        mFolioPageViewPager = (DirectionalViewpager) findViewById(R.id.folioPageViewPager);\r
+        mFolioPageViewPager.setOnPageChangeListener(new DirectionalViewpager.OnPageChangeListener() {\r
+            @Override\r
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {\r
+            }\r
+\r
+            @Override\r
+            public void onPageSelected(int position) {\r
+                BUS.post(new MediaOverlayPlayPauseEvent(mSpineReferenceList.get(mChapterPosition).href, false, true));\r
+                mPlayPauseBtn.setImageDrawable(ContextCompat.getDrawable(FolioActivity.this, R.drawable.play_icon));\r
+                mChapterPosition = position;\r
+            }\r
+\r
+            @Override\r
+            public void onPageScrollStateChanged(int state) {\r
+//                if (state == DirectionalViewpager.SCROLL_STATE_IDLE) {\r
+//                    title.setText(mSpineReferenceList.get(mChapterPosition).bookTitle);\r
+//                }\r
+            }\r
+        });\r
+\r
+        if (mSpineReferenceList != null) {\r
+            mFolioPageFragmentAdapter = new FolioPageFragmentAdapter(getSupportFragmentManager(), mSpineReferenceList, bookFileName, mBookId);\r
+            mFolioPageViewPager.setAdapter(mFolioPageFragmentAdapter);\r
+        }\r
+\r
+        if (AppUtil.checkPreviousBookStateExist(FolioActivity.this, bookFileName)) {\r
+            mFolioPageViewPager.setCurrentItem(AppUtil.getPreviousBookStatePosition(FolioActivity.this, bookFileName));\r
+        }\r
+    }\r
+\r
+    private void configDrawerLayoutButtons() {\r
+        findViewById(R.id.btn_close).setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                onBackPressed();\r
+            }\r
+        });\r
+\r
+        findViewById(R.id.btn_config).setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                mConfigBottomSheetDialogFragment = new ConfigBottomSheetDialogFragment();\r
+                mConfigBottomSheetDialogFragment.show(getSupportFragmentManager(), mConfigBottomSheetDialogFragment.getTag());\r
+            }\r
+        });\r
+    }\r
+\r
+    private void saveBookState() {\r
+        if (mSpineReferenceList.size() > 0) {\r
+            AppUtil.saveBookState(FolioActivity.this, bookFileName, mFolioPageViewPager.getCurrentItem(), mFolioPageViewPager\r
+                    .getExpectedAdapterCount(), mWebViewScrollPosition);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void hideOrshowToolBar() {\r
+//        if (mIsActionBarVisible) {\r
+//            toolbarAnimateHide();\r
+//        } else {\r
+//            toolbarAnimateShow();\r
+//        }\r
+    }\r
+\r
+    @Override\r
+    public void hideToolBarIfVisible() {\r
+//        if (mIsActionBarVisible) {\r
+//            toolbarAnimateHide();\r
+//        }\r
+    }\r
+\r
+    @Override\r
+    public void setPagerToPosition(String href) {\r
+    }\r
+\r
+    @Override\r
+    public void setLastWebViewPosition(int position) {\r
+        this.mWebViewScrollPosition = position;\r
+    }\r
+\r
+    @Override\r
+    public void goToChapter(String href) {\r
+        String spineHref = href.substring(href.indexOf(bookFileName + "/") + bookFileName.length() + 1);\r
+           String anchorHref = new String(spineHref);\r
+        if (href.contains("#")) {\r
+            spineHref = spineHref.substring(0, spineHref.indexOf("#"));\r
+        }\r
+        for (Link spine : mSpineReferenceList) {\r
+            if (spine.href.contains(spineHref)) {\r
+                mChapterPosition = mSpineReferenceList.indexOf(spine);\r
+                mFolioPageViewPager.setCurrentItem(mChapterPosition);\r
+                title.setText(spine.getChapterTitle());\r
+                BUS.post(new AnchorIdEvent(anchorHref));\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    private void toolbarAnimateShow() {\r
+//        if (!mIsActionBarVisible) {\r
+//            mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();\r
+//            mIsActionBarVisible = true;\r
+//        }\r
+    }\r
+\r
+    private void toolbarAnimateHide() {\r
+//        mIsActionBarVisible = false;\r
+//        mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(2)).start();\r
+    }\r
+\r
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\r
+    private void toolbarSetElevation(float elevation) {\r
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\r
+            mToolbar.setElevation(elevation);\r
+        }\r
+    }\r
+\r
+    public HighlightImpl setCurrentPagerPostion(HighlightImpl highlightImpl) {\r
+//        highlight.setCurrentPagerPostion(mFolioPageViewPager.getCurrentItem());\r
+        return highlightImpl;\r
+    }\r
+\r
+    @Override\r
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        if (requestCode == ACTION_CONTENT_HIGHLIGHT && resultCode == RESULT_OK && data.hasExtra(TYPE)) {\r
+\r
+            String type = data.getStringExtra(TYPE);\r
+            if (type.equals(CHAPTER_SELECTED)) {\r
+                String selectedChapterHref = data.getStringExtra(SELECTED_CHAPTER_POSITION);\r
+                for (Link spine : mSpineReferenceList) {\r
+                    if (selectedChapterHref.contains(spine.href)) {\r
+                        mChapterPosition = mSpineReferenceList.indexOf(spine);\r
+                        mFolioPageViewPager.setCurrentItem(mChapterPosition);\r
+                        title.setText(data.getStringExtra(Constants.BOOK_TITLE));\r
+                        BUS.post(new AnchorIdEvent(selectedChapterHref));\r
+                        break;\r
+                    }\r
+                }\r
+            } else if (type.equals(HIGHLIGHT_SELECTED)) {\r
+                HighlightImpl highlightImpl = data.getParcelableExtra(HIGHLIGHT_ITEM);\r
+                int position = highlightImpl.getPageNumber();\r
+                mFolioPageViewPager.setCurrentItem(position);\r
+                BUS.post(new WebViewPosition(mSpineReferenceList.get(mChapterPosition).href, highlightImpl.getRangy()));\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void onDestroy() {\r
+        super.onDestroy();\r
+        if (mEpubServer != null) {\r
+            mEpubServer.stop();\r
+        }\r
+        BUS.unregister(this);\r
+    }\r
+\r
+    public int getmChapterPosition() {\r
+        return mChapterPosition;\r
+    }\r
+\r
+    @Override\r
+    public void onLoadPublication(EpubPublication publication) {\r
+        mSpineReferenceList.addAll(publication.spines);\r
+        if (publication.metadata.title != null) {\r
+            title.setText(publication.metadata.title);\r
+        }\r
+\r
+        if (mBookId == null) {\r
+            if (publication.metadata.identifier != null) {\r
+                mBookId = publication.metadata.identifier;\r
+            } else {\r
+                if (publication.metadata.title != null) {\r
+                    mBookId = String.valueOf(publication.metadata.title.hashCode());\r
+                } else {\r
+                    mBookId = String.valueOf(bookFileName.hashCode());\r
+                }\r
+            }\r
+        }\r
+        configFolio();\r
+    }\r
+\r
+    private void setConfig() {\r
+        if (AppUtil.getSavedConfig(this) != null) {\r
+            mConfig = AppUtil.getSavedConfig(this);\r
+        } else if (getIntent().getParcelableExtra(Config.INTENT_CONFIG) != null) {\r
+            mConfig = getIntent().getParcelableExtra(Config.INTENT_CONFIG);\r
+            AppUtil.saveConfig(this, mConfig);\r
+        } else {\r
+            mConfig = new Config.ConfigBuilder().build();\r
+            AppUtil.saveConfig(this, mConfig);\r
+        }\r
+    }\r
+\r
+\r
+    //*************************************************************************//\r
+    //                           AUDIO PLAYER                                  //\r
+    //*************************************************************************//\r
+    private StyleableTextView mHalfSpeed, mOneSpeed, mTwoSpeed, mOneAndHalfSpeed;\r
+    private StyleableTextView mBackgroundColorStyle, mUnderlineStyle, mTextColorStyle;\r
+    private RelativeLayout audioContainer;\r
+    private boolean mIsSpeaking;\r
+    private ImageButton mPlayPauseBtn, mPreviousButton, mNextButton;\r
+    private RelativeLayout shade;\r
+\r
+    private void initAudioView() {\r
+        mHalfSpeed = (StyleableTextView) findViewById(R.id.btn_half_speed);\r
+        mOneSpeed = (StyleableTextView) findViewById(R.id.btn_one_x_speed);\r
+        mTwoSpeed = (StyleableTextView) findViewById(R.id.btn_twox_speed);\r
+        audioContainer = (RelativeLayout) findViewById(R.id.container);\r
+        shade = (RelativeLayout) findViewById(R.id.shade);\r
+        mOneAndHalfSpeed = (StyleableTextView) findViewById(R.id.btn_one_and_half_speed);\r
+        mPlayPauseBtn = (ImageButton) findViewById(R.id.play_button);\r
+        mPreviousButton = (ImageButton) findViewById(R.id.prev_button);\r
+        mNextButton = (ImageButton) findViewById(R.id.next_button);\r
+        mBackgroundColorStyle = (StyleableTextView) findViewById(R.id.btn_backcolor_style);\r
+        mUnderlineStyle = (StyleableTextView) findViewById(R.id.btn_text_undeline_style);\r
+        mTextColorStyle = (StyleableTextView) findViewById(R.id.btn_text_color_style);\r
+        mIsSpeaking = false;\r
+\r
+        final Context mContext = mHalfSpeed.getContext();\r
+        mOneAndHalfSpeed.setText(Html.fromHtml(mContext.getString(R.string.one_and_half_speed)));\r
+        mHalfSpeed.setText(Html.fromHtml(mContext.getString(R.string.half_speed_text)));\r
+        String styleUnderline =\r
+                mHalfSpeed.getContext().getResources().getString(R.string.style_underline);\r
+        mUnderlineStyle.setText(Html.fromHtml(styleUnderline));\r
+\r
+        setupColors(mContext);\r
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {\r
+            findViewById(R.id.playback_speed_Layout).setVisibility(View.GONE);\r
+        }\r
+\r
+        shade.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                if (isOpen) {\r
+                    audioContainer.startAnimation(slide_up);\r
+                    audioContainer.setVisibility(View.VISIBLE);\r
+                    shade.setVisibility(View.VISIBLE);\r
+                } else {\r
+                    audioContainer.startAnimation(slide_down);\r
+                    audioContainer.setVisibility(View.INVISIBLE);\r
+                    shade.setVisibility(View.GONE);\r
+                }\r
+                isOpen = !isOpen;\r
+            }\r
+        });\r
+\r
+        mPlayPauseBtn.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                if (mIsSpeaking) {\r
+                    BUS.post(new MediaOverlayPlayPauseEvent(mSpineReferenceList.get(mChapterPosition).href, false, false));\r
+                    mPlayPauseBtn.setImageDrawable(ContextCompat.getDrawable(FolioActivity.this, R.drawable.play_icon));\r
+                    UiUtil.setColorToImage(mContext, mConfig.getThemeColor(), mPlayPauseBtn.getDrawable());\r
+                } else {\r
+                    BUS.post(new MediaOverlayPlayPauseEvent(mSpineReferenceList.get(mChapterPosition).href, true, false));\r
+                    mPlayPauseBtn.setImageDrawable(ContextCompat.getDrawable(FolioActivity.this, R.drawable.pause_btn));\r
+                    UiUtil.setColorToImage(mContext, mConfig.getThemeColor(), mPlayPauseBtn.getDrawable());\r
+                }\r
+                mIsSpeaking = !mIsSpeaking;\r
+            }\r
+        });\r
+\r
+        mHalfSpeed.setOnClickListener(new View.OnClickListener() {\r
+            @TargetApi(Build.VERSION_CODES.M)\r
+            @Override\r
+            public void onClick(View v) {\r
+                mHalfSpeed.setSelected(true);\r
+                mOneSpeed.setSelected(false);\r
+                mOneAndHalfSpeed.setSelected(false);\r
+                mTwoSpeed.setSelected(false);\r
+                BUS.post(new MediaOverlaySpeedEvent(MediaOverlaySpeedEvent.Speed.HALF));\r
+            }\r
+        });\r
+\r
+        mOneSpeed.setOnClickListener(new View.OnClickListener() {\r
+            @TargetApi(Build.VERSION_CODES.M)\r
+            @Override\r
+            public void onClick(View v) {\r
+                mHalfSpeed.setSelected(false);\r
+                mOneSpeed.setSelected(true);\r
+                mOneAndHalfSpeed.setSelected(false);\r
+                mTwoSpeed.setSelected(false);\r
+                BUS.post(new MediaOverlaySpeedEvent(MediaOverlaySpeedEvent.Speed.ONE));\r
+            }\r
+        });\r
+        mOneAndHalfSpeed.setOnClickListener(new View.OnClickListener() {\r
+            @TargetApi(Build.VERSION_CODES.M)\r
+            @Override\r
+            public void onClick(View v) {\r
+                mHalfSpeed.setSelected(false);\r
+                mOneSpeed.setSelected(false);\r
+                mOneAndHalfSpeed.setSelected(true);\r
+                mTwoSpeed.setSelected(false);\r
+                BUS.post(new MediaOverlaySpeedEvent(MediaOverlaySpeedEvent.Speed.ONE_HALF));\r
+            }\r
+        });\r
+        mTwoSpeed.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                mHalfSpeed.setSelected(false);\r
+                mOneSpeed.setSelected(false);\r
+                mOneAndHalfSpeed.setSelected(false);\r
+                mTwoSpeed.setSelected(true);\r
+                BUS.post(new MediaOverlaySpeedEvent(MediaOverlaySpeedEvent.Speed.TWO));\r
+            }\r
+        });\r
+\r
+        mBackgroundColorStyle.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                mBackgroundColorStyle.setSelected(true);\r
+                mUnderlineStyle.setSelected(false);\r
+                mTextColorStyle.setSelected(false);\r
+                BUS.post(new MediaOverlayHighlightStyleEvent(MediaOverlayHighlightStyleEvent.Style.DEFAULT));\r
+            }\r
+        });\r
+\r
+        mUnderlineStyle.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                mBackgroundColorStyle.setSelected(false);\r
+                mUnderlineStyle.setSelected(true);\r
+                mTextColorStyle.setSelected(false);\r
+                BUS.post(new MediaOverlayHighlightStyleEvent(MediaOverlayHighlightStyleEvent.Style.UNDERLINE));\r
+\r
+            }\r
+        });\r
+\r
+        mTextColorStyle.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View v) {\r
+                mBackgroundColorStyle.setSelected(false);\r
+                mUnderlineStyle.setSelected(false);\r
+                mTextColorStyle.setSelected(true);\r
+                BUS.post(new MediaOverlayHighlightStyleEvent(MediaOverlayHighlightStyleEvent.Style.BACKGROUND));\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+    private void setupColors(Context context) {\r
+        mHalfSpeed.setTextColor(UiUtil.getColorList(context, mConfig.getThemeColor(), R.color.grey_color));\r
+        mOneAndHalfSpeed.setTextColor(UiUtil.getColorList(context, mConfig.getThemeColor(), R.color.grey_color));\r
+        mTwoSpeed.setTextColor(UiUtil.getColorList(context, mConfig.getThemeColor(), R.color.grey_color));\r
+        mOneSpeed.setTextColor(UiUtil.getColorList(context, mConfig.getThemeColor(), R.color.grey_color));\r
+        mUnderlineStyle.setTextColor(UiUtil.getColorList(context, mConfig.getThemeColor(), R.color.grey_color));\r
+        mBackgroundColorStyle.setTextColor(UiUtil.getColorList(context, R.color.white, R.color.grey_color));\r
+        mBackgroundColorStyle.setBackgroundDrawable(UiUtil.convertColorIntoStateDrawable(this, mConfig.getThemeColor(), android.R.color.transparent));\r
+        mTextColorStyle.setTextColor(UiUtil.getColorList(context, mConfig.getThemeColor(), R.color.grey_color));\r
+        UiUtil.setColorToImage(context, mConfig.getThemeColor(), mPlayPauseBtn.getDrawable());\r
+        UiUtil.setColorToImage(context, mConfig.getThemeColor(), mNextButton.getDrawable());\r
+        UiUtil.setColorToImage(context, mConfig.getThemeColor(), mPreviousButton.getDrawable());\r
+    }\r
+\r
+    @Override\r
+    public void onError() {\r
+    }\r
+\r
+    private void setupBook() {\r
+        bookFileName = FileUtil.getEpubFilename(this, mEpubSourceType, mEpubFilePath, mEpubRawId);\r
+        initBook(bookFileName, mEpubRawId, mEpubFilePath, mEpubSourceType);\r
+    }\r
+\r
+    @Override\r
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {\r
+        switch (requestCode) {\r
+            case Constants.WRITE_EXTERNAL_STORAGE_REQUEST:\r
+                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {\r
+                    setupBook();\r
+                } else {\r
+                    Toast.makeText(this, getString(R.string.cannot_access_epub_message), Toast.LENGTH_LONG).show();\r
+                    finish();\r
+                }\r
+                break;\r
+        }\r
+    }\r
+}\r