package net.bible.android.control.download;
import android.util.Log;
import net.bible.android.SharedConstants;
import net.bible.android.activity.R;
import net.bible.android.view.activity.base.Dialogs;
import net.bible.service.common.CommonUtils;
import net.bible.service.download.DownloadManager;
import net.bible.service.download.RepoBase;
import net.bible.service.download.RepoFactory;
import net.bible.service.download.XiphosRepo;
import net.bible.service.font.FontControl;
import net.bible.service.sword.SwordDocumentFacade;
import org.apache.commons.lang3.StringUtils;
import org.crosswire.common.util.Language;
import org.crosswire.common.util.LucidException;
import org.crosswire.common.util.Version;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookMetaData;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.sword.SwordBookMetaData;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static net.bible.android.control.download.DocumentStatus.DocumentInstallStatus.BEING_INSTALLED;
import static net.bible.android.control.download.DocumentStatus.DocumentInstallStatus.ERROR_DOWNLOADING;
import static net.bible.android.control.download.DocumentStatus.DocumentInstallStatus.INSTALLED;
import static net.bible.android.control.download.DocumentStatus.DocumentInstallStatus.NOT_INSTALLED;
import static net.bible.android.control.download.DocumentStatus.DocumentInstallStatus.UPGRADE_AVAILABLE;
/** Support the download screen
*
* @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.
*/
public class DownloadControl {
private DocumentDownloadProgressCache documentDownloadProgressCache;
private final DownloadQueue downloadQueue;
private final RepoFactory repoFactory;
private final FontControl fontControl;
private final SwordDocumentFacade swordDocumentFacade;
private static final String TAG = "DownloadControl";
public DownloadControl(DownloadQueue downloadQueue, RepoFactory repoFactory, FontControl fontControl, SwordDocumentFacade swordDocumentFacade) {
this.downloadQueue = downloadQueue;
this.repoFactory = repoFactory;
this.fontControl = fontControl;
this.swordDocumentFacade = swordDocumentFacade;
// Listen for Progress changes and update the ui
documentDownloadProgressCache = new DocumentDownloadProgressCache();
}
/** pre-download document checks
*/
public boolean checkDownloadOkay() {
boolean okay = true;
if (CommonUtils.getSDCardMegsFree()<SharedConstants.REQUIRED_MEGS_FOR_DOWNLOADS) {
Dialogs.getInstance().showErrorMsg(R.string.storage_space_warning);
okay = false;
} else if (!CommonUtils.isInternetAvailable()) {
Dialogs.getInstance().showErrorMsg(R.string.no_internet_connection);
okay = false;
}
return okay;
}
/** @return a list of all available docs that have not already been downloaded, have no lang, or don't work
*/
public List<Book> getDownloadableDocuments(boolean refresh) {
List<Book> availableDocs;
try {
availableDocs = swordDocumentFacade.getDownloadableDocuments(refresh);
// there are a number of books we need to filter out of the download list for various reasons
for (Iterator<Book> iter=availableDocs.iterator(); iter.hasNext(); ) {
Book doc = iter.next();
if (doc.getLanguage()==null) {
Log.d(TAG, "Ignoring "+doc.getInitials()+" because it has no language");
iter.remove();
} else if (doc.isQuestionable()) {
Log.d(TAG, "Ignoring "+doc.getInitials()+" because it is questionable");
iter.remove();
} else if (doc.getInitials().equalsIgnoreCase("westminster")) {
Log.d(TAG, "Ignoring "+doc.getInitials()+" because some sections are too large for a mobile phone e.g. Q91-150");
iter.remove();
} else if (doc.getInitials().equalsIgnoreCase("BDBGlosses_Strongs")) {
Log.d(TAG, "Ignoring "+doc.getInitials()+" because I still need to make it work");
iter.remove();
} else if (doc.getInitials().equalsIgnoreCase("passion")) {
Log.d(TAG, "Ignoring "+doc.getInitials());
iter.remove();
} else if (doc.getInitials().equals("WebstersDict")) {
Log.d(TAG, "Ignoring "+doc.getInitials()+" because it is too big and crashes dictionary code");
iter.remove();
}
}
// get fonts.properties at the same time as repo list, or if not yet downloaded
// the download happens in another thread
fontControl.checkFontPropertiesFile(refresh);
Collections.sort(availableDocs);
} catch (Exception e) {
Log.e(TAG, "Error downloading document list", e);
availableDocs = new ArrayList<>();
}
return availableDocs;
}
public List<Language> sortLanguages(Collection<Language> languages) {
List<Language> languageList = new ArrayList<>();
if (languages!=null) {
languageList.addAll(languages);
// sort languages alphabetically
Collections.sort(languageList, new RelevantLanguageSorter(Books.installed().getBooks()));
}
return languageList;
}
public void downloadDocument(Book document) throws LucidException {
Log.d(TAG, "Download requested");
// ensure SBMD is fully, not just partially, loaded
BookMetaData bmd = document.getBookMetaData();
if (bmd!=null && bmd instanceof SwordBookMetaData) {
// load full bmd but must retain repo key
String repoKey = bmd.getProperty(DownloadManager.REPOSITORY_KEY);
((SwordBookMetaData)bmd).reload();
bmd.setProperty(DownloadManager.REPOSITORY_KEY, repoKey);
}
if (!downloadQueue.isInQueue(document)) {
final XiphosRepo xiphosRepo = repoFactory.getXiphosRepo();
if (xiphosRepo.needsPostDownloadAction(document)) {
xiphosRepo.addHandler(document);
}
// the download happens in another thread
RepoBase repo = repoFactory.getRepoForBook(document);
downloadQueue.addDocumentToDownloadQueue(document, repo);
// if a font is required then download that too
String font = fontControl.getFontForBook(document);
if (!StringUtils.isEmpty(font) && !fontControl.exists(font)) {
// the download happens in another thread
fontControl.downloadFont(font);
}
}
}
/** return install status - installed, not inst, or upgrade **/
public DocumentStatus getDocumentStatus(Book document) {
String initials = document.getInitials();
if (downloadQueue.isInQueue(document)) {
return new DocumentStatus(initials, BEING_INSTALLED, documentDownloadProgressCache.getPercentDone(document));
}
if (downloadQueue.isErrorDownloading(document)) {
return new DocumentStatus(initials, ERROR_DOWNLOADING, 0);
}
Book installedBook = swordDocumentFacade.getDocumentByInitials(document.getInitials());
if (installedBook!=null) {
// see if the new document is a later version
try {
Version newVersionObj = new Version(document.getBookMetaData().getProperty("Version"));
Version installedVersionObj = new Version(installedBook.getBookMetaData().getProperty("Version"));
if (newVersionObj.compareTo(installedVersionObj)>0) {
return new DocumentStatus(initials, UPGRADE_AVAILABLE, 100);
}
} catch (Exception e) {
Log.e(TAG, "Error comparing versions", e);
// probably not the same version if an error occurred comparing
return new DocumentStatus(initials, UPGRADE_AVAILABLE, 100);
}
// otherwise same document is already installed
return new DocumentStatus(initials, INSTALLED, 100);
} else {
return new DocumentStatus(initials, NOT_INSTALLED, 0);
}
}
public void startMonitoringDownloads() {
documentDownloadProgressCache.startMonitoringDownloads();
}
public void stopMonitoringDownloads() {
documentDownloadProgressCache.stopMonitoringDownloads();
}
}