# Configuration Constants
PARTICLE_COUNT = 300
MANDALA_ROTATION_SPEED = 0.008
STAR_ROTATION_SPEED = -0.005

# Particle Management & Global Tracking Angles
sparks = []
angle_mandala = 0.0
angle_star = 0.0

def setup():
    size(800, 600)
    print("...setup...")
    colorMode(HSB, 360, 100, 100, 100)
    frameRate(60)

    for i in range(PARTICLE_COUNT):
        sparks.append(Spark())

def draw():
    global angle_mandala, angle_star

    # H=22, S=73, B=6 — near-black dark amber, matches original RGB(15,8,4)
    background(22, 73, 6)

    translate(width / 2, height / 2)

    # 1. Draw the ambient glowing sparks
    for s in sparks:
        s.update()
        s.display()

    # 2. Draw the primary Eldritch Mandalas
    pushMatrix()
    rotate(angle_mandala)
    draw_mystic_shield()
    popMatrix()

    # 3. Draw the interlaced, counter-rotating geometric star array
    pushMatrix()
    rotate(angle_star)
    draw_interlaced_stars()
    popMatrix()

    angle_mandala += MANDALA_ROTATION_SPEED
    angle_star += STAR_ROTATION_SPEED

def draw_mystic_shield():
    noFill()

    # Outer fiery boundary ring — H=33 (orange), A=71 (~180/255 scaled)
    stroke(33, 100, 100, 71)
    strokeWeight(3)
    ellipse(0, 0, 320, 320)

    # Thick main internal ring — H=26 (deep orange), A=86 (~220/255 scaled)
    stroke(26, 100, 100, 86)
    strokeWeight(6)
    ellipse(0, 0, 280, 280)

    # Satellite sigils — H=36 (amber), S=92, A=78 (~200/255 scaled)
    satellite_circles = 8
    strokeWeight(2)
    stroke(36, 92, 100, 78)
    for i in range(satellite_circles):
        pushMatrix()
        rotate((TWO_PI / satellite_circles) * i)
        ellipse(140, 0, 45, 45)
        ellipse(140, 0, 25, 25)
        popMatrix()

    # Inner core ring — H=31, A=59 (~150/255 scaled)
    stroke(31, 100, 100, 59)
    strokeWeight(2)
    ellipse(0, 0, 100, 100)

def draw_interlaced_stars():
    noFill()
    # H=34 (warm amber), S=96, A=67 (~170/255 scaled)
    stroke(34, 96, 100, 67)
    strokeWeight(2.5)

    rectMode(CENTER)
    pushMatrix()
    rect(0, 0, 200, 200)
    rotate(QUARTER_PI)
    rect(0, 0, 200, 200)
    popMatrix()

class Spark(object):
    def __init__(self):
        self.reset()
        # Randomize starting radius so sparks don't all burst outward at once
        self.radius = random(20, 250)

    def reset(self):
        self.radius = random(40, 100)
        self.angle = random(TWO_PI)
        self.speed = random(1.5, 4.0)
        self.size = random(2, 5)
        # Offset proportionally scaled: ~100/255 * original 0-100 = 0-40
        self.alpha_offset = random(0, 40)

    def update(self):
        self.radius += self.speed
        self.angle += random(-0.01, 0.03)

        if self.radius > width / 2 or self.radius > 300:
            self.reset()

    def display(self):
        life_ratio = map(self.radius, 40, 300, 1.0, 0.0)
        # Alpha in 0-100 range to match HSB colorMode scale
        current_alpha = (life_ratio * 100) - self.alpha_offset

        if current_alpha > 0:
            x = self.radius * cos(self.angle)
            y = self.radius * sin(self.angle)

            noStroke()
            # H=24-47 spans deep orange to golden amber (matches rnd(100,200) green in RGB)
            fill(random(24, 47), 100, 100, current_alpha)
            ellipse(x, y, self.size, self.size)
