package yuku.alkitab.model;
import android.support.annotation.Nullable;
import yuku.alkitab.util.Ari;
import yuku.alkitab.util.IntArrayList;
import java.util.List;
public abstract class Version {
/**
* Get the short name (abbreviation) of this version.
*/
public abstract String getShortName();
public abstract String getLongName();
public abstract String getLocale();
/**
* @return The highest bookId on this version plus one.
*/
public abstract int getMaxBookIdPlusOne();
/**
* For enumerating available books.
* Note that using this, no guarantee that return_value[bookId].bookId == bookId.
*/
public abstract Book[] getConsecutiveBooks();
/**
* @return null if bookId is out of range, or the book is not available on this version.
*/
public abstract Book getBook(int bookId);
public abstract Book getFirstBook();
/**
* Load a single verse from this version.
* @return null if the verse is not available.
*/
@Nullable public abstract String loadVerseText(int ari);
/**
* Load a single verse from this version.
* @return null if the verse is not available.
*/
@Nullable public abstract String loadVerseText(Book book, int chapter_1, int verse_1);
/**
* @param ariRanges list of aris where even-indexed elements are start and odd-indexed elements are end (inclusive) aris
* @param result_aris (non-null, will be cleared first) list of aris loaded
* @param result_verses (non-null, will be cleared first) list of verse texts loaded
* @return the number of verses successfully loaded
*/
public abstract int loadVersesByAriRanges(IntArrayList ariRanges, IntArrayList result_aris, List<String> result_verses);
/**
* Loads the list of pericopes for a chapter
* @param aris output parameter; will be filled in with the aris where the pericopes start
* @param pericopeBlocks output parameter; will be filled with the content of the pericopes
* @param max the maximum number of pericopes to return. The output arrays must have at least max entries.
* @return the number of pericopes loaded. 0 if the version does not have pericopes or some errors happen.
*/
public abstract int loadPericope(int bookId, int chapter_1, int[] aris, PericopeBlock[] pericopeBlocks, int max);
@Nullable
public abstract SingleChapterVerses loadChapterText(Book book, int chapter_1);
@Nullable
public abstract SingleChapterVerses loadChapterTextLowercased(Book book, int chapter_1);
/**
* Load a whole chapter as a single string with verses separated by '\n' from this version.
* @return null if the chapter is not available.
*/
public abstract String loadChapterTextLowercasedWithoutSplit(Book book, int chapter_1);
/**
* @param arif 24bit ari at the MSB + which xref field at the 8bit LSB (starts from 1)
*/
public abstract XrefEntry getXrefEntry(final int arif);
/**
* @param arif 24bit ari at the MSB + which xref field at the 8bit LSB (starts from 1)
*/
public abstract FootnoteEntry getFootnoteEntry(final int arif);
private static class UnavailableBookNames {
static String[] names = {
"Gen", "Ex", "Lev", "Num", "Deut", "Josh", "Judg", "Ruth", "1Sam", "2Sam", "1Ki", "2Ki", "1Chr", "2Chr", "Ezr", "Neh", "Est", "Job", "Ps", "Prov", "Ecc", "Song", "Isa", "Jer", "Lam", "Eze", "Dan", "Hos", "Joel", "Amos", "Ob", "Jon", "Mi", "Nah", "Hab", "Zeph", "Hag", "Zech", "Mal", "Mt", "Mk", "Luk", "Jn", "Acts", "Rm", "1Cor", "2Cor", "Gal", "Eph", "Php", "Col", "1Ths", "2The", "1Tim", "2Tim", "Tit", "Phm", "Hb", "Jam", "1Pt", "2Pt", "1Jn", "2Jn", "3Jn", "Jud", "Rev",
};
}
public String reference(int ari) {
int bookId = Ari.toBook(ari);
int chapter_1 = Ari.toChapter(ari);
int verse_1 = Ari.toVerse(ari);
return reference(bookId, chapter_1, verse_1);
}
public String referenceWithVerseCount(final int ari, final int verseCount) {
int bookId = Ari.toBook(ari);
int chapter_1 = Ari.toChapter(ari);
int verse_1 = Ari.toVerse(ari);
if (verse_1 == 0 || verseCount == 1) { // verseCount does not matter
return reference(bookId, chapter_1, verse_1);
} else {
return reference(bookId, chapter_1, verse_1) + "\u2013" /* endash */ + (verse_1 + verseCount - 1);
}
}
private String getBookOrPlaceholder(final int bookId) {
final Book book = getBook(bookId);
if (book != null) {
return book.shortName;
}
if (bookId < 0 || bookId >= UnavailableBookNames.names.length) {
return "[?]";
}
return "[[" + UnavailableBookNames.names[bookId] + "]]";
}
public String reference(int bookId, int chapter_1, int verse_1) {
final String shortName = getBookOrPlaceholder(bookId);
if (verse_1 == 0) {
if (chapter_1 == 0) {
return shortName;
} else {
return Book.reference(shortName, chapter_1);
}
} else {
return Book.reference(shortName, chapter_1, verse_1);
}
}
private String getLastVerseString(final int bookId, final int chapter_1) {
final Book book = getBook(bookId);
if (book == null) {
return "end";
}
if (chapter_1 < 1 || chapter_1 > book.chapter_count) {
return "end";
}
return "" + book.verse_counts[chapter_1 - 1];
}
public String referenceRange(final int ari_start, final int ari_end) {
// 5 parts required for e.g. Matthew 5:3–6:10
// bcstr_start "Matthew 5"
// vstr_start ":3"
// en-dash "–"
// bcstr_end "6"
// vstr_end ":10"
final String bcstr_start;
final String vstr_start;
final String en_dash;
final String bcstr_end;
final String vstr_end;
final boolean same_book_and_chapter;
if (Ari.toBookChapter(ari_start) == Ari.toBookChapter(ari_end)) { // same book, same chapter
final int bookId = Ari.toBook(ari_start);
final int chapter_1 = Ari.toChapter(ari_start);
bcstr_start = Book.reference(getBookOrPlaceholder(bookId), chapter_1);
bcstr_end = "";
same_book_and_chapter = true;
} else if (Ari.toBook(ari_start) == Ari.toBook(ari_end)) { // same book, different chapter
final int bookId = Ari.toBook(ari_start);
final int chapter_1_start = Ari.toChapter(ari_start);
final int chapter_1_end = Ari.toChapter(ari_end);
bcstr_start = Book.reference(getBookOrPlaceholder(bookId), chapter_1_start);
bcstr_end = "" + chapter_1_end;
same_book_and_chapter = false;
} else { // different book, different chapter
final int bookId_start = Ari.toBook(ari_start);
final int bookId_end = Ari.toBook(ari_end);
final int chapter_1_start = Ari.toChapter(ari_start);
final int chapter_1_end = Ari.toChapter(ari_end);
bcstr_start = Book.reference(getBookOrPlaceholder(bookId_start), chapter_1_start);
bcstr_end = Book.reference(getBookOrPlaceholder(bookId_end), chapter_1_end);
same_book_and_chapter = false;
}
// en-dash is only empty if both aris are exactly the same
en_dash = ari_start == ari_end ? "" : "\u2013";
// How to show verse depending on whether the verse is 0:
// start, end, show start as, show end as (0 means verse is 0, 1 means verse is non-0)
// 0, 0, nothing, nothing
// 0, 1, :1, :verse
// 1, 0, :verse, :end
// 1, 1, :verse, :verse
final int verse_1_start = Ari.toVerse(ari_start);
final int verse_1_end = Ari.toVerse(ari_end);
switch ((verse_1_start != 0 ? 2 : 0) + (verse_1_end != 0 ? 1 : 0)) {
case 0:
default: // should not happen
vstr_start = vstr_end = "";
break;
case 1:
vstr_start = ":1";
vstr_end = (same_book_and_chapter ? "" : ":") + verse_1_end;
break;
case 2:
vstr_start = ":" + verse_1_start;
vstr_end = (same_book_and_chapter ? "" : ":") + getLastVerseString(Ari.toBook(ari_end), Ari.toChapter(ari_end));
break;
case 3:
vstr_start = ":" + verse_1_start;
if (ari_start == ari_end) {
vstr_end = "";
} else {
vstr_end = (same_book_and_chapter ? "" : ":") + verse_1_end;
}
break;
}
return bcstr_start + vstr_start + en_dash + bcstr_end + vstr_end;
}
}