package org.ebookdroid.common.settings;
import org.ebookdroid.common.settings.books.BookSettings;
import org.ebookdroid.common.settings.definitions.AppPreferences;
import org.ebookdroid.common.settings.definitions.BookPreferences;
import org.ebookdroid.common.settings.listeners.IAppSettingsChangeListener;
import org.ebookdroid.common.settings.types.DocumentViewMode;
import org.ebookdroid.common.settings.types.FontSize;
import org.ebookdroid.common.settings.types.PageAlign;
import org.ebookdroid.common.settings.types.RotationType;
import org.ebookdroid.common.settings.types.ToastPosition;
import org.ebookdroid.core.curl.PageAnimationType;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import org.emdev.common.backup.BackupManager;
import org.emdev.common.backup.IBackupAgent;
import org.emdev.common.settings.backup.SettingsBackupHelper;
import org.emdev.common.xml.XmlParsers;
import org.emdev.utils.CompareUtils;
import org.json.JSONObject;
public class AppSettings implements AppPreferences, BookPreferences, IBackupAgent {
public static final String BACKUP_KEY = "app-settings";
private static AppSettings current;
/* =============== UI settings =============== */
public final String lang;
public final boolean loadRecent;
public final boolean confirmClose;
public final boolean brightnessInNightModeOnly;
public final int brightness;
public final boolean keepScreenOn;
public final RotationType rotation;
public final boolean fullScreen;
public final boolean showTitle;
public final boolean pageInTitle;
public final ToastPosition pageNumberToastPosition;
public final ToastPosition zoomToastPosition;
public final boolean showAnimIcon;
/* =============== Tap & Scroll settings =============== */
public final boolean tapsEnabled;
public final int scrollHeight;
public final boolean animateScrolling;
public final boolean volumeKeyScrolling;
public final boolean tapTogglesFullscreen;
/* =============== Tap & Keyboard settings =============== */
public final String tapProfiles;
public final String keysBinding;
/* =============== Navigation & History settings =============== */
public final boolean showBookmarksInMenu;
public final int linkHighlightColor;
public final int searchHighlightColor;
public final int currentSearchHighlightColor;
public final boolean storeGotoHistory;
public final boolean storeLinkGotoHistory;
public final boolean storeOutlineGotoHistory;
public final boolean storeSearchGotoHistory;
/* =============== Performance settings =============== */
public final int pagesInMemory;
public final int decodingThreads;
public final int decodingThreadPriority;
public final int drawThreadPriority;
public final boolean decodingOnScroll;
public final int bitmapSize;
public final int heapPreallocate;
public final int pdfStorageSize;
/* =============== Default rendering settings =============== */
public final boolean nightMode;
public final boolean tint;
public final int tintColor;
public boolean positiveImagesInNightMode;
final int contrast;
final int gamma;
final int exposure;
final boolean autoLevels;
final boolean splitPages;
final boolean splitRTL;
final boolean cropPages;
public final DocumentViewMode viewMode;
final PageAlign pageAlign;
final PageAnimationType animationType;
final boolean rtl;
/* =============== DjVU Format-specific settings =============== */
public final int djvuRenderingMode;
/* =============== PDF Format-specific settings =============== */
public final boolean useCustomDpi;
public final int xDpi;
public final int yDpi;
public final boolean slowCMYK;
/* =============== FB2 Format-specific settings =============== */
public final XmlParsers fb2XmlParser;
public final String fb2FontPack;
public final FontSize fontSize;
public final boolean fb2HyphenEnabled;
public final boolean fb2CacheImagesOnDisk;
/* =============================================== */
private AppSettings() {
BackupManager.addAgent(this);
final SharedPreferences prefs = SettingsManager.prefs;
/* =============== UI settings =============== */
lang = LANG.getPreferenceValue(prefs);
loadRecent = LOAD_RECENT.getPreferenceValue(prefs);
confirmClose = CONFIRM_CLOSE.getPreferenceValue(prefs);
brightnessInNightModeOnly = BRIGHTNESS_NIGHT_MODE_ONLY.getPreferenceValue(prefs);
brightness = BRIGHTNESS.getPreferenceValue(prefs);
keepScreenOn = KEEP_SCREEN_ON.getPreferenceValue(prefs);
rotation = ROTATION.getPreferenceValue(prefs);
fullScreen = FULLSCREEN.getPreferenceValue(prefs);
showTitle = SHOW_TITLE.getPreferenceValue(prefs);
pageInTitle = SHOW_PAGE_IN_TITLE.getPreferenceValue(prefs);
pageNumberToastPosition = PAGE_NUMBER_TOAST_POSITION.getPreferenceValue(prefs);
zoomToastPosition = ZOOM_TOAST_POSITION.getPreferenceValue(prefs);
showAnimIcon = SHOW_ANIM_ICON.getPreferenceValue(prefs);
/* =============== Tap & Scroll settings =============== */
tapsEnabled = TAPS_ENABLED.getPreferenceValue(prefs);
scrollHeight = SCROLL_HEIGHT.getPreferenceValue(prefs);
animateScrolling = ANIMATE_SCROLLING.getPreferenceValue(prefs);
volumeKeyScrolling = VOLUME_KEY_SCROLLING.getPreferenceValue(prefs);
tapTogglesFullscreen = TAP_TOGGLES_FULLSCREEN.getPreferenceValue(prefs);
/* =============== Navigation & History settings =============== */
showBookmarksInMenu = SHOW_BOOKMARKs_MENU.getPreferenceValue(prefs);
linkHighlightColor = LINK_HIGHLIGHT_COLOR.getPreferenceValue(prefs);
searchHighlightColor = SEARCH_HIGHLIGHT_COLOR.getPreferenceValue(prefs);
currentSearchHighlightColor = CURRENT_SEARCH_HIGHLIGHT_COLOR.getPreferenceValue(prefs);
storeGotoHistory = STORE_GOTO_HISTORY.getPreferenceValue(prefs);
storeLinkGotoHistory = STORE_LINK_GOTO_HISTORY.getPreferenceValue(prefs);
storeOutlineGotoHistory = STORE_OUTLINE_GOTO_HISTORY.getPreferenceValue(prefs);
storeSearchGotoHistory = STORE_SEARCH_GOTO_HISTORY.getPreferenceValue(prefs);
/* =============== Tap & Keyboard settings =============== */
tapProfiles = TAP_PROFILES.getPreferenceValue(prefs);
keysBinding = KEY_BINDINGS.getPreferenceValue(prefs);
/* =============== Performance settings =============== */
pagesInMemory = PAGES_IN_MEMORY.getPreferenceValue(prefs);
decodingThreads = DECODING_THREADS.getPreferenceValue(prefs);
decodingThreadPriority = DECODE_THREAD_PRIORITY.getPreferenceValue(prefs);
drawThreadPriority = DRAW_THREAD_PRIORITY.getPreferenceValue(prefs);
decodingOnScroll = DECODING_ON_SCROLL.getPreferenceValue(prefs);
bitmapSize = BITMAP_SIZE.getPreferenceValue(prefs);
heapPreallocate = HEAP_PREALLOCATE.getPreferenceValue(prefs);
pdfStorageSize = PDF_STORAGE_SIZE.getPreferenceValue(prefs);
/* =============== Default rendering settings =============== */
nightMode = NIGHT_MODE.getPreferenceValue(prefs);
tint = TINT.getPreferenceValue(prefs);
tintColor = TINT_COLOR.getPreferenceValue(prefs);
positiveImagesInNightMode = NIGHT_MODE_POS_IMAGES.getPreferenceValue(prefs);
contrast = CONTRAST.getPreferenceValue(prefs);
gamma = GAMMA.getPreferenceValue(prefs);
exposure = EXPOSURE.getPreferenceValue(prefs);
autoLevels = AUTO_LEVELS.getPreferenceValue(prefs);
splitPages = SPLIT_PAGES.getPreferenceValue(prefs);
splitRTL = SPLIT_RTL.getPreferenceValue(prefs);
cropPages = CROP_PAGES.getPreferenceValue(prefs);
viewMode = VIEW_MODE.getPreferenceValue(prefs);
pageAlign = PAGE_ALIGN.getPreferenceValue(prefs);
animationType = ANIMATION_TYPE.getPreferenceValue(prefs);
rtl = RTL.getPreferenceValue(prefs);
/* =============== DjVU Format-specific settings =============== */
djvuRenderingMode = DJVU_RENDERING_MODE.getPreferenceValue(prefs);
/* =============== PDF Format-specific settings =============== */
useCustomDpi = PDF_CUSTOM_DPI.getPreferenceValue(prefs);
xDpi = PDF_CUSTOM_XDPI.getPreferenceValue(prefs);
yDpi = PDF_CUSTOM_YDPI.getPreferenceValue(prefs);
slowCMYK = PDF_SLOW_CMYK.getPreferenceValue(prefs);
/* =============== FB2 Format-specific settings =============== */
fb2XmlParser = FB2_XML_PARSER.getPreferenceValue(prefs);
fb2FontPack = FB2_FONT_PACK.getPreferenceValue(prefs);
fontSize = FB2_FONT_SIZE.getPreferenceValue(prefs);
fb2HyphenEnabled = FB2_HYPHEN.getPreferenceValue(prefs);
fb2CacheImagesOnDisk = FB2_CACHE_IMAGES.getPreferenceValue(prefs);
}
/* =============== UI settings =============== */
/* =============== Tap & Scroll settings =============== */
/* =============== Tap & Keyboard settings =============== */
/* =============== Default rendering settings =============== */
/* =============== Format-specific settings =============== */
public float getXDpi(final float def) {
return useCustomDpi ? xDpi : def;
}
public float getYDpi(final float def) {
return useCustomDpi ? yDpi : def;
}
/* =============== */
public static void init() {
current = new AppSettings();
}
public static AppSettings current() {
SettingsManager.lock.readLock().lock();
try {
return current;
} finally {
SettingsManager.lock.readLock().unlock();
}
}
public static void toggleFullScreen() {
SettingsManager.lock.writeLock().lock();
try {
final Editor edit = SettingsManager.prefs.edit();
AppPreferences.FULLSCREEN.setPreferenceValue(edit, !current.fullScreen);
edit.commit();
onSettingsChanged();
} finally {
SettingsManager.lock.writeLock().unlock();
}
}
public static void toggleTitleVisibility() {
setTitleVisibility(!current.showTitle);
}
public static void setTitleVisibility(boolean visible) {
SettingsManager.lock.writeLock().lock();
try {
final Editor edit = SettingsManager.prefs.edit();
AppPreferences.SHOW_TITLE.setPreferenceValue(edit, visible);
edit.commit();
onSettingsChanged();
} finally {
SettingsManager.lock.writeLock().unlock();
}
}
public static void updateTapProfiles(final String profiles) {
SettingsManager.lock.writeLock().lock();
try {
final Editor edit = SettingsManager.prefs.edit();
AppPreferences.TAP_PROFILES.setPreferenceValue(edit, profiles);
edit.commit();
onSettingsChanged();
} finally {
SettingsManager.lock.writeLock().unlock();
}
}
public static void updateKeysBinding(final String json) {
SettingsManager.lock.writeLock().lock();
try {
final Editor edit = SettingsManager.prefs.edit();
AppPreferences.KEY_BINDINGS.setPreferenceValue(edit, json);
edit.commit();
onSettingsChanged();
} finally {
SettingsManager.lock.writeLock().unlock();
}
}
/* =============== */
static void setDefaultSettings(final BookSettings bs) {
bs.nightMode = current.nightMode;
bs.positiveImagesInNightMode = current.positiveImagesInNightMode;
bs.tint = current.tint;
bs.tintColor = current.tintColor;
bs.contrast = current.contrast;
bs.gamma = current.gamma;
bs.exposure = current.exposure;
bs.autoLevels = current.autoLevels;
bs.splitPages = current.splitPages;
bs.splitRTL = current.splitRTL;
bs.cropPages = current.cropPages;
bs.viewMode = current.viewMode;
bs.pageAlign = current.pageAlign;
bs.animationType = current.animationType;
bs.rtl = current.rtl;
}
static void fillBookSettings(final BookSettings bs) {
final SharedPreferences prefs = SettingsManager.prefs;
bs.nightMode = BOOK_NIGHT_MODE.getPreferenceValue(prefs, current.nightMode);
bs.positiveImagesInNightMode = BOOK_NIGHT_MODE_POS_IMAGES.getPreferenceValue(prefs, current.positiveImagesInNightMode);
bs.tint = BOOK_TINT.getPreferenceValue(prefs, current.tint);
bs.tintColor = BOOK_TINT_COLOR.getPreferenceValue(prefs, current.tintColor);
bs.contrast = BOOK_CONTRAST.getPreferenceValue(prefs, current.contrast);
bs.gamma = BOOK_GAMMA.getPreferenceValue(prefs, current.gamma);
bs.exposure = BOOK_EXPOSURE.getPreferenceValue(prefs, current.exposure);
bs.autoLevels = BOOK_AUTO_LEVELS.getPreferenceValue(prefs, current.autoLevels);
bs.splitPages = BOOK_SPLIT_PAGES.getPreferenceValue(prefs, current.splitPages);
bs.splitRTL = BOOK_SPLIT_RTL.getPreferenceValue(prefs, current.splitRTL);
bs.cropPages = BOOK_CROP_PAGES.getPreferenceValue(prefs, current.cropPages);
bs.rotation = BOOK_ROTATION.getPreferenceValue(prefs, RotationType.UNSPECIFIED);
bs.viewMode = BOOK_VIEW_MODE.getPreferenceValue(prefs, current.viewMode);
bs.pageAlign = BOOK_PAGE_ALIGN.getPreferenceValue(prefs, current.pageAlign);
bs.animationType = BOOK_ANIMATION_TYPE.getPreferenceValue(prefs, current.animationType);
bs.firstPageOffset = BOOK_FIRST_PAGE_OFFSET.getPreferenceValue(prefs);
bs.rtl = BOOK_RTL.getPreferenceValue(prefs, current.rtl);
}
static void clearPseudoBookSettings() {
final SharedPreferences prefs = SettingsManager.prefs;
final Editor edit = prefs.edit();
edit.remove(BOOK.key);
edit.remove(BOOK_NIGHT_MODE.key);
edit.remove(BOOK_NIGHT_MODE_POS_IMAGES.key);
edit.remove(BOOK_TINT.key);
edit.remove(BOOK_TINT_COLOR.key);
edit.remove(BOOK_CONTRAST.key);
edit.remove(BOOK_GAMMA.key);
edit.remove(BOOK_EXPOSURE.key);
edit.remove(BOOK_AUTO_LEVELS.key);
edit.remove(BOOK_SPLIT_PAGES.key);
edit.remove(BOOK_SPLIT_RTL.key);
edit.remove(BOOK_CROP_PAGES.key);
edit.remove(BOOK_ROTATION.key);
edit.remove(BOOK_VIEW_MODE.key);
edit.remove(BOOK_PAGE_ALIGN.key);
edit.remove(BOOK_ANIMATION_TYPE.key);
edit.remove(BOOK_FIRST_PAGE_OFFSET.key);
edit.remove(BOOK_RTL.key);
edit.commit();
}
static void updatePseudoBookSettings(final BookSettings bs) {
final SharedPreferences prefs = SettingsManager.prefs;
final Editor edit = prefs.edit();
BOOK.setPreferenceValue(edit, bs.fileName);
BOOK_NIGHT_MODE.setPreferenceValue(edit, bs.nightMode);
BOOK_NIGHT_MODE_POS_IMAGES.setPreferenceValue(edit, bs.positiveImagesInNightMode);
BOOK_TINT.setPreferenceValue(edit, bs.tint);
BOOK_TINT_COLOR.setPreferenceValue(edit, bs.tintColor);
BOOK_CONTRAST.setPreferenceValue(edit, bs.contrast);
BOOK_GAMMA.setPreferenceValue(edit, bs.gamma);
BOOK_EXPOSURE.setPreferenceValue(edit, bs.exposure);
BOOK_AUTO_LEVELS.setPreferenceValue(edit, bs.autoLevels);
BOOK_SPLIT_PAGES.setPreferenceValue(edit, bs.splitPages);
BOOK_SPLIT_RTL.setPreferenceValue(edit, bs.splitRTL);
BOOK_CROP_PAGES.setPreferenceValue(edit, bs.cropPages);
BOOK_ROTATION.setPreferenceValue(edit, bs.rotation);
BOOK_VIEW_MODE.setPreferenceValue(edit, bs.viewMode);
BOOK_PAGE_ALIGN.setPreferenceValue(edit, bs.pageAlign);
BOOK_ANIMATION_TYPE.setPreferenceValue(edit, bs.animationType);
BOOK_FIRST_PAGE_OFFSET.setPreferenceValue(edit, bs.firstPageOffset);
BOOK_RTL.setPreferenceValue(edit, bs.rtl);
edit.commit();
}
static Diff onSettingsChanged() {
final AppSettings oldAppSettings = current;
current = new AppSettings();
return applySettingsChanges(oldAppSettings, current);
}
static AppSettings.Diff applySettingsChanges(final AppSettings oldSettings, final AppSettings newSettings) {
final AppSettings.Diff diff = new AppSettings.Diff(oldSettings, newSettings);
final IAppSettingsChangeListener l = SettingsManager.listeners.getListener();
l.onAppSettingsChanged(oldSettings, newSettings, diff);
return diff;
}
@Override
public String key() {
return BACKUP_KEY;
}
@Override
public JSONObject backup() {
return SettingsBackupHelper.backup(BACKUP_KEY, SettingsManager.prefs, AppPreferences.class);
}
@Override
public void restore(final JSONObject backup) {
SettingsBackupHelper.restore(BACKUP_KEY, SettingsManager.prefs, AppPreferences.class, backup);
onSettingsChanged();
}
public static class Diff {
private static final int D_Lang = 0x0001 << 0;
private static final int D_Rotation = 0x0001 << 1;
private static final int D_FullScreen = 0x0001 << 2;
private static final int D_ShowTitle = 0x0001 << 3;
private static final int D_PageInTitle = 0x0001 << 4;
private static final int D_TapsEnabled = 0x0001 << 5;
private static final int D_ScrollHeight = 0x0001 << 6;
private static final int D_PagesInMemory = 0x0001 << 7;
private static final int D_Brightness = 0x0001 << 8;
private static final int D_BrightnessInNightMode = 0x0001 << 9;
private static final int D_KeepScreenOn = 0x0001 << 10;
private static final int D_LoadRecent = 0x0001 << 11;
private static final int D_UseBookcase = 0x0001 << 12;
private static final int D_DjvuRenderingMode = 0x0001 << 13;
private static final int D_AutoScanDirs = 0x0001 << 14;
private static final int D_AllowedFileTypes = 0x0001 << 15;
private static final int D_TapConfigChanged = 0x0001 << 16;
private static final int D_KeyBindingChanged = 0x0001 << 17;
private int mask;
private final boolean firstTime;
public Diff(final AppSettings olds, final AppSettings news) {
firstTime = olds == null;
if (firstTime) {
mask = 0xFFFFFFFF;
} else if (news != null) {
if (CompareUtils.compare(olds.lang, news.lang) != 0) {
mask |= D_Lang;
}
if (olds.rotation != news.rotation) {
mask |= D_Rotation;
}
if (olds.fullScreen != news.fullScreen) {
mask |= D_FullScreen;
}
if (olds.showTitle != news.showTitle) {
mask |= D_ShowTitle;
}
if (olds.pageInTitle != news.pageInTitle) {
mask |= D_PageInTitle;
}
if (olds.tapsEnabled != news.tapsEnabled) {
mask |= D_TapsEnabled;
}
if (olds.scrollHeight != news.scrollHeight) {
mask |= D_ScrollHeight;
}
if (olds.pagesInMemory != news.pagesInMemory) {
mask |= D_PagesInMemory;
}
if (olds.brightness != news.brightness) {
mask |= D_Brightness;
}
if (olds.brightnessInNightModeOnly != news.brightnessInNightModeOnly) {
mask |= D_BrightnessInNightMode;
}
if (olds.keepScreenOn != news.keepScreenOn) {
mask |= D_KeepScreenOn;
}
if (olds.loadRecent != news.loadRecent) {
mask |= D_LoadRecent;
}
if (olds.djvuRenderingMode != news.djvuRenderingMode) {
mask |= D_DjvuRenderingMode;
}
if (!olds.tapProfiles.equals(news.tapProfiles)) {
mask |= D_TapConfigChanged;
}
if (!olds.keysBinding.equals(news.keysBinding)) {
mask |= D_KeyBindingChanged;
}
}
}
public boolean isFirstTime() {
return firstTime;
}
public boolean isLangChanged() {
return 0 != (mask & D_Lang);
}
public boolean isRotationChanged() {
return 0 != (mask & D_Rotation);
}
public boolean isFullScreenChanged() {
return 0 != (mask & D_FullScreen);
}
public boolean isShowTitleChanged() {
return 0 != (mask & D_ShowTitle);
}
public boolean isPageInTitleChanged() {
return 0 != (mask & D_PageInTitle);
}
public boolean isTapsEnabledChanged() {
return 0 != (mask & D_TapsEnabled);
}
public boolean isScrollHeightChanged() {
return 0 != (mask & D_ScrollHeight);
}
public boolean isPagesInMemoryChanged() {
return 0 != (mask & D_PagesInMemory);
}
public boolean isBrightnessChanged() {
return 0 != (mask & D_Brightness);
}
public boolean isBrightnessInNightModeChanged() {
return 0 != (mask & D_BrightnessInNightMode);
}
public boolean isKeepScreenOnChanged() {
return 0 != (mask & D_KeepScreenOn);
}
public boolean isLoadRecentChanged() {
return 0 != (mask & D_LoadRecent);
}
public boolean isUseBookcaseChanged() {
return 0 != (mask & D_UseBookcase);
}
public boolean isDjvuRenderingModeChanged() {
return 0 != (mask & D_DjvuRenderingMode);
}
public boolean isAutoScanDirsChanged() {
return 0 != (mask & D_AutoScanDirs);
}
public boolean isAllowedFileTypesChanged() {
return 0 != (mask & D_AllowedFileTypes);
}
public boolean isTapConfigChanged() {
return 0 != (mask & D_TapConfigChanged);
}
public boolean isKeyBindingChanged() {
return 0 != (mask & D_KeyBindingChanged);
}
}
}