"""Mario-sprite-galleri: svamp -> 1UP -> stjärna -> eldblomma -> snurrande mynt.
Slide-övergångar mellan varje (sidescroll-stil)."""
import machine, neopixel, time, random

PIN = 4
W, H = 8, 8
NUM = W * H
np = neopixel.NeoPixel(machine.Pin(PIN), NUM)

def xy(x, y):
    return y * W + x

# Färgpalett (låg ljusstyrka)
PAL = {
    '.': (0, 0, 0),
    'R': (24, 0, 0),     # Mario-röd
    'W': (18, 18, 18),   # vit
    'G': (0, 22, 0),     # 1UP-grön
    'Y': (24, 20, 0),    # gul
    'O': (26, 8, 0),     # orange
    'B': (4, 4, 4),      # mörkbrun/svart-kontur
}

MUSHROOM = [
    "..RRRR..",
    ".RWWWWR.",
    "RWWRWRWR",
    "RRRRRRRR",
    "RRWRRWRR",
    ".RRRRRR.",
    "..WWWW..",
    "..WWWW..",
]

ONE_UP = [
    "..GGGG..",
    ".GWWWWG.",
    "GWWGWGWG",
    "GGGGGGGG",
    "GGWGGWGG",
    ".GGGGGG.",
    "..WWWW..",
    "..WWWW..",
]

STAR = [
    "...YY...",
    "..YYYY..",
    "YYYYYYYY",
    ".YYYYYY.",
    ".YYYYYY.",
    ".YY..YY.",
    ".Y....Y.",
    "Y......Y",
]

FLOWER = [
    "..ORRO..",
    ".OYYYYO.",
    "OYYWWYYO",
    ".OYYYYO.",
    "...OO...",
    "...GG...",
    "..GGGG..",
    "..G..G..",
]

COIN_FRONT = [
    "..YYYY..",
    ".YYYYYY.",
    "YYOYYOYY",
    "YYOYYOYY",
    "YYYYYYYY",
    "YYOOOOYY",
    ".YYYYYY.",
    "..YYYY..",
]

COIN_NARROW = [
    "...YY...",
    "...YY...",
    "...OY...",
    "...OY...",
    "...YY...",
    "...OY...",
    "...YY...",
    "...YY...",
]

COIN_EDGE = [
    "....Y...",
    "....Y...",
    "....Y...",
    "....Y...",
    "....Y...",
    "....Y...",
    "....Y...",
    "....Y...",
]

def clear():
    for i in range(NUM):
        np[i] = (0, 0, 0)

def draw(sprite, sx=0, tint=1.0):
    """Rita sprite med vänster kant vid kolumn sx. tint skalar färgen."""
    for ry in range(8):
        row = sprite[ry]
        for rx in range(8):
            x = rx + sx
            if 0 <= x < W:
                c = PAL[row[rx]]
                if c != (0, 0, 0):
                    np[xy(x, ry)] = (int(c[0] * tint), int(c[1] * tint), int(c[2] * tint))

def show_static(sprite, dur_ms=2200):
    t0 = time.ticks_ms()
    while time.ticks_diff(time.ticks_ms(), t0) < dur_ms:
        clear()
        draw(sprite)
        np.write()
        time.sleep_ms(80)

def show_star(dur_ms=2500):
    """Stjärna med gnistor runt om."""
    t0 = time.ticks_ms()
    sparkle_positions = []  # (x, y, life)
    while time.ticks_diff(time.ticks_ms(), t0) < dur_ms:
        clear()
        draw(STAR)
        # gnistor: lägg till nya
        for _ in range(2):
            sparkle_positions.append([random.randint(0, W - 1),
                                      random.randint(0, H - 1), 4])
        # rita gnistor, minska livstid
        new_sparkles = []
        for sp in sparkle_positions:
            x, y, life = sp
            if life > 0:
                # tona ned vit gnista
                v = 6 * life
                # endast lägg till om pixeln är svart (inte ovanpå stjärnan)
                idx = xy(x, y)
                if np[idx] == (0, 0, 0):
                    np[idx] = (v, v, v // 2)
                sp[2] = life - 1
                new_sparkles.append(sp)
        sparkle_positions = new_sparkles
        np.write()
        time.sleep_ms(80)

def show_flower(dur_ms=2500):
    """Eldblomma som pulserar mellan röd-orange och gul-orange."""
    t0 = time.ticks_ms()
    frame = 0
    while time.ticks_diff(time.ticks_ms(), t0) < dur_ms:
        clear()
        # pulsera mellan 0.5 och 1.0 ljusstyrka via sin
        import math
        tint = 0.55 + 0.45 * (0.5 + 0.5 * math.sin(frame * 0.25))
        draw(FLOWER, tint=tint)
        np.write()
        frame += 1
        time.sleep_ms(60)

def show_coin(dur_ms=2500):
    """Snurrande mynt: front -> narrow -> edge -> narrow -> front -> ..."""
    frames = [COIN_FRONT, COIN_FRONT, COIN_NARROW, COIN_EDGE,
              COIN_NARROW, COIN_FRONT, COIN_FRONT, COIN_FRONT]
    t0 = time.ticks_ms()
    i = 0
    while time.ticks_diff(time.ticks_ms(), t0) < dur_ms:
        clear()
        draw(frames[i % len(frames)])
        np.write()
        i += 1
        time.sleep_ms(110)

def transition(s_out, s_in, dur_ms=700):
    """Slide-övergång: s_out åker ut åt vänster, s_in glider in från höger."""
    steps = 9
    for k in range(steps):
        clear()
        draw(s_out, sx=-k)
        draw(s_in, sx=8 - k)
        np.write()
        time.sleep_ms(dur_ms // steps)

# Sekvens: (sprite, visa-funktion, övergångs-sprite-för-slide)
SHOWS = [
    (MUSHROOM,    lambda: show_static(MUSHROOM)),
    (ONE_UP,      lambda: show_static(ONE_UP)),
    (STAR,        show_star),
    (FLOWER,      show_flower),
    (COIN_FRONT,  show_coin),
]

try:
    i = 0
    while True:
        sprite, show_fn = SHOWS[i]
        show_fn()
        next_sprite = SHOWS[(i + 1) % len(SHOWS)][0]
        transition(sprite, next_sprite)
        i = (i + 1) % len(SHOWS)
except KeyboardInterrupt:
    clear()
    np.write()
