################### Libraries ###########################
from samplebase import SampleBase
from rgbmatrix import graphics
import time
from datetime import datetime
from PIL import Image
from PIL import ImageSequence
import pygame
import my_spotify
import os
import RPi.GPIO as GPIO
import sys
import my_spotify
import json

#################### Setup Environment ##################
os.putenv('SDL_VIDEODRIVER', 'fbcon')
os.putenv('SDL_FBDEV', '/dev/fb0') 
os.putenv('SDL_MOUSEDRV', 'TSLIB') # Track mouse clicks on piTFT
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')

print("start")

print("init")
pygame.init()
TFT_SIZE = width, height = 320, 240
print("setmode")
screen = pygame.display.set_mode(TFT_SIZE)

################## Constants ############################



print("initializing spotify")
# initialize spotify
sp = my_spotify.spotify_init()
my_spotify.add_playlist_to_queue(sp)
print("finished initializing spotify")

# pygame colors
BLACK = 0, 0, 0
WHITE = 255, 255, 255
RED = 252, 65, 3
ORANGE = 252, 154, 48
GREEN = 111, 224, 101
BLUE = 3, 148, 252
PURPLE = 209, 109, 227
GREY = 128, 128, 128

led_white = graphics.Color(255,255,255)



############## GLOBAL VARIABLES ###################
code_run = True
is_home = True
is_music_player = False
is_scribble = False
is_weather = False
playing = False
drawing = True
brush_color = WHITE

################### TFT ###########################

print("setup pygame")


# setup pygame on tft
screen.fill(BLACK)

# surfaces and icons
spotify_surface = pygame.Surface(TFT_SIZE)
home_surface = pygame.Surface(TFT_SIZE)


spotify_icon = pygame.image.load("img/spotify_icon.png")
spotify_icon = pygame.transform.scale(spotify_icon, (50,50))
spotify_rect = spotify_icon.get_rect().move((40,120))

scribble_icon = pygame.image.load("img/scribble.png")
scribble_icon = pygame.transform.scale(scribble_icon, (50,50))
scribble_rect = scribble_icon.get_rect().move((130,120))

weather_icon = pygame.image.load("img/weather_icon.png")
weather_icon = pygame.transform.scale(weather_icon, (50,50))
weather_rect = weather_icon.get_rect().move(220,120)

home_icon = pygame.image.load("img/home_icon.png")
home_icon = pygame.transform.scale(home_icon, (50,50))
home_rect = home_icon.get_rect().move(40,0)

clear_icon = pygame.image.load("img/clear_icon.png")
clear_icon = pygame.transform.scale(clear_icon, (50,50))
clear_rect = clear_icon.get_rect().move(40,80)

pause_rect_1 = pygame.Rect(148,108,10,30)
pause_rect_2 = pygame.Rect(163,108,10,30)

