# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

"""
Eclairage à LED Neopixel
avec contrôle (encodeur rotatif)
"""
__author__ = "arofarn"
__version__ = 0.2

# Imports

import time
import machine
import neopixel
from uos import uname
from encoder import Encoder

#Paramètres

NB_PIX = 8                  # Nombre de pixels
MAX_LUM = 100               # Luminosité max (100 max.)
COULEUR = [255, 255, 255]   # Couleur de base (à luminosité max)

#Déclaration des objets et initialisation des variables

board_type = uname()[0]
print("Système :", board_type)

# Neopixels

if board_type == 'esp8266':
    NEOPIX_PIN = 2
    # Les deux broches suivantes doivent être capable d'interruption !!!
    # sur ESP8266 => : 4, 5, 12, 13 et 14
    ENC_PIN_A = 13      # N° de la 1ere broche de l'encodeur
    ENC_PIN_B = 12      # N° de la 2e broche de l'encodeur
    ENC_BOUTON = 14     # broche du clic central de l'encodeur

    # With ESP8266 (no timing parameter)
    pixel_strip = neopixel.NeoPixel(machine.Pin(NEOPIX_PIN), NB_PIX)

elif board_type == 'esp32':
    NEOPIX_PIN = 14
    # Pins
    ENC_PIN_A = 15      # N° de la 1ere broche de l'encodeur
    ENC_PIN_B = 33      # N° de la 2e broche de l'encodeur
    ENC_BOUTON = 27     # broche du clic central de l'encodeur

    # # Only with ESP32 : add timing param.
    # # timing param =0 for "old" 400kHz neopixel (default)
    # #              =1 for "new" 800kHz neopixel
    pixel_strip = neopixel.NeoPixel(machine.Pin(NEOPIX_PIN), NB_PIX, timing=1)

else:
    # ce code n'est pas prévu pour d'autre carte pour l'instant
    print("Carte non-supportée")
    quit()

# # Only with ESP32 : add timing param.
# # timing param =0 for "old" 400kHz neopixel (default)
# #              =1 for "new" 800kHz neopixel
# pixel_strip = neopixel.NeoPixel(machine.Pin(NEOPIX_PIN), NB_PIX, timing=1)
# coul_tmp = [0, 0, 0]

#Eteint tout à l'initialisation
pixel_strip.fill([0, 0, 0])
pixel_strip.write()

# Encodeur rotatif
enc = Encoder(ENC_PIN_B, ENC_PIN_A,
              min_val=0, max_val=MAX_LUM,
              clicks=1)

#Bouton
bout = machine.Pin(ENC_BOUTON, machine.Pin.IN)

#Variable d'état
LUM = 0            # Luminosité (0 - 100)
PWR = False        # Est-ce que l'éclairage est allumé ?
BOUT_PRESS_STATE = 1

def update_neopixel(np_strp, coul, lum=50):
    """Update NeoPixel strip with one color
    :param np_strp : NeoPixel object
    :param coul : color [R, G, B]
    :param lum : brightness 0-100 (default: 50)
    """
    col_tmp = [0, 0, 0]

    for i in range(3):
        col_tmp[i] = int(coul[i] * lum / 100)

    pixel_strip.fill(col_tmp)
    pixel_strip.write()

while True:

    # Si on a un changement de valeur, on met à jour la luminisité et l'éclairage
    # des NeoPixel
    if PWR and LUM != enc.value:
        print(enc.value)
        LUM = enc.value
        update_neopixel(pixel_strip, COULEUR, LUM)

    # Quand le bouton central est appuyé puis relâché, on allume ou on éteint
    if bout.value() == 0 and BOUT_PRESS_STATE == 1:
        PWR = not PWR
        print("Power :", PWR)
        if not PWR:
            # Extinction des LED
            pixel_strip.fill((0, 0, 0))
            pixel_strip.write()
        else:
            # On remet l'encodeur à la dernière luminosité connue
            # pour ignorer les mouvements pendant l'extinction
            enc.reset(LUM)
            update_neopixel(pixel_strip, COULEUR, LUM)

    BOUT_PRESS_STATE = bout.value()

    time.sleep_ms(20)
