package net.bible.android.control.versification;
import android.support.annotation.Nullable;
import android.util.Log;
import org.crosswire.jsword.passage.Key;
import org.crosswire.jsword.passage.KeyUtil;
import org.crosswire.jsword.passage.Passage;
import org.crosswire.jsword.passage.PassageKeyFactory;
import org.crosswire.jsword.passage.RangedPassage;
import org.crosswire.jsword.passage.RestrictionType;
import org.crosswire.jsword.passage.Verse;
import org.crosswire.jsword.passage.VerseRange;
import org.crosswire.jsword.versification.Versification;
import org.crosswire.jsword.versification.VersificationsMapper;
import java.util.Iterator;
/** Manage conversion of verses to a specific versification
*
* @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 VersificationConverter {
private static final String TAG = "VersificationConverter";
private VersificationsMapper versificationsMapper = VersificationsMapper.instance();
/**
* Flexible converter for the generic Key base class.
* Return the key in the required versification, mapping if necessary
* Currently only handles Passage, RangedPassage, and Verse
*/
public Key convert(Key key, Versification toVersification) {
try {
if (key instanceof RangedPassage) {
return convert((RangedPassage)key, toVersification);
} else if (key instanceof VerseRange) {
return convert((VerseRange)key, toVersification);
} else if (key instanceof Passage) {
return convert((Passage)key, toVersification);
} else if (key instanceof Verse) {
return convert((Verse)key, toVersification);
}
} catch (Exception e) {
// unexpected problem during mapping
Log.e(TAG, "JSword Versification mapper failed to map "+key.getOsisID()+" to "+toVersification.getName(), e);
}
return PassageKeyFactory.instance().createEmptyKeyList(toVersification);
}
public Passage convert(Passage passage, Versification toVersification) {
return versificationsMapper.map(passage, toVersification);
}
public RangedPassage convert(RangedPassage rangedPassage, Versification toVersification) {
RangedPassage result = new RangedPassage(toVersification);
Iterator<VerseRange> iter = rangedPassage.rangeIterator(RestrictionType.NONE);
while (iter.hasNext()) {
result.add(convert(iter.next(), toVersification));
}
return result;
}
public VerseRange convert(VerseRange verseRange, Versification toVersification) {
Verse startVerse = verseRange.getStart();
Verse endVerse = verseRange.getEnd();
Verse convertedStartVerse = convert(startVerse, toVersification);
Verse convertedEndVerse = convert(endVerse, toVersification);
return new VerseRange(toVersification, convertedStartVerse, convertedEndVerse);
}
/** Return the verse in the required versification, mapping if necessary
*/
public Verse convert(Verse verse, Versification toVersification) {
Verse mappedVerse = convertVerseStrictly(verse, toVersification);
if (mappedVerse != null) return mappedVerse;
// just try to retain information by forcing creation of a similar verse with the new v11n
return new Verse(toVersification, verse.getBook(), verse.getChapter(), verse.getVerse());
}
public boolean isConvertibleTo(Verse verse, Versification v11n) {
return convertVerseStrictly(verse, v11n)!=null;
}
/**
* Convert the verse correctly to the v11n or return null
*/
@Nullable
private Verse convertVerseStrictly(Verse verse, Versification toVersification) {
try {
Key key = versificationsMapper.mapVerse(verse, toVersification);
Verse mappedVerse = KeyUtil.getVerse(key);
// If target v11n does not contain mapped verse then an exception normally occurs and the ordinal is set to 0
if (mappedVerse.getOrdinal()>0) {
return mappedVerse;
}
} catch (Exception e) {
// unexpected problem during mapping
Log.e(TAG, "JSword Versification mapper failed to map "+verse.getOsisID()+" from "+verse.getVersification().getName()+" to "+toVersification.getName(), e);
}
return null;
}
}