
from collections import defaultdict
import random
import yaml
import chevron
import sys

class GrawlixCodex():

    def __init__(self, width=55, wordcount=50000, chaplength=4000, parlength=200):
        self.width = width
        self.smallest = 1
        self.longest = 6
        self.wordcount = wordcount
        self.chapleast = int(chaplength * 0.8)
        self.chapmost = int(chaplength * 1.2)
        self.parleast = int(parlength * 0.5)
        self.parmost = int(parlength * 1.5)


    def config(self, cffile):
        with open(cffile) as cf:
            try:
                self.cf = yaml.load(cf, Loader=yaml.Loader)
            except yaml.YAMLError as exc:
                print("%s parse error: %s" % ( self.args.config, exc ))
                if hasattr(exc, 'problem_mark'):
                    mark = exc.problem_mark
                    print("Error position: (%s:%s)" % (mark.line + 1, mark.column + 1))
 
    def load_emojos(self):
        self.emojos = []
        self.groups = defaultdict(set)
        with open(self.cf["emojos"], "r") as efh:
            for line in efh:
                parts = line.split()
                glyph = parts[0][1:-1]
                self.emojos.append(glyph)
                for tag in parts[1:]:
                    self.groups[tag].add(glyph)
        self.tags = [ t for t in self.groups.keys() if not t == "blank" ]
        self.blank = list(self.groups["blank"])[0]
        self.word_glyphs = list(self.groups["mono"])
        
    def word(self):
        l = random.randint(self.smallest, self.longest)
        for g in range(l):
            yield random.choice(self.word_glyphs)

    def text(self):
        p = 0
        parlength = random.randint(self.parleast, self.parmost)
        for w in range(self.wordcount):
            if w % 1000 == 0:
                print(f"{w} words", file=sys.stderr)
            for g in self.word():
                yield g
            if random.randint(1, 10) > 8:
                yield random.choice(list(self.groups["colour"]))
            p += 1
            if p == parlength:
                yield(":par:")
                p = 0
                parlength = random.randint(self.parleast, self.parmost)
            else:
                yield(self.blank)


    def line(self, gs, cls):
        glyphs = [ f'<img class="{cls}" src="img/{g}.png" />' for g in gs ]
        return ''.join(glyphs) 

    def chap_title(self):
        title = []
        for w in range(1, random.randint(1, 5)):
            for g in self.word():
                title.append(g)
            title.append(self.blank)
        title = title[:-1]
        title.append(random.choice(list(self.groups["colour"])))
        return title
        

    def chapters(self):
        chap_length = random.randint(self.chapleast, self.chapmost)
        n = 0
        row = []
        html = ""
        for g in self.text():
            if g != ":par:" and not ( g == "grawlix_null" and len(row) == 0):
                row.append(g)
            if len(row) == self.width or g == ":par:":
                html += self.line(row, "gl")
                row = []
                if g == ":par:":
                    html += "<br /><br />"
            n += 1
            if n > chap_length:
                chap_length = random.randint(self.chapleast, self.chapmost)
                n = 0
                yield {
                    "title": self.line(self.chap_title(), "ct"),
                    "text": html
                }

gc = GrawlixCodex(wordcount=50000, chaplength=10000)
gc.config("./config.yml")
gc.load_emojos()

n = 1;

chapters = list(gc.chapters())

index = []
for i in range(0, len(chapters)):
    c = chapters[i]
    c["nav"] = ""
    ci = i + 1
    fn = f"chapter_{ci}.html"
    index.append({
        "link": fn,
        "title": c["title"]
    })
    n = i + 2
    if i < len(chapters) - 1:
        c["nav"] = f'<a href="chapter_{n}.html">'
        c["nav"] += chapters[i + 1]["title"] + '</a>'
    with open("chapter.mustache", "r") as tf:
        with open(f"output/{fn}", "w") as cf:
            print(chevron.render(tf, c), file=cf)
            print(f"Chapter {ci}", file=sys.stderr)


with open("index.mustache", "r") as tf:
    with open(f"output/index.html", "w") as cf:
        print(chevron.render(tf, {"index": index}), file=cf)
        print("Index", file=sys.stderr)


