import 'dart:async'; 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:flutter_form_bloc/flutter_form_bloc.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; AnimationController bmiAnimationController; double quantity = 12; double unitQuantity = 30; 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, ); int timerValue; @override ExerciseNewBloc({this.exerciseRepository, this.menuBloc, this.customerRepository, 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.toInt()); 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(); exerciseRepository.end = DateTime.now(); await exerciseRepository.addExercise(); // exerciseRepository.initExercise(); menuBloc.add(MenuTreeDown(parent: 0)); Cache().initBadges(); Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType.name); yield ExerciseNewSaved(); } else if (event is ExerciseNewBMIAnimate) { yield ExerciseNewLoading(); yield ExerciseNewReady(); } } on Exception catch (e) { yield ExerciseNewError(message: e.toString()); } } double getBMI() { if (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 (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 (this.bmi == 0) { getBMI(); } final double distortionWidth = customerRepository.mediaWidth / baseWidth; final double distortionHeight = distortionWidth - 0.02; //mediaHeight / baseHeight; /* log("Width: " + mediaWidth.toStringAsFixed(0) + " Height: " + mediaHeight.toStringAsFixed(0) + " BaseW: " + baseWidth.toStringAsFixed(0) + " BaseH: " + baseHeight.toStringAsFixed(0) + " DistW: " + distortionWidth.toStringAsFixed(2) + " DistH: " + distortionHeight.toStringAsFixed(2)); */ this.bmiAngle = (bmi * 90 / 25) - 90; if (bmi < 18.5) { goalMilestoneBMI = 19; goalBMI = 21.75; this.bmiTop = 99 * distortionHeight; this.bmiLeft = 77 * distortionWidth; bmiAngle = -62; } else if (bmi > 18.5 && bmi < 25) { goalBMI = 21.75; goalMilestoneBMI = 21.75; this.bmiTop = 48 * distortionHeight; this.bmiLeft = 130 * distortionWidth; bmiAngle = -23; } else if (bmi < 30 && bmi > 24.9) { goalMilestoneBMI = 24; goalBMI = 21.75; this.bmiTop = 40.0 * distortionHeight; this.bmiLeft = 184.0 * distortionWidth; bmiAngle = 7.2; } else if (bmi < 34.9 && 29.9 < bmi) { goalMilestoneBMI = 29; goalBMI = 24; bmiTop = 48 * distortionHeight; bmiLeft = 211 * distortionWidth; } else if (bmi > 35) { goalMilestoneBMI = 34; goalBMI = 24; bmiTop = 94 * distortionHeight; bmiLeft = 260 * distortionWidth; bmiAngle = 59; } this.goalWeight = goalBMI * (height * height / 10000); this.goalMilestoneWeight = goalMilestoneBMI * (height * height / 10000); //print("Angle: " + bmiAngle.toStringAsFixed(1)); return goalBMI; } }