#!/usr/bin/env python3

import colorama
from colorama import Fore, Back, Style
import math
import random
import time

HEART_OPEN = [
    '0b01100110',
    '0b10011001',
    '0b10000001',
    '0b10000001',
    '0b01000010',
    '0b00100100',
    '0b00011000',
    '0b00000000'
]

HEART_FILLED = [
    '0b01100110',
    '0b11111111',
    '0b11111111',
    '0b11111111',
    '0b01111110',
    '0b00111100',
    '0b00011000',
    '0b00000000'
]

SMILEY_HAPPY = [
    '0b00111100',
    '0b01000010',
    '0b10100101',
    '0b10000001',
    '0b10100101',
    '0b10011001',
    '0b01000010',
    '0b00111100'
]

MATRIX_WIDTH = 15
MATRIX_HEIGHT = 20
NUM_LEDS = 300
AUDIO_MAP = [7, 4, 6, 3, 4, 7, 8, 3, 9, 5, 6, 4, 7, 4, 7]
TRANSITION_POS = 0
TRANSITION_DIRECTION = 1
TRANSITION_TIMES = 0

leds = [0]*NUM_LEDS

bufMatrix = [[0 for x in range(MATRIX_WIDTH)] for y in range(MATRIX_HEIGHT)]

def arduino_map(x, in_min, in_max, out_min, out_max):
    return math.floor((x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min)

def testBit(int_type, offset):
    mask = 1 << offset
    return(int_type & mask)

def transition(times):
    global TRANSITION_POS
    global TRANSITION_DIRECTION
    global TRANSITION_TIMES

    print(TRANSITION_POS)
    print(TRANSITION_DIRECTION)

    for x in range(0, MATRIX_WIDTH):
        bufMatrix[TRANSITION_POS][x] = 1
        bufMatrix[TRANSITION_POS+1][x] = 1
        bufMatrix[TRANSITION_POS+2][x] = 4
        bufMatrix[TRANSITION_POS+3][x] = 4
        bufMatrix[TRANSITION_POS+4][x] = 5
        bufMatrix[TRANSITION_POS+5][x] = 5
    
    if TRANSITION_POS >= (MATRIX_HEIGHT -6):
        TRANSITION_DIRECTION = -1
    if TRANSITION_POS == 0:
        TRANSITION_DIRECTION = 1
        TRANSITION_TIMES += 1
        if TRANSITION_TIMES >= times+1:
            TRANSITION_TIMES = 0
            return 0

    TRANSITION_POS += TRANSITION_DIRECTION
    return 1

def drawSprite(sprite, offset_x, offset_y, color):
    for y in range(0, 8):
        line = sprite[y];
        for x in range (0, 8):
            led = testBit(int(line, 2), 7-x)
            if led > 0:
                ypos = y + offset_y
                xpos = x + offset_x
                if 0 <= xpos < 15 and 0 <= ypos < 20:
                    bufMatrix[ypos][xpos] = color

def drawAudio(value):
    value = arduino_map(value, 0, 255, 0, 20)
    for x in range(MATRIX_WIDTH):
        barValue = math.floor(value * (AUDIO_MAP[x] / 10))
        #print(barValue)
        for y in range(barValue):
            yval = MATRIX_HEIGHT - y -1
            #print("yval: {0} for x: {1}".format(yval, x))
            bufMatrix[yval][x] = 1

def printMatrix(buffer):
    for y in range(MATRIX_HEIGHT):
        print("")
        for x in range(MATRIX_WIDTH):
            color_prepend = Style.DIM
            color_append = Style.RESET_ALL
            led = bufMatrix[y][x]
            if led != 0:
                if led == 1:
                    color_prepend = Fore.RED
                elif led == 2:
                    color_prepend = Fore.BLUE
                elif led == 3:
                    color_prepend = Fore.MAGENTA
                elif led == 4:
                    color_prepend = Fore.YELLOW
                elif led == 5:
                    color_prepend = Fore.GREEN
            print(color_prepend + "{0} ".format(led) + color_append, end="")
    print("")

def printLedArray():
    print("")
    for index, led in enumerate(leds):
        color_prepend = Style.DIM
        color_append = Style.RESET_ALL
        if led != 0:
            if led == 1:
                color_prepend = Fore.RED
            elif led == 2:
                color_prepend = Fore.BLUE
            elif led == 3:
                color_prepend = Fore.MAGENTA
        print(color_prepend + "{0} ".format(led) + color_append, end="")
        if((index + 1) % MATRIX_WIDTH == 0):
                print("")

def formatMatrixForLedStrip():
    for y in range(MATRIX_HEIGHT):
        for x in range(MATRIX_WIDTH):
            if y % 2 != 0: #reversed row
                leds[y*MATRIX_WIDTH + MATRIX_WIDTH-1 - x] = bufMatrix[y][x]
            else:
                leds[y*MATRIX_WIDTH + x] = bufMatrix[y][x]

def clearBuffer():
    for y in range(MATRIX_HEIGHT):
        for x in range(MATRIX_WIDTH):
            bufMatrix[y][x] = 0

if __name__ == '__main__':
    print("Led Matrix tester")
    #drawSprite(HEART_FILLED, 0, 0, 3)
    #drawSprite(HEART_FILLED, 9, 6, 2)
    #drawSprite(HEART_FILLED, -4, 10, 3)
    while True:
        # level = random.randint(50, 255)
        # print(level)
        # drawAudio(level)
        print(transition(3))
        printMatrix(bufMatrix)
        clearBuffer()
        time.sleep(0.1)
        #formatMatrixForLedStrip()
        #printLedArray()