"""

Uhr

TODO: Zeitzone anzeigen. Abhängig von Lat, Lon

 Es sollen verschiedene Modi unterstützt werden
 - Analoguhr
 - Digitaluhr
 - Regattauhr / -timer

"""

import os
import cairo
import math
from .page import Page
from datetime import datetime, timezone, timedelta
import astral

class Clock(Page):

    def __init__(self, pageno, cfg, appdata, boatdata):
        super().__init__(pageno, cfg, appdata, boatdata)
        self.buttonlabel[1] = 'MODE'
        self.buttonlabel[2] = 'TZ'
        self.mode = ('A', 'D', 'T') # (A)nalog (D)igital (T)imer
        self.modeindex = 1
        self.utc = True
        self.tzoffset = cfg['tzoffset']
        self.bv_lat = boatdata.getRef("LAT")
        self.bv_lon = boatdata.getRef("LON")
        # Eine beliebiger Ort damit irgendetwas gesetzt ist
        self.set_location('Norderstedt', 'Germany', 53.710105, 10.0574378)
        self.bgimg = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "unknown.png"))

    def handle_key(self, buttonid):
        if buttonid == 1:
            if self.modeindex < len(self.mode) - 1:
                self.modeindex += 1
            else:
                self.modeindex = 0
            return True
        if buttonid == 2:
            self.utc = not self.utc
            return True
        return False

    def set_location(self, city, country, lat, lon):
        try:
            # Astral ab Debian 13
            self.location = astral.LocationInfo((city, country, lat, lon, 'UTC'))
        except AttributeError:
            # Astral bis Debian 12 (Version 1.6.1)
            self.location = astral.Location((city, country, lat, lon, 'UTC'))
            self.location.astral = astral.Astral()

    def display_new(self):
        """
        Position für Sonnenauf- und Untergang neu ermitteln
        Machen wir hier einmal je Seitenaufruf, besser wäre es
        in regelmäßigen Zeitabständen. Das kann dann später implementiert
        werden.
        """
        if self.bv_lat.valid and self.bv_lon.valid:
            self.set_location('Ship', 'World', self.bv_lat.getValue, self.bv_lon.getValue, 'UTC')

    def draw(self, ctx):
        ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)

        # akuellen Modus anzeigen
        if self.mode[self.modeindex] == 'A':
            self.draw_analog(ctx)
        elif self.mode[self.modeindex] == 'D':
            self.draw_digital(ctx)
        else:
            self.draw_timer(ctx)

    def draw_digital(self, ctx):

        # TODO
        # Sonnenauf- und Untergang
        # Zeitzone

        ts = datetime.now()

        ctx.set_font_size(20)
        ctx.move_to(10, 60)
        ctx.show_text("RTC")

        ctx.select_font_face("DSEG7 Classic")
        ctx.set_font_size(72)
        # Zentrieren funktioniert nicht richtig, da der Leerraum vor der "1"
        # mitgerechnet wird. Dafür muß ggf. der Zeichensatz angepaßt werden.
        # self.draw_text_center(ctx, 200, 150, ts.strftime("%H:%M:%S"))
        ctx.move_to(0, 200)
        ctx.show_text(ts.strftime("%-H:%M:%S"))

    def draw_timer(self, ctx):
        ts = datetime.now()
        ctx.set_font_size(24)
        ctx.move_to(10, 50)
        ctx.show_text("Race Timer")
        ctx.select_font_face("AtariST8x16SystemFont")
        ctx.set_font_size(16)
        self.draw_text_center(ctx, 200, 230, "Here be dragons")
        ctx.save()
        ctx.set_source_surface(self.bgimg, 140, 80)
        ctx.paint()
        ctx.restore()

    def draw_analog(self, ctx):

        ts = datetime.now()
        if self.utc:
            pass
        # Location ist in UTC definiert
        sunrise = self.location.sunrise(ts)
        sunset = self.location.sunset(ts)
        if not self.utc:
            td = timedelta(hours=self.tzoffset)
            sunrise += td
            sunset += td

        # Wochentag
        # ts.strftime('%a')

        # Werte in den Ecken der Uhr 
        ctx.set_font_size(24)
        ctx.move_to(10, 220)
        ctx.show_text("Time")
        ctx.move_to(10, 95)
        ctx.show_text("Date")
        ctx.move_to(335, 95)
        ctx.show_text("SunR")
        ctx.move_to(335, 220)
        ctx.show_text("SunS")
        ctx.stroke()

        ctx.set_font_size(16)

        # Datum links oben
        ctx.move_to(10, 65)
        ctx.show_text(ts.strftime("%d.%m.%Y"))
        # Uhrzeit links unten
        ctx.move_to(10, 250)
        ctx.show_text(ts.strftime("%H:%M"))
        # Sonnenaufgang rechts oben
        ctx.move_to(335, 65)
        ctx.show_text(sunrise.strftime("%H:%M"))
        # Sonnenuntergang rechts unten
        ctx.move_to(335, 250)
        ctx.show_text(sunset.strftime("%H:%M"))
        ctx.stroke()

        # Horizontale Trennlinien
        ctx.rectangle(0, 149, 60, 3)
        ctx.rectangle(340, 149, 60, 3)
        ctx.fill()

        # Uhr
        cx = 200
        cy = 150
        r = 110
        ctx.arc(cx, cy, r + 10, 0, 2*math.pi)
        ctx.arc(cx, cy, r + 7, 0, 2*math.pi)
        ctx.stroke()

        ctx.set_font_size(20)
        self.draw_text_center(ctx, cx, cy-40, 'UTC' if self.utc else 'LOT')

        ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
        ctx.set_font_size(24)

        for i in range(360):
            x = cx + (r - 30) * math.sin(i/180*math.pi)
            y = cy - (r - 30) * math.cos(i/180*math.pi)

            char = ""
            if i == 0:
                char = "12"
            elif i == 90:
                char = "3"
            elif i == 180:
                char = "6"
            elif i == 270:
                char = "9"

            if i % 90 == 0:
                #ctx.move_to(x, y)
                self.draw_text_center(ctx, x, y, char)
                #ctx.stroke()

            ctx.set_line_width(3.0)
            if i % 6 == 0:
                if i % 30 == 0:
                    x0 = cx + (r - 10) * math.sin(i/180*math.pi)
                    y0 = cy - (r - 10) * math.cos(i/180*math.pi)
                    x1 = cx + (r + 10) * math.sin(i/180*math.pi)
                    y1 = cy - (r + 10) * math.cos(i/180*math.pi)
                    ctx.move_to(x0, y0)
                    ctx.line_to(x1, y1)
                    ctx.stroke()
                else:
                    x = cx + r * math.sin(i/180*math.pi)
                    y = cy - r * math.cos(i/180*math.pi)
                    ctx.arc(x, y, 2, 0, 2*math.pi)         
                    ctx.fill()
        
        # Stundenzeiger
        p = ((cx - 2, cy - (r - 50)), (cx + 2, cy - (r - 50)), (cx + 6, cy + 16), (cx - 6, cy + 16))
        angle_h = (ts.hour % 12  + ts.minute / 60) * 30
        zeiger = self.rotate((cx, cy), p, angle_h)
        ctx.move_to(*zeiger[0])
        for point in zeiger[1:]:
            ctx.line_to(*point)
        ctx.fill()

        # Minutenzeiger
        p = ((cx - 1, cy - (r - 15)), (cx + 1, cy - (r - 15)), (cx + 6, cy + 20), (cx - 6, cy + 20))
        angle_m = ts.minute * 6
        zeiger = self.rotate((cx, cy), p, angle_m)
        ctx.move_to(*zeiger[0])
        for point in zeiger[1:]:
            ctx.line_to(*point)
        ctx.fill()

        # Zentraler Kreis
        ctx.set_source_rgb(0, 0, 0)
        ctx.arc(cx, cy, 12, 0, 2*math.pi)
        ctx.fill()

        # Wozu dieses?
        ctx.set_source_rgb(0.86, 0.86, 0.86)
        ctx.arc(cx, cy, 10, 0, 2*math.pi)
        ctx.fill()

        ctx.set_source_rgb(0, 0, 0)
        ctx.arc(cx, cy, 2, 0, 2*math.pi)
        ctx.fill()
