perfectstar2k 0.1.0

A modern TUI homage to WordStar & WordPerfect for DOS — a real writing tool built on WordStar's touch-typist command language and long-hand-page metaphor.
use ratatui::style::{Color, Modifier, Style};

/// A color scheme. The default is the WordPerfect 5.1 white-on-blue look;
/// ANSI Blue matches the DOS palette's #0000AA on most terminals, which also
/// keeps us working on terminals without truecolor support.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThemeKind {
    WpBlue,
    WordStar,
    TerminalDefault,
}

#[derive(Debug, Clone, Copy)]
pub struct Theme {
    pub kind: ThemeKind,
    pub base: Style,
    pub status: Style,
    pub dim: Style,
    /// Marked-block highlight.
    pub block: Style,
    /// Search-match highlight.
    pub highlight: Style,
    // Markdown styling
    pub md_marker: Style,
    pub md_bold: Style,
    pub md_italic: Style,
    pub md_code: Style,
    pub md_heading: Style,
}

impl Theme {
    pub fn wp_blue() -> Self {
        Theme {
            kind: ThemeKind::WpBlue,
            base: Style::new().fg(Color::White).bg(Color::Blue),
            status: Style::new().fg(Color::Black).bg(Color::Cyan),
            dim: Style::new().fg(Color::Cyan).bg(Color::Blue),
            block: Style::new().fg(Color::Blue).bg(Color::White),
            highlight: Style::new().fg(Color::Black).bg(Color::Yellow),
            md_marker: Style::new().fg(Color::Cyan).bg(Color::Blue),
            md_bold: Style::new()
                .fg(Color::White)
                .bg(Color::Blue)
                .add_modifier(Modifier::BOLD),
            md_italic: Style::new()
                .fg(Color::White)
                .bg(Color::Blue)
                .add_modifier(Modifier::ITALIC),
            md_code: Style::new().fg(Color::Yellow).bg(Color::Blue),
            md_heading: Style::new()
                .fg(Color::Yellow)
                .bg(Color::Blue)
                .add_modifier(Modifier::BOLD),
        }
    }

    pub fn wordstar() -> Self {
        Theme {
            kind: ThemeKind::WordStar,
            base: Style::new().fg(Color::Gray).bg(Color::Black),
            status: Style::new().fg(Color::Black).bg(Color::Gray),
            dim: Style::new().fg(Color::DarkGray).bg(Color::Black),
            block: Style::new().fg(Color::Black).bg(Color::Gray),
            highlight: Style::new().fg(Color::Black).bg(Color::Yellow),
            md_marker: Style::new().fg(Color::DarkGray).bg(Color::Black),
            md_bold: Style::new()
                .fg(Color::White)
                .bg(Color::Black)
                .add_modifier(Modifier::BOLD),
            md_italic: Style::new()
                .fg(Color::Gray)
                .bg(Color::Black)
                .add_modifier(Modifier::ITALIC),
            md_code: Style::new().fg(Color::Yellow).bg(Color::Black),
            md_heading: Style::new()
                .fg(Color::White)
                .bg(Color::Black)
                .add_modifier(Modifier::BOLD),
        }
    }

    pub fn terminal_default() -> Self {
        Theme {
            kind: ThemeKind::TerminalDefault,
            base: Style::new(),
            status: Style::new().add_modifier(ratatui::style::Modifier::REVERSED),
            dim: Style::new().add_modifier(ratatui::style::Modifier::DIM),
            block: Style::new().add_modifier(ratatui::style::Modifier::REVERSED),
            highlight: Style::new().fg(Color::Black).bg(Color::Yellow),
            md_marker: Style::new().add_modifier(Modifier::DIM),
            md_bold: Style::new().add_modifier(Modifier::BOLD),
            md_italic: Style::new().add_modifier(Modifier::ITALIC),
            md_code: Style::new().fg(Color::Yellow),
            md_heading: Style::new().add_modifier(Modifier::BOLD),
        }
    }

    pub fn next(&self) -> Self {
        match self.kind {
            ThemeKind::WpBlue => Self::wordstar(),
            ThemeKind::WordStar => Self::terminal_default(),
            ThemeKind::TerminalDefault => Self::wp_blue(),
        }
    }
}

impl Default for Theme {
    fn default() -> Self {
        Self::wp_blue()
    }
}