use zellij_utils::pane_size::Viewport;
use crate::output::CharacterChunk;
use crate::panes::terminal_character::{TerminalCharacter, EMPTY_TERMINAL_CHARACTER, RESET_STYLES};
use crate::tab::Pane;
use ansi_term::Colour::{Fixed, RGB};
use std::collections::HashMap;
use zellij_utils::errors::prelude::*;
use zellij_utils::{data::PaletteColor, shared::colors};
use std::fmt::{Display, Error, Formatter};
pub mod boundary_type {
pub const TOP_RIGHT: &str = "┐";
pub const TOP_RIGHT_ROUND: &str = "╮";
pub const VERTICAL: &str = "│";
pub const HORIZONTAL: &str = "─";
pub const TOP_LEFT: &str = "┌";
pub const TOP_LEFT_ROUND: &str = "╭";
pub const BOTTOM_RIGHT: &str = "┘";
pub const BOTTOM_RIGHT_ROUND: &str = "╯";
pub const BOTTOM_LEFT: &str = "└";
pub const BOTTOM_LEFT_ROUND: &str = "╰";
pub const VERTICAL_LEFT: &str = "┤";
pub const VERTICAL_RIGHT: &str = "├";
pub const HORIZONTAL_DOWN: &str = "┬";
pub const HORIZONTAL_UP: &str = "┴";
pub const CROSS: &str = "┼";
}
pub type BoundaryType = &'static str; // easy way to refer to boundary_type above
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BoundarySymbol {
boundary_type: BoundaryType,
invisible: bool,
color: Option<PaletteColor>,
}
impl BoundarySymbol {
pub fn new(boundary_type: BoundaryType) -> Self {
BoundarySymbol {
boundary_type,
invisible: false,
color: Some(PaletteColor::EightBit(colors::GRAY)),
}
}
pub fn color(&mut self, color: Option<PaletteColor>) -> Self {
self.color = color;
*self
}
pub fn as_terminal_character(&self) -> Result<TerminalCharacter> {
let tc = if self.invisible {
EMPTY_TERMINAL_CHARACTER
} else {
let character = self
.boundary_type
.chars()
.next()
.context("no boundary symbols defined")
.with_context(|| {
format!(
"failed to convert boundary symbol {} into terminal character",
self.boundary_type
)
})?;
TerminalCharacter::new_singlewidth_styled(
character,
RESET_STYLES
.foreground(self.color.map(|palette_color| palette_color.into()))
.into(),
)
};
Ok(tc)
}
}
impl Display for BoundarySymbol {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match self.invisible {
true => write!(f, " "),
false => match self.color {
Some(color) => match color {
PaletteColor::Rgb((r, g, b)) => {
write!(f, "{}", RGB(r, g, b).paint(self.boundary_type))
},
PaletteColor::EightBit(color) => {
write!(f, "{}", Fixed(color).paint(self.boundary_type))
},
},
None => write!(f, "{}", self.boundary_type),
},
}
}
}
fn combine_symbols(
current_symbol: BoundarySymbol,
next_symbol: BoundarySymbol,
) -> Option<BoundarySymbol> {
use boundary_type::*;
let invisible = current_symbol.invisible || next_symbol.invisible;
let color = current_symbol.color.or(next_symbol.col