import ugfx

ugfx.init()
ugfx.clear(ugfx.BLACK)
ugfx.flush()
ugfx.clear(ugfx.WHITE)
ugfx.flush()

real_screen_size = (296, 128)
screen_size = (real_screen_size[0]-15,real_screen_size[1])
font_types = (
    ("Roboto_Regular12", 12, 45),
    ("Roboto_Regular18", 18, 33),
    ("Roboto_Regular22", 22, 20))


def get_string_width(string, font_id):
    return ugfx.get_string_width(string, font_types[font_id][0])


def parse_input_line(input_line, breaking_mode):
    if input_line.startswith("###"):
        font_id = 0
    elif input_line.startswith("##"):
        font_id = 1
    elif input_line.startswith("#"):
        font_id = 2
    else:
        font_id = 0

    input_line = input_line.lstrip("#")

    if breaking_mode=="better":
        output_lines = [""]
        output_fonts = [font_id]
        counter = 0
        current_width = 0
        for char in input_line:
            current_char_width = get_string_width(char, font_id)
            if current_width + current_char_width < screen_size[0]:
                output_lines[counter] += char
                current_width += current_char_width
            else:
                output_lines += [char]
                output_fonts += [font_id]

                counter += 1
                current_width = 0
    elif breaking_mode == "worse":
        output_lines = []
        output_fonts = []
        length = font_types[font_id][2]
        while input_line:
            if len(input_line) >= length:
                output_lines += [input_line[:length]]
                output_fonts += [font_id]
                input_line = input_line[length:]
            else:
                output_lines += [input_line]
                output_fonts += [font_id]
                input_line = ""
    else: 
        raise ValueError("this breaking mode does not exist")

    return output_lines, output_fonts

def create_view(start_position, action):
    global view
    global parsed_lines
    global parsed_fonts
    global article_length
    ugfx.clear(ugfx.WHITE)
    steps = 0
    if action == "next":
        current_height = 0, font_types[parsed_fonts[start_position]][1]
        while current_height[1] <= screen_size[1] and steps+start_position < article_length:
            ugfx.string(
                5,
                current_height[0],
                parsed_lines[start_position+steps].strip(),
                font_types[parsed_fonts[start_position+steps]][0],
                ugfx.BLACK)
            steps += 1
            current_height = (current_height[1],
                              current_height[1] + font_types[parsed_fonts[start_position+steps]][1])
        view = (start_position, start_position + steps)
    elif action == "prev":
        current_height = 0, font_types[parsed_fonts[start_position]][1]
        while current_height[1] <= screen_size[1] and steps+start_position > 0:
            ugfx.string(
                5,
                screen_size[1] - current_height[1],
                parsed_lines[start_position+steps].strip(),
                font_types[parsed_fonts[start_position+steps]][0],
                ugfx.BLACK)
            steps -= 1
            current_height = (current_height[1],
                              current_height[1] + font_types[parsed_fonts[start_position+steps]][1])
        view = (start_position+steps, start_position)
    else:
        raise ValueError("this action doesn't exist")

    ugfx.flush()
    return view


def move_view(button_direction, pressed):
    global view
    global article_length
    if pressed:
        if button_direction == "down":
            start_position = view[0]+1
            action = "next"
        elif button_direction == "up":
            start_position = view[0]-1
            action = "next"
        elif button_direction == "right":
            start_position = view[1]
            action = "next"
        elif button_direction == "left":
            start_position = view[0]
            action = "prev"
        else:
            raise ValueError("this direction doesn't exist")
        if start_position <= 0:
            start_position = 0
            action = "next"
        elif start_position >= article_length:
            start_position = article_length
            action= "prev"
        view = create_view(start_position, action)



def read(path, breaking_mode="better"):
    global parsed_lines 
    global parsed_fonts
    global view
    global article_length
    parsed_lines = []
    parsed_fonts = []
    with open(path) as f:
        for raw_line in f:
            temp_parsed_lines, temp_parsed_fonts = parse_input_line(raw_line, breaking_mode)
            parsed_lines += temp_parsed_lines
            parsed_fonts += temp_parsed_fonts

    article_length = len(parsed_lines)
    view = create_view(0, "next")

    ugfx.input_init()

    ugfx.input_attach(ugfx.JOY_DOWN, lambda pressed: move_view("down", pressed))
    ugfx.input_attach(ugfx.JOY_UP, lambda pressed: move_view("up", pressed))
    ugfx.input_attach(ugfx.JOY_LEFT, lambda pressed: move_view("left", pressed))
    ugfx.input_attach(ugfx.JOY_RIGHT, lambda pressed: move_view("right", pressed))

    while True:
        pass

print("This is in a very early alpha, a lot of functions are still missing.\n This program can read markdown file and will interprete a very small subset of markdown's features. \n You can use pandoc to convert ebooks to markdown, for later usage with this script. \nUsage: badgebook.read('/path/to/ebook.md', <mode>), mode can be any of 'better' or 'worse'.")