#!/usr/bin/env python3

import os
import re

from openpyxl import load_workbook, Workbook
from openpyxl.worksheet.worksheet import Worksheet


def escape_latex(content):
    content = content.replace("⁄", "/")
    # content = content.replace("℔", r"\ lb")
    content = content.replace("½", "$\\frac{1}{2}$")
    content = content.replace("¼", "$\\frac{1}{4}$")
    content = content.replace("¾", "$\\frac{3}{4}$")
    content = content.replace("\n", "\n\n")
    content = content.replace("°", r"$^\circ$")
    content = content.replace("&", r"\&")
    content = content.replace("ö", "ö")

    content = re.sub(r'(\d) (\d+)/(\d+)', r'$\1\\frac{\2}{\3}$', content)
    content = re.sub(r'(\d+)/(\d+)', r'$\\frac{\1}{\2}$', content)
    content = re.sub(r'([\d$]g?) ?- ?([\d$])', '\\1--\\2', content)
    content = content.replace("$ ", r"$\,")

    return content


# Define output file
f_latex = open("rezepte.tex", "w+")
f_latex.write("%!TEX ROOT = ./main.tex\n\n")

# Load cookbook
cb: Workbook = load_workbook('kekse.xlsx', data_only=True)
sheets = cb.sheetnames

# Find worksheet with recipes
ws: Worksheet = cb["Rezepte"]

# Variables to store information while parsing

# Legend gives the column with descriptions and starting row for the recipes
legend_row = 0
legend_col = 0

# Ingredients
# Find the corresponding rows to all properties of recipes 
ingredients_row_start = 0

in_ingredients = False
in_recipe = False

ingredients = {}
ingredients_unit = {}
ingredients_comment = {}

ingredients_other_row = 0

# Other fields
type_row = 0
instructions_row = 0
baking_time_row = 0
baking_temperature_row = 0
number_row = 0
resting_time_row = 0
specials_row = 0

# Years
first_year_row = 0
last_year_row = 0
first_year = 0

#####

