1 package org.coolreader.crengine;
2 
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.Comparator;
10 
11 import android.util.Log;
12 
13 public class BookInfo {
14 	private FileInfo fileInfo;
15 	private Bookmark lastPosition;
16 	private ArrayList<Bookmark> bookmarks = new ArrayList<Bookmark>();
17 
setShortcutBookmark(int shortcut, Bookmark bookmark)18 	synchronized public void setShortcutBookmark(int shortcut, Bookmark bookmark)
19 	{
20 		bookmark.setShortcut(shortcut);
21 		for ( int i=0; i<bookmarks.size(); i++ ) {
22 			Bookmark bm = bookmarks.get(i);
23 			if ( bm.getType()==Bookmark.TYPE_POSITION && bm.getShortcut()==shortcut ) {
24 				bookmark.setId(bm.getId());
25 				bookmarks.set(i, bookmark);
26 				return;
27 			}
28 		}
29 		bookmarks.add(bookmark);
30 	}
31 
findShortcutBookmark( int shortcut )32 	synchronized public Bookmark findShortcutBookmark( int shortcut )
33 	{
34 		for ( Bookmark bm : bookmarks )
35 			if ( bm.getType()==Bookmark.TYPE_POSITION && bm.getShortcut()==shortcut )
36 				return bm;
37 		return null;
38 	}
39 
updateAccess()40 	public void updateAccess()
41 	{
42 		if (lastPosition != null) {
43 			lastPosition.setTimeStamp(System.currentTimeMillis());
44 		}
45 	}
46 
updateTimeElapsed(long timeElapsed)47 	public void updateTimeElapsed(long timeElapsed)
48 	{
49 		if (lastPosition != null) {
50 			lastPosition.setTimeElapsed(timeElapsed);
51 		}
52 	}
53 
54 	/**
55 	 * Deep copy.
56 	 * @param bookInfo is source object to copy from.
57 	 */
BookInfo(BookInfo bookInfo)58 	public BookInfo(BookInfo bookInfo) {
59 		this.fileInfo = new FileInfo(bookInfo.fileInfo);
60 		if (bookInfo.lastPosition != null)
61 			this.lastPosition = new Bookmark(bookInfo.lastPosition);
62 		for (int i=0; i < bookInfo.getBookmarkCount(); i++) {
63 			this.addBookmark(new Bookmark(bookInfo.getBookmark(i)));
64 		}
65 	}
66 
BookInfo(FileInfo fileInfo)67 	public BookInfo(FileInfo fileInfo)
68 	{
69 		this.fileInfo = fileInfo; //new FileInfo(fileInfo);
70 	}
71 
getLastPosition()72 	public Bookmark getLastPosition()
73 	{
74 		return lastPosition;
75 	}
76 
setLastPosition( Bookmark position )77 	public void setLastPosition( Bookmark position )
78 	{
79 		synchronized (this) {
80 			if ( lastPosition!=null ) {
81 				if (position.getStartPos()!=null && position.getStartPos().equals(lastPosition.getStartPos()))
82 					return; // not changed
83 				position.setId(lastPosition.getId());
84 			}
85 			lastPosition = position;
86 			fileInfo.lastAccessTime = lastPosition.getTimeStamp();
87 		}
88 	}
89 
getFileInfo()90 	public FileInfo getFileInfo()
91 	{
92 		return fileInfo;
93 	}
94 
addBookmark( Bookmark bm )95 	synchronized public void addBookmark( Bookmark bm )
96 	{
97 		if (bm.getType() == Bookmark.TYPE_LAST_POSITION) {
98 			lastPosition = bm;
99 		} else {
100 			if (findBookmarkIndex(bm) >= 0) {
101 				L.w("duplicate bookmark added " + bm.getUniqueKey());
102 			} else {
103 				bookmarks.add(bm);
104 			}
105 		}
106 	}
107 
getBookmarkCount()108 	synchronized public int getBookmarkCount()
109 	{
110 		return bookmarks.size();
111 	}
112 
getBookmark( int index )113 	synchronized public Bookmark getBookmark( int index )
114 	{
115 		return bookmarks.get(index);
116 	}
117 
getAllBookmarks()118 	synchronized public ArrayList<Bookmark> getAllBookmarks()
119 	{
120 		ArrayList<Bookmark> list = new ArrayList<Bookmark>(bookmarks.size() + 1);
121 		if (lastPosition != null)
122 			list.add(lastPosition);
123 		list.addAll(bookmarks);
124 		return list;
125 	}
126 
findBookmark(Bookmark bm)127 	synchronized public Bookmark findBookmark(Bookmark bm)
128 	{
129 		if ( bm==null )
130 			return null;
131 		int index = findBookmarkIndex(bm);
132 		if (index < 0)
133 			return null;
134 		return bookmarks.get(index);
135 	}
136 
findBookmarkIndex(Bookmark bm)137 	private int findBookmarkIndex(Bookmark bm)
138 	{
139 		if (bm == null)
140 			return -1;
141 		for ( int i=0; i<bookmarks.size(); i++ ) {
142 			Bookmark item = bookmarks.get(i);
143 			if (item.equalUniqueKey(bm))
144 				return i;
145 		}
146 		return -1;
147 	}
148 
syncBookmark(Bookmark bm)149 	synchronized public Bookmark syncBookmark(Bookmark bm)
150 	{
151 		if ( bm==null )
152 			return null;
153 		int index = findBookmarkIndex(bm);
154 		if (index < 0) {
155 			addBookmark(bm);
156 			return bm;
157 		}
158 		Bookmark item = bookmarks.get(index);
159 		if (item.getTimeStamp() >= bm.getTimeStamp())
160 			return null;
161 		item.setType(bm.getType());
162 		item.setTimeStamp(bm.getTimeStamp());
163 		item.setPosText(bm.getPosText());
164 		item.setCommentText(bm.getCommentText());
165 		return item;
166 	}
167 
updateBookmark(Bookmark bm)168 	synchronized public Bookmark updateBookmark(Bookmark bm)
169 	{
170 		if ( bm==null )
171 			return null;
172 		int index = findBookmarkIndex(bm);
173 		if ( index<0 ) {
174 			Log.e("cr3", "cannot find bookmark " + bm);
175 			return null;
176 		}
177 		Bookmark item = bookmarks.get(index);
178 		item.setTimeStamp(bm.getTimeStamp());
179 		item.setPosText(bm.getPosText());
180 		item.setCommentText(bm.getCommentText());
181 		return item;
182 	}
removeBookmark(Bookmark bm)183 	synchronized public Bookmark removeBookmark(Bookmark bm)
184 	{
185 		if ( bm==null )
186 			return null;
187 		int index = findBookmarkIndex(bm);
188 		if ( index<0 ) {
189 			Log.e("cr3", "cannot find bookmark " + bm);
190 			return null;
191 		}
192 		return bookmarks.remove(index);
193 	}
194 
sortBookmarks()195 	synchronized public void sortBookmarks() {
196 		Collections.sort(bookmarks, new Comparator<Bookmark>() {
197 			@Override
198 			public int compare(Bookmark bm1, Bookmark bm2) {
199 				if ( bm1.getPercent() < bm2.getPercent() )
200 					return -1;
201 				if ( bm1.getPercent() > bm2.getPercent() )
202 					return 1;
203 				return 0;
204 			}
205 		});
206 	}
207 
getBookmarksExportText()208 	synchronized public String getBookmarksExportText() {
209 		StringBuilder buf = new StringBuilder();
210 		File pathname = new File(fileInfo.getPathName());
211 		buf.append("# file name: " + pathname.getName() + "\n");
212 		buf.append("# file path: " + pathname.getParent() + "\n");
213 		buf.append("# book title: " + fileInfo.title + "\n");
214 		buf.append("# author: " + fileInfo.authors + "\n");
215 		buf.append("\n");
216 		for ( Bookmark bm : bookmarks ) {
217 			if ( bm.getType()!=Bookmark.TYPE_COMMENT && bm.getType()!=Bookmark.TYPE_CORRECTION )
218 				continue;
219 			int percent = bm.getPercent();
220 			String ps = String.valueOf(percent%100);
221 			if ( ps.length()<2 )
222 				ps = "0" + ps;
223 			ps = String.valueOf(percent/100) + "." + ps  + "%";
224 			buf.append("## " + ps + " - " + (bm.getType()==Bookmark.TYPE_COMMENT ? "comment" : "correction")  + "\n");
225 			if ( bm.getTitleText()!=null )
226 				buf.append("## " + bm.getTitleText() + "\n");
227 			if ( bm.getPosText()!=null )
228 				buf.append("<< " + bm.getPosText() + "\n");
229 			if ( bm.getCommentText()!=null )
230 				buf.append(">> " + bm.getCommentText() + "\n");
231 			buf.append("\n");
232 		}
233 		return buf.toString();
234 	}
235 
exportBookmarks( String fileName )236 	synchronized public boolean exportBookmarks( String fileName ) {
237 		Log.i("cr3", "Exporting bookmarks to file " + fileName);
238 		try (FileOutputStream stream = new FileOutputStream(new File(fileName));
239 			 OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8")) {
240 			writer.write(0xfeff);
241 			writer.write("# Cool Reader 3 - exported bookmarks\r\n");
242 			File pathname = new File(fileInfo.getPathName());
243 			writer.write("# file name: " + pathname.getName() + "\r\n");
244 			writer.write("# file path: " + pathname.getParent() + "\r\n");
245 			writer.write("# book title: " + fileInfo.title + "\r\n");
246 			writer.write("# author: " + fileInfo.authors + "\r\n");
247 			writer.write("# series: " + fileInfo.series + "\r\n");
248 			writer.write("\r\n");
249 			for ( Bookmark bm : bookmarks ) {
250 				if ( bm.getType()!=Bookmark.TYPE_COMMENT && bm.getType()!=Bookmark.TYPE_CORRECTION )
251 					continue;
252 				int percent = bm.getPercent();
253 				String ps = String.valueOf(percent%100);
254 				if ( ps.length()<2 )
255 					ps = "0" + ps;
256 				ps = percent / 100 + "." + ps  + "%";
257 				writer.write("## " + ps + " - " + (bm.getType()==Bookmark.TYPE_COMMENT ? "comment" : "correction")  + "\r\n");
258 				if ( bm.getTitleText()!=null )
259 					writer.write("## " + bm.getTitleText() + "\r\n");
260 				if ( bm.getPosText()!=null )
261 					writer.write("<< " + bm.getPosText() + "\r\n");
262 				if ( bm.getCommentText()!=null )
263 					writer.write(">> " + bm.getCommentText() + "\r\n");
264 				writer.write("\r\n");
265 			}
266 			return true;
267 		} catch ( IOException e ) {
268 			Log.e("cr3", "Cannot write bookmark file " + fileName);
269 			return false;
270 		}
271 	}
272 
removeBookmark( int index )273 	synchronized public Bookmark removeBookmark( int index )
274 	{
275 		return bookmarks.remove(index);
276 	}
277 
setBookmarks(ArrayList<Bookmark> list)278 	synchronized public void setBookmarks(ArrayList<Bookmark> list)
279 	{
280 		lastPosition = null;
281 		bookmarks = new ArrayList<Bookmark>();
282 		if (list == null)
283 			return;
284 		for (Bookmark bm : list)
285 			addBookmark(bm);
286 	}
287 
288 	@Override
toString()289 	public String toString() {
290 		return "BookInfo [fileInfo=" + fileInfo + ", lastPosition="
291 				+ lastPosition + "]";
292 	}
293 
294 
295 
296 }
297