import machine
import utime
import plasma
from plasma import plasma2040

# define LED colour selection
NUM_COLOURS = 8 #none,red,orange,yellow,green,blue,indigo,violet,white
RGBW = [[0,0,0,0],[255,0,0,0],[255,140,0,0],[255,255,0,0],[0,255,0,0],[0,0,255,0],[75,0,130,0],[255,0,255,0],[0,0,0,255]]

# initialize LED's
NUM_LEDS = 12
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, rgbw=True)
led_strip.start()

for i in range(NUM_LEDS): #switch off LED's if on
   led_strip.set_rgb(i, 0, 0, 0, 0)

button = 0              #push button value to enable colour or intensity
intensity = NUM_COLOURS #LED intensity divider
counter = 0             #value to select colour
status = False          #valid rotation flag
tdiff = 0               #rotation direction +1 or -1
phase_a = 0             #channel A level
phase_b = 0             #channel B level

def ENC_A_change(pin):
    global phase_a, ENC_A_status, phase_b, tdiff
    phase_a = ENC_A()
    phase_b = ENC_B()
    if phase_a == phase_b:
        tdiff = 1
    phase_a = ENC_A()
    ENC_compare()
    #utime.sleep_ms(5)

    return
 
def ENC_B_change(pin):
    global phase_b, ENC_B_status, phase_a, tdiff
    phase_b = ENC_B()
    phase_a = ENC_A()
    if phase_a == phase_b:
        tdiff = -1
    phase_b = ENC_B()
    ENC_compare()
    #utime.sleep_ms(5)
    
    return

def ENC_compare():
    global status
    status = True

    return

# assign pins for encoder and initialise IRQ and levels for EC11 rotary encoder
ENC_A = machine.Pin(26, machine.Pin.IN, machine.Pin.PULL_UP)
ENC_A.irq(trigger=machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING, handler=ENC_A_change)
ENC_B = machine.Pin(27, machine.Pin.IN, machine.Pin.PULL_UP)
ENC_B.irq(trigger=machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING, handler=ENC_B_change)
# assign pin for encoder switch
ENC_C = machine.Pin(28, machine.Pin.IN, machine.Pin.PULL_UP)

def isNeg(val): #determine numeric sign
    if val < 0: #negative
       return True 
    if val > 0: #positive
       return False 

def isButtonPushDown():
  if not(ENC_C.value()):
      utime.sleep_ms(5)
      if not(ENC_C.value()):
          return True
  else:
    return False

def LED_intensity():
 # change each RGB value by the same fraction to adjust brightness
 global intensity, NUM_COLOURS   
 
 led = [] #storage for new RGB values
 bright = (intensity/NUM_COLOURS) #fraction of brightness
  
 if bright > 0:
  for i in range(4):
   led.append(int((RGBW[counter][i])*bright))
 else:
  led=[0, 0, 0, 0] #LED's off
 
 for i in range(NUM_LEDS): 
     led_strip.set_rgb(i, led[0], led[1], led[2], led[3])
     utime.sleep_ms(5)
 
 return

while True:

 if isButtonPushDown():
  button += 1
  if button > 1:
      button = 0
  #print("button press", button)     
 else:
  if status:
   if button == 0: 
    #change the colours
    if isNeg(tdiff):
     counter -= 1
     if counter < 0:
       counter = 0
    if not(isNeg(tdiff)):
     counter += 1
     if counter > NUM_COLOURS:
       counter = NUM_COLOURS  
    for i in range(NUM_LEDS):
       led_strip.set_rgb(i, RGBW[counter][0], RGBW[counter][1], RGBW[counter][2], RGBW[counter][3])
    
    LED_intensity() #retain intensity change if previously updated
   
   else:
    #change the brightness
    if isNeg(tdiff):
     intensity -= 1
     if intensity < 0:
       intensity = 0
    if not(isNeg(tdiff)):
     intensity += 1
     if intensity > NUM_COLOURS:
       intensity = NUM_COLOURS  

    LED_intensity()
 
 status = False

 utime.sleep_ms(400)
