#include <libft.h>
# include <ft_printf.h>
#include "derive.h"
static size_t max(size_t a, size_t b)
{
return (a > b ? a : b);
}
t_error derive_dimensions(
struct s_derived_dimensions *dimensions,
struct s_state_terminal terminal,
t_list2_meta options)
{
if (DERIVE_PADDING_TOP + DERIVE_PADDING_BOTTOM + 1 > terminal.rows)
return (errorf("terminal too short to display options"));
dimensions->rows =
terminal.rows - DERIVE_PADDING_TOP - DERIVE_PADDING_BOTTOM;
dimensions->columns =
(options.len / dimensions->rows) +
((options.len % dimensions->rows) ? 1 : 0);
return (ERROR_NULL);
}
t_error derive_column_width(
size_t **res,
struct s_derived_dimensions dimensions,
t_list2_meta options)
{
size_t row_index;
size_t column_index;
t_list2_conn *conn;
*res = ft_memalloc(dimensions.columns * sizeof(**res));
if (*res == NULL)
return errorf("unable to malloc column width array");
conn = options.first;
column_index = 0;
while (column_index < dimensions.columns)
{
row_index = 0;
while (row_index < dimensions.rows && conn != NULL)
{
(*res)[column_index] = max(
ft_strlen(unpack_option(conn)->name),
(*res)[column_index]);
conn = conn->next;
row_index++;
}
column_index++;
}
return (ERROR_NULL);
}
static t_error malloc_rows(
struct s_state_option ****res,
struct s_derived_dimensions dimensions)
{
size_t row_index;
*res = ft_memalloc(sizeof(**res) * dimensions.rows);
if (*res == NULL)
return errorf("unable to malloc rows array");
row_index = 0;
while (row_index < dimensions.rows)
{
(*res)[row_index] = ft_memalloc(sizeof(***res) * dimensions.columns);
if ((*res)[row_index] == NULL)
return errorf("unable to malloc column in rows array");
row_index++;
}
return (ERROR_NULL);
}
t_error derive_rows(
struct s_state_option ****res,
struct s_derived_dimensions dimensions,
t_list2_meta options)
{
size_t row_index;
size_t column_index;
t_list2_conn *conn;
t_error error;
error = malloc_rows(res, dimensions);
if (is_error(error))
return (error);
conn = options.first;
column_index = 0;
while (column_index < dimensions.columns)
{
row_index = 0;
while (row_index < dimensions.rows && conn != NULL)
{
(*res)[row_index][column_index] = unpack_option(conn);
conn = conn->next;
row_index++;
}
column_index++;
}
return (ERROR_NULL);
}
bool derive_enough_columns(
struct s_state_terminal terminal,
struct s_derived_dimensions dimensions,
size_t *column_width)
{
size_t total_width;
size_t i;
total_width = DERIVE_PADDING_LEFT + DERIVE_PADDING_RIGHT;
i = 0;
while (i < dimensions.columns)
{
total_width += DERIVE_OPTION_PADDING_LEFT
+ column_width[i] + DERIVE_OPTION_PADDING_RIGHT;
i++;
}
return (total_width <= terminal.columns);
}
void derive_free_rows(
struct s_derived_dimensions dimensions,
struct s_state_option ****rows)
{
size_t row_index;
row_index = 0;
while (row_index < dimensions.rows)
{
ft_memdel((void **)&(*rows)[row_index]);
row_index++;
}
ft_memdel((void **)rows);
}