import 'dart:async'; import 'package:aitrainer_app/bloc/timer/timer_bloc.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:meta/meta.dart'; part 'exercise_control_event.dart'; part 'exercise_control_state.dart'; class ExerciseControlBloc extends Bloc { final TimerBloc timerBloc; final ExerciseRepository exerciseRepository; final bool readonly; int step = 1; double initialRM; double unitQuantity; double quantity; double origQuantity; double oneRepQuantity; double oneRepUnitQuantity; double firstQuantity; // quantity of the first test double firstUnitQuantity; // unit quantity of the first test double scrollOffset = 0; @override ExerciseControlBloc({this.exerciseRepository, this.readonly, @required this.timerBloc}) : super(ExerciseControlInitial()) { print("Exercise ${exerciseRepository.exercise.toJson()}"); oneRepQuantity = exerciseRepository.exercise.quantity; oneRepUnitQuantity = exerciseRepository.exercise.unitQuantity; initialRM = this.calculate1RM(percent75: false); unitQuantity = this.calculate1RM(percent75: true).roundToDouble(); quantity = 12; origQuantity = quantity; exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setQuantity(quantity); timerBloc.add(TimerStart(duration: 300)); } @override Stream mapEventToState(ExerciseControlEvent event) async* { try { if (event is ExerciseControlLoad) { yield ExerciseControlLoading(); step = 1; yield ExerciseControlReady(); } else if (event is ExerciseControlQuantityChange) { //yield ExerciseControlLoading(); if (event.step == step) { exerciseRepository.setQuantity(event.quantity); quantity = event.quantity; } //yield ExerciseControlReady(); } else if (event is ExerciseControlUnitQuantityChange) { yield ExerciseControlLoading(); if (event.step == step) { this.unitQuantity = event.quantity; exerciseRepository.setUnitQuantity(event.quantity); unitQuantity = event.quantity; quantity = calculateQuantityByUnitQuantity().toDouble(); exerciseRepository.setQuantity(quantity); origQuantity = quantity; } yield ExerciseControlReady(); } else if (event is ExerciseControlSubmit) { yield ExerciseControlLoading(); if (event.step == step) { step++; scrollOffset = step * 400.0; quantity = origQuantity; if (exerciseRepository.exercise.quantity == null) { exerciseRepository.setQuantity(quantity); } exerciseRepository.end = DateTime.now(); await exerciseRepository.addExercise(); //exerciseRepository.initExercise(); step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd()); } yield ExerciseControlReady(); } } on Exception catch (e) { yield ExerciseControlError(message: e.toString()); } } double calculate1RM({bool percent75}) { if (exerciseRepository.exercise == null) { exerciseRepository.getLastExercise(); } double weight = exerciseRepository.exercise.unitQuantity; double repeat = exerciseRepository.exercise.quantity; if (weight == 0 || repeat == 0) { return 0; } double rmWendler = weight * repeat * 0.0333 + weight; double rmOconner = weight * (1 + repeat / 40); print("Weight: $weight repeat: $repeat, $rmWendler, Oconner: $rmOconner"); double average = (rmWendler + rmOconner) / 2; return percent75 ? average * 0.75 : average; } int calculateQuantityByUnitQuantity() { double weight = oneRepUnitQuantity; double repeat = oneRepQuantity; final double rmWendler = weight * repeat * 0.0333 + weight; final double rmOconner = weight * (1 + repeat / 40); print("Weight: $weight oneRepQuantity: $repeat, $rmWendler, Oconner: $rmOconner"); weight = exerciseRepository.exercise.unitQuantity; repeat = exerciseRepository.exercise.quantity; final double repeatWendler = (rmWendler - weight) / 0.0333 / weight; final double repeatOconner = (rmOconner / weight - 1) * 40; final newRepeat = ((repeatOconner + repeatWendler) / 2).ceil(); print("Initial 1RM: $initialRM Weight: $weight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat"); return newRepeat; } }