package net.bible.android.control.document;
import android.util.Log;
import net.bible.android.control.ApplicationScope;
import net.bible.android.control.page.CurrentPage;
import net.bible.android.control.page.CurrentPageManager;
import net.bible.android.control.page.window.ActiveWindowPageManagerProvider;
import net.bible.android.control.versification.ConvertibleVerse;
import net.bible.service.sword.SwordDocumentFacade;
import org.crosswire.common.util.Filter;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookCategory;
import org.crosswire.jsword.book.BookException;
import org.crosswire.jsword.book.FeatureType;
import org.crosswire.jsword.book.basic.AbstractPassageBook;
import org.crosswire.jsword.passage.Verse;
import org.crosswire.jsword.versification.BibleBook;
import java.util.List;
import javax.inject.Inject;
/** Control use of different documents/books/modules - used by front end
*
* @author Martin Denham [mjdenham at gmail dot com]
* @see gnu.lgpl.License for license details.<br>
* The copyright to this program is held by it's author.
*/
@ApplicationScope
public class DocumentControl {
private final ActiveWindowPageManagerProvider activeWindowPageManagerProvider;
private SwordDocumentFacade swordDocumentFacade;
private static final String TAG = "DocumentControl";
@Inject
public DocumentControl(ActiveWindowPageManagerProvider activeWindowPageManagerProvider, SwordDocumentFacade swordDocumentFacade) {
this.activeWindowPageManagerProvider = activeWindowPageManagerProvider;
this.swordDocumentFacade = swordDocumentFacade;
}
/**
* user wants to change to a different document/module
*/
public void changeDocument(Book newDocument) {
activeWindowPageManagerProvider.getActiveWindowPageManager().setCurrentDocument( newDocument );
}
/**
* Book is deletable according to the driver if it is in the download dir i.e. not sdcard\jsword
* and according to And Bible if it is not currently selected
*/
public boolean canDelete(Book document) {
if (document==null) {
return false;
}
boolean lastBible = BookCategory.BIBLE.equals(document.getBookCategory()) &&
swordDocumentFacade.getBibles().size()==1;
return !lastBible &&
document.getDriver().isDeletable(document);
}
/** delete selected document, even of current doc (Map and Gen Book only currently) and tidy up CurrentPage
*/
public void deleteDocument(Book document) throws BookException {
swordDocumentFacade.deleteDocument(document);
CurrentPage currentPage = activeWindowPageManagerProvider.getActiveWindowPageManager().getBookPage(document);
if (currentPage!=null) {
currentPage.checkCurrentDocumentStillInstalled();
}
}
/**
* Suggest an alternative dictionary to view or return null
*/
public boolean isStrongsInBook() {
try {
Book currentBook = activeWindowPageManagerProvider.getActiveWindowPageManager().getCurrentPage().getCurrentDocument();
// very occasionally the below has thrown an Exception and I don't know why, so I wrap all this in a try/catch
return currentBook.getBookMetaData().hasFeature(FeatureType.STRONGS_NUMBERS);
} catch (Exception e) {
Log.e(TAG, "Error checking for strongs Numbers in book", e);
return false;
}
}
/**
* Are we currently in Bible, Commentary, Dict, or Gen Book mode
*/
public BookCategory getCurrentCategory() {
return activeWindowPageManagerProvider.getActiveWindowPageManager().getCurrentPage().getBookCategory();
}
/**
* Show split book/chap/verse buttons in toolbar for Bibles and Commentaries
*/
public boolean showSplitPassageSelectorButtons() {
BookCategory currentCategory = getCurrentCategory();
return (BookCategory.BIBLE.equals(currentCategory) ||
BookCategory.COMMENTARY.equals(currentCategory) ||
BookCategory.OTHER.equals(currentCategory));
}
/**
* Suggest an alternative bible to view or return null
*/
public Book getSuggestedBible() {
CurrentPageManager currentPageManager = activeWindowPageManagerProvider.getActiveWindowPageManager();
Book currentBible = currentPageManager.getCurrentBible().getCurrentDocument();
final ConvertibleVerse requiredVerseConverter = getRequiredVerseForSuggestions();
// only show bibles that contain verse
Filter<Book> bookFilter = new Filter<Book>() {
@Override
public boolean test(Book book) {
return book.contains(requiredVerseConverter.getVerse(((AbstractPassageBook)book).getVersification()));
}
};
return getSuggestedBook(swordDocumentFacade.getBibles(), currentBible, bookFilter, currentPageManager.isBibleShown());
}
/** Suggest an alternative commentary to view or return null
*/
public Book getSuggestedCommentary() {
CurrentPageManager currentPageManager = activeWindowPageManagerProvider.getActiveWindowPageManager();
Book currentCommentary = currentPageManager.getCurrentCommentary().getCurrentDocument();
final ConvertibleVerse requiredVerseConverter = getRequiredVerseForSuggestions();
// only show commentaries that contain verse - extra checks for TDavid because it always returns true
Filter<Book> bookFilter = new Filter<Book>() {
@Override
public boolean test(Book book) {
Verse verse = requiredVerseConverter.getVerse(((AbstractPassageBook)book).getVersification());
if (!book.contains(verse)) {
return false;
}
// book claims to contain the verse but
// TDavid has a flawed index and incorrectly claims to contain contents for all books of the bible so only return true if !TDavid or is Psalms
return !book.getInitials().equals("TDavid") ||
verse.getBook().equals(BibleBook.PS);
}
};
return getSuggestedBook(swordDocumentFacade.getBooks(BookCategory.COMMENTARY), currentCommentary, bookFilter, currentPageManager.isCommentaryShown());
}
/** Suggest an alternative dictionary to view or return null
*/
public Book getSuggestedDictionary() {
CurrentPageManager currentPageManager = activeWindowPageManagerProvider.getActiveWindowPageManager();
Book currentDictionary = currentPageManager.getCurrentDictionary().getCurrentDocument();
return getSuggestedBook(swordDocumentFacade.getBooks(BookCategory.DICTIONARY), currentDictionary, null, currentPageManager.isDictionaryShown());
}
/**
* Possible books will often not include the current verse but most will include chap 1 verse 1
*/
private ConvertibleVerse getRequiredVerseForSuggestions() {
Verse currentVerse = activeWindowPageManagerProvider.getActiveWindowPageManager().getCurrentBible().getSingleKey();
return new ConvertibleVerse(currentVerse.getBook(), 1, 1);
}
/**
* Suggest an alternative document to view or return null
*/
private Book getSuggestedBook(List<Book> books, Book currentDocument, Filter<Book> filter, boolean isBookTypeShownNow) {
Book suggestion = null;
if (!isBookTypeShownNow) {
// allow easy switch back to current doc
suggestion = currentDocument;
} else {
// only suggest alternative if more than 1
if (books.size()>1) {
// find index of current document
int currentDocIndex = -1;
for (int i=0; i<books.size(); i++) {
if (books.get(i).equals(currentDocument)) {
currentDocIndex = i;
}
}
// find the next doc containing related content e.g. if in NT then don't show TDavid
for (int i=0; i<books.size()-1 && suggestion==null; i++) {
Book possibleDoc = books.get((currentDocIndex+i+1)%books.size());
if (filter==null || filter.test(possibleDoc)) {
suggestion = possibleDoc;
}
}
}
}
return suggestion;
}
}