#!/bin/env python3
 
import curses
 
from classes import Project, Board, Column, Task
import constants
import strings
 
def main(stdscr):
    project = Project("New Project")
    project.load()
    #
    # Create test project
    # -------------------
    #project.boards.append(Board("testing", "test description"))
    #project.boards[0].columns[0].tasks.append(Task("test task 1"))
    #project.boards[0].columns[0].tasks.append(Task("test task 2"))
    #project.boards[0].columns[1].tasks.append(Task("test task 3"))
    #project.boards[0].columns[2].tasks.append(Task("test task 4 this is a super duper mega long task name and i need to just to verify that task names are sliced correctly"))
    #project.boards[0].columns[2].tasks.append(Task("test task 5"))
    #project.boards[0].columns[2].tasks.append(Task("test task 6"))
    #project.active_board = 0
 
    state = constants.BOARD
    selection = [constants.BOARD_SELECT_BOARD, 0, 0]
    curses.curs_set(False)
 
    while True:
        stdscr.clear()
 
 
        # ======
        # States
        # ======
        # 
        # Project info
        # ------------
        if state == constants.PROJECT_INFO:
            print_project_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
        elif state == constants.HELP_PROJECT_SETTINGS:
            print_help(stdscr, strings.HELP_PROJECT_SETTINGS)
            state = constants.PROJECT_INFO
            continue
        elif state == constants.SET_PROJECT_NAME:
            print_project_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
            name = get_input(stdscr, strings.PROMPT_PROJECT_NAME)
            if len(name) > 0:
                project.name = name
                project.save()
            state = constants.PROJECT_INFO
            continue
        elif state == constants.NEW_BOARD:
            print_project_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
            name = get_input(stdscr, strings.PROMPT_NEW_BOARD)
            if len(name) > 0:
                project.boards.append(Board(name))
            else:
                project.boards.append(Board())
            project.save()
            state = constants.PROJECT_INFO
            continue
        elif state == constants.SET_ACTIVE_BOARD:
            select_board(stdscr, project)
            project.save()
            state = constants.PROJECT_INFO
            continue
        elif state == constants.REMOVE_BOARD:
            remove_board(stdscr, project)
            project.save()
            state = constants.PROJECT_INFO
            continue
 
        # Board info
        # ----------
        if state == constants.BOARD_INFO:
            print_board_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
        elif state == constants.HELP_BOARD_SETTINGS:
            print_help(stdscr, strings.HELP_BOARD_SETTINGS)
            state = constants.BOARD_INFO
            continue
        elif state == constants.SET_BOARD_NAME:
            print_board_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
            name = get_input(stdscr, strings.PROMPT_BOARD_NAME)
            if len(name) > 0:
                project.get_active().name = name
                project.save()
            state = constants.BOARD_INFO
            continue
        elif state == constants.SET_BOARD_DESCRIPTION:
            print_board_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
            description = get_input(stdscr, strings.PROMPT_BOARD_DESCRIPTION)
            if len(description) > 0:
                project.get_active().description = description
                project.save()
            state = constants.BOARD_INFO
            continue
        elif state == constants.ADD_COLUMN:
            print_board_info(stdscr, project)
            print_menu(stdscr, strings.MENU_TEXT)
            name = get_input(stdscr, strings.PROMPT_ADD_COLUMN)
            if len(name) > 0:
                project.get_active().columns.append(Column(name))
            else:
                project.get_active().columns.append(Column())
            project.save()
            state = constants.BOARD_INFO
            continue
        elif state == constants.REMOVE_COLUMN:
            remove_column(stdscr, project)
            project.save()
            state = constants.BOARD_INFO
            continue
 
        # Column info
        # -----------
        if state == constants.COLUMN_INFO:
            print_column_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
        elif state == constants.HELP_COLUMN_SETTINGS:
            print_help(stdscr, strings.HELP_COLUMN_SETTINGS)
            state = constants.COLUMN_INFO
            continue
        elif state == constants.SET_COLUMN_NAME:
            print_column_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
            name = get_input(stdscr, strings.PROMPT_COLUMN_NAME)
            if len(name) > 0:
                project.get_active().columns[selection[1]].name = name
                project.save()
            state = constants.COLUMN_INFO
            continue
        elif state == constants.SET_COLUMN_DESCRIPTION:
            print_column_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
            description = get_input(stdscr, strings.PROMPT_COLUMN_DESCRIPTION)
            if len(description) > 0:
                project.get_active().columns[selection[1]].description = description
                project.save()
            state = constants.COLUMN_INFO
            continue
        elif state == constants.SET_COLUMN_TASK_LIMIT:
            print_column_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
            task_limit = get_input(stdscr, strings.PROMPT_COLUMN_TASK_LIMIT)
            if task_limit.isdigit():
                project.get_active().columns[selection[1]].task_limit = task_limit
                project.save()
            state = constants.COLUMN_INFO
            continue
 
        # Task info
        # ---------
        if state == constants.TASK_INFO:
            print_task_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
        elif state == constants.HELP_TASK_SETTINGS:
            print_help(stdscr, strings.HELP_TASK_SETTINGS)
            state = constants.TASK_INFO
            continue
        elif state == constants.SET_TASK_NAME:
            print_task_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
            name = get_input(stdscr, strings.PROMPT_TASK_NAME)
 
            if len(name) > 0:
                project.get_active().columns[selection[1]].tasks[selection[2]].name = name
                project.save()
            state = constants.TASK_INFO
            continue
        elif state == constants.SET_TASK_DESCRIPTION:
            print_task_info(stdscr, project, selection)
            print_menu(stdscr, strings.MENU_TEXT)
            description = get_input(stdscr, strings.PROMPT_TASK_DESCRIPTION)
            if len(description) > 0:
                project.get_active().columns[selection[1]].tasks[selection[2]].description = description
                project.save()
            state = constants.TASK_INFO
            continue
 
        # Board view
        # ----------
        elif state == constants.BOARD:
            if project.get_active() is not None:
                print_board(stdscr, project, selection)
                if selection[0] == constants.BOARD_SELECT_BOARD:
                    print_menu(stdscr, strings.MENU_TEXT)
                elif selection[0] == constants.BOARD_SELECT_COLUMN:
                    print_menu(stdscr, strings.MENU_TEXT)
                elif selection[0] == constants.BOARD_SELECT_TASK:
                    print_menu(stdscr, strings.MENU_TEXT)
            else:
                state = constants.PROJECT_INFO
                continue
        elif state == constants.HELP_BOARD:
            print_help(stdscr, strings.HELP_BOARD)
            state = constants.BOARD
            continue
        elif state == constants.MOVE_COLUMN:
            print_board(stdscr, project, selection)
            print_info(stdscr, strings.INFO_MOVE_COLUMN)
            print_menu(stdscr, strings.MENU_TEXT)
            key = 0
            while key not in (ord("h"), ord("l")):
                key = stdscr.getch()
            if key == ord("h"):
                if selection[1] > 0:
                    project.get_active().columns[selection[1] - 1], project.get_active().columns[selection[1]] = project.get_active().columns[selection[1]], project.get_active().columns[selection[1] - 1]
                    selection[1] -= 1
            elif key == ord("l"):
                if selection[1] < len(project.get_active().columns) - 1:
                    project.get_active().columns[selection[1]], project.get_active().columns[selection[1] + 1] = project.get_active().columns[selection[1] + 1], project.get_active().columns[selection[1]]
                    selection[1] += 1
            project.save()
            state = constants.BOARD
            continue
        elif state == constants.ADD_TASK:
            print_board(stdscr, project, selection)
            if selection[0] == constants.BOARD_SELECT_COLUMN:
                print_menu(stdscr, strings.MENU_TEXT)
            elif selection[0] == constants.BOARD_SELECT_TASK:
                print_menu(stdscr, strings.MENU_TEXT)
            if len(project.get_active().columns[selection[1]].tasks) < int(project.get_active().columns[selection[1]].task_limit) or int(project.get_active().columns[selection[1]].task_limit) == 0:
                name = get_input(stdscr, strings.PROMPT_ADD_TASK)
                if len(name) > 0:
                    project.get_active().columns[selection[1]].tasks.append(Task(name))
                else:
                    project.get_active().columns[selection[1]].tasks.append(Task())
                project.save()
            else:
                # TODO: Task limit reached error
                pass
            state = constants.BOARD
            continue
        elif state == constants.REMOVE_TASK:
            project.get_active().columns[selection[1]].tasks.pop(selection[2])
            if selection[2] >= len(project.get_active().columns[selection[1]].tasks):
                selection[2] -= 1
            if selection[2] < 0:
                selection[2] = 0
                selection[0] = constants.BOARD_SELECT_COLUMN
            project.save()
            state = constants.BOARD
            continue
        elif state == constants.MOVE_TASK:
            print_board(stdscr, project, selection)
            print_info(stdscr, strings.INFO_MOVE_TASK)
            print_menu(stdscr, strings.MENU_TEXT)
            key = 0
            while key not in (ord("h"), ord("l")):
                key = stdscr.getch()
            if key == ord("h"):
                if selection[1] > 0:
                    if len(project.get_active().columns[selection[1] - 1].tasks) < int(project.get_active().columns[selection[1] - 1].task_limit) or project.get_active().columns[selection[1] - 1].task_limit == 0:
                        task = project.get_active().columns[selection[1]].tasks.pop(selection[2])
                        project.get_active().columns[selection[1] - 1].tasks.append(task)
            elif key == ord("l"):
                if selection[1] < (len(project.get_active().columns) - 1):
                    if len(project.get_active().columns[selection[1] + 1].tasks) < int(project.get_active().columns[selection[1] + 1].task_limit) or project.get_active().columns[selection[1] + 1].task_limit == 0:
                        task = project.get_active().columns[selection[1]].tasks.pop(selection[2])
                        project.get_active().columns[selection[1] + 1].tasks.append(task)
            project.save()
            state = constants.BOARD
            continue
 
 
        # ============= 
        # Command input
        # ============= 
 
        stdscr.refresh()
        key = stdscr.getch()
 
        if key == ord("!"):
            break
        elif state == constants.PROJECT_INFO:
            if key == ord("a"):
                state = constants.NEW_BOARD
            elif key == ord("?"):
                state = constants.HELP_PROJECT_SETTINGS
            elif key == ord("b"):
                state = constants.SET_ACTIVE_BOARD
            elif key == ord("n"):
                state = constants.SET_PROJECT_NAME
            elif key == ord("r"):
                state = constants.REMOVE_BOARD
            elif key == ord("q"):
                state = constants.BOARD
        elif state == constants.BOARD_INFO:
            if key == ord("n"):
                state = constants.SET_BOARD_NAME
            elif key == ord("?"):
                state = constants.HELP_BOARD_SETTINGS
            elif key == ord("q"):
                state = constants.BOARD
            elif key == ord("d"):
                state = constants.SET_BOARD_DESCRIPTION
            elif key == ord("a"):
                state = constants.ADD_COLUMN
            elif key == ord("r"):
                state = constants.REMOVE_COLUMN
        elif state == constants.COLUMN_INFO:
            if key == ord("q"):
                state = constants.BOARD
            elif key == ord("?"):
                state = constants.HELP_COLUMN_SETTINGS
            elif key == ord("n"):
                state = constants.SET_COLUMN_NAME
            elif key == ord("d"):
                state = constants.SET_COLUMN_DESCRIPTION
            elif key == ord("l"):
                state = constants.SET_COLUMN_TASK_LIMIT
        elif state == constants.TASK_INFO:
            if key == ord("q"):
                state = constants.BOARD
            elif key == ord("?"):
                state = constants.HELP_TASK_SETTINGS
            elif key == ord("n"):
                state = constants.SET_TASK_NAME
            elif key == ord("d"):
                state = constants.SET_TASK_DESCRIPTION
        elif state == constants.BOARD:
            if key == ord("q"):
                break
            elif key == ord("?"):
                state = constants.HELP_BOARD
            elif key == ord("p"):
                state = constants.PROJECT_INFO
            elif key == ord("s"):
                if selection[0] == constants.BOARD_SELECT_BOARD:
                    state = constants.BOARD_INFO
                elif selection[0] == constants.BOARD_SELECT_COLUMN:
                    state = constants.COLUMN_INFO
                elif selection[0] == constants.BOARD_SELECT_TASK:
                    state = constants.TASK_INFO
            elif key == ord("a"):
                if selection[0] != constants.BOARD_SELECT_BOARD:
                    state = constants.ADD_TASK
            elif key == ord("x"):
                if selection[0] == constants.BOARD_SELECT_TASK:
                    state = constants.REMOVE_TASK
            elif key == ord("m"):
                if selection[0] == constants.BOARD_SELECT_COLUMN:
                    state = constants.MOVE_COLUMN
                elif selection[0] == constants.BOARD_SELECT_TASK:
                    state = constants.MOVE_TASK
            elif key in (ord("j"), curses.KEY_DOWN):
                if selection[0] == constants.BOARD_SELECT_BOARD:
                    selection = [constants.BOARD_SELECT_COLUMN, 0, 0]
                elif selection[0] == constants.BOARD_SELECT_COLUMN and len(project.get_active().columns[selection[1]].tasks) > 0:
                    selection[0] = constants.BOARD_SELECT_TASK
                    selection[2] = 0
                elif selection[0] == constants.BOARD_SELECT_TASK and selection[2] < len(project.get_active().columns[selection[1]].tasks) - 1:
                    selection[2] += 1
            elif key in (ord("k"), curses.KEY_UP):
                if selection[0] == constants.BOARD_SELECT_COLUMN:
                    selection = [constants.BOARD_SELECT_BOARD, 0, 0]
                elif selection[0] == constants.BOARD_SELECT_TASK:
                    if selection[2] > 0:
                        selection[2] -= 1
                    else:
                        selection[0] = constants.BOARD_SELECT_COLUMN
            elif key in (ord("l"), curses.KEY_RIGHT):
                if selection[0] != constants.BOARD_SELECT_BOARD:
                    if selection[1] < len(project.get_active().columns) - 1:
                        if len(project.get_active().columns[selection[1] + 1].tasks) == 0:
                            selection[2] = 0
                            selection[0] = constants.BOARD_SELECT_COLUMN
 
                        elif selection[2] > len(project.get_active().columns[selection[1] + 1].tasks) - 1:
                            selection[2] = len(project.get_active().columns[selection[1] + 1].tasks) - 1
                        selection[1] += 1
            elif key in (ord("h"), curses.KEY_LEFT):
                if selection[0] != constants.BOARD_SELECT_BOARD:
                    if selection[1] > 0:
                        if len(project.get_active().columns[selection[1] - 1].tasks) == 0:
                            selection[2] = 0
                            selection[0] = constants.BOARD_SELECT_COLUMN
                        elif selection[2] > len(project.get_active().columns[selection[1] - 1].tasks) - 1:
                            selection[2] = len(project.get_active().columns[selection[1] - 1].tasks) - 1
                        selection[1] -= 1
 
