#!/usr/bin/env python3
"""Recolour the GTK widget assets from Nordic's palette to Darkmatter's.

Run from the theme root:  python3 src/recolor-assets.py
Idempotent only against the pristine Nordic assets -- re-running over already
converted files will drift, so restore from Nordic first if you need to redo.
"""

import glob
import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "lib"))

import darkmatter as dm
from png import Png
from remap import Remapper

R = dm.rgb

# Nordic source colour -> Darkmatter target, for every asset that has no
# override below. Surfaces keep their stacking order; the cyan ramp that
# upstream used for selection collapses onto the orange accent ramp.
ANCHORS = [
    # surfaces
    ("#000000", "#000000"),
    ("#0b0d10", dm.SHADOW),
    ("#1d2129", dm.DARK),
    ("#232831", dm.BG),
    ("#3b4252", dm.BASE),
    ("#5d6a83", "#4a494b"),   # control outlines (unchecked check/radio)
    ("#7f8a99", "#6a696b"),
    ("#a0a0a6", dm.DIM),
    ("#b7b7bf", dm.SUBTLE),
    ("#c4c4c4", "#c4c4c4"),
    ("#f0f0f3", "#f0f0f0"),
    ("#f5f5f5", "#f5f5f5"),
    ("#fafafa", "#fafafa"),
    ("#fefefe", "#fefefe"),
    ("#ffffff", dm.FG),
    # the accent ramp
    ("#0f8099", dm.ORANGE_D2),
    ("#779c9b", "#c2733f"),
    ("#1396b2", dm.ORANGE_D1),
    ("#13a0bf", dm.ORANGE),
    ("#37b9a5", dm.ORANGE),
    ("#8fbcbb", dm.ORANGE),
    ("#42b3cc", dm.ORANGE_L1),
    ("#13b1d5", dm.ORANGE_L1),
    ("#5ec3d8", dm.ORANGE_L2),
    ("#13d5ff", dm.ORANGE_L3),
    # remaining hues
    ("#ebcb8b", dm.CREAM),
    ("#bf616a", dm.RED),
    ("#a3be8c", dm.TEAL),
]

# The window controls are traffic lights: a coloured disc on a dark rim, with
# the hue carrying the state. Darkmatter keeps them grey and spends the accent
# on hover instead, so the disc colour depends on which file it appears in.
DISC = {
    "close":              dm.DIM,
    "close_prelight":     dm.ORANGE,
    "close_unfocused":    dm.BORDER_HI,
    "maximize":           dm.DIM,
    "maximize_prelight":  dm.SUBTLE,
    "maximize_unfocused": dm.BORDER_HI,
    "min":                dm.DIM,
    "min_prelight":       dm.SUBTLE,
    "min_unfocused":      dm.BORDER_HI,
}
# which source colour holds the disc in each of those files
DISC_SRC = {
    "close": "#bf616a", "close_prelight": "#bf616a", "close_unfocused": "#3b4252",
    "maximize": "#a3be8c", "maximize_prelight": "#a3be8c", "maximize_unfocused": "#3b4252",
    "min": "#ebcb8b", "min_prelight": "#ebcb8b", "min_unfocused": "#3b4252",
}


def anchors_for(path):
    stem = os.path.basename(path)[:-4].replace("@2", "")
    if stem not in DISC:
        return ANCHORS
    over = {R(DISC_SRC[stem]): R(DISC[stem]), R("#232831"): R(dm.SHADOW)}
    return [(s, over.get(s, t)) for s, t in
            [(R(a), R(b)) for a, b in ANCHORS]]


def normalise(anchors):
    if anchors and isinstance(anchors[0][0], str):
        return [(R(a), R(b)) for a, b in anchors]
    return anchors


def main():
    files = sorted(glob.glob("assets/*.png"))
    if not files:
        sys.exit("run me from the theme root (no assets/*.png found)")
    changed = 0
    for path in files:
        remap = Remapper(normalise(anchors_for(path)))
        img = Png(path)
        if img.color_type == 6:
            px = img.rgba()
            img.set_rgba([remap(p[:3]) + (p[3],) for p in px])
        elif img.color_type == 3:
            img.set_palette([remap(c) for c in img.palette()])
        else:
            print("  skipped (unsupported colour type %d): %s" % (img.color_type, path))
            continue
        img.save()
        changed += 1
    print("recoloured %d of %d assets" % (changed, len(files)))


if __name__ == "__main__":
    main()
