#include <stdbool.h>
#include <unistd.h>
#include <ft_printf.h>
#include <libft.h>
#include "state.h"
#include "derive.h"
#include "terminal.h"
#include "render.h"
static void box_top(const struct s_state_terminal terminal)
{
size_t i;
ft_dprintf(STDERR_FILENO, "%*s\n", terminal.columns, "");
ft_dprintf(STDERR_FILENO, " ┏");
i = 1;
while (i < terminal.columns - 5)
{
ft_dprintf(STDERR_FILENO, "━");
i++;
}
ft_dprintf(STDERR_FILENO, "┓ \n");
}
static void box_bottom(const struct s_state_terminal terminal)
{
size_t i;
ft_dprintf(STDERR_FILENO, " ┗");
i = 1;
while (i < terminal.columns - 5)
{
ft_dprintf(STDERR_FILENO, "━");
i++;
}
ft_dprintf(STDERR_FILENO, "┛ \n");
}
static void box_option(char *option, bool selected, bool focus, size_t width)
{
ft_dprintf(STDERR_FILENO, "%c%c", focus ? '[' : ' ', selected ? '*' : ' ');
if (focus)
terminal_send(TERMINAL_FMT_BEGIN_UNDERLINE);
if (selected)
terminal_send(TERMINAL_FMT_BEGIN_REVERSE_VIDEO);
ft_dprintf(STDERR_FILENO, "%-*s", (int)width, option);
terminal_send(TERMINAL_FMT_EXIT);
ft_dprintf(STDERR_FILENO, "%c", focus ? ']' : ' ');
}
void render(const struct s_state state)
{
struct s_derived_dimensions dimensions;
size_t *column_width;
struct s_state_option ***rows;
size_t column_index;
size_t row_index;
size_t total_column_width;
t_error error;
terminal_send(TERMINAL_CURSOR_HOME);
error = derive_dimensions(&dimensions, state.terminal, state.options);
if (is_error(error))
{
terminal_send(TERMINAL_CLEAR_SCREEN);
ft_dprintf(STDERR_FILENO, "%s", error.msg);
return ;
}
error = derive_column_width(&column_width, dimensions, state.options);
if (is_error(error))
{
terminal_send(TERMINAL_CLEAR_SCREEN);
ft_dprintf(STDERR_FILENO, "%s", error.msg);
return ;
}
if (!derive_enough_columns(state.terminal, dimensions, column_width))
{
terminal_send(TERMINAL_CLEAR_SCREEN);
ft_dprintf(STDERR_FILENO, "terminal too small to display options");
return ;
}
error = derive_rows(&rows, dimensions, state.options);
if (is_error(error))
{
ft_dprintf(STDERR_FILENO, "%s", error.msg);
return ;
}
box_top(state.terminal);
row_index = 0;
while (row_index < dimensions.rows)
{
ft_dprintf(STDERR_FILENO, " ┃ ");
column_index = 0;
total_column_width = 0;
while (column_index < dimensions.columns &&
rows[row_index][column_index] != NULL)
{
box_option(
rows[row_index][column_index]->name,
rows[row_index][column_index]->selected,
unpack_option(state.cursor) == rows[row_index][column_index],
column_width[column_index]);
total_column_width += column_width[column_index]
+ DERIVE_OPTION_PADDING_LEFT + DERIVE_OPTION_PADDING_RIGHT;
column_index++;
}
ft_dprintf(STDERR_FILENO, "%*s ┃ \n",
state.terminal.columns - total_column_width
- DERIVE_PADDING_LEFT - DERIVE_PADDING_RIGHT, "");
row_index++;
}
box_bottom(state.terminal);
ft_memdel((void **)&column_width);
derive_free_rows(dimensions, &rows);
}