use std::sync::Arc;
use parking_lot::Mutex;
use frontend::commands::{block_commands, list_commands};
use frontend::common::types::EntityId;
use crate::inner::TextDocumentInner;
use crate::text_block::{TextBlock, format_list_marker};
use crate::{ListFormat, ListStyle};
#[derive(Clone)]
pub struct TextList {
pub(crate) doc: Arc<Mutex<TextDocumentInner>>,
pub(crate) list_id: usize,
}
impl TextList {
pub fn id(&self) -> usize {
self.list_id
}
pub fn style(&self) -> ListStyle {
let inner = self.doc.lock();
list_commands::get_list(&inner.ctx, &(self.list_id as u64))
.ok()
.flatten()
.map(|l| l.style)
.unwrap_or(ListStyle::Disc)
}
pub fn indent(&self) -> u8 {
let inner = self.doc.lock();
list_commands::get_list(&inner.ctx, &(self.list_id as u64))
.ok()
.flatten()
.map(|l| l.indent as u8)
.unwrap_or(0)
}
pub fn prefix(&self) -> String {
let inner = self.doc.lock();
list_commands::get_list(&inner.ctx, &(self.list_id as u64))
.ok()
.flatten()
.map(|l| l.prefix)
.unwrap_or_default()
}
pub fn suffix(&self) -> String {
let inner = self.doc.lock();
list_commands::get_list(&inner.ctx, &(self.list_id as u64))
.ok()
.flatten()
.map(|l| l.suffix)
.unwrap_or_default()
}
pub fn count(&self) -> usize {
let inner = self.doc.lock();
let list_entity_id = self.list_id as EntityId;
let all_blocks = block_commands::get_all_block(&inner.ctx).unwrap_or_default();
all_blocks
.iter()
.filter(|b| b.list == Some(list_entity_id))
.count()
}
pub fn item(&self, index: usize) -> Option<TextBlock> {
let inner = self.doc.lock();
let list_entity_id = self.list_id as EntityId;
let all_blocks = block_commands::get_all_block(&inner.ctx).unwrap_or_default();
let mut list_blocks: Vec<_> = all_blocks
.iter()
.filter(|b| b.list == Some(list_entity_id))
.collect();
list_blocks.sort_by_key(|b| b.document_position);
list_blocks.get(index).map(|b| TextBlock {
doc: Arc::clone(&self.doc),
block_id: b.id as usize,
})
}
pub fn format(&self) -> ListFormat {
let inner = self.doc.lock();
list_commands::get_list(&inner.ctx, &(self.list_id as u64))
.ok()
.flatten()
.map(|l| ListFormat {
style: Some(l.style),
indent: Some(l.indent as u8),
prefix: Some(l.prefix),
suffix: Some(l.suffix),
})
.unwrap_or_default()
}
pub fn item_marker(&self, index: usize) -> String {
let inner = self.doc.lock();
match list_commands::get_list(&inner.ctx, &(self.list_id as u64))
.ok()
.flatten()
{
Some(list_dto) => format_list_marker(&list_dto, index),
None => String::new(),
}
}
}