package com.vgmlr.shim
import android.content.Context
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.core.content.edit
import androidx.core.graphics.toColorInt
internal const val SPACING_DEFAULT = 14
internal const val TAG_BG_DEFAULT = "#324540"
@Composable
fun ShimTheme(
themeManager: ShimThemeManager,
content: @Composable () -> Unit
) {
val colorScheme = darkColorScheme(
primary = Color(0xFF486860),
background = themeManager.backgroundColor.value,
onBackground = themeManager.textColor.value,
surface = themeManager.backgroundColor.value,
onSurface = themeManager.textColor.value
)
MaterialTheme(
colorScheme = colorScheme,
typography = Typography(),
content = content
)
}
class ShimThemeManager(private val context: Context) {
private val prefs = context.getSharedPreferences("shim_prefs", Context.MODE_PRIVATE)
var backgroundColor = mutableStateOf(Color(context.getColor(R.color.background_color)))
var textColor = mutableStateOf(Color(context.getColor(R.color.text_color)))
var tagBgColor = mutableStateOf(Color(TAG_BG_DEFAULT.toColorInt()))
var fontSize = mutableFloatStateOf(15.5f)
var isMonospace = mutableStateOf(false)
var showDates = mutableStateOf(false)
var lineHeight = mutableFloatStateOf(1.3f)
var lineSpacing = mutableFloatStateOf(0.2f)
var shimSpacing = mutableIntStateOf(SPACING_DEFAULT)
var hexBgColor = "#%06X".format(0xFFFFFF and context.getColor(R.color.background_color))
var hexTextColor = "#%06X".format(0xFFFFFF and context.getColor(R.color.text_color))
var hexTagBgColor = TAG_BG_DEFAULT
init {
refresh()
}
private fun getSafeString(key: String, default: String): String =
prefs.getString(key, default) ?: default
private fun formatHex(hex: String): String = if (hex.startsWith("#")) hex else "#$hex"
private fun formatNum(num: String): String = num.replace(Regex("[^0-9.]"), "")
fun saveTheme(
bg: String,
text: String,
tagBg: String,
mono: Boolean,
size: String,
height: String,
spacing: String,
gap: String,
dates: Boolean
) {
prefs.edit {
putString("main_background", formatHex(bg))
putString("main_color", formatHex(text))
putString("tag_bg", formatHex(tagBg))
putBoolean("is_monospace", mono)
putString("main_size", formatNum(size))
putString("line_height", height)
putString("line_spacing", spacing)
putString("shim_spacing", formatNum(gap))
putBoolean("show_dates", dates)
}
refresh()
}
fun refresh() {
val defaultBg = "#%06X".format(0xFFFFFF and context.getColor(R.color.background_color))
val defaultText = "#%06X".format(0xFFFFFF and context.getColor(R.color.text_color))
hexBgColor = getSafeString("main_background", defaultBg)
hexTextColor = getSafeString("main_color", defaultText)
hexTagBgColor = getSafeString("tag_bg", TAG_BG_DEFAULT)
backgroundColor.value = try {
Color(hexBgColor.toColorInt())
} catch (_: Exception) {
Color(context.getColor(R.color.background_color))
}
textColor.value = try {
Color(hexTextColor.toColorInt())
} catch (_: Exception) {
Color(context.getColor(R.color.text_color))
}
tagBgColor.value = try {
Color(hexTagBgColor.toColorInt())
} catch (_: Exception) {
Color(TAG_BG_DEFAULT.toColorInt())
}
isMonospace.value = prefs.getBoolean("is_monospace", false)
showDates.value = prefs.getBoolean("show_dates", false)
fontSize.floatValue = getSafeString("main_size", "15.5").toFloatOrNull() ?: 15.5f
lineHeight.floatValue = getSafeString("line_height", "1.35").toFloatOrNull() ?: 1.35f
lineSpacing.floatValue = getSafeString("line_spacing", "0.2").toFloatOrNull() ?: 0.2f
shimSpacing.intValue =
getSafeString("shim_spacing", "$SPACING_DEFAULT").toIntOrNull() ?: SPACING_DEFAULT
}
}