1 package org.coolreader.crengine;
2 
3 import java.util.ArrayList;
4 
5 import org.coolreader.db.CRDBService;
6 
7 import android.util.Log;
8 
9 public class History extends FileInfoChangeSource {
10 	private ArrayList<BookInfo> mBooks = new ArrayList<>();
11 	private FileInfo mRecentBooksFolder;
12 
History(Scanner scanner)13 	public History(Scanner scanner)
14 	{
15 		this.mScanner = scanner;
16 	}
17 
getLastBook()18 	public BookInfo getLastBook()
19 	{
20 		if ( mBooks.size()==0 )
21 			return null;
22 		return mBooks.get(0);
23 	}
24 
getPreviousBook()25 	public BookInfo getPreviousBook()
26 	{
27 		if ( mBooks.size()<2 )
28 			return null;
29 		return mBooks.get(1);
30 	}
31 
32 	public interface BookInfoLoadedCallback {
onBookInfoLoaded(BookInfo bookInfo)33 		void onBookInfoLoaded(BookInfo bookInfo);
34 	}
35 
getOrCreateBookInfo(final CRDBService.LocalBinder db, final FileInfo file, final BookInfoLoadedCallback callback)36 	public void getOrCreateBookInfo(final CRDBService.LocalBinder db, final FileInfo file, final BookInfoLoadedCallback callback)
37 	{
38 		BookInfo res = getBookInfo(file);
39 		if (res != null) {
40 			callback.onBookInfoLoaded(res);
41 			return;
42 		}
43 		db.loadBookInfo(file, bookInfo -> {
44 			if (bookInfo == null) {
45 				bookInfo = new BookInfo(file);
46 				mBooks.add(0, bookInfo);
47 			}
48 			callback.onBookInfoLoaded(bookInfo);
49 		});
50 	}
51 
getBookInfo( FileInfo file )52 	public BookInfo getBookInfo( FileInfo file )
53 	{
54 		int index = findBookInfo( file );
55 		if ( index>=0 )
56 			return mBooks.get(index);
57 		return null;
58 	}
59 
getBookInfo( String pathname )60 	public BookInfo getBookInfo( String pathname )
61 	{
62 		int index = findBookInfo( pathname );
63 		if ( index>=0 )
64 			return mBooks.get(index);
65 		return null;
66 	}
67 
removeBookInfo(final CRDBService.LocalBinder db, FileInfo fileInfo, boolean removeRecentAccessFromDB, boolean removeBookFromDB)68 	public void removeBookInfo(final CRDBService.LocalBinder db, FileInfo fileInfo, boolean removeRecentAccessFromDB, boolean removeBookFromDB)
69 	{
70 		int index = findBookInfo(fileInfo);
71 		if (index >= 0)
72 			mBooks.remove(index);
73 		if ( removeBookFromDB )
74 			db.deleteBook(fileInfo);
75 		else if ( removeRecentAccessFromDB )
76 			db.deleteRecentPosition(fileInfo);
77 		updateRecentDir();
78 	}
79 
updateBookInfo(BookInfo bookInfo)80 	public void updateBookInfo(BookInfo bookInfo)
81 	{
82 		Log.v("cr3", "History.updateBookInfo() for " + bookInfo.getFileInfo().getPathName());
83 		bookInfo.updateAccess();
84 		int index = findBookInfo(bookInfo.getFileInfo());
85 		if ( index>=0 ) {
86 			BookInfo info = mBooks.get(index);
87 			if ( index>0 ) {
88 				mBooks.remove(index);
89 				mBooks.add(0, info);
90 			}
91 			info.setBookmarks(bookInfo.getAllBookmarks());
92 		} else {
93 			mBooks.add(0, bookInfo);
94 		}
95 	}
96 
updateBookAccess(BookInfo bookInfo, long timeElapsed)97 	public void updateBookAccess(BookInfo bookInfo, long timeElapsed)
98 	{
99 		Log.v("cr3", "History.updateBookAccess() for " + bookInfo.getFileInfo().getPathName());
100 		bookInfo.updateAccess();
101 		bookInfo.updateTimeElapsed(timeElapsed);
102 		int index = findBookInfo(bookInfo.getFileInfo());
103 		if ( index>=0 ) {
104 			BookInfo info = mBooks.get(index);
105 			if ( index>0 ) {
106 				mBooks.remove(index);
107 				mBooks.add(0, info);
108 			}
109 			info.setBookmarks(bookInfo.getAllBookmarks());
110 		} else {
111 			mBooks.add(0, bookInfo);
112 		}
113 		updateRecentDir();
114 	}
115 
findBookInfo( String pathname )116 	public int findBookInfo( String pathname )
117 	{
118 		for ( int i=0; i<mBooks.size(); i++ )
119 			if ( pathname.equals(mBooks.get(i).getFileInfo().getPathName()) )
120 				return i;
121 		return -1;
122 	}
123 
findBookInfo( FileInfo file )124 	public int findBookInfo( FileInfo file )
125 	{
126 		for ( int i=0; i<mBooks.size(); i++ )
127 			if (file.pathNameEquals(mBooks.get(i).getFileInfo()))
128 				return i;
129 		return -1;
130 	}
131 
getLastPos( FileInfo file )132 	public Bookmark getLastPos( FileInfo file )
133 	{
134 		int index = findBookInfo(file);
135 		if ( index<0 )
136 			return null;
137 		return mBooks.get(index).getLastPosition();
138 	}
updateRecentDir()139 	protected void updateRecentDir()
140 	{
141 		Log.v("cr3", "History.updateRecentDir()");
142 		if ( mRecentBooksFolder!=null ) {
143 			mRecentBooksFolder.clear();
144 			for ( BookInfo book : mBooks )
145 				mRecentBooksFolder.addFile(book.getFileInfo());
146 			onChange(mRecentBooksFolder, false);
147 		} else {
148 			Log.v("cr3", "History.updateRecentDir() : mRecentBooksFolder is null");
149 		}
150 	}
151 	Scanner mScanner;
152 
153 
getOrLoadRecentBooks(final CRDBService.LocalBinder db, final CRDBService.RecentBooksLoadingCallback callback)154 	public void getOrLoadRecentBooks(final CRDBService.LocalBinder db, final CRDBService.RecentBooksLoadingCallback callback) {
155 		if (mBooks != null && mBooks.size() > 0) {
156 			callback.onRecentBooksListLoaded(mBooks);
157 		} else {
158 			// not yet loaded. Wait until ready: sync with DB thread.
159 			db.sync(() -> callback.onRecentBooksListLoaded(mBooks));
160 		}
161 	}
162 
loadFromDB(final CRDBService.LocalBinder db, int maxItems )163 	public boolean loadFromDB(final CRDBService.LocalBinder db, int maxItems )
164 	{
165 		Log.v("cr3", "History.loadFromDB()");
166 		mRecentBooksFolder = mScanner.getRecentDir();
167 		db.loadRecentBooks(100, bookList -> {
168 			if (bookList != null) {
169 				mBooks = bookList;
170 				updateRecentDir();
171 			}
172 		});
173 		if ( mRecentBooksFolder==null )
174 			Log.v("cr3", "History.loadFromDB() : mRecentBooksFolder is null");
175 		return true;
176 	}
177 
178 }
179