#! /usr/bin/env python3

import argparse
import freetype
import io
from PIL import Image, ImageDraw, ImageFont
import csv
import datetime as dt
from dateutil import relativedelta
from cairosvg import svg2png

CURRENT_TIME = dt.date.today()
NEXT_MONTH = CURRENT_TIME + relativedelta.relativedelta(months=1, day=1)
DAYS_OF_WEEK_SR = ("PON", "UTO", "SRE", "ČET", "PET", "SUB", "NED")
MONTHS_SR = ("Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust",\
        "Septembar", "Oktobar", "Novembar", "Decembar")

def parseArgs(parser):
    """
        Parse all arguments and return the list of argument values
    """
    parser.add_argument("month", metavar = "MM", help = "two digit number representing the month for which to generate poster", default = "empty", nargs = "?")
    return parser.parse_args()

def load_events(csv_path:str, month:int) -> list[dict]:
    monthafter = month + relativedelta.relativedelta(months=1, day=1)
    events = []
    with open(csv_path) as csv_file:
        csv_reader = csv.reader(csv_file)
        next(csv_reader, None)
        for event in csv_reader:
            event_date = event[0]
            event_date_parsed = dt.datetime.strptime(event_date, "%d-%m-%Y").date()
            event_time = event[1]
            event_title = event[3]
            current_event = {"date":event_date_parsed,
                             "time":event_time,
                             "title":event_title.strip()}
            if event_date_parsed >= month and event_date_parsed < monthafter:
                events.append(current_event)
        return events

def drawPoster(events, bg, fg, month:int):
    fontFacade = ImageFont.truetype('./site/font/Facade-Sud.woff', size=365)
    fontIosevka = ImageFont.truetype('./site/font/iosevka-regular.woff', size=200)
    fontIosevkaSmall = ImageFont.truetype('./site/font/iosevka-regular.woff', size=150)

    W = 3508
    H = 4960 
    img = Image.new('RGB', (W, H), bg)
    draw = ImageDraw.Draw(img)

    header = "DECENTRALA"
    _, _, w, _ = draw.textbbox((0, 0), header, font=fontFacade)
    draw.text(((W-w)/2, 165), header, font=fontFacade, fill=fg)

    subheader = f"Plan za {MONTHS_SR[month.month - 1]}"
    _, _, w, _ = draw.textbbox((0, 0), subheader, font=fontIosevka)
    draw.text(((W-w)/2, 560), subheader, font=fontIosevka, fill=fg)

    height = 990

    draw.text((165, height), "Pondeljkom i utorkom u 19h u DC Krovu", font=fontIosevkaSmall, fill=fg)
    height += 200

    draw.text((165, height), "Sredom u 18h na MATF-u", font=fontIosevkaSmall, fill=fg)
    height += 200

    draw.text((165, height), "Svi dogadjaji su uvek besplatni", font=fontIosevkaSmall, fill=fg)
    height += 300

    # Write list of events to sperate text file as well
    textfile=open("poster.txt","w")

    textfile.write(f"Plan za {MONTHS_SR[month.month - 1]}\n\n")
    textfile.write("Radionice pocinju u 19h u DC Krovu\n")
    textfile.write("Svi dogadjaji su uvek besplatni\n\n")

    # Loop to write events both to poster image and text file
    for event in events:

        # Add event to image poster
        date = DAYS_OF_WEEK_SR[event["date"].weekday()]
        day = event["date"].day
        title = event["title"]
        pad = " " if event["date"].day < 10 else ""
        eventText = f"{date} {day}. {pad}{title}"
        draw.text((165, height), eventText, font=fontIosevkaSmall, fill=fg)
        height += 200

        # Add event to textfile
        textfile.write(eventText + "\n")

    textfile.close()

    def drawCircle(x, y):
        r = 50
        draw.ellipse((x - r, y - r, x + r, y+r), fill=fg, outline=(0, 0, 0), width=0)

    LCX = 415 # logo center x
    LCY = 4350 # logo center y
    d = 190 # delta
    drawCircle(LCX - d, LCY)
    drawCircle(LCX, LCY)
    drawCircle(LCX, LCY - d)
    drawCircle(LCX, LCY + d)
    drawCircle(LCX + d, LCY)

    draw.line([(LCX - d, LCY), (LCX + d, LCY)], fill=fg, width=20, joint=None)
    draw.line([(LCX, LCY), (LCX, LCY + d), (LCX + d, LCY), (LCX, LCY - d)], fill=fg, width=20, joint=None)
    draw.text((LCX - 1.7*d, LCY + 1.5*d), "dmz.rs", font=fontIosevka, fill=fg)

    mesh_svg = svg2png(url='site/img/mesh-light.svg')
    mesh_svg_bytes = io.BytesIO(mesh_svg)
    mesh_img = Image.open(mesh_svg_bytes)
    if bg == (0,0,0):
        pixdata = mesh_img.load()
        for y in range(mesh_img.size[1]):
            for x in range(mesh_img.size[0]):
                if pixdata[x,y] != (0,0,0,0):
                    pixdata[x, y] = (0, 100, 0, 255)

    mesh_img = mesh_img.resize((W,H))
    mesh_img.thumbnail((W,H), Image.Resampling.LANCZOS)

    mesh_w, mesh_h = mesh_img.size
    mesh_position = (W - mesh_w, H - mesh_h)
    img.paste(mesh_img, mesh_position, mesh_img)

    return img

def main():
    # Parse arguments
    parser = argparse.ArgumentParser(description="Generate images of the poster")
    args = parseArgs(parser)

    # Set month based on user input
    month = NEXT_MONTH
    if args.month.isdigit():
      month = dt.date(CURRENT_TIME.year, int(args.month), 1)
    elif args.month != "empty":
      print("Month has to be specified as a number. I will use next month as the default")

    # Load events and draw a poseter
    events = load_events("dogadjaji.csv", month)

    img = drawPoster(events, (0, 0, 0), (20, 250, 50), month)
    img.save('poster_dark.png')

    img = drawPoster(events, (255, 255, 255), (0, 0, 0), month)
    img.save('poster_light.png')

if __name__ == "__main__":
    main()