spotify_surface.blit(home_icon, (40,0))
play_button = pygame.draw.circle(spotify_surface, WHITE, (width//2, height//2), 30)

offset = 80
next_track_rect_1 = pygame.draw.polygon(spotify_surface, WHITE, ((147+offset,135),(147+offset,105),(177+offset,120)))
offset = 105
next_track_rect_2 = pygame.draw.polygon(spotify_surface, WHITE, ((147+offset,135),(147+offset,105),(177+offset,120)))

offset = 80
prev_track_rect_1 = pygame.draw.polygon(spotify_surface, WHITE, ((147-offset,135),(147-offset,105),(177-offset-60,120)))
offset = 55
prev_track_rect_2 = pygame.draw.polygon(spotify_surface, WHITE, ((147-offset,135),(147-offset,105),(177-offset-60,120)))

def draw_music_player():
    screen.fill(BLACK)
    if not playing:
        pygame.draw.circle(spotify_surface, WHITE, (width//2, height//2), 30)
        pygame.draw.polygon(spotify_surface, BLACK, ((147,135),(147,105),(177,120)))
    elif playing:
        pygame.draw.circle(spotify_surface, WHITE, (width//2, height//2), 30)
        pygame.draw.rect(spotify_surface, BLACK, pause_rect_1)
        pygame.draw.rect(spotify_surface, BLACK, pause_rect_2)

    screen.blit(spotify_surface, (0,0))
    pygame.display.flip()

def draw_home():
    global spotify_rect
    screen.fill(BLACK)
    home_surface.blit(spotify_icon, spotify_rect)
    home_surface.blit(scribble_icon, scribble_rect)
    home_surface.blit(weather_icon, weather_rect)
    screen.blit(home_surface,(0,0))
    pygame.display.flip()




# scribble helper 
def color_pallete():
    # init pallette surface, fill it and draw circles on it, return the surface and the circle rects
    pallete_surface = pygame.Surface((40, 240))
    pallete_surface.fill(GREY)
    red_circle = pygame.draw.circle(pallete_surface, RED, (20, 20), 10)
    orange_circle = pygame.draw.circle(pallete_surface, ORANGE, (20, 60), 10)
    green_circle = pygame.draw.circle(pallete_surface, GREEN, (20, 100), 10)
    blue_circle = pygame.draw.circle(pallete_surface, BLUE, (20, 140), 10)
    purple_circle = pygame.draw.circle(pallete_surface, PURPLE, (20, 180), 10)
    white_circle = pygame.draw.circle(pallete_surface, WHITE, (20, 220), 10)
    return pallete_surface, red_circle, orange_circle, green_circle, blue_circle, purple_circle, white_circle

print("setup pallete surface")
#--------- Setting up the surface and prepare to enter drawing mode -----------------  
pallete_surface, red_circle, orange_circle, green_circle, blue_circle, purple_circle, white_circle = color_pallete()
print("finished setup pallete surface")

# init the draw surface
draw_surface = pygame.Surface((280, 240))
draw_surface.fill(BLACK)

scribble_surface = pygame.Surface((320,240))

# blit and flip both
scribble_surface.blit(pallete_surface, (0, 0))
scribble_surface.blit(draw_surface, (40, 0))
scribble_surface.blit(home_icon, (0,0))
scribble_surface.blit(clear_icon, (40,80))
print("finished setup pygame")

save_scribble = []
for i in range(64):
    save_scribble.append([])
    for j in range(32):
        save_scribble[i].append(BLACK)

def GPIO19_callback(channel):
    print("quit")
    global code_run
    code_run = False

GPIO.setmode(GPIO.BCM)
GPIO.setup(19, GPIO.IN, GPIO.PUD_DOWN)
GPIO.add_event_detect(19, GPIO.FALLING, callback = GPIO19_callback, bouncetime=300)

        
def map_led_matrix(canvas, led_matrix):
    # canvas.Clear()
    for i in range(64):
        for j in range(32):
            r,g,b = led_matrix[i][j]
            canvas.SetPixel(i,j,r,g,b)

################# weather page #####################
f = open('weather.json')
weather_dict = json.load(f)
weather_dict_all = weather_dict
weather_dict = weather_dict["current"]
temp = weather_dict["temp"]
hum = 'Hum:' + str(weather_dict["humidity"]) + '%'
current_weather =  weather_dict["weather"][0]["main"]
sunrise_utc = int(weather_dict["sunrise"]) + int(weather_dict_all["timezone_offset"])
sunset_utc = int(weather_dict["sunset"]) + int(weather_dict_all["timezone_offset"])
sun_condition = ''
print(sunrise_utc)
f.close()

time_now = datetime.now()
hour = int(time_now.strftime("%H"))
if hour < 12:
    sun_condition = datetime.utcfromtimestamp(sunrise_utc).strftime('%H:%M')
    sun_condition = 'Sunrise:' + sun_condition
    weather_gif = ["sun.gif", "snow.gif", "rain.gif", "cloudy_day.gif"]
else:
    sun_condition = datetime.utcfromtimestamp(sunset_utc).strftime('%H:%M')
    sun_condition = 'Sunset:' + sun_condition
    weather_gif = ["moon.gif", "snow.gif", "rain.gif", "cloudy_night.gif"]

weathers = [["Clear"],["Snow"], ["Rain", "Thunderstorm", "Drizzle"],["Clouds"]]

gif = []
category_count = 0
found = False
while not found:
    for category in weathers:
        for weather in category:
            if current_weather == weather:
                img = weather_gif[category_count]
                found = True
                break
        category_count += 1
        
with Image.open("img/" + img) as im:
    for frame in ImageSequence.Iterator(im):
        frame_processed = frame.resize((64,32),Image.ANTIALIAS).convert("RGB")
        gif.append(frame_processed)           

def update_album_cover(sp):
    my_spotify.download_curr_album_cover(sp)
    im = Image.open("album_cover.jpg")
    album_cover = im.resize((26,26),Image.ANTIALIAS).convert("RGB")
    return album_cover
    
################### LED ###########################
class Dashboard(SampleBase):
    def __init__(self, *args, **kwargs):
        super(Dashboard, self).__init__(*args, **kwargs)

    def run(self):
        print("running dashboard")
        canvas = self.matrix

        font = graphics.Font()
        
        time_now = datetime.now()
        curr_date = time_now.strftime("%m/%d/%Y")
        curr_time = time_now.strftime("%H:%M")
        
        font.LoadFont("../rpi-rgb-led-matrix/fonts/4x6.bdf")

        # graphics.DrawText(canvas, font, 22, 10, led_white, curr_date)
        # graphics.DrawText(canvas, font, 30, 20, led_white, curr_time)
        # graphics.DrawText(canvas, font, 22, 28, led_white, greeting)
        
        # hour = int(time_now.strftime("%H"))
        # greeting = ""
        # if (hour >= 5 and hour < 12):
        #     greeting = "Good morning"
        # elif (hour >= 12 and hour < 18):
        #     greeting = "Good afternoon"
        # elif (hour >= 18 and hour < 22):
        #     greeting = "Good evening"
        # else:
        #     greeting = "Good night"
        
        # my_spotify.download_curr_album_cover(sp)
        # im = Image.open("album_cover.jpg")
        # album_cover = im.resize((26,26),Image.ANTIALIAS).convert("RGB")
        

        
        start_time = time.time()

        global is_home
        global is_music_player
        global is_scribble
        global is_weather
        global drawing
        global sp
        global code_run
        global playing
        global brush_color
        
        album_cover = update_album_cover(sp)
        track_name, artist = my_spotify.get_curr_track_info(sp)
        print("running while loop")

        while(code_run):
                # print(str(code_run))
            try:
                for event in pygame.event.get():
                    if (event.type == pygame.KEYUP and event.key == pygame.K_c and event.mod & pygame.KMOD_CTRL):
                        print("quit event")
                        img = Image.new('RGB', (64,32))
                        for i in range(64):
                            for j in range(32):
                                img.putpixel((i,j),save_scribble[i][j])
                        img.save("output.png")
                        pygame.quit()
                        sys.exit()
                    
                    if event.type == pygame.MOUSEBUTTONUP:
                        mouse_pos = pygame.mouse.get_pos()

                        if is_home:
                            if spotify_rect.collidepoint(mouse_pos):
                                is_music_player = True
                                is_home = False
                                is_scribble = False
                                
                                album_cover = update_album_cover(sp)
                                track_name, artist = my_spotify.get_curr_track_info(sp)

                            elif scribble_rect.collidepoint(mouse_pos):
                                is_music_player = False
                                is_home = False
                                is_scribble = True
                            
                            elif weather_rect.collidepoint(mouse_pos):
                                is_home = False
                                is_weather = True
                                print("detected is weather")

                        elif is_music_player:
                            if (play_button.collidepoint(mouse_pos)):
                                if not playing:
                                    sp.start_playback()
                                    playing = True
                                else:
                                    sp.pause_playback()
                                    playing = False

                            elif(home_rect.collidepoint(mouse_pos)):
                                is_music_player = False
                                is_home = True

                            elif (next_track_rect_1.collidepoint(mouse_pos) or next_track_rect_2.collidepoint(mouse_pos)):
                                sp.next_track()
                                playing = True
                                # my_spotify.download_curr_album_cover(sp)
                                album_cover = update_album_cover(sp)
                                track_name, artist = my_spotify.get_curr_track_info(sp)


                            elif (prev_track_rect_1.collidepoint(mouse_pos) or prev_track_rect_2.collidepoint(mouse_pos)):
                                sp.next_track()
                                playing = True
                                # my_spotify.download_curr_album_cover(sp)
                                album_cover = update_album_cover(sp)
                                track_name, artist = my_spotify.get_curr_track_info(sp)

                        elif is_scribble:
                            if home_rect.collidepoint(mouse_pos):
                                is_home = True
                                is_scribble = False
                            elif clear_rect.collidepoint(mouse_pos):
                                canvas.Clear()
                                for i in range(64):
                                    for j in range(32):
                                        save_scribble[i][j] = BLACK
                                draw_surface.fill(BLACK)
                                screen.blit(draw_surface, (0,0))
                                screen.blit(pallete_surface,(0,0))
                                screen.blit(home_icon, (40,0))
                                screen.blit(clear_icon, (40,80))
                                pygame.display.flip()
                            if (red_circle.collidepoint(mouse_pos)):
                                brush_color = RED
                            elif (green_circle.collidepoint(mouse_pos)):
                                brush_color = GREEN
                            elif (blue_circle.collidepoint(mouse_pos)):
                                brush_color = BLUE
                            elif (white_circle.collidepoint(mouse_pos)):
                                brush_color = WHITE
                            elif(orange_circle.collidepoint(mouse_pos)):
                                brush_color = ORANGE
                            elif(purple_circle.collidepoint(mouse_pos)):
                                brush_color = PURPLE
                            else: 
                                drawing = False
                        
                        elif is_weather:
                            if home_rect.collidepoint(mouse_pos):
                                is_home = True
                                is_weather = False

                    elif event.type == pygame.MOUSEBUTTONDOWN and is_scribble:
                        drawing = True

################################ TFT Screen ########################################
                if is_music_player:
                    draw_music_player()
                elif is_home:
                    draw_home()
                elif is_scribble:
                    screen.fill(BLACK)
                    if drawing:
                        mouse_pos = pygame.mouse.get_pos()
                        save_scribble[int(mouse_pos[0]/5)][int(mouse_pos[1]/7.5)] = brush_color
                        draw_surface.set_at(mouse_pos, brush_color)
                    screen.blit(draw_surface, (0, 0))
                    screen.blit(pallete_surface, (0, 0))
                    screen.blit(home_icon, (40,0))
                    screen.blit(clear_icon, (40,80))
                    pygame.display.flip()

                elif is_weather:
                    screen.fill(BLACK)
                    screen.blit(home_icon, (40,0))
                    pygame.display.flip()

##################################################################################
                if(is_home):
                    time_now = datetime.now()
                    curr_date = time_now.strftime("%m/%d/%Y")
                    curr_time = time_now.strftime("%H:%M")

                    hour = int(time_now.strftime("%H"))
                    greeting = ""
                    if (hour >= 5 and hour < 12):
                        greeting = "Good morning"
                    elif (hour >= 12 and hour < 18):
                        greeting = "Good afternoon"
                    elif (hour >= 18 and hour < 22):
                        greeting = "Good evening"
                    else:
                        greeting = "Good night"

                    bear = Image.open("img/bear.png")
                    bear = bear.resize((32,32),Image.ANTIALIAS).convert("RGB")
                    
                    canvas.Clear()
                    canvas.SetImage(bear, 32, 0)
                    graphics.DrawText(canvas, font, 2, 10, led_white, curr_date)
                    graphics.DrawText(canvas, font, 2, 20, led_white, curr_time)
                    graphics.DrawText(canvas, font, 2, 30, led_white, greeting)

                elif is_music_player:
                    canvas.Clear()
                    canvas.SetImage(album_cover, 3,3)
                    graphics.DrawText(canvas, font, 30, 10, led_white, track_name)    
                    graphics.DrawText(canvas, font, 30, 20, led_white, artist)     

                elif is_scribble:
                    canvas.Clear()
                    map_led_matrix(canvas, save_scribble)

                elif is_weather:
                    canvas.Clear()
                                    
                    for frame in gif[0:10]:
                        if not is_weather:
                            break
                        # canvas.SetImage(image, 0,15)
                        canvas.SetImage(frame, 0,0)
                        graphics.DrawText(canvas, font, 2, 18, led_white, current_weather)
                        graphics.DrawText(canvas, font, 2, 25, led_white, hum)
                        graphics.DrawText(canvas, font, 2, 31, led_white, sun_condition)
            
                        time.sleep(0.1)
                                    


                time.sleep(0.05)
                
            except KeyboardInterrupt:
                print("keyboard interrupt")
                code_run = False
                break

        print("exit while loop")
        canvas.Clear()
        GPIO.cleanup()
        pygame.display.quit()
        return
        # pygame.quit()
        # sys.exit()
        # quit() 

if __name__ == "__main__":
    print("enter main")
    graphics_test = Dashboard()
    if (not graphics_test.process()):
        graphics_test.print_help()