#![no_std]
#![cfg_attr(test, no_main)]
#![cfg_attr(test, feature(custom_test_frameworks))]
#![cfg_attr(test, reexport_test_harness_main = "test_main")]
#![cfg_attr(test, test_runner(agb::test_runner::test_runner))]

pub mod multi_typewriter;
pub mod renderer;
pub mod typewriter;

extern crate alloc;

pub mod prelude {
    pub use crate::TextAlign;
    pub use crate::TextOverflow;
    pub use crate::multi_typewriter::*;
    pub use crate::renderer::*;
    pub use crate::typewriter::*;
    pub use gba_agb_font_eb::prelude::*;
}

/// Bundles overflow mode, alignment, clear region, and palette id for a draw call
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct TextFormat {
    pub overflow: TextOverflow,
    pub align: TextAlign,
    pub clear: (u16, u16),
}

impl TextFormat {
    /// Construct a [`TextFormat`] with explicit parameters. `clear` is `(width, height)` in pixels; pass `(0, 0)` to skip clearing.
    pub const fn new(overflow: TextOverflow, align: TextAlign, clear: (u16, u16)) -> Self {
        Self {
            overflow,
            align,
            clear,
        }
    }
}

impl Default for TextFormat {
    #[inline]
    fn default() -> Self {
        Self {
            clear: (0, 0),
            align: TextAlign::default(),
            overflow: TextOverflow::default(),
        }
    }
}

/// Controls what happens when rendered text reaches the horizontal limit
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum TextOverflow {
    /// No overflow handling; text renders until the string ends.
    #[default]
    Nothing,
    /// Stop rendering glyphs once the cursor reaches this pixel offset from the draw origin.
    Cutoff(u16),
    /// Wrap to a new line once the cursor would exceed this pixel width.
    /// If the bool is `true`, wraps at whitespace (words longer than the width still break).
    /// If `false`, breaks at the character boundary
    Wrap(u16, bool),
}

/// Horizontal alignment for a block of rendered text
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum TextAlign {
    /// Align to the left edge; no column width needed.
    #[default]
    Left,
    /// Center text within a column of the given pixel width.
    Center(u16),
    /// Right-align text within a column of the given pixel width.
    Right(u16),
}
