workouttest_util/lib/repository/exercise_repository.dart
2023-02-12 22:42:51 +01:00

533 lines
18 KiB
Dart

import 'dart:collection';
import 'package:workouttest_util/util/app_language.dart';
import 'package:workouttest_util/model/cache.dart';
import 'package:workouttest_util/model/customer.dart';
import 'package:workouttest_util/model/exercise.dart';
import 'package:workouttest_util/model/exercise_type.dart';
import 'package:workouttest_util/model/workout_menu_tree.dart';
import 'package:workouttest_util/service/exercise_service.dart';
import 'package:intl/intl.dart';
import 'package:workouttest_util/util/logging.dart';
class ExerciseRepository with Logging {
Exercise? exercise;
Customer? customer;
ExerciseType? exerciseType;
List<Exercise>? exerciseList;
List<Exercise>? exerciseLogList = [];
List<Exercise>? actualExerciseList = [];
bool noRegistration = false;
double rmWendler = 0;
double rmMcglothlin = 0;
double rmLombardi = 0;
double rmMayhew = 0;
double rmOconner = 0;
double rmWathen = 0;
DateTime? start;
DateTime? end;
ExerciseRepository() {
createNew();
}
createNew() {
exercise = Exercise();
exercise!.dateAdd = DateTime.now();
}
setQuantity(double quantity) {
if (exercise == null) {
createNew();
}
exercise!.quantity = quantity;
}
setUnitQuantity(double unitQuantity) {
if (exercise == null) {
createNew();
}
exercise!.unitQuantity = unitQuantity;
}
setUnit(String unit) {
if (exercise == null) {
createNew();
}
exercise!.unit = unit;
}
setDatetimeExercise(DateTime datetimeExercise) {
if (exercise == null) {
createNew();
}
exercise!.dateAdd = datetimeExercise;
}
double? get unitQuantity => exercise!.unitQuantity;
double? get quantity => exercise!.quantity;
Exercise? getExercise() => exercise;
Future<Exercise> addExercise() async {
if (customer == null) {
throw Exception("Please log in");
}
final Exercise modelExercise = exercise!;
modelExercise.customerId = customer!.customerId;
modelExercise.exerciseTypeId = exerciseType!.exerciseTypeId;
if (exerciseType!.unitQuantity != "1") {
modelExercise.unitQuantity = null;
}
Exercise copy = modelExercise.copy();
actualExerciseList!.add(copy);
//final int index = actualExerciseList.length - 1;
//print("$index. actual exercise " + actualExerciseList[index].toJson().toString());
Exercise savedExercise = await ExerciseApi().addExercise(modelExercise);
//actualExerciseList[index].exerciseId = savedExercise.exerciseId;
if (customer!.customerId == Cache().userLoggedIn!.customerId) {
Cache().addExercise(savedExercise);
} else if (Cache().getTrainee() != null && customer!.customerId == Cache().getTrainee()!.customerId) {
Cache().addExerciseTrainee(savedExercise);
}
return savedExercise;
}
void addExerciseNoRegistration() {
final Exercise modelExercise = exercise!;
modelExercise.exerciseTypeId = exerciseType!.exerciseTypeId;
if (exerciseType!.unitQuantity != "1") {
modelExercise.unitQuantity = null;
}
Exercise copy = modelExercise.copy();
actualExerciseList!.add(copy);
exerciseList = [];
exerciseList!.add(copy);
noRegistration = true;
}
void initExercise() {
createNew();
exerciseType = exerciseType;
setUnit(exerciseType!.unit);
exercise!.exerciseTypeId = exerciseType!.exerciseTypeId;
setQuantity(12);
setUnitQuantity(30);
exercise!.exercisePlanDetailId = 0;
exercise!.exerciseId = 0;
start = DateTime.now();
}
Future<void> deleteExercise(Exercise exercise) async {
await ExerciseApi().deleteExercise(exercise);
}
setCustomer(Customer customer) => customer = customer;
setExerciseType(ExerciseType exerciseType) => exerciseType = exerciseType;
Future<List<Exercise>> getExercisesByCustomer(int customerId) async {
final results = await ExerciseApi().getExercisesByCustomer(customerId);
exerciseList = results;
if (Cache().userLoggedIn != null) {
if (customerId == Cache().userLoggedIn!.customerId) {
Cache().setExercises(exerciseList!);
} else if (Cache().getTrainee() != null && customerId == Cache().getTrainee()!.customerId) {
Cache().setExercisesTrainee(exerciseList!);
}
}
return exerciseList!;
}
List<Exercise>? getExerciseList() {
exerciseList = Cache().getExercises();
return exerciseList;
}
List<Exercise>? getExerciseListTrainee() {
exerciseList = Cache().getExercisesTrainee();
return exerciseList;
}
String? nextMissingBaseExercise(SplayTreeMap sortedTree) {
exerciseList ??= Cache().getExercises();
if (exerciseList == null) {
return null;
}
String? missingTreeName;
String? foundTreeName;
bool isBreak = false;
sortedTree.forEach((key, list) {
List<WorkoutMenuTree> listByMuscle = list as List<WorkoutMenuTree>;
String treeName = key as String;
treeName = treeName.substring(3);
foundTreeName = null;
for (var exercise in listByMuscle) {
missingTreeName ??= treeName;
if (exercise.base) {
if (exerciseList != null) {
for (var element in exerciseList!) {
if (element.exerciseTypeId == exercise.exerciseTypeId) {
foundTreeName = treeName;
//print("Found " + foundTreeName + " Missing actual: " + missingTreeName);
isBreak = true;
}
}
}
}
}
if (foundTreeName == null && !isBreak) {
missingTreeName = treeName;
isBreak = true;
}
});
return missingTreeName;
}
void getBaseExerciseFinishedPercent() {
List<int> checkedExerciseTypeId = [];
List<int> baseTreeItem = [];
List<int> checkedBaseTreeItem = [];
int count1RMExercises = 0;
LinkedHashMap<String, WorkoutMenuTree> tree = Cache().getWorkoutMenuTree();
if (tree.isEmpty) {
return;
}
tree.forEach((key, value) {
WorkoutMenuTree treeItem = value;
if (treeItem.exerciseType != null && treeItem.exerciseType!.base == true && !baseTreeItem.contains(treeItem.parent)) {
baseTreeItem.add(treeItem.parent);
}
});
exerciseList ??= Cache().getExercises();
if (exerciseList == null) {
return;
}
for (var element in exerciseList!) {
Exercise exercise = element;
if (!checkedExerciseTypeId.contains(exercise.exerciseTypeId)) {
checkedExerciseTypeId.add(exercise.exerciseTypeId!);
tree.forEach((key, value) {
WorkoutMenuTree treeItem = value;
if (treeItem.exerciseType != null &&
treeItem.exerciseType!.base == true &&
exercise.exerciseTypeId == treeItem.exerciseType!.exerciseTypeId &&
!checkedBaseTreeItem.contains(treeItem.parent)) {
//print ("id: " + exercise.exerciseTypeId.toString());
checkedBaseTreeItem.add(treeItem.parent);
count1RMExercises++;
}
});
}
}
//print ("checkedExerciseTypeid: " + checkedExerciseTypeId.toString());
//print ("baseTreeItem: " + baseTreeItem.toString());
//print ("count1RMExercises: " + count1RMExercises.toString());
final double percent = count1RMExercises / baseTreeItem.length;
Cache().setPercentExercises(percent);
}
void getLastExercise() {
List<Exercise>? exercises = getExerciseList();
Exercise? lastExercise = exercises == null ? null : exercises[0];
if (exercises != null) {
for (var element in exercises) {
Exercise actualExercise = element;
if (actualExercise.dateAdd!.compareTo(lastExercise!.dateAdd!) > 0) {
lastExercise = actualExercise;
}
}
}
exercise = lastExercise;
customer = Cache().userLoggedIn!;
exerciseType = getExerciseTypeById(exercise!.exerciseTypeId!);
return;
}
ExerciseType? getExerciseTypeById(int exerciseTypeId) {
ExerciseType? actualExerciseType;
List<ExerciseType>? exercises = Cache().getExerciseTypes();
if (exercises != null) {
for (var element in exercises) {
ExerciseType exerciseType = element;
if (exerciseType.exerciseTypeId == exerciseTypeId) {
actualExerciseType = exerciseType;
}
}
}
if (actualExerciseType == null) {
throw Exception("Data error, no ExerciseType for exerciseTypeId $exerciseTypeId");
}
return actualExerciseType;
}
void getSameExercise(int exerciseTypeId, String day) {
if (!noRegistration) {
actualExerciseList = [];
}
if (exerciseList != null) {
int index = 0;
for (int i = 0; i < exerciseList!.length; i++) {
Exercise exercise = exerciseList![i];
final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
if (exerciseTypeId == exercise.exerciseTypeId && exerciseDate == day && index < 4) {
actualExerciseList!.add(exercise);
index++;
}
}
}
}
double calculate1RM(Exercise exercise) {
double weight = exercise.unitQuantity!;
double repeat = exercise.quantity!;
if (weight == 0 || repeat == 0) {
return 0;
}
double rmWendler = weight * repeat * 0.0333 + weight;
double rmOconner = weight * (1 + repeat / 40);
double average = (rmWendler + rmOconner) / 2;
return average;
}
double getBest1RM(Exercise exercise) {
double result = 0;
if (exerciseList == null || exerciseList!.isEmpty) {
exerciseList = Cache().getExercises();
}
final int exerciseTypeId = exercise.exerciseTypeId!;
double toCompare = calculate1RM(exercise);
result = toCompare;
final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(DateTime.now());
List<Exercise> oldExercises = [];
if (exerciseList == null) {
return toCompare;
}
for (var exercise in exerciseList!) {
final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) {
oldExercises.add(exercise);
}
}
if (oldExercises.isNotEmpty) {
oldExercises.sort((a, b) {
double sumA = 0;
double sumB = 0;
if (a.unitQuantity != null && b.unitQuantity != null) {
sumA = a.quantity! * a.unitQuantity!;
sumB = b.quantity! * b.unitQuantity!;
} else {
sumA = a.quantity!;
sumB = b.quantity!;
}
return sumA >= sumB ? 1 : -1;
});
double withCompare = calculate1RM(oldExercises.last);
//result = toCompare >= withCompare ? (1 - toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100;
result = toCompare >= withCompare ? toCompare : withCompare;
}
return result;
}
double getLast1RMPercent(Exercise exercise) {
double result = 0;
if (exerciseList == null || exerciseList!.isEmpty) {
exerciseList = Cache().getExercises();
}
final int exerciseTypeId = exercise.exerciseTypeId!;
double toCompare = calculate1RM(exercise);
final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
List<Exercise> oldExercises = [];
if (exerciseList == null) {
return result;
}
for (var exercise in exerciseList!) {
final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) {
oldExercises.add(exercise);
}
}
if (oldExercises.isNotEmpty) {
double withCompare = calculate1RM(oldExercises.first);
result = toCompare >= withCompare ? (toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100;
}
return result;
}
double getBestVolume(Exercise exercise) {
double result = 0;
if (exerciseList == null || exerciseList!.isEmpty) {
exerciseList = Cache().getExercises();
}
final int exerciseTypeId = exercise.exerciseTypeId!;
double toCompare = exercise.unitQuantity != null ? exercise.quantity! * exercise.unitQuantity! : exercise.quantity!;
result = toCompare;
final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(DateTime.now());
List<Exercise> oldExercises = [];
if (exerciseList == null) {
return toCompare;
}
for (var exercise in exerciseList!) {
final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) {
oldExercises.add(exercise);
}
}
if (oldExercises.isNotEmpty) {
oldExercises.sort((a, b) {
double sumA = 0;
double sumB = 0;
if (a.unitQuantity != null && b.unitQuantity != null) {
sumA = a.quantity! * a.unitQuantity!;
sumB = b.quantity! * b.unitQuantity!;
} else {
sumA = a.quantity!;
sumB = b.quantity!;
}
return sumA >= sumB ? 1 : -1;
});
double withCompare =
oldExercises.last.unitQuantity != null ? oldExercises.last.quantity! * oldExercises.last.unitQuantity! : oldExercises.last.quantity!;
//result = toCompare >= withCompare ? (1 - toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100;
//print("Last Best: ${oldExercises.last} - result: $result");
result = toCompare >= withCompare ? toCompare : withCompare;
}
return result;
}
double getLastExercisePercent(Exercise exercise) {
double result = 0;
if (exerciseList == null || exerciseList!.isEmpty) {
exerciseList = Cache().getExercises();
}
final int exerciseTypeId = exercise.exerciseTypeId!;
double toCompare = exercise.unitQuantity != null ? exercise.quantity! * exercise.unitQuantity! : exercise.quantity!;
final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
List<Exercise> oldExercises = [];
if (exerciseList == null) {
return result;
}
for (var exercise in exerciseList!) {
final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) {
oldExercises.add(exercise);
}
}
if (oldExercises.isNotEmpty) {
double withCompare =
oldExercises.first.unitQuantity != null ? oldExercises.first.quantity! * oldExercises.first.unitQuantity! : oldExercises.first.quantity!;
result = toCompare >= withCompare ? (toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100;
log("Last Last: ${oldExercises.first} vs. $exercise - - result: $result");
}
return result;
}
void sortByDate() {
if (exerciseList == null || exerciseList!.isEmpty) {
return;
}
exerciseList!.sort((a, b) {
final String datePartA = DateFormat('yyyyMMdd', AppLanguage().appLocal.toString()).format(a.dateAdd!);
String aId = "${datePartA}_${a.exerciseTypeId}";
final String datePartB = DateFormat('yyyyMMdd', AppLanguage().appLocal.toString()).format(b.dateAdd!);
String bId = "${datePartB}_${b.exerciseTypeId}";
return bId.compareTo(aId);
});
exerciseLogList = [];
String summary = "";
String prevDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exerciseList![0].dateAdd!);
int prevExerciseTypeId = exerciseList![0].exerciseTypeId!;
Exercise prevExercise = exerciseList![0];
int prevCount = 0;
for (int i = 0; i < exerciseList!.length; i++) {
Exercise exercise = exerciseList![i];
int exerciseTypeId = exercise.exerciseTypeId!;
String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
//print(" -- $prevExerciseTypeId - '$prevDate' against $exerciseTypeId - '$exerciseDate'");
if (exerciseTypeId != prevExerciseTypeId || prevDate != exerciseDate) {
ExerciseType? exerciseType = Cache().getExerciseTypeById(prevExercise.exerciseTypeId!);
String unit = exerciseType != null && exerciseType.unitQuantityUnit != null ? exerciseType.unitQuantityUnit! : prevExercise.unit!;
prevExercise.summary = "$summary $unit";
exerciseLogList!.add(prevExercise);
//print("Log add " + exercise.toJson().toString());
summary = "";
prevCount = 0;
}
String delimiter = "";
if (prevCount > 0) delimiter = ", ";
double quantity = exercise.quantity == null ? 0 : exercise.quantity!;
summary += delimiter + quantity.toStringAsFixed(0);
ExerciseType? exerciseType = Cache().getExerciseTypeById(exercise.exerciseTypeId!);
//print("exerciseType " + (exerciseType == null ? "NULL" : exerciseType.name) + " ID " + exercise.exerciseTypeId.toString());
if (exerciseType != null) {
if (exerciseType.unitQuantity == "1") {
summary += "x${exercise.unitQuantity!.toStringAsFixed(0)}";
}
//print(" --- sum " + exerciseType.name + " $summary");
}
prevExerciseTypeId = exerciseTypeId;
prevDate = exerciseDate;
prevExercise = exercise;
prevCount++;
}
prevExercise.summary = summary;
exerciseLogList!.add(prevExercise);
}
List<Exercise> getExercisesByExerciseTypeId(int exerciseTypeId) {
List<Exercise> list = [];
List<Exercise>? allExercise = Cache().getExercises();
if (allExercise == null) {
return list;
}
for (var element in allExercise) {
if (element.exerciseTypeId == exerciseTypeId) {
list.add(element);
}
}
return list;
}
}