import 'dart:convert'; import 'package:aitrainer_app/util/app_language.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:badges/badges.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class DateRate { static String daily = "daily"; static String weekly = "weekly"; static String monthly = "monthly"; static String yearly = "yearly"; } mixin Common { final emailError = "Please type a right email address here."; final passwordError = "The password must have at least 8 characters."; String toJson(Map map) { String rc = "{"; map.forEach((key, value) { rc += "'$key':'$value'"; }); rc += "}"; return rc; } ExerciseType? getExerciseType(int exerciseTypeId) { ExerciseType? returnElement; List? listExerciseType = Cache().getExerciseTypes(); if (listExerciseType != null) { for (var element in listExerciseType) { if (exerciseTypeId == element.exerciseTypeId) { returnElement = element; break; } } } return returnElement; } String getDateLocale(DateTime datetime, bool timeDisplay) { var date = datetime; String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(date.toUtc()); if (timeDisplay) { dateName += " " + DateFormat(DateFormat.HOUR_MINUTE, AppLanguage().appLocal.toString()).format(date.toUtc()); } return dateName; } String utf8convert(String text) { List bytes = text.toString().codeUnits; return utf8.decode(bytes); } double mediaSizeWidth(BuildContext context) { return MediaQuery.of(context).size.width; } bool validateEmail(UserRepository userRepository) { final String email = userRepository.user.email!; final RegExp _emailRegExp = RegExp( r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$', ); return _emailRegExp.hasMatch(email); } bool validatePassword(UserRepository userRepository) { final password = userRepository.user.password!; final RegExp _passwordRegExp = RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$'); return _passwordRegExp.hasMatch(password); } /// Calculates week number from a date as per https://en.wikipedia.org/wiki/ISO_week_date#Calculation int weekNumber(DateTime date) { int dayOfYear = int.parse(DateFormat("D").format(date)); return ((dayOfYear - date.weekday + 10) / 7).floor(); } String getDatePart(DateTime date, String dateRate) { String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date); if (dateRate == DateRate.weekly) { datePart = weekNumber(date).toString(); } else if (dateRate == DateRate.monthly) { datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date); } else if (dateRate == DateRate.yearly) { datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date); } else if (dateRate == DateRate.daily) { datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date); } return datePart; } static String? emailValidation(String? email) { final String error = "Please type an email address"; if (email == null) { return error; } bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email); return emailValid ? null : error; } static String? passwordValidation(String? value) { final String error = "Password too short"; if (value == null || value.length == 0) { return error; } bool valid = 8 < value.length; return valid ? null : error; } static Widget badgedIcon(Color color, IconData icon, String badgeKey) { //print("BadgetIcon: " + Cache().getBadges().toString()); int? badgeValue = Cache().getBadges()[badgeKey]; bool show = (badgeValue != null); int counter = show ? badgeValue : 0; //print("show $show BadgeKey $badgeKey count $counter"); return Badge( position: BadgePosition.topEnd(top: -10, end: -10), animationDuration: Duration(milliseconds: 500), animationType: BadgeAnimationType.slide, badgeColor: Colors.red, showBadge: show, badgeContent: Text( counter.toString(), style: TextStyle(color: Colors.white), ), child: Icon( icon, color: color, ), ); } static normalizeDecimal(String value) { if (value.isEmpty) { return 0; } value = value.replaceFirst(",", "."); value = value.replaceAll(RegExp(r'[^0-9.]'), ""); return value; } static double calculate1RM(double weight, double repeat) { 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 average; } static double get1RMPercent(int repeats) { double percent = 1; if (repeats >= 35) { percent = 0.50; } else if (repeats > 12) { percent = (100 - 2 * repeats) / 100; } else { percent = (100.0 - 2 * repeats) / 100; } //print("1RM Percent: $percent repeats: $repeats"); return percent; } static double roundWeight(double weight) { double rounded = weight.round().toDouble(); if (weight > 35) { final double remainder = weight % 5; if (remainder < 1) { rounded = ((weight / 5).floor() * 5).toDouble(); } else if (remainder > 1 && remainder <= 2.5) { rounded = (weight / 5).floor() * 5 + 2.5; } else if (remainder > 2.5 && remainder < 3.25) { rounded = (weight / 5).floor() * 5 + 2.5; } else { rounded = (((weight / 5).ceil() * 5) + 5).toDouble(); } } return rounded; } static int calculateQuantityByChangedWeight(double initialRM, double weight, double repeat) { final double repeatWendler = (initialRM - weight) / 0.0333 / weight; final double repeatOconner = (initialRM / 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; } static int reCalculateRepeatsByChangedWeight(double weight, double repeat, double changedWeight) { final double rmWendler = weight * repeat * 0.0333 + weight; final double rmOconner = weight * (1 + repeat / 40); final double repeatWendler = (rmWendler - changedWeight) / 0.0333 / changedWeight; final double repeatOconner = (rmOconner / changedWeight - 1) * 40; final newRepeat = ((repeatOconner + repeatWendler) / 2).ceil(); print( "Weight: $weight changedWeight: $changedWeight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat"); return newRepeat; } static double calculateWeigthByChangedQuantity(double weight, double repeat, double changedRepeats) { final double rmWendler = weight * repeat * 0.0333 + weight; final double rmOconner = weight * (1 + repeat / 40); final double initialRM = (rmWendler + rmOconner) / 2; final double weightWendler = rmWendler / (changedRepeats * 0.0333 + 1); final double weightOconner = rmOconner / (1 + changedRepeats / 40); final double newWeight = ((weightWendler + weightOconner) / 2); print( "Initial 1RM: $initialRM repeat: $repeat changedRepeat: $changedRepeats Weight: $weight weightWendler: $weightWendler weight Oconner: $weightOconner. NEW WEIGHT: $newWeight"); return newWeight; } static List getExerciseTypeAlternatives(int? exerciseTypeId) { if (exerciseTypeId == null || exerciseTypeId <= 0) { return []; } List list = []; List? exerciseTypes = Cache().getExerciseTypes(); if (exerciseTypes != null) { exerciseTypes.forEach((exerciseType) { if (exerciseType.alternatives.isNotEmpty) { exerciseType.alternatives.forEach((childId) { if (childId == exerciseTypeId) { list.add(exerciseType); } }); } }); } return list; } }