import 'dart:collection'; import 'sheet.dart'; /// Types of changes that can be queued for server synchronization. enum ChangeType { sheetNameChange, composerNameChange, addTagChange, removeTagChange, } /// Represents a single pending change to be synced with the server. /// /// Changes are stored locally when offline and applied once /// the device regains connectivity. class Change { final ChangeType type; final String sheetUuid; final String value; Change({ required this.type, required this.sheetUuid, required this.value, }); /// Serializes this change to a map for storage. Map toMap() => { 'type': type.index, 'sheetUuid': sheetUuid, 'value': value, }; /// Deserializes a change from a stored map. /// /// Note: Adding new [ChangeType] values may cause issues with /// previously stored changes that use index-based serialization. factory Change.fromMap(Map map) { return Change( type: ChangeType.values[map['type']], sheetUuid: map['sheetUuid'], value: map['value'], ); } } /// A queue of pending changes to be synchronized with the server. /// /// Changes are stored in FIFO order (oldest first) and applied /// to sheets in sequence when syncing. class ChangeQueue { final Queue _queue = Queue(); ChangeQueue(); /// Adds a change to the end of the queue. void addChange(Change change) { _queue.addLast(change); } /// Returns the number of pending changes. int get length => _queue.length; /// Whether the queue has any pending changes. bool get isEmpty => _queue.isEmpty; /// Whether the queue has pending changes. bool get isNotEmpty => _queue.isNotEmpty; /// Applies all queued changes to the provided list of sheets. /// /// Each change modifies the corresponding sheet's properties /// based on the change type. void applyToSheets(List sheets) { for (final change in _queue) { final sheet = sheets.firstWhere( (s) => s.uuid == change.sheetUuid, orElse: () => throw StateError( 'Sheet with UUID ${change.sheetUuid} not found', ), ); switch (change.type) { case ChangeType.sheetNameChange: sheet.name = change.value; case ChangeType.composerNameChange: sheet.composerName = change.value; case ChangeType.addTagChange: throw UnimplementedError('Tag support not yet implemented'); case ChangeType.removeTagChange: throw UnimplementedError('Tag support not yet implemented'); } } } }