|  |  |  | import 'dart:async'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import 'package:appinio_swiper/appinio_swiper.dart'; | 
					
						
							|  |  |  | import 'package:easy_localization/easy_localization.dart'; | 
					
						
							|  |  |  | import 'package:flutter/cupertino.dart'; | 
					
						
							|  |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/api/marathon/demo_marathon_repo.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/api/marathon/marathon_api_client.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/app_state/app_state.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/classes/consts.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/classes/utils.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/config/routes.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/marathon/marathon_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/marathon/question_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/marathon/winner_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/models/privilege_list_model.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; | 
					
						
							|  |  |  | import 'package:video_player/video_player.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MarathonProvider extends ChangeNotifier { | 
					
						
							|  |  |  |   //************************************************ VARIABLES **********************************************************
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final AppinioSwiperController swiperController = AppinioSwiperController(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MarathonDetailModel marathonDetailModel = MarathonDetailModel(); | 
					
						
							|  |  |  |   MarathonDetailModel demoMarathonDetailModel = MarathonDetailModel(); | 
					
						
							|  |  |  |   List<CardContent> cardContentList = <CardContent>[]; | 
					
						
							|  |  |  |   QuestionModel currentQuestion = QuestionModel(); | 
					
						
							|  |  |  |   List<QuestionCardStatus> answerStatusesList = <QuestionCardStatus>[]; | 
					
						
							|  |  |  |   QuestionCardStatus questionCardStatus = QuestionCardStatus.question; | 
					
						
							|  |  |  |   List<WinnerModel>? selectedWinners; | 
					
						
							|  |  |  |   int? selectedOptionIndex; | 
					
						
							|  |  |  |   String? selectedOptionId; | 
					
						
							|  |  |  |   int? totalQualifiers; | 
					
						
							|  |  |  |   Locale savedLocale = const Locale("en", "US"); | 
					
						
							|  |  |  |   String? gapTimeImage; | 
					
						
							|  |  |  |   String? gapTimeText; | 
					
						
							|  |  |  |   int? gapTimeType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool iAmWinner = false; | 
					
						
							|  |  |  |   bool isGettingQualifiers = false; | 
					
						
							|  |  |  |   bool isPrivilegedWithMarathon = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _isLoading = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get isLoading => _isLoading; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set isLoading(bool value) { | 
					
						
							|  |  |  |     _isLoading = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _isUpComingMarathon = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get isUpComingMarathon => _isUpComingMarathon; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set isUpComingMarathon(bool value) { | 
					
						
							|  |  |  |     _isUpComingMarathon = value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _itsMarathonTime = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get itsMarathonTime => _itsMarathonTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set itsMarathonTime(bool value) { | 
					
						
							|  |  |  |     _itsMarathonTime = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _canPlayDemo = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get canPlayDemo => _canPlayDemo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set canPlayDemo(bool value) { | 
					
						
							|  |  |  |     _canPlayDemo = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _isButtonEnabled = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get isButtonEnabled => _isButtonEnabled; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set isButtonEnabled(bool value) { | 
					
						
							|  |  |  |     _isButtonEnabled = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _isUserWaiting = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get isUserWaiting => _isUserWaiting; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set isUserWaiting(bool value) { | 
					
						
							|  |  |  |     _isUserWaiting = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool _isMarathonCompleted = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get isMarathonCompleted => _isMarathonCompleted; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set isMarathonCompleted(bool value) { | 
					
						
							|  |  |  |     _isMarathonCompleted = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool isUserOutOfGame = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set updateIsUserOutOfGame(bool value) { | 
					
						
							|  |  |  |     isUserOutOfGame = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int _currentQuestionNumber = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int get currentQuestionNumber => _currentQuestionNumber; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set currentQuestionNumber(int value) { | 
					
						
							|  |  |  |     _currentQuestionNumber = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int _totalMarathoners = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int get totalMarathoners => _totalMarathoners; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set totalMarathoners(int value) { | 
					
						
							|  |  |  |     _totalMarathoners = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //****************SPONSOR VIDEO PLAYER**********
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   late VideoPlayerController videoController; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> initializeVideoPlayer() async { | 
					
						
							|  |  |  |     videoController = VideoPlayerController.network(ApiConsts.marathonBaseUrlServices + marathonDetailModel.sponsors!.first.video!); | 
					
						
							|  |  |  |     await videoController.initialize(); | 
					
						
							|  |  |  |     await videoController.play(); | 
					
						
							|  |  |  |     await videoController.setVolume(1.0); | 
					
						
							|  |  |  |     await videoController.setLooping(false); | 
					
						
							|  |  |  |     totalSponsorVideoSeconds = videoController.value.duration.inSeconds; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void disposeVideoPlayer() { | 
					
						
							|  |  |  |     videoController.dispose(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // 9c47d281-c5b5-4b5d-a90a-08dacb8cbdb6
 | 
					
						
							|  |  |  |   // MarathonI
 | 
					
						
							|  |  |  |   //************************************************ TIMERS **********************************************************
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int sponsorsSecondsCounter = 0; | 
					
						
							|  |  |  |   int totalSponsorVideoSeconds = 0; | 
					
						
							|  |  |  |   Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void startTimerForSponsorVideo() { | 
					
						
							|  |  |  |     const Duration oneSec = Duration(seconds: 1); | 
					
						
							|  |  |  |     timerForSponsorVideo = Timer.periodic( | 
					
						
							|  |  |  |       oneSec, | 
					
						
							|  |  |  |       (Timer timer) async { | 
					
						
							|  |  |  |         sponsorsSecondsCounter++; | 
					
						
							|  |  |  |         if (totalSponsorVideoSeconds == 0) { | 
					
						
							|  |  |  |           timer.cancel(); | 
					
						
							|  |  |  |           notifyListeners(); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           totalSponsorVideoSeconds--; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int totalSecondsToWaitForMarathon = 30; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set updateTotalSecondsToWaitForMarathon(int value) { | 
					
						
							|  |  |  |     totalSecondsToWaitForMarathon = value; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void startTimerToWaitForMarathon() { | 
					
						
							|  |  |  |     const Duration oneSec = Duration(seconds: 1); | 
					
						
							|  |  |  |     timerToWaitForMarathon = Timer.periodic( | 
					
						
							|  |  |  |       oneSec, | 
					
						
							|  |  |  |       (Timer timer) async { | 
					
						
							|  |  |  |         if (totalSecondsToWaitForMarathon == 0) { | 
					
						
							|  |  |  |           timer.cancel(); | 
					
						
							|  |  |  |           if (isUserWaiting) { | 
					
						
							|  |  |  |             MarathonApiClient().joinMarathonAsParticipant().whenComplete(() async { | 
					
						
							|  |  |  |               await callNextQuestionApi(); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             isButtonEnabled = false; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           totalSecondsToWaitForMarathon--; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int totalCurrentQuestionTime = 0; | 
					
						
							|  |  |  |   int currentGapTime = 0; | 
					
						
							|  |  |  |   Timer timerForQuestion = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); | 
					
						
							|  |  |  |   int callCountThreshold = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void startTimerForQuestion() { | 
					
						
							|  |  |  |     const Duration oneSec = Duration(seconds: 1); | 
					
						
							|  |  |  |     timerForQuestion = Timer.periodic( | 
					
						
							|  |  |  |       oneSec, | 
					
						
							|  |  |  |       (Timer timer) async { | 
					
						
							|  |  |  |         // This 1 is just to show the color of answer tile for 1 and then update card status
 | 
					
						
							|  |  |  |         if (totalCurrentQuestionTime - currentGapTime == 1) { | 
					
						
							|  |  |  |           if (callCountThreshold == 0) { | 
					
						
							|  |  |  |             getCorrectAnswerAndUpdateAnswerColor(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (totalCurrentQuestionTime - currentGapTime == -2) { | 
					
						
							|  |  |  |           if (callCountThreshold == 0) { | 
					
						
							|  |  |  |             updateCardStatusToAnswer(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           // scheduleMicrotask(() async {
 | 
					
						
							|  |  |  |           //   if (AppState().getIsDemoMarathon || isUserOutOfGame) {
 | 
					
						
							|  |  |  |           //     await callNextQuestionApi();
 | 
					
						
							|  |  |  |           //   } else {
 | 
					
						
							|  |  |  |           //     await callSubmitOptionApi().then((bool value) async {
 | 
					
						
							|  |  |  |           //       updateIsUserOutOfGame = !value;
 | 
					
						
							|  |  |  |           //       await callNextQuestionApi();
 | 
					
						
							|  |  |  |           //     });
 | 
					
						
							|  |  |  |           //   }
 | 
					
						
							|  |  |  |           // });
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (currentQuestionNumber == (AppState().getIsDemoMarathon ? demoMarathonDetailModel.totalQuestions! : marathonDetailModel.totalQuestions!)) { | 
					
						
							|  |  |  |             isGettingQualifiers = true; | 
					
						
							|  |  |  |             updateQuestionCardStatus(QuestionCardStatus.findingWinner); | 
					
						
							|  |  |  |             timer.cancel(); | 
					
						
							|  |  |  |             cancelTimer(); | 
					
						
							|  |  |  |             notifyListeners(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           totalCurrentQuestionTime--; | 
					
						
							|  |  |  |           callCountThreshold = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (totalCurrentQuestionTime == 0) { | 
					
						
							|  |  |  |           gapTimeImage = currentQuestion.gapImage; | 
					
						
							|  |  |  |           gapTimeText = currentQuestion.gapText; | 
					
						
							|  |  |  |           gapTimeType = currentQuestion.gapType; | 
					
						
							|  |  |  |           updateCardData(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           if (totalCurrentQuestionTime - currentGapTime != -2) { | 
					
						
							|  |  |  |             totalCurrentQuestionTime--; | 
					
						
							|  |  |  |             callCountThreshold = 0; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int totalSecondsToWaitForWinner = 30; | 
					
						
							|  |  |  |   Timer timerForWinnerSelection = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void startTimerForWinnerSelection() { | 
					
						
							|  |  |  |     const Duration oneSec = Duration(seconds: 1); | 
					
						
							|  |  |  |     timerForWinnerSelection = Timer.periodic( | 
					
						
							|  |  |  |       oneSec, | 
					
						
							|  |  |  |       (Timer timer) async { | 
					
						
							|  |  |  |         if (totalSecondsToWaitForWinner == 1) { | 
					
						
							|  |  |  |           await callGetSelectedWinnersApi().whenComplete(() => updateQuestionCardStatus(QuestionCardStatus.winnerFound)); | 
					
						
							|  |  |  |           timer.cancel(); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } else if (totalSecondsToWaitForWinner == 15) { | 
					
						
							|  |  |  |           totalSecondsToWaitForWinner--; | 
					
						
							|  |  |  |           await callGetQualifiersApi(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           totalSecondsToWaitForWinner--; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //************************************************ FUNCTIONS **********************************************************
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateLanguageAsPerMarathon(BuildContext context, MarathonDetailModel detailModel) { | 
					
						
							|  |  |  |     savedLocale = context.locale; | 
					
						
							|  |  |  |     if (detailModel.selectedLanguage == 1) { | 
					
						
							|  |  |  |       context.setLocale(const Locale("en", "US")); | 
					
						
							|  |  |  |     } else if (detailModel.selectedLanguage == 2) { | 
					
						
							|  |  |  |       context.setLocale(const Locale("ar", "SA")); | 
					
						
							|  |  |  |     } else if (detailModel.selectedLanguage == 3) { | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       context.setLocale(const Locale("en", "US")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<bool> callSubmitOptionApi() async { | 
					
						
							|  |  |  |     return await MarathonApiClient().submitSelectedOption(marathonId: marathonDetailModel.id!, questionId: currentQuestion.id, selectedAnswerId: selectedOptionId); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> callGetQualifiersApi() async { | 
					
						
							|  |  |  |     if (AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |       totalQualifiers = isUserOutOfGame ? 0 : 1; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       totalQualifiers = await MarathonApiClient().getQualifiers(marathonId: marathonDetailModel.id!); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     isGettingQualifiers = false; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> callGetSelectedWinnersApi() async { | 
					
						
							|  |  |  |     if (AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     selectedWinners = await MarathonApiClient().getSelectedWinner(marathonId: marathonDetailModel.id!); | 
					
						
							|  |  |  |     if (selectedWinners != null) { | 
					
						
							|  |  |  |       selectedWinners!.removeWhere((WinnerModel element) { | 
					
						
							|  |  |  |         if (element.employeeId == AppState().memberInformationList!.eMPLOYEENUMBER) { | 
					
						
							|  |  |  |           iAmWinner = true; | 
					
						
							|  |  |  |           return true; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> callNextQuestionApi() async { | 
					
						
							|  |  |  |     if (currentQuestionNumber < (AppState().getIsDemoMarathon ? demoMarathonDetailModel.totalQuestions! : marathonDetailModel.totalQuestions!)) { | 
					
						
							|  |  |  |       if (currentQuestionNumber == 0) { | 
					
						
							|  |  |  |         if (!AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |           Utils.showLoading(AppRoutes.navigatorKey.currentContext!); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         currentQuestion = AppState().getIsDemoMarathon | 
					
						
							|  |  |  |             ? await DemoMarathonRepo().getDemoNextQuestion(currentQuestionNumber: currentQuestionNumber) | 
					
						
							|  |  |  |             : (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!)); | 
					
						
							|  |  |  |         gapTimeImage = currentQuestion.gapImage; | 
					
						
							|  |  |  |         gapTimeText = currentQuestion.gapText; | 
					
						
							|  |  |  |         gapTimeType = currentQuestion.gapType; | 
					
						
							|  |  |  |         if (Utils.isLoading) { | 
					
						
							|  |  |  |           Utils.hideLoading(AppRoutes.navigatorKey.currentContext!); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         startTimerForQuestion(); | 
					
						
							|  |  |  |         updateCardData(); | 
					
						
							|  |  |  |         Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         currentQuestion = AppState().getIsDemoMarathon | 
					
						
							|  |  |  |             ? await DemoMarathonRepo().getDemoNextQuestion(currentQuestionNumber: currentQuestionNumber) | 
					
						
							|  |  |  |             : (await MarathonApiClient().getNextQuestion(questionId: currentQuestion.id, marathonId: marathonDetailModel.id!)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateCardData() { | 
					
						
							|  |  |  |     if (currentQuestionNumber > 0) { | 
					
						
							|  |  |  |       swiperController.swipeLeft(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     selectedOptionIndex = null; | 
					
						
							|  |  |  |     currentQuestionNumber++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cardContentList.add(const CardContent()); | 
					
						
							|  |  |  |     totalCurrentQuestionTime = currentQuestion.questionTime! + currentQuestion.nextQuestGap!; | 
					
						
							|  |  |  |     currentGapTime = currentQuestion.nextQuestGap!; | 
					
						
							|  |  |  |     totalMarathoners = currentQuestion.remainingParticipantCount!; | 
					
						
							|  |  |  |     questionCardStatus = QuestionCardStatus.question; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void populateQuestionStatusesList() { | 
					
						
							|  |  |  |     answerStatusesList.clear(); | 
					
						
							|  |  |  |     if (demoMarathonDetailModel.totalQuestions != null) { | 
					
						
							|  |  |  |       for (int i = 0; i < demoMarathonDetailModel.totalQuestions!; i++) { | 
					
						
							|  |  |  |         answerStatusesList.add(QuestionCardStatus.question); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (isUpComingMarathon) { | 
					
						
							|  |  |  |       if (marathonDetailModel.totalQuestions != null) { | 
					
						
							|  |  |  |         for (int i = 0; i < marathonDetailModel.totalQuestions!; i++) { | 
					
						
							|  |  |  |           answerStatusesList.add(QuestionCardStatus.question); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateAnswerStatusesList(QuestionCardStatus status) { | 
					
						
							|  |  |  |     answerStatusesList[currentQuestionNumber - 1] = status; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void addItemToList(CardContent value) { | 
					
						
							|  |  |  |     cardContentList.add(value); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateCurrentQuestionOptionStatus(QuestionsOptionStatus status, int index) { | 
					
						
							|  |  |  |     for (int i = 0; i < currentQuestion.questionOptions!.length; i++) { | 
					
						
							|  |  |  |       currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     currentQuestion.questionOptions![index].optionStatus = status; | 
					
						
							|  |  |  |     selectedOptionId = currentQuestion.questionOptions![index].id; | 
					
						
							|  |  |  |     selectedOptionIndex = index; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateQuestionCardStatus(QuestionCardStatus status) { | 
					
						
							|  |  |  |     if (status == QuestionCardStatus.wrongAnswer || status == QuestionCardStatus.skippedAnswer) { | 
					
						
							|  |  |  |       if (AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |         updateIsUserOutOfGame = true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     questionCardStatus = status; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void getCorrectAnswerAndUpdateAnswerColor() { | 
					
						
							|  |  |  |     callCountThreshold = 1; | 
					
						
							|  |  |  |     if (selectedOptionIndex != null) { | 
					
						
							|  |  |  |       scheduleMicrotask(() async { | 
					
						
							|  |  |  |         if (AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |           if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { | 
					
						
							|  |  |  |             updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!); | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           await callSubmitOptionApi().then((bool value) async { | 
					
						
							|  |  |  |             updateIsUserOutOfGame = !value; | 
					
						
							|  |  |  |             if (value) { | 
					
						
							|  |  |  |               updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       if (!AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |         scheduleMicrotask(() async { | 
					
						
							|  |  |  |           await callSubmitOptionApi().then((bool value) async { | 
					
						
							|  |  |  |             updateIsUserOutOfGame = !value; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void updateCardStatusToAnswer() { | 
					
						
							|  |  |  |     if (currentQuestionNumber == 0) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     callCountThreshold = 1; | 
					
						
							|  |  |  |     scheduleMicrotask(() async { | 
					
						
							|  |  |  |       await callNextQuestionApi(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (selectedOptionIndex == null) { | 
					
						
							|  |  |  |       updateQuestionCardStatus(QuestionCardStatus.skippedAnswer); | 
					
						
							|  |  |  |       updateAnswerStatusesList(QuestionCardStatus.skippedAnswer); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (AppState().getIsDemoMarathon) { | 
					
						
							|  |  |  |       if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { | 
					
						
							|  |  |  |         updateQuestionCardStatus(QuestionCardStatus.correctAnswer); | 
					
						
							|  |  |  |         updateAnswerStatusesList(QuestionCardStatus.correctAnswer); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         updateQuestionCardStatus(QuestionCardStatus.wrongAnswer); | 
					
						
							|  |  |  |         updateAnswerStatusesList(QuestionCardStatus.wrongAnswer); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!isUserOutOfGame) { | 
					
						
							|  |  |  |       updateQuestionCardStatus(QuestionCardStatus.correctAnswer); | 
					
						
							|  |  |  |       updateAnswerStatusesList(QuestionCardStatus.correctAnswer); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     updateQuestionCardStatus(QuestionCardStatus.wrongAnswer); | 
					
						
							|  |  |  |     updateAnswerStatusesList(QuestionCardStatus.wrongAnswer); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void resetValues() async { | 
					
						
							|  |  |  |     _currentQuestionNumber = 0; | 
					
						
							|  |  |  |     iAmWinner = false; | 
					
						
							|  |  |  |     cardContentList.clear(); | 
					
						
							|  |  |  |     itsMarathonTime = false; | 
					
						
							|  |  |  |     timerForWinnerSelection.cancel(); | 
					
						
							|  |  |  |     timerForSponsorVideo.cancel(); | 
					
						
							|  |  |  |     timerToWaitForMarathon.cancel(); | 
					
						
							|  |  |  |     timerForQuestion.cancel(); | 
					
						
							|  |  |  |     _isMarathonCompleted = false; | 
					
						
							|  |  |  |     isUserOutOfGame = false; | 
					
						
							|  |  |  |     isButtonEnabled = false; | 
					
						
							|  |  |  |     isUserWaiting = false; | 
					
						
							|  |  |  |     canPlayDemo = true; | 
					
						
							|  |  |  |     totalCurrentQuestionTime = 0; | 
					
						
							|  |  |  |     sponsorsSecondsCounter = 0; | 
					
						
							|  |  |  |     totalSponsorVideoSeconds = 0; | 
					
						
							|  |  |  |     totalSecondsToWaitForWinner = 30; | 
					
						
							|  |  |  |     totalSecondsToWaitForMarathon = 30; | 
					
						
							|  |  |  |     AppState().setIsDemoMarathon = false; | 
					
						
							|  |  |  |     currentGapTime = 0; | 
					
						
							|  |  |  |     currentQuestion = QuestionModel(); | 
					
						
							|  |  |  |     if (answerStatusesList.isNotEmpty) { | 
					
						
							|  |  |  |       for (int i = 0; i < answerStatusesList.length; i++) { | 
					
						
							|  |  |  |         answerStatusesList[i] = QuestionCardStatus.question; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     AppRoutes.navigatorKey.currentContext!.setLocale(savedLocale); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void cancelTimer() { | 
					
						
							|  |  |  |     timerForQuestion.cancel(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool checkIfPrivilegedForMarathon() { | 
					
						
							|  |  |  |     for (PrivilegeListModel element in AppState().privilegeListModel!) { | 
					
						
							|  |  |  |       if (element.serviceName == "Marathon") { | 
					
						
							|  |  |  |         if (element.previlege != null) { | 
					
						
							|  |  |  |           return element.previlege!; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> getMarathonDetailsFromApi() async { | 
					
						
							|  |  |  |     isLoading = true; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |     isPrivilegedWithMarathon = checkIfPrivilegedForMarathon(); | 
					
						
							|  |  |  |     demoMarathonDetailModel = await DemoMarathonRepo().getDemoMarathonDetails(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isPrivilegedWithMarathon) { | 
					
						
							|  |  |  |       marathonDetailModel = await MarathonApiClient().getMarathonDetails(); | 
					
						
							|  |  |  |       updateTotalSecondsToWaitForMarathon = marathonDetailModel.marathonBufferTime ?? 30; | 
					
						
							|  |  |  |       if (marathonDetailModel.id == null) { | 
					
						
							|  |  |  |         isUpComingMarathon = false; | 
					
						
							|  |  |  |         isLoading = false; | 
					
						
							|  |  |  |         populateQuestionStatusesList(); | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       isUpComingMarathon = true; | 
					
						
							|  |  |  |       if (DateTime.parse(marathonDetailModel.startTime!).isAfter(DateTime.now())) { | 
					
						
							|  |  |  |         itsMarathonTime = false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       populateQuestionStatusesList(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     isLoading = false; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> onJoinMarathonPressed(BuildContext context) async { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       isUserWaiting = true; | 
					
						
							|  |  |  |       Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       Utils.confirmDialog(context, e.toString()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<void> onJoinDemoMarathonPressed(BuildContext context) async { | 
					
						
							|  |  |  |     AppState().setIsDemoMarathon = true; | 
					
						
							|  |  |  |     await callNextQuestionApi(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |