1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use crossterm::{
    cursor, execute,
    style::Print,
    terminal::{Clear, ClearType},
};
use std::io::{stdout, Write};
use textwrap::fill;

pub struct InfoBox {
    pub title: String,
    pub message: String,
    pub width: usize,
}

impl InfoBox {
    pub fn new(title: String, message: String, width: usize) -> Self {
        Self {
            title,
            message,
            width,
        }
    }

    pub fn render(&self) -> Result<(), Box<dyn std::error::Error>> {
        let mut stdout = stdout();
        let total_width = self.width + 8;

        execute!(stdout, cursor::MoveToColumn(0))?;
        execute!(stdout, Clear(ClearType::UntilNewLine))?;
        execute!(
            stdout,
            Print(format!(
                "{: <width$}",
                self.title,
                width = total_width as usize
            ))
        )?;
        execute!(stdout, Print("\n"))?;
        execute!(stdout, Print("┌"))?;
        for _ in 0..self.width {
            execute!(stdout, Print("─"))?;
        }
        execute!(stdout, Print("┐\n"))?;

        let wrapped_message = fill(&self.message, self.width);
        for line in wrapped_message.lines() {
            execute!(stdout, Print("│"))?; // Moved this line to the start of the loop
            execute!(
                stdout,
                Print(format!("{: <width$}", line, width = self.width as usize))
            )?;
            execute!(stdout, Print("│\n"))?;
        }

        execute!(stdout, Print("└"))?;
        for _ in 0..self.width {
            execute!(stdout, Print("─"))?;
        }
        execute!(stdout, Print("┘\n"))?;
        stdout.flush()?;

        Ok(())
    }
}