def get_input(stdscr, message):
    """
    Shows the input line and takes input. The input must be
    decoded, or else a bytestring is returned.
    """
    max_yx = stdscr.getmaxyx()
    stdscr.addstr(max_yx[0] - 2, 1, message)
    curses.curs_set(True)
    curses.echo()
    input_string = stdscr.getstr(max_yx[0] - 2, 1 + len(message))
    curses.noecho()
    curses.curs_set(False)
    return input_string.decode()
 
def print_info(stdscr, message):
    """
    Prints the provided message on the next to last line.
    """
    max_yx = stdscr.getmaxyx()
    stdscr.addstr(max_yx[0] - 2, 1, message)
 
def print_board(stdscr, project, selection):
    """
    Prints the active board.
    """
    board = project.get_active()
    max_yx = stdscr.getmaxyx()
    width_without_vlines = max_yx[1] - 1 - len(board.columns)
    columns = [width_without_vlines // len(board.columns)] * len(board.columns)
    remains = width_without_vlines % len(board.columns)
    counter = 0
    while remains > 0:
        columns[counter] += 1
        remains -= 1
        counter += 1
        if counter == 4:
            counter = 0
 
    # ==================
    # PRINT BOARD HEADER
    # ==================
 
    if selection[0] == constants.BOARD_SELECT_BOARD:
        print_box(stdscr, 0, 0, ": ".join([board.name, board.description]), curses.A_REVERSE)
    else:
        print_box(stdscr, 0, 0, ": ".join([board.name, board.description]))
    if len(board.columns) == 0:
        # print error message / go to create columns
        pass
    else:
        # PRINT COLUMN HEADERS
        stdscr.addch(3, 0, curses.ACS_ULCORNER)
        for index, column in enumerate(columns):
            for i in range(column):
                stdscr.addch(curses.ACS_HLINE)
            stdscr.addch(curses.ACS_TTEE)
        stdscr.addch(curses.ACS_TTEE)
        stdscr.addch(3, max_yx[1] - 1, curses.ACS_URCORNER)
        stdscr.addch(curses.ACS_VLINE)
        for index, column in enumerate(columns):
            if int(board.columns[index].task_limit) > 0:
                print_string = "".join([" [", board.columns[index].task_limit, "] ", board.columns[index].name])
            else:
                print_string = "".join([" ", board.columns[index].name])
            if len(print_string) > column:
                print_string = print_string[:column]
            else:
                print_string = "".join([print_string, " " * (column - len(print_string))])
            if selection[0] == constants.BOARD_SELECT_COLUMN:
                if selection[1] == index:
                    stdscr.addstr(print_string, curses.A_REVERSE)
                else:
                    stdscr.addstr(print_string)
            else:
                stdscr.addstr(print_string)
            stdscr.addch(curses.ACS_VLINE)
        stdscr.addch(curses.ACS_LTEE)
        for column in columns:
            for i in range(column):
                stdscr.addch(curses.ACS_HLINE)
            stdscr.addch(curses.ACS_PLUS)
        stdscr.addch(5, max_yx[1] - 1, curses.ACS_RTEE)
 
 
        # =============
        # PRINT COLUMNS
        # =============
 
        for i in range(max_yx[0] - 9):
            stdscr.addch(i + 6, 0, curses.ACS_VLINE)
            offset = 0
            for column in columns:
                offset += column + 1
                stdscr.addch(i + 6, offset, curses.ACS_VLINE)
        stdscr.addch(max_yx[0] - 3, 0, curses.ACS_LLCORNER)
        for column in columns:
            for i in range(column):
                stdscr.addch(curses.ACS_HLINE)
            stdscr.addch(curses.ACS_BTEE)
        stdscr.addch(max_yx[0] - 3, max_yx[1] - 1, curses.ACS_LRCORNER)
 
 
        # ===========
        # PRINT TASKS
        # ===========
 
        offset_y = 6
        offset_x = 1
        for column_index, column in enumerate(columns):
            stdscr.move(offset_y, offset_x)
            for task_index, task in enumerate(board.columns[column_index].tasks):
                if selection[0] == constants.BOARD_SELECT_TASK and selection[1] == column_index and selection[2] == task_index:
                    stdscr.addstr("".join([" ", task.name[:column - 2], " "]), curses.A_REVERSE)
                else:
                    stdscr.addstr(" ")
                    stdscr.addstr(task.name[:column - 2])
                offset_y += 1
                stdscr.move(offset_y, offset_x)
            offset_y = 6
            offset_x += column + 1
 
def print_project_info(stdscr, project):
    """
    Prints the project info.
    """
    stdscr.addstr(1, 1, project.name)
    for index, board in enumerate(project.boards):
        if index == project.active_board:
            stdscr.addstr(index + 3, 2, "".join(["* ", str(project.boards[index])]))
        else:
            stdscr.addstr(index + 3, 2, "".join(["  ", str(project.boards[index])]))
 
def print_board_info(stdscr, project):
    """
    Prints the board info.
    """
    stdscr.addstr(1, 1, "Board name:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", project.get_active().name]))
    stdscr.addstr(3, 1, "Board description:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", project.get_active().description]))
    stdscr.addstr(5, 1, "Board columns:", curses.A_UNDERLINE)
    for index, column in enumerate(project.get_active().columns):
        stdscr.addstr(index + 6, 1, str(column.name))
 
