workouttest_app/lib/bloc/exercise_control/exercise_control_bloc.dart
2021-09-05 07:47:15 +02:00

155 lines
5.4 KiB
Dart

import 'dart:async';
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/model/exercise.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';
enum ExerciseTypeLocal { oneRepMax, endurance }
extension ExerciseTypeLocalExt on ExerciseTypeLocal {
String toStr() => this.toString().split(".").last;
bool equalsTo(ExerciseTypeLocal type) => this.toString() == type.toString();
bool equalsStringTo(String type) => this.toStr() == type;
}
class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlState> {
final TimerBloc timerBloc;
final ExerciseRepository exerciseRepository;
final bool readonly;
int step = 1;
late double initialRM;
late double unitQuantity;
late double quantity;
late double oneRepQuantity;
late double oneRepUnitQuantity;
double? firstQuantity; // quantity of the first test
double? firstUnitQuantity; // unit quantity of the first test
double scrollOffset = 0;
late ExerciseTypeLocal exerciseTypeLocal;
List<Exercise> controlList = [];
@override
ExerciseControlBloc({required this.exerciseRepository, required this.readonly, required this.timerBloc})
: super(ExerciseControlInitial()) {
print("Exercise ${exerciseRepository.exercise!.toJson()}");
exerciseTypeLocal = ExerciseTypeLocal.oneRepMax;
oneRepQuantity = exerciseRepository.exercise!.quantity!;
if (oneRepQuantity > 25) {
exerciseTypeLocal = ExerciseTypeLocal.endurance;
}
oneRepUnitQuantity = exerciseRepository.exercise!.unitQuantity!;
initialRM = this.calculate1RM(percent75: false);
unitQuantity = this.calculate1RM(percent75: true).roundToDouble();
quantity = 12;
if (oneRepQuantity > 25) {
quantity = 35;
}
exerciseRepository.setUnitQuantity(unitQuantity);
exerciseRepository.setQuantity(quantity);
for (int i = 0; i < 3; i++) {
Exercise exercise = Exercise();
exercise.quantity = quantity;
exercise.unitQuantity = unitQuantity;
controlList.add(exercise);
}
timerBloc.add(TimerStart(duration: 300));
}
@override
Stream<ExerciseControlState> mapEventToState(ExerciseControlEvent event) async* {
try {
if (event is ExerciseControlQuantityChange) {
if (event.step == step) {
exerciseRepository.setQuantity(event.quantity);
quantity = event.quantity;
controlList[step - 1].quantity = quantity;
}
} else if (event is ExerciseControlUnitQuantityChange) {
yield ExerciseControlLoading();
print("event step ${event.step} quantity ${event.quantity}");
if (event.step == step) {
this.unitQuantity = event.quantity;
exerciseRepository.setUnitQuantity(event.quantity);
unitQuantity = event.quantity;
quantity = calculateQuantityByUnitQuantity().toDouble();
exerciseRepository.setQuantity(quantity);
controlList[step - 1].unitQuantity = event.quantity;
controlList[step - 1].quantity = quantity;
}
yield ExerciseControlReady();
} else if (event is ExerciseControlSubmit) {
yield ExerciseControlLoading();
if (event.step == step) {
step++;
scrollOffset = step * 400.0;
if (exerciseRepository.exercise!.quantity == null) {
exerciseRepository.setQuantity(quantity);
}
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd(duration: 300));
}
yield ExerciseControlReady();
}
} on Exception catch (e) {
yield ExerciseControlError(message: e.toString());
}
}
double calculate1RM({bool percent75 = true}) {
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;
double serieQuantity = 0.75;
if (exerciseTypeLocal.equalsTo(ExerciseTypeLocal.endurance)) {
serieQuantity = 0.5;
}
return percent75 ? average * serieQuantity : 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;
}
}