package cl.monsoon.s1next.data.pref;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.ColorInt;
import android.support.annotation.IntDef;
import android.support.annotation.StyleRes;
import android.support.v4.graphics.ColorUtils;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import cl.monsoon.s1next.R;
/**
* A manager manage the theme preference that is associated with settings.
*/
public final class ThemeManager {
public static final int TRANSLUCENT_THEME_DARK = R.style.Theme_Translucent_Dark;
/**
* Default theme in AndroidManifest.xml is light theme.
*/
private static final Theme DEFAULT_THEME = Theme.LIGHT_THEME;
/**
* https://www.google.com/design/spec/style/color.html#color-ui-color-application
*/
private static final int WHITE_BACKGROUND_SECONDARY_TEXT_ALPHA = (int) (0.54 * 255);
private static final int WHITE_BACKGROUND_HINT_OR_DISABLED_TEXT_ALPHA = (int) (0.38 * 255);
private static final int BLACK_BACKGROUND_SECONDARY_TEXT_ALPHA = (int) (0.70 * 255);
private static final int BLACK_BACKGROUND_HINT_OR_DISABLED_TEXT_ALPHA = (int) (0.30 * 255);
@Retention(RetentionPolicy.SOURCE)
@IntDef({
WHITE_BACKGROUND_SECONDARY_TEXT_ALPHA,
WHITE_BACKGROUND_HINT_OR_DISABLED_TEXT_ALPHA,
BLACK_BACKGROUND_SECONDARY_TEXT_ALPHA,
BLACK_BACKGROUND_HINT_OR_DISABLED_TEXT_ALPHA
})
private @interface BackgroundAlphaDef {}
private final Context mContext;
private final GeneralPreferencesRepository mGeneralPreferencesProvider;
/**
* Lazy Initialization.
*/
private final Supplier<Theme> mThemeSupplier = new Supplier<Theme>() {
@Override
public Theme get() {
Theme theme = Theme.VALUES.get(Integer.parseInt(
mGeneralPreferencesProvider.getThemeString()));
invalidateAccentColor(theme);
return theme;
}
};
private volatile Supplier<Theme> mThemeMemorized = Suppliers.memoize(mThemeSupplier);
@ColorInt
private volatile int mColorAccent;
public ThemeManager(Context context, GeneralPreferencesRepository generalPreferencesProvider) {
this.mContext = context;
this.mGeneralPreferencesProvider = generalPreferencesProvider;
}
/**
* Used for invalidating the theme preference if settings change.
*/
public void invalidateTheme() {
mThemeMemorized = Suppliers.memoize(mThemeSupplier);
}
/**
* Commits theme preference change for settings.
*
* @param index The theme index.
*/
public void applyTheme(int index) {
mGeneralPreferencesProvider.applyThemeString(String.valueOf(index));
}
public Theme getTheme() {
return mThemeMemorized.get();
}
@StyleRes
public int getThemeStyle() {
return getTheme().style;
}
public int getThemeIndex() {
return Theme.VALUES.indexOf(getTheme());
}
public void setThemeByIndex(int i) {
Theme theme = Theme.VALUES.get(i);
mThemeMemorized = Suppliers.ofInstance(theme);
invalidateAccentColor(theme);
}
public boolean isDefaultTheme() {
return getTheme() == DEFAULT_THEME;
}
public boolean isDarkTheme() {
Theme theme = getTheme();
return theme == Theme.DARK_THEME
|| theme == Theme.DARK_THEME_NIGHT_MODE
|| theme == Theme.DARK_THEME_NIGHT_MODE_AMOLED;
}
/**
* Used for invalidating the accent color if theme changes.
*/
private void invalidateAccentColor(Theme theme) {
// get current theme's accent color
TypedArray typedArray = mContext.obtainStyledAttributes(theme.style,
new int[]{R.attr.colorAccent});
mColorAccent = typedArray.getColor(0, -1);
typedArray.recycle();
Preconditions.checkState(mColorAccent != -1);
}
@ColorInt
public int getGentleAccentColor() {
return ColorUtils.setAlphaComponent(mColorAccent, getSecondaryTextAlpha());
}
@ColorInt
public int getHintOrDisabledGentleAccentColor() {
return ColorUtils.setAlphaComponent(mColorAccent, getHintOrDisabledTextAlpha());
}
@BackgroundAlphaDef
private int getSecondaryTextAlpha() {
if (isDarkTheme()) {
return BLACK_BACKGROUND_SECONDARY_TEXT_ALPHA;
} else {
return WHITE_BACKGROUND_SECONDARY_TEXT_ALPHA;
}
}
@BackgroundAlphaDef
private int getHintOrDisabledTextAlpha() {
if (isDarkTheme()) {
return BLACK_BACKGROUND_HINT_OR_DISABLED_TEXT_ALPHA;
} else {
return WHITE_BACKGROUND_HINT_OR_DISABLED_TEXT_ALPHA;
}
}
public enum Theme {
LIGHT_THEME(R.style.Theme_Light),
LIGHT_THEME_INVERSE_AMBER(R.style.Theme_Light_Inverse_Amber),
LIGHT_THEME_INVERSE_GREEN(R.style.Theme_Light_Inverse_Green),
LIGHT_THEME_INVERSE_LIGHT_BLUE(R.style.Theme_Light_Inverse_LightBlue),
LIGHT_THEME_INVERSE_PURPLE(R.style.Theme_Light_Inverse_Purple),
DARK_THEME(R.style.Theme_Dark),
DARK_THEME_NIGHT_MODE(R.style.Theme_Dark_NightMode),
DARK_THEME_NIGHT_MODE_AMOLED(R.style.Theme_Dark_NightMode_Amoled);
private static final List<Theme> VALUES = Arrays.asList(Theme.values());
@StyleRes
private final int style;
Theme(@StyleRes int style) {
this.style = style;
}
}
}