def print_column_info(stdscr, project, selection):
    """
    Prints the column info.
    """
    stdscr.addstr(1, 1, "Column name:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", project.get_active().columns[selection[1]].name]))
    stdscr.addstr(3, 1, "Column description:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", project.get_active().columns[selection[1]].description]))
    stdscr.addstr(5, 1, "Column task limit:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", str(project.get_active().columns[selection[1]].task_limit)]))
 
def print_task_info(stdscr, project, selection):
    """
    Prints the task info.
    """
    stdscr.addstr(1, 1, "Task name:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", project.get_active().columns[selection[1]].tasks[selection[2]].name]))
    stdscr.addstr(3, 1, "Task description:", curses.A_UNDERLINE)
    stdscr.addstr("".join([" ", project.get_active().columns[selection[1]].tasks[selection[2]].description]))
 
def print_box(stdscr, y, x, print_string, attribute=None):
    """
    Prints a string inside a box with its upper left corners
    at the given coordinates.
    """
    stdscr.addch(y, x, curses.ACS_ULCORNER)
    print_chars = 1 + len(print_string) + 1
    for i in range(print_chars):
        stdscr.addch(curses.ACS_HLINE)
    stdscr.addch(curses.ACS_URCORNER)
    stdscr.addch(y + 1, 0, curses.ACS_VLINE)
    if attribute is None:
        stdscr.addstr(y + 1, 1, "".join([" ", print_string, " "]))
    else:
        stdscr.addstr(y + 1, 1, "".join([" ", print_string, " "]), attribute)
    stdscr.addch(curses.ACS_VLINE)
    stdscr.addch(y + 2, 0, curses.ACS_LLCORNER)
    for i in range(print_chars):
        stdscr.addch(curses.ACS_HLINE)
    stdscr.addch(curses.ACS_LRCORNER)
