Skip to main content

ass_editor/core/fluent/
event_ops.rs

1//! Fluent API builder for event operations.
2
3use super::event_deleter::EventDeleter;
4use super::event_merge_timing::{EventMerger, EventTimer};
5use super::event_toggle_effect::{EventEffector, EventToggler};
6use super::{EventAccessor, EventInfo, EventQuery, EventSortCriteria, OwnedEvent};
7use crate::commands::{
8    BatchDeleteEventsCommand, DeleteEventCommand, EditorCommand, SplitEventCommand,
9};
10use crate::core::{EditorDocument, Position, Range, Result};
11use ass_core::parser::ast::{Event, EventType, Section};
12
13#[cfg(not(feature = "std"))]
14use alloc::{string::ToString, vec::Vec};
15
16/// Fluent API builder for event operations
17pub struct EventOps<'a> {
18    document: &'a mut EditorDocument,
19}
20
21impl<'a> EventOps<'a> {
22    /// Create a new event operations builder
23    pub(crate) fn new(document: &'a mut EditorDocument) -> Self {
24        Self { document }
25    }
26
27    /// Split an event at a specific time
28    pub fn split(self, event_index: usize, split_time: &str) -> Result<&'a mut EditorDocument> {
29        let command = SplitEventCommand::new(event_index, split_time.to_string());
30        command.execute(self.document)?;
31        Ok(self.document)
32    }
33
34    /// Merge two consecutive events
35    pub fn merge(self, first_index: usize, second_index: usize) -> EventMerger<'a> {
36        EventMerger::new(self.document, first_index, second_index)
37    }
38
39    /// Adjust timing for events
40    pub fn timing(self) -> EventTimer<'a> {
41        EventTimer::new(self.document)
42    }
43
44    /// Toggle event types between Dialogue and Comment
45    pub fn toggle_type(self) -> EventToggler<'a> {
46        EventToggler::new(self.document)
47    }
48
49    /// Modify event effects
50    pub fn effects(self) -> EventEffector<'a> {
51        EventEffector::new(self.document)
52    }
53
54    // ============================================================================
55    // Direct Event Access Methods (NEW!)
56    // ============================================================================
57
58    /// Get event information by index
59    pub fn get(self, index: usize) -> Result<Option<EventInfo>> {
60        self.document
61            .parse_script_with(|script| -> Result<Option<EventInfo>> {
62                let mut current_index = 0;
63
64                for section in script.sections() {
65                    if let Section::Events(events) = section {
66                        for event in events {
67                            if current_index == index {
68                                let event_info = EventInfo {
69                                    index,
70                                    event: OwnedEvent::from(event),
71                                    line_number: self.find_line_number_for_event(event)?,
72                                    range: self.find_range_for_event(event)?,
73                                };
74                                return Ok(Some(event_info));
75                            }
76                            current_index += 1;
77                        }
78                    }
79                }
80
81                Ok(None)
82            })?
83    }
84
85    /// Get event by index with fluent access to properties
86    pub fn event(self, index: usize) -> EventAccessor<'a> {
87        EventAccessor::new(self.document, index)
88    }
89
90    /// Get all events as a vector
91    pub fn all(self) -> Result<Vec<EventInfo>> {
92        EventQuery::new(self.document).execute()
93    }
94
95    /// Get event count
96    pub fn count(self) -> Result<usize> {
97        self.document.parse_script_with(|script| {
98            let mut count = 0;
99
100            for section in script.sections() {
101                if let Section::Events(events) = section {
102                    count += events.len();
103                }
104            }
105
106            count
107        })
108    }
109
110    // ============================================================================
111    // Query and Filtering Methods (NEW!)
112    // ============================================================================
113
114    /// Start a query chain for filtering and sorting events
115    pub fn query(self) -> EventQuery<'a> {
116        EventQuery::new(self.document)
117    }
118
119    /// Shorthand for common filters
120    pub fn dialogues(self) -> EventQuery<'a> {
121        EventQuery::new(self.document).filter_by_type(EventType::Dialogue)
122    }
123
124    pub fn comments(self) -> EventQuery<'a> {
125        EventQuery::new(self.document).filter_by_type(EventType::Comment)
126    }
127
128    pub fn in_time_range(self, start_cs: u32, end_cs: u32) -> EventQuery<'a> {
129        EventQuery::new(self.document).filter_by_time_range(start_cs, end_cs)
130    }
131
132    pub fn with_style(self, pattern: &str) -> EventQuery<'a> {
133        EventQuery::new(self.document).filter_by_style(pattern)
134    }
135
136    /// Find events by text pattern
137    pub fn containing(self, text: &str) -> EventQuery<'a> {
138        EventQuery::new(self.document).filter_by_text(text)
139    }
140
141    /// Get events in order they appear in document
142    pub fn in_order(self) -> EventQuery<'a> {
143        EventQuery::new(self.document).sort(EventSortCriteria::Index)
144    }
145
146    /// Get events sorted by time
147    pub fn by_time(self) -> EventQuery<'a> {
148        EventQuery::new(self.document).sort_by_time()
149    }
150
151    /// Delete a single event by index
152    pub fn delete(self, index: usize) -> Result<&'a mut EditorDocument> {
153        let command = DeleteEventCommand::new(index);
154        command.execute(self.document)?;
155        Ok(self.document)
156    }
157
158    /// Delete multiple events by indices
159    pub fn delete_multiple(self, indices: Vec<usize>) -> Result<&'a mut EditorDocument> {
160        let command = BatchDeleteEventsCommand::new(indices);
161        command.execute(self.document)?;
162        Ok(self.document)
163    }
164
165    /// Delete all events matching a query
166    pub fn delete_query(self) -> EventDeleter<'a> {
167        EventDeleter::new(self.document)
168    }
169
170    // ============================================================================
171    // Helper Methods
172    // ============================================================================
173
174    fn find_line_number_for_event(&self, _event: &Event) -> Result<usize> {
175        // For now, return a placeholder. This would need to be implemented
176        // by tracking line numbers during parsing or using rope byte-to-line conversion
177        Ok(1)
178    }
179
180    fn find_range_for_event(&self, _event: &Event) -> Result<Range> {
181        // For now, return a placeholder range. This would need to be implemented
182        // by using the event's span information from the parser
183        Ok(Range::new(Position::new(0), Position::new(0)))
184    }
185}