/** * @file ChapterTreeInfo.java * * @revision: none * * @version 0.0.01 * @author: Zenki (zhajun), zenki2001cn@163.com * @date: 2011-4-27 上午09:48:49 */ package com.easyview.ebook.reader.engine.model; import java.util.ArrayList; import android.util.Log; import com.easyview.ebook.reader.engine.model.strategy.IHasChapter; import com.easyview.ebook.reader.engine.model.strategy.JudgeByChapterList; import com.easyview.ebook.reader.engine.model.strategy.JudgeByTotalChapterNumber; import com.easyview.ebook.reader.engine.util.Logger; /** * 目錄樹信息類 */ public class ChapterTreeInfo { private static final String TAG = "ChapterTreeInfo"; /** * JudgeByChapterList */ private static final JudgeByChapterList JBCL = new JudgeByChapterList(); /** * JudgeByTotalChapterNumber */ private static final JudgeByTotalChapterNumber JBTCN = new JudgeByTotalChapterNumber(); protected int maxChapterNum = -1; protected int curChapterIndex; protected ChapterTreeState state; protected IHasChapter iHasChapter; protected ArrayList<Chapter> list; protected String[] titles; protected int[] numbers; static private int mBookType; protected ChapterTreeInfo(int bookType) { state = ChapterTreeState.UNKNOWN; list = new ArrayList<Chapter>(); mBookType = bookType; } protected void add(int index, int chapterIndex, String title) { Chapter cpt = new Chapter(); cpt.index = index; cpt.firstDirectoryChapterPageIndex = chapterIndex; cpt.title = title; list.add(cpt); } protected int getCurChapterIndex() { Logger.dLog(TAG, "get curChapterIndex: " + curChapterIndex); return curChapterIndex; } protected void setCurChapterIndex(int curChapterIndex) { this.curChapterIndex = curChapterIndex; Logger.dLog(TAG, "set curChapterIndex: " + curChapterIndex); } protected ChapterTreeState getState() { return state; } protected void setState(ChapterTreeState state) { this.state = state; } protected int getMaxChapterNum() { Logger.dLog(TAG, "get maxChapterNum: " + maxChapterNum); return maxChapterNum; } protected void setMaxChapterNum(int maxChapterNum) { Logger.dLog(TAG, "set maxChapterNum: " + maxChapterNum); this.maxChapterNum = maxChapterNum; } protected String[] getChapterTitles() { return titles; } protected boolean hasNextChapter(Book book) { if (state == ChapterTreeState.CURRENT_LOADED) { iHasChapter = JBTCN; } else if (state == ChapterTreeState.LIST_LOADED) { iHasChapter = JBCL; } else { iHasChapter = null; } if (iHasChapter != null) { return iHasChapter.hasNextChapter(book); } return false; } protected boolean hasPreviousChapter(Book book) { if (state == ChapterTreeState.CURRENT_LOADED) { iHasChapter = JBTCN; } else if (state == ChapterTreeState.LIST_LOADED) { iHasChapter = JBCL; } else { iHasChapter = null; } if (iHasChapter != null) { return iHasChapter.hasPreviousChapter(book); } return false; } /** * init初始化章节树结构,并内部维护一个index标识(以0为基数计算) * * @param indexs * : 表示该章节的页码序号,该序号用于跳转定位 * * @param chapters * : 表示该章节标题字符串 */ protected boolean init(int[] indexs, String[] chapters) { if ((null == indexs) || (null == chapters)) { maxChapterNum = -1; return false; } titles = chapters; numbers = new int[chapters.length]; int chapterIndex = -1; int firstDirectoryChapterPageIndex = -1; for (int i = 0; i < chapters.length; i++) { Chapter cpt = new Chapter(); cpt.title = chapters[i]; cpt.pageIndex = indexs[i]; numbers[i] = cpt.pageIndex; cpt.index = i; if (cpt.isChapterBorder()) { chapterIndex++; firstDirectoryChapterPageIndex = cpt.pageIndex; } cpt.firstDirectoryChapterPageIndex = firstDirectoryChapterPageIndex; list.add(cpt); } maxChapterNum = chapters.length; return true; } protected void clear() { state = ChapterTreeState.UNKNOWN; list.clear(); titles = null; numbers = null; curChapterIndex = 0; maxChapterNum = 0; } /** * Get specified chapter index. * * @param title * : chapter's title * @return the index of the chapter title ,-1 returned the title not found */ protected int getChapterIndex(String title) { for (Chapter c : list) { if (c.title.indexOf(title) != -1) { return c.index; } } return -1; } /** * * Get the next chapter's index from the current page's index. Note that * next chapter means chapter 1 , chapter 2... , but it doesn't mean chapter * 1.1. if the current chapter is 1.1, next chapter will return the index of * chapter 2 but chapter 1.2. * * @param pageIndex * : the page index of current page * @return next chapter index . */ protected int getNextChapterIndex(int pageIndex) { int nextChapterIndex = 0; int size = list.size(); Chapter c; for (int i = 0; i < size; i++) { c = list.get(i); // Logger.dLog(TAG, "c.pageIndex = " + c.pageIndex + "pageIndex = " // + pageIndex); if (c.pageIndex > pageIndex && c.isChapterBorder()) { nextChapterIndex = c.index; break; } } // Logger.dLog(TAG, "title next chapter index: " + nextChapterIndex); return nextChapterIndex; } /** * * Get the previous chapter's index from the current page's index. Note that * previous chapter means chapter 1 , chapter 2... , but it doesn't mean * chapter 1.1. if the current chapter is 1.1, the previous chapter will * return the index of chapter 0 but chapter 1. * * @param pageIndex * : the page index of current page * @return previous chapter index . */ protected int getPreviousChapterIndex(int pageIndex) { int previousChapterIndex = 0; int curChapterPageIndex = pageIndex; int size = list.size(); Chapter c; for (int i = size - 1; i >= 0; i--) { c = list.get(i); // Logger.dLog(TAG, "c.pageIndex = " + c.pageIndex + "pageIndex = " // + pageIndex + "isChapterBorder = " + c.isChapterBorder() + " title = " + c.title); if (c.pageIndex <= pageIndex && c.isChapterBorder()) { curChapterPageIndex = c.pageIndex; break; } } for (int i = size - 1; i >= 0; i--) { c = list.get(i); // Logger.dLog(TAG, "loop2 pageIndex = " + c.pageIndex // + "curChapterPageIndex = " + curChapterPageIndex + " title = " // + c.title); if (c.pageIndex < curChapterPageIndex && c.isChapterBorder()) { previousChapterIndex = c.index; break; } } // Logger.dLog(TAG, "getPreviousChapterIndex index = " // + previousChapterIndex); return previousChapterIndex; } protected int getPageIndexForChapter(int index) { int curPageIndex = 0; for (Chapter chapter : list) { if (index == chapter.index) { curPageIndex = chapter.pageIndex; } } return curPageIndex; } public static class Chapter { public int index; public int firstDirectoryChapterPageIndex; public int pageIndex; public String title; public boolean isChapterBorder() { // Adobe 分为主章节和副章节,主章节标题以 "-" 开头作为标识 // 当前只处理主章节的目录结构 switch (mBookType) { case Book.BookType.PDF: return (title.startsWith("-") && !title.startsWith("--")); case Book.BookType.EPUB: return true; default: return true; } } } protected ArrayList<Chapter> getChapterList() { return list; } protected int[] getChapterPageNums() { return numbers; } public static enum ChapterTreeState { UNKNOWN, CURRENT_LOADED, LIST_LOADED, LIST_EMPTY } }