def print_menu(stdscr, menu_text):
    """
    Prints a text in the last row of the terminal window.
    """
    stdscr.addstr(stdscr.getmaxyx()[0] - 1, 1, strings.MENU_TEXT)
 
def print_help(stdscr, string):
    """
    Prints the given help string.
    """
    # 1. re-format string to fit the current terminal window
    # # 2. create pad
    # 3. add string to pad
    # # 4. listen for j/k/q
    # # 5. if q, go back to board view
    # 6. if j, move pad up (scroll down)
    # 7. if k, move pad down (scroll up)
    lines = string.splitlines()
    text_height = len(lines) + 2
    text_width = 72
    max_yx = stdscr.getmaxyx()
    help_pad = curses.newpad(text_height, text_width)
    scroll = 0
    while True:
        help_pad.clear()
        help_pad.border(0)
        for index, line in enumerate(lines):
            help_pad.addstr(index + 1, 2, lines[index])
        help_pad.refresh(scroll, 0, 0, 0, text_height, text_width)
        key = 0
        key = help_pad.getch()
        if key == ord("q"):
            break
        elif key == ord("j"):
            #scroll -= 1
            pass
        elif key == ord("k"):
            #scroll += 1
            pass
 
# ========================
# WILL PROBABLY BE REMOVED
# ========================
def print_menu2(stdscr, menu):
    """
    Prints a menu. Menu texts are defined in strings.py.
    Menu definitions are lists of strings. One letter in each string
    is parenthesized. The parenthexised letter will be printed as underlined
    to indicate keyboard commands.
    """
    max_yx = stdscr.getmaxyx()
    offset = 0
    for item in menu:
        # If there is a split, split at the closing parenthesis as well.
        if item.count("(") == item.count(")") == 1:
            split_text = item.split("(")
            if len(split_text) > 1:
                split_text[1] = split_text[1].split(")")
            # If the first part is longer than 0, print it in normal text.
            if len(split_text[0]) > 0:
                stdscr.addstr(max_yx[0] - 1, 1 + offset, split_text[0])
            # Print the underlined part.
            stdscr.addstr(max_yx[0] - 1, 1 + offset + len(split_text[0]), split_text[1][0], curses.A_UNDERLINE)
            if len(split_text[1][1]) > 0:
                stdscr.addstr(max_yx[0] - 1, 1 + offset + len(split_text[0]) + len(split_text[1][0]), split_text[1][1])
        else:
            stdscr.addstr(max_yx[0] - 1, 1 + offset, item)
        offset += len(item) + 3
 
def select_board(stdscr, project):
    """
    Prints the project info, but with the addition that the user
    is able to select one board with up/down keys or j/k and
    the enter key.
    """
    if project.active_board is None:
        selection = 0
    else:
        selection = project.active_board
 
    key = 0
    while key != 10:
        stdscr.clear()
        print_project_info(stdscr, project)
        print_menu(stdscr, strings.MENU_TEXT)
        stdscr.addstr(selection + 3, 4, str(project.boards[selection]), curses.A_REVERSE)
        key = stdscr.getch()
        if selection == 0:
            if key in (curses.KEY_DOWN, ord("j")):
                selection += 1
        elif selection == (len(project.boards) - 1):
            if key in (curses.KEY_UP, ord("k")):
                selection -= 1
        else:
            if key in (curses.KEY_DOWN, ord("j")):
                selection += 1
            if key in (curses.KEY_UP, ord("k")):
                selection -= 1
    project.active_board = selection
 
def remove_board(stdscr, project):
    """
    Lets the user select a board and removes it.
    """
 
    selection = 0
 
    key = 0
    while key != 10:
        stdscr.clear()
        print_project_info(stdscr, project)
        print_menu(stdscr, strings.MENU_TEXT)
        stdscr.addstr(selection + 3, 4, str(project.boards[selection]), curses.A_REVERSE)
        key = stdscr.getch()
        if selection == 0:
            if key in (curses.KEY_DOWN, ord("j")):
                selection += 1
        elif selection == (len(project.boards) - 1):
            if key in (curses.KEY_UP, ord("k")):
                selection -= 1
        else:
            if key in (curses.KEY_DOWN, ord("j")):
                selection += 1
            if key in (curses.KEY_UP, ord("k")):
                selection -= 1
    project.boards.pop(selection)
 
def remove_column(stdscr, project):
    """
    Lets the user select a column and removes it.
    """
 
    selection = 0
 
    key = 0
    while key != 10:
        stdscr.clear()
        print_board_info(stdscr, project)
        print_menu(stdscr, strings.MENU_TEXT)
        stdscr.addstr(selection + 6, 1, project.get_active().columns[selection].name, curses.A_REVERSE)
        key = stdscr.getch()
        if selection == 0:
            if key in (curses.KEY_DOWN, ord("j")):
                selection += 1
        elif selection == (len(project.get_active().columns) - 1):
            if key in (curses.KEY_UP, ord("k")):
                selection -= 1
        else:
            if key in (curses.KEY_DOWN, ord("j")):
                selection += 1
            if key in (curses.KEY_UP, ord("k")):
                selection -= 1
    project.get_active().columns.pop(selection)
 
 
if __name__ == "__main__":
    curses.wrapper(main)