# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""CircuitPython Essentials DotStar example"""
import time
from rainbowio import colorwheel
import adafruit_dotstar
import board
import random

num_pixels = 12
pixels = adafruit_dotstar.DotStar(board.GP18, board.GP19, num_pixels, brightness=0.1, auto_write=False)
sleepy_time = 0.1

RED = (255, 0, 0)
YELLOW = (255, 150, 0)
ORANGE = (255, 40, 0)
GREEN = (0, 255, 0)
TEAL = (0, 255, 120)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
MAGENTA = (255, 0, 20)
WHITE = (255, 255, 255)

def color_fill(color, wait):
    pixels.fill(color)
    pixels.show()
    time.sleep(wait)

def slice_alternating(wait):
    pixels[::2] = [RED] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [ORANGE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [YELLOW] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [GREEN] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [TEAL] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [CYAN] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [BLUE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [PURPLE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [MAGENTA] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [WHITE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)

#Function below only works if the number of pixels can de devided by 6
def slice_rainbow(wait):
    pixels[::6] = [RED] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[1::6] = [ORANGE] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[2::6] = [YELLOW] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[3::6] = [GREEN] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[4::6] = [BLUE] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[5::6] = [PURPLE] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)

def rainbow_cycle(wait):
    for j in range(255):
        for i in range(num_pixels):
            rc_index = (i * 256 // num_pixels) + j
            pixels[i] = colorwheel(rc_index & 255)
        pixels.show()
        time.sleep(wait)

def clear():
    for i in range (num_pixels):
        pixels[i] = (0, 0, 0)

def bounce(r, g, b, wait): 
    for i in range(num_pixels * 4):
        for j in range(num_pixels):
            pixels[j] = (r, g, b)
        if (i // num_pixels) % 2 == 0:
            pixels[i % num_pixels] = (0, 0, 0)
        else:
            pixels[num_pixels - 1 - (i % num_pixels)] = (0, 0, 0)
        pixels.show()        
        time.sleep(wait)        

def cycle(r, g, b, wait):
    for i in range(num_pixels * 4):
        for j in range(num_pixels):
            pixels[j] = (0, 0, 0)
        pixels[i % num_pixels] = (r, g, b)
        pixels.show()
        time.sleep(wait)

def singlekitt(color, wait):
    for j in range(num_pixels): #going up!
        for dot in range(num_pixels):
            if dot==j:
                pixels[dot] = color
            else:
                pixels[dot] = (0, 0, 0)
        pixels.show()
        time.sleep(sleepy_time)

    for k in range(num_pixels-1,0,-1): #going down!
        for dot in range(num_pixels):
            if dot==k:
                pixels[dot] = color
            else:
                pixels[dot] = (0, 0, 0)
        pixels.show()
        time.sleep(wait)
        
def cylonloop(eyebright, eyedim, eyesize, wait):
    for i in range(num_pixels-eyesize-2): #going up!
        clear()
        pixels[i] = eyedim
        for j in range(i+1, i+eyesize+1): #i+1 is the first dim
            pixels[j] = eyebright
        pixels[i+eyesize+1] = eyedim
        pixels.show()
        time.sleep(wait)

    for i in range(num_pixels-eyesize-2, 0, -1): #going down!
        clear()
        pixels[i] = eyedim
        for j in range(i+1, i+eyesize+1):
            pixels[j] = eyebright
        pixels[i+eyesize+1] = eyedim
        pixels.show()
        time.sleep(sleepy_time)
        
def wheel(pos):
    if pos < 0 or pos > 255:
        return (0, 0, 0)
    if pos < 85:
        return (255 - pos * 3, pos * 3, 0)
    if pos < 170:
        pos -= 85
        return (0, 255 - pos * 3, pos * 3)
    pos -= 170
    return (pos * 3, 0, 255 - pos * 3)

def rainbow_cycle(wait): #needs a short wait time to be noticeable
    for j in range(255):
        for i in range(num_pixels):
            rc_index = (i * 256 // num_pixels) + j
            pixels[i] = wheel(rc_index & 255)
        pixels.show()
        time.sleep(wait)

def breathe_red(colormax, increment, wait):
    for color in range(0, colormax, increment):
        for dot in range(num_pixels):
            pixels[dot] = (color, 0, 0)
        pixels.show()
        time.sleep(wait)
    for color in range(colormax, 0, -increment):
        for dot in range(num_pixels):
            pixels[dot] = (color, 0, 0)
        pixels.show()
        time.sleep(wait)
        
def sparkle(colorlow, colorspark, sparklytime, mindelay, maxdelay):
    for k in range(num_pixels):
        spark = (random.randrange(0, num_pixels))
        for dot in range(num_pixels):
            if dot==spark:
                pixels[dot] = colorspark
            else:
                pixels[dot] = colorlow
        pixels.show()
        time.sleep(sparklytime)
        clear()
        for i in range(num_pixels):
            pixels[i] = colorlow
        pixels.show()
        sleepwait = random.uniform(mindelay, maxdelay)
        time.sleep(sleepwait)

while True:
    
    #sparkle((10, 10, 10), (255, 255, 255), 0.05, 0.01, 1)  #has no end  
    for i in range(4):
        breathe_red(155, 30, sleepy_time)
    for i in range(2):
        singlekitt((255, 0, 0), sleepy_time)
    for i in range(3):
        cylonloop((255, 0, 0), (25, 0, 0), 4, sleepy_time)
    rainbow_cycle(0)
    cycle(255, 255, 0, sleepy_time)
    bounce (255, 0, 255, sleepy_time)
    
    # Change this number to change how long it stays on each solid color.
    color_fill(RED, sleepy_time)
    color_fill(YELLOW, sleepy_time)
    color_fill(ORANGE, sleepy_time)
    color_fill(GREEN, sleepy_time)
    color_fill(TEAL, sleepy_time)
    color_fill(CYAN, sleepy_time)
    color_fill(BLUE, sleepy_time)
    color_fill(PURPLE, sleepy_time)
    color_fill(MAGENTA, sleepy_time)
    color_fill(WHITE, sleepy_time)

    # Increase or decrease this to speed up or slow down the animation.
    slice_alternating(sleepy_time)

    color_fill(WHITE, sleepy_time)

    # Increase or decrease this to speed up or slow down the animation.
    slice_rainbow(sleepy_time)

    time.sleep(sleepy_time)

    # Increase this number to slow down the rainbow animation. Keep it between 0 and 0.1 for a noticeable effect
    rainbow_cycle(sleepy_time/10)
