import 'package:flutter_bloc/flutter_bloc.dart'; /// Explizite Zustandsfolge Plan -> Connect -> Upload -> Fly /// (Architektur-Doku 2.2). enum AppMode { plan, connect, upload, fly } class AppModeState { const AppModeState({ this.mode = AppMode.plan, this.missionUploaded = false, this.missionVerified = false, this.droneArmed = false, }); final AppMode mode; final bool missionUploaded; final bool missionVerified; final bool droneArmed; /// Ready-to-Fly-Gate (Doku 2.2 / 4.5): Upload + verifiziert + disarmed. /// Muss technisch erzwungen werden, nicht nur als UI-Konvention gelten. bool get readyToFly => missionUploaded && missionVerified && !droneArmed; AppModeState copyWith({ AppMode? mode, bool? missionUploaded, bool? missionVerified, bool? droneArmed, }) { return AppModeState( mode: mode ?? this.mode, missionUploaded: missionUploaded ?? this.missionUploaded, missionVerified: missionVerified ?? this.missionVerified, droneArmed: droneArmed ?? this.droneArmed, ); } } class AppModeCubit extends Cubit { AppModeCubit() : super(const AppModeState()); void toConnect() => emit(state.copyWith(mode: AppMode.connect)); void toUpload() => emit(state.copyWith(mode: AppMode.upload)); void missionUploadConfirmed() => emit(state.copyWith(missionUploaded: true)); void missionVerifiedConfirmed() => emit(state.copyWith(missionVerified: true)); void droneArmedChanged(bool armed) => emit(state.copyWith(droneArmed: armed)); /// Wirft, wenn das Ready-to-Fly-Gate nicht erfuellt ist (Doku 4.5). void toFly() { if (!state.readyToFly) { throw StateError('Ready-to-Fly-Gate nicht erfuellt.'); } emit(state.copyWith(mode: AppMode.fly)); } /// Verlassen des Fly-Modus setzt den kompletten Handover-Status zurueck. void toPlan() => emit(const AppModeState()); }