#ifndef SHADE_TTY_H
#define SHADE_TTY_H

#include <shade/cansid.h>
#include <stdbool.h>

/**
 * @brief A type to represent a printable char
 * 
 */
typedef struct tty_ochar_struct {
    char character;
    char style;
} tty_ochar_t;

/**
 * @brief A type to represent a tty driver
 * 
 */
typedef struct tty_driver_struct {
    int max_rows;
    int max_cols;

    void (*putchar) (char c, int x, int y, char style);
    void (*setcurxy) (int x, int y);
} tty_driver_t;

/**
 * @brief A type to represent a tty
 * 
 */
typedef struct tty_struct {
    // size information
    int rows;
    int cols;

    // cursor information
    int cursor_row;
    int cursor_col;
    
    // stateful information
    cansid_state cansid;

    // buffers
    tty_ochar_t output_buffer[65536];
    char input_buffer[1024];

    // driver
    tty_driver_t driver;

    // flags
    bool active;
} tty_t;

static tty_t ttys[10];
static int active_tty;

/**
 * @brief Create a new tty_t with the provided driver
 * 
 * @param driver 
 * @return tty_t 
 */
tty_t tty_new(tty_driver_t driver);

/**
 * @brief Switch the screen to the provided tty - clear screen and flip to that tty
 * 
 * @param index 
 */
void tty_switch(int index);

/**
 * @brief Print the specified char c on the tty tty, at the current cursor location
 * 
 * @param tty 
 * @param c 
 * @see tty_mvpchar
 */
void tty_pchar(int tty, char c);
/**
 * @brief Print the specified char t to the tty tty, but move the cursor to x, y first.
 * 
 * @param tty 
 * @param c 
 * @param x 
 * @param y 
 * @see tty_pchar
 */
void tty_mvpchar(int tty, char c, int x, int y);

// tty_pnl family
/**
 * @brief Print a newline at the current cursor location on the tty tty.
 * 
 * @param tty 
 * @see tty_mvpnl
 */
void tty_pnl(int tty);
/**
 * @brief Move to the specified cursor location and print a newline.
 * 
 * @param tty 
 * @param c 
 * @param x 
 * @param y 
 * @see tty_pnl
 */
void tty_mvpnl(int tty, int x, int y);

// tty_clr family
/**
 * @brief Clear the entire screen of the specified tty. Uses tty_clrl internally.
 * 
 * @param tty 
 * @see tty_clrl
 */
void tty_clr(int tty);
/**
 * @brief Clear the specified line of the specified tty.
 * 
 * @param tty 
 * @param line 
 * @see tty_clr
 */
void tty_clrl(int tty, int line);

/**
 * @brief Set the cursor position on the specified tty to the specified position.
 * 
 * @param tty 
 * @param x 
 * @param y 
 */
void tty_setcurxy(int tty, int x, int y);

#endif