import 'dart:async'; import 'package:aitrainer_app/repository/mautic_repository.dart'; import 'package:intl/intl.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/fitness_state.dart'; import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/track.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; import 'package:stop_watch_timer/stop_watch_timer.dart'; part 'exercise_new_event.dart'; part 'exercise_new_state.dart'; class ExerciseNewBloc extends Bloc with Logging { final ExerciseRepository exerciseRepository; final CustomerRepository customerRepository; final MenuBloc menuBloc; late AnimationController bmiAnimationController; double quantity = -1; double unitQuantity = -1; double bmi = 0; double bmr = 0; double goalBMI = 0; double goalWeight = 0; double goalMilestoneBMI = 0; double goalMilestoneWeight = 0; double bmiAngle = 0; double bmiTop = 0; double bmiLeft = 0; double? weight; double? height; double bmrEnergy = 0; int? birthYear; String? fitnessLevel; bool changedWeight = false; bool changedSizes = false; final double baseWidth = 312; final double baseHeight = 675.2; double mediaWidth = 0; double mediaHeight = 0; String exerciseTask = ""; final StopWatchTimer stopWatchTimer = StopWatchTimer( isLapHours: false, ); late int timerValue; @override ExerciseNewBloc( {required this.exerciseRepository, required this.menuBloc, required this.customerRepository, required ExerciseType exerciseType}) : super(ExerciseNewInitial()) { exerciseRepository.exerciseType = exerciseType; exerciseRepository.setUnit(exerciseType.unit); exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setQuantity(quantity); exerciseRepository.exercise!.exercisePlanDetailId = 0; exerciseRepository.start = DateTime.now(); if (Cache().userLoggedIn != null) { customerRepository.customer = Cache().userLoggedIn!; weight = customerRepository.customer!.getProperty("Weight"); height = customerRepository.customer!.getProperty("Height"); birthYear = customerRepository.customer!.birthYear!; fitnessLevel = customerRepository.customer!.fitnessLevel!; } if (exerciseType.unit == "second") { stopWatchTimer.rawTime.listen((value) => {timerValue = value, this.setQuantity((value / 1000).toDouble())}); } } void setQuantity(double quantity) { this.quantity = quantity; exerciseRepository.setQuantity(quantity); } @override Stream mapEventToState(ExerciseNewEvent event) async* { try { if (event is ExerciseNewLoad) { yield ExerciseNewLoading(); yield ExerciseNewReady(); } else if (event is ExerciseNewQuantityChange) { yield ExerciseNewLoading(); log("Event quantity " + event.quantity.toStringAsFixed(0)); this.setQuantity(event.quantity); yield ExerciseNewReady(); } else if (event is ExerciseNewQuantityUnitChange) { yield ExerciseNewLoading(); log("Event quantityUnit " + event.quantity.toStringAsFixed(0)); exerciseRepository.setUnitQuantity(event.quantity); unitQuantity = event.quantity; yield ExerciseNewReady(); } else if (event is ExerciseNewWeightChange) { yield ExerciseNewLoading(); customerRepository.setWeight(event.value); changedWeight = true; weight = event.value; getBMI(); getGoalBMI(); getBMR(); yield ExerciseNewReady(); } else if (event is ExerciseNewFitnessLevelChange) { yield ExerciseNewLoading(); customerRepository.setFitnessLevel(event.value); fitnessLevel = event.value; changedWeight = true; getBMR(); yield ExerciseNewReady(); } else if (event is ExerciseNewBirthyearChange) { yield ExerciseNewLoading(); changedWeight = true; customerRepository.setBirthYear(event.value.toInt()); birthYear = event.value; getBMR(); yield ExerciseNewReady(); } else if (event is ExerciseNewHeightChange) { yield ExerciseNewLoading(); customerRepository.setHeight(event.value.toInt()); changedWeight = true; height = event.value; getBMI(); getGoalBMI(); getBMR(); yield ExerciseNewReady(); } else if (event is ExerciseNewSaveWeight) { yield ExerciseNewLoading(); customerRepository.saveCustomer(); changedWeight = false; this.changedSizes = false; Cache().initBadges(); Track().track(TrackingEvent.sizes); yield ExerciseNewReady(); } else if (event is ExerciseNewSizeChange) { yield ExerciseNewLoading(); this.changedSizes = true; this.customerRepository.updateSizes(event.propertyName, event.value); customerRepository.setCustomerProperty(event.propertyName, event.value); yield ExerciseNewReady(); } else if (event is ExerciseNewSubmit) { yield ExerciseNewLoading(); if (quantity == -1 || unitQuantity == -1) { yield ExerciseNewReady(); throw Exception("Please type in a real number"); } exerciseRepository.end = DateTime.now(); await exerciseRepository.addExercise(); MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository); await mauticRepository.sendMauticExercise(); // exerciseRepository.initExercise(); menuBloc.add(MenuTreeDown(parent: 0)); Cache().initBadges(); Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType!.name); yield ExerciseNewSaved(); } else if (event is ExerciseNewSubmitNoRegistration) { yield ExerciseNewLoading(); exerciseRepository.addExerciseNoRegistration(); menuBloc.add(MenuTreeDown(parent: 0)); Track().track(TrackingEvent.exercise_new_no_registration, eventValue: exerciseRepository.exerciseType!.name); yield ExerciseNewSaved(); } else if (event is ExerciseNewBMIAnimate) { yield ExerciseNewLoading(); yield ExerciseNewReady(); } else if (event is ExerciseNewAddError) { yield ExerciseNewLoading(); yield ExerciseNewError(message: event.message); } } on Exception catch (e) { yield ExerciseNewError(message: e.toString()); } } double getBMI() { if (weight == null || height == null || height == 0 || weight == 0) { this.bmi = 0; return 0; } this.bmi = weight! / (height! * height! / 10000); this.getGoalBMI(); return this.bmi; } double getBMR() { var date = DateTime.now(); if (weight == null || height == null || height == 0 || weight == 0) { this.bmi = 0; return 0; } int year = int.parse(DateFormat(DateFormat.YEAR).format(date)); if (customerRepository.customer!.sex == "m") { //66.47 + ( 13.75 × tömeg kg-ban ) + ( 5.003 × magasság cm-ben ) − ( 6.755 × életkor évben kifejezve ) bmr = 66.47 + (13.75 * weight!) + (5.003 * height!) - (6.755 * (year - customerRepository.customer!.birthYear!)); } else { //BMR = 655.1 + ( 9.563 × ömeg kg-ban ) + ( 1.85 × magasság cm-ben) − ( 4.676 × életkor évben kifejezve ) bmr = 655.1 + (9.563 * weight!) + (1.85 * height!) - (4.676 * (year - customerRepository.customer!.birthYear!)); } bmrEnergy = bmr; if (customerRepository.customer!.fitnessLevel == FitnessState.beginner) { bmr *= 1.2; } else if (customerRepository.customer!.fitnessLevel == FitnessState.intermediate) { bmr *= 1.375; } else if (customerRepository.customer!.fitnessLevel == FitnessState.advanced) { bmr *= 1.55; } else if (customerRepository.customer!.fitnessLevel == FitnessState.professional) { bmr *= 1.9; } return bmr; } double getGoalBMI() { if (weight == null || height == null) { return 0; } if (this.bmi == 0) { getBMI(); } if (bmi < 18.5) { goalMilestoneBMI = 19; } else if (bmi > 18.5 && bmi < 25) { goalMilestoneBMI = 21.75; } else if (bmi < 30 && bmi > 24.9) { goalMilestoneBMI = 24; bmiAngle = 7.2; } else if (bmi < 34.9 && 29.9 < bmi) { goalMilestoneBMI = 29; } else if (bmi > 35) { goalMilestoneBMI = 34; } goalBMI = 24; this.goalWeight = goalBMI * (height! * height! / 10000); this.goalMilestoneWeight = goalMilestoneBMI * (height! * height! / 10000); //print("Angle: " + bmiAngle.toStringAsFixed(1)); return goalBMI; } }