import numpy as np

import matplotlib.pyplot as plt
from matplotlib import collections as mc
from matplotlib import animation

from datetime import datetime


def init(fcas, fcam, fcah):
    global cas, cam, cah
    cas, cam, cah = fcas, fcam, fcah


def dessine_cadran(axis):
    tt = np.linspace(0, 2*np.pi, 60)
    axis.plot(np.cos(tt), np.sin(tt), color='black', lw=3)

    lc = mc.LineCollection([[(np.cos(t), np.sin(t)), (0.94*np.cos(t), 0.94*np.sin(t))]
                            for t in np.arange(0, 2*np.pi, 2*np.pi / 60)], color='black', lw=1)
    axis.add_collection(lc)

    lc = mc.LineCollection([[(np.cos(t), np.sin(t)), (0.9*np.cos(t), 0.9*np.sin(t))]
                            for t in np.arange(0, 2*np.pi, 2*np.pi / 12)], color='black', lw=2)
    axis.add_collection(lc)
    
    aih, = axis.plot([], [], color='black', lw=6, solid_capstyle='round')
    aim, = axis.plot([], [], color='black', lw=6, solid_capstyle='round')
    ais, = axis.plot([], [], color='red', lw=4, solid_capstyle='round')
    
    return aih, aim, ais


def cah(h, m, s):
    th = 2 * np.pi * (0.25 - (h + ((m + s / 60) / 60)) / 12)
    return (np.cos(th), np.sin(th))


def cam(h, m, s):
    tm = 2 * np.pi * (0.25 - (m + s / 60) / 60)
    return (np.cos(tm), np.sin(tm))


def cas(h, m, s):
    ts = 2 * np.pi * (0.25 - s / 60)
    return (np.cos(ts), np.sin(ts))


def dessine_aiguille_heures(lines, h, m, s):
    x, y = cah(h, m, s)
    lines.set_data([-0.15 * x, 0.5 * x], [-0.15 * y, 0.5 * y])


def dessine_aiguille_minutes(lines, h, m, s):
    x, y = cam(h, m, s)
    lines.set_data([-0.15 * x, 0.75 * x], [-0.15 * y, 0.75 * y])


def dessine_aiguille_secondes(lines, h, m, s):
    x, y = cas(h, m, s)
    lines.set_data([-0.15 * x, 0.8 * x], [-0.15 * y, 0.8 * y])


def hms(heure=None):
    if heure is None:
        n = datetime.now()
        h, m, s = n.hour, n.minute, n.second
    else:
        h, m, s = map(int, heure.split(':'))

    return h % 12, m, s


def horloge(heure=None, anime=False):
    fig = plt.figure(figsize=(4, 4))
    ax = fig.gca(frameon=False)

    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    aih, aim, ais = dessine_cadran(ax)

    def animate(i):
        h, m, s = hms(heure)

        dessine_aiguille_heures(aih, h, m, s)
        dessine_aiguille_minutes(aim, h, m, s)
        dessine_aiguille_secondes(ais, h, m, s)

        return ais,

    if anime:
        anim = animation.FuncAnimation(fig, animate, init_func=lambda: (ais,),
                                       frames=10, interval=1000, blit=True)
        return anim
    else:
        animate(0)


def horloge_animee():
    return horloge(anime=True)