# Go through worksheet and parse all information
for column in ws.columns:
    for cell in column:

        # Find row of type of recipe
        if cell.value == "Art":
            type_row = cell.row
            legend_row = cell.row
            legend_col = cell.column

        if cell.column == legend_col:
            # Find row of recipe name, this is in the row with 'Zutaten'
            if cell.value == "Zutaten":
                name_row = cell.row
                ingredients_row_start = cell.row + 1
                in_ingredients = True

            # Find position of ingredients
            if cell.value == "Hauptaromen":
                aroma_row = cell.row

            # Find position of source
            if cell.value == "Quelle":
                source_row = cell.row

            # Instructions
            if cell.value == "Anleitung":
                instructions_row = cell.row

            # Check if we are at end of ingredients
            if cell.value == "Sonstiges (Deko)":
                ingredients_other_row = cell.row
                in_ingredients = False

            # Make list of all ingredients and their units
            if cell.row >= ingredients_row_start and in_ingredients:
                string = cell.value

                if "(" in string and ")" in string:
                    m = re.match(r'^([^(\n]*)(?: \((\S+ [^)]+)\))?(?: \(([^)]+)\))?$', cell.value)
                    assert m
                    ingredients[cell.row] = m.group(1)
                    ingredients_unit[cell.row] = m.group(3)
                    ingredients_comment[cell.row] = m.group(2)
                else:
                    ingredients[cell.row] = string
                    ingredients_unit[cell.row] = ""
                    ingredients_comment[cell.row] = ""

            # Further instructions
            if cell.value == "Backzeit (Minuten)":
                baking_time_row = cell.row
            if cell.value == "Backtemperatur Umluft (Grad)":
                baking_temperature_row = cell.row
            if cell.value == "Ruhezeit (Minuten)":
                resting_time_row = cell.row
            if cell.value == "Anzahl (ca.)":
                number_row = cell.row
            if cell.value == "Besonderheiten":
                specials_row = cell.row

            # Years
            if cell.value == 2013:
                first_year_row = cell.row
                last_year_row = cell.row
                first_year = 2013

            if first_year_row > 0 and cell.value == "Kommentare zur Bearbeitung.":
                # cell.row -2 instead of -1 to ignore current year 2021
                last_year_row = cell.row - 2

        # By now, we should have found everything in the legend

    #####

    # Parse recipe
    # Go through worksheet vertically, starting with the first column
    # If right of legend, then it must be a recipe
    if cell.column > legend_col:

        # Obtain information of recipe in the right order, so that we can directly write it to the tex-file.

        # Name of recipe
        content = ws.cell(name_row, cell.column).value
        if content != "None\n" and content is not None:
            f_latex.write("\\newpage\n")

            # if (content[-5:]=="(Oma)"):
            #    content="Omas " + content[:-6]
            f_latex.write("\\section{%s}\\vspace{0.5cm minus 0.5cm}\n" % content)

            f_latex.write("\\begin{tabular}{lll}\n")

            # Aroma
            content = ws.cell(aroma_row, cell.column).value
            if content != "None\n" and content is not None:
                f_latex.write("\\faHeart & \\textbf{Hauptzutat} & %s" % content)

                f_latex.write("\\index{\\textbf{%s}}" % content.replace(", ", "}} \\index{\\textbf{"))
                f_latex.write("\\\\\n")

            # Type
            content = ws.cell(type_row, cell.column).value
            if content != "None\n" and content is not None:
                f_latex.write("\\faEye & \\textbf{Form} & %s" % content)
                f_latex.write("\\index[formen]{\\textbf{%s}}" % content.replace(", ", "}} \\index[formen]{\\textbf{"))
                f_latex.write("\\\\\n")

            # Source
            content = ws.cell(source_row, cell.column).value
            if content != "None\n" and content is not None:
                f_latex.write("\\faBook & \\textbf{Quelle} & %s" % content)
                f_latex.write("\\\\\n")

            # Specials
            content = ws.cell(specials_row, cell.column).value
            if content == "(vegan)" or content == "(Vegan)":
                content = "Vegan möglich"
            if content == "(zuckerfrei)" or content == "(Zuckerfrei)":
                content = "Zuckerfrei möglich"
            if content != "None\n" and content is not None:
                f_latex.write("\\faStar & \\textbf{Besonderheiten} & %s" % content)
                f_latex.write("\\index[specials]{\\textbf{%s}}" % content.replace(", ", "}} \\index[specials]{\\textbf{"))
                f_latex.write("\\\\\n")

            # Baking
            content1 = str(ws.cell(baking_time_row, cell.column).value)
            content2 = str(ws.cell(baking_temperature_row, cell.column).value)

            if (content1 != "None" and content1 is not None and content1 != "0") or (content2 != "None" and content2 is not None and content2 != "0"):
                f_latex.write("\\Oven & \\textbf{Backzeit} &")
                if content1 != "None" and content1 is not None and content1 != "0":
                    if content1[-4:] == "Min.":
                        content1 = content1[:-4]
                    content1 = re.sub(r'(\d) ?- ?(\d)', '\\1--\\2', content1)
                    f_latex.write("%s Minuten bei " % content1)
                else:
                    f_latex.write(" bei")
                if content2 != "None" and content2 is not None and content2 != "0":
                    f_latex.write(" %s~$^\circ$C" % content2)
                f_latex.write("\\\\\n")

            # Resting time
            content = str(ws.cell(resting_time_row, cell.column).value)
            if content != "None" and content is not None and content != "0":
                f_latex.write("\\faClockO & \\textbf{Ruhezeit} &")
                if content[-1:] == "h":
                    f_latex.write(" %s Stunden" % content[:-1])
                else:
                    f_latex.write("%s Minuten" % content)
                f_latex.write("\\\\\n")

            # Amount
            content = ws.cell(number_row, cell.column).value
            if content != "None\n" and content is not None:
                f_latex.write("\\faHashtag & \\textbf{Anzahl} & %s Stück\\\\\n" % content)

            # Years
            year = first_year
            count = 0
            output = "\\faCalendar & \\textbf{Gebacken} &"
            for i in range(first_year_row, last_year_row + 1):
                content = ws.cell(i, cell.column).value
                if content != "None\n" and content is not None:
                    # Cookie was baked in year
                    output = output + " " + str(year) + ","
                    count += 1
                year += 1
            if count == 0:
                output = output + " Noch nie gebacken"
            else:
                output = output[:-1]
            f_latex.write(str(output + "\\\\\n"))

            if count > 0:
                f_latex.write("\\faLineChart & \\textbf{Häufigkeit} & " + str(round(100 / (year - first_year) * count)) + "\\,\\%\\\\\n")

            f_latex.write("\\end{tabular}\n")

            # List of Ingredients
            f_latex.write("\\subsection*{Zutaten}\n")

            f_latex.write("\\begin{multicols}2\\raggedright\n")
            f_latex.write("\\begin{compactitem}\n")
            for i in range(ingredients_row_start, ingredients_other_row):
                number = str(ws.cell(i, cell.column).value)
                if number != "None\n" and number is not None and number != "None":

                    # Add unit and whitespaces
                    if not ingredients_unit[i]:
                        unit = ""
                    elif ingredients_unit[i][0].islower():
                        unit = "\\," + ingredients_unit[i]
                    else:
                        unit = "~" + ingredients_unit[i]

                    # Add Ingredient name
                    label = ingredients[i]
                    if ingredients[i] == "Ei":
                        unit = ""
                        if number == "1":
                            label = "Ei"
                        else:
                            label = "Eier"

                    # Add comment if available
                    if ingredients_comment[i]:
                        label += r" \penalty-10(" + ingredients_comment[i] + ")"

                    label = escape_latex(label)
                    f_latex.write("\\item %s%s %s \n" % (number, unit, label))

            f_latex.write("\\end{compactitem}\n")
            f_latex.write("\\end{multicols}\n")
            f_latex.write("\\vspace{0.2cm minus 0.2cm}\n")

            # Other ingredients
            content = ws.cell(ingredients_other_row, cell.column).value

            if content != "None\n" and content is not None and content != "None":
                content = escape_latex(content)
                f_latex.write("\\textit{Außerdem:} %s \n" % content)

            # Instructions
            content = ws.cell(instructions_row, cell.column).value
            if content != "None\n" and content is not None:
                content = escape_latex(content)
                content = re.sub(r'/([a-z])', r'/\\allowbreak{}\1', content, flags=re.I)
                content = re.sub(r'(\d) ([a-z])', r'\1~\2', content, flags=re.I)

                f_latex.write("\\subsection*{Anleitung} %s\n" % content)

            f_latex.write("\\vspace{2cm minus 1cm}\n")

# That's all, so close files
f_latex.close()

os.system("latexmk -pdf main.tex")
