# display animated Swiss style clockwork
# https://gitlab.com/erlenmayr/card10
# contact: verbuecheln@posteo.de
# License: GPLv2

import color
import display
import math
import utime
import htmlcolor
import os

GREEN = (0, 80, 0)
RED = (80, 0, 0)
BLACK = color.BLACK
GEAR = (60, 60, 60)
GEAR1 = (70, 60, 60)
GEAR2 = (60, 70, 60)
GEAR3 = (60, 60, 70)
GEAR4 = (65, 65, 60)
WHEEL = (140, 100, 10)
HOUR = htmlcolor.GOLD
MINUTE = htmlcolor.GOLD
SECOND = htmlcolor.ORANGERED

def draw_spring(disp, charge):
    disp.rect(10, 5, 99, 14, col=RED)
    disp.rect(100, 5, 159, 14, col=GREEN)
    disp.rect(0, 0, 10, 20, col=BLACK)
    disp.rect(1, 1, 9, 19, col=GEAR)    
    p = round(90 - 60 * charge)
    disp.rect(10 + p, 0, 80 + p, 20, col=BLACK)
    disp.rect(11 + p, 1, 79 + p, 19, col=GEAR)

    for i in range(6):
        f = 10 + round((2 * i + 1) * (p / 12.0))
        g = 10 + round((2 * i + 2) * (p / 12.0))
        disp.line(f, 2, g, 18, col=BLACK, size=3)
        disp.line(f, 2, g, 18, col=GEAR, size=1)



def draw_gear(disp, x, y, radius, ang, col):
    xd = round(radius * math.sin(ang))
    yd = round(radius * math.cos(ang))
    disp.circ(x, y, radius, col=BLACK, filled=False, size=7)
    disp.line(x + xd, y + yd, x - xd, y - yd, col=BLACK, size=8)
    disp.circ(x, y, radius, col=col, filled=False, size=6)
    disp.line(x + xd, y + yd, x - xd, y - yd, col=col, size=6)



def draw_gears(disp, t):
    ms = utime.time_ms() % 1000
    # flywheel
    draw_gear(disp, 90, 39, 48, 1.570796 - 1.047198  * math.sin(0.006283185 * ms), WHEEL)
    # minute gears
    draw_gear(disp, 80, 40, 35, t[4] * -0.1047198, GEAR1)
    draw_gear(disp, 134, 50, 15, t[4] * 0.3665192, GEAR2)
    # second gears
    draw_gear(disp, 80, 40, 15, t[5] * -0.1047198, GEAR3)
    draw_gear(disp, 35, 46, 25, t[5] * 0.05235988, GEAR4)



def draw_hand(disp, x, y, len, ang, col, thick):
    xs = x - round(len * math.sin(ang))
    ys = y - round(len * math.cos(ang))
    disp.line(x, y, xs, ys, col=BLACK, size=thick+2)
    disp.line(x, y, xs, ys, col=col, size=thick)



def draw_hands(disp, t):
    # hour hand
    draw_hand(disp, 80, 40, 20, (t[3] + t[4] / 60.0) * -0.5235988, HOUR, 2)
    # minute hand
    draw_hand(disp, 80, 40, 30, t[4] * -0.1047198, MINUTE, 2)
    # second hand
    draw_hand(disp, 80, 40, 35, t[5] * -0.1047198, SECOND, 1)
    disp.circ(80, 40, 4, col=BLACK, filled=True, size=1)
    disp.circ(80, 40, 3, col=SECOND, filled=True, size=1)



def animate():
    with display.open() as disp:
        while True:
            disp.clear()        

            # calculate battery charge and draw spring
            volt = os.read_battery()
            charge = (volt - 3.4) / 0.8
            draw_spring(disp, charge)
            
            # draw gears and hands
            t = utime.localtime()
            draw_gears(disp, t)
            draw_hands(disp, t)

            disp.update()



animate()