import 'dart:async'; import 'dart:collection'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/exercise_device_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/cupertino.dart'; import 'package:meta/meta.dart'; import 'package:aitrainer_app/library/image_cache.dart' as wt; part 'menu_event.dart'; part 'menu_state.dart'; class MenuBloc extends Bloc with Trans, Logging { final WorkoutTreeRepository menuTreeRepository; final ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository(); int parent = 0; WorkoutMenuTree workoutItem; final List listFilterDevice = List(); String infoTitle = ""; String infoText = ""; String infoText2 = ""; String infoText3 = ""; String infoLink = ""; int missingParent = 0; String missingTreeName = ""; BuildContext context; ExerciseAbility ability; MenuBloc({this.menuTreeRepository}) : super(MenuInitial()) { parent = 0; } void setMenuInfo() { double percent = Cache().getPercentExercises(); if (percent == -1) { exerciseRepository.getBaseExerciseFinishedPercent(); percent = Cache().getPercentExercises(); } if (context == null) return; percent = percent * 100; //log("Percent " + percent.toString()); if (percent == -1 || percent == 0) { infoTitle = t("Greetings!"); infoText = t("The purpose is to measure you physical condition") + " " + t("The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf."); infoText2 = t("I suggest begin your tests with a"); infoText3 = t("Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise."); infoLink = t("Bring me there"); } else if (percent > 0 && percent < 20) { infoTitle = t("Nice! This is a good start"); } else if (percent > 20 && percent < 40) { infoTitle = t("Go on!") + " " + t("You are on track"); } else if (percent > 60 && percent < 80) { infoTitle = t("Persistence!") + " " + t("Not so much left"); } else if (percent > 80 && percent < 100) { infoTitle = t("Almost!") + " " + t("You have only 1-2 exercise left to finish!"); } else { infoTitle = t("Congratulation!"); infoText2 = t("You have achieved to first 100% test-round!"); infoText3 = t("Now you unlocked: Development By Muscles and the Suggested Trainings Plan"); } menuTreeRepository.sortByMuscleType(); missingTreeName = exerciseRepository.nextMissingBaseExercise(menuTreeRepository.sortedTree); //log("Missing " + missingTreeName); if (missingTreeName != null) { if (percent > 0) { infoText = t("Please continue your tests with a") + " '" + missingTreeName + "' " + t("exercise!"); infoLink = t("Bring me there"); } } } void setContext(BuildContext context) { this.context = context; } @override Stream mapEventToState( MenuEvent event, ) async* { try { if (event is MenuCreate) { yield MenuLoading(); //await menuTreeRepository.createTree(); //menuTreeRepository.getBranch(this.parent); setMenuInfo(); exerciseDeviceRepository.setDevices(Cache().getDevices()); yield MenuReady(); } else if (event is MenuRecreateTree) { yield MenuLoading(); // ie. at language changes await menuTreeRepository.createTree(); yield MenuReady(); } else if (event is MenuTreeDown) { yield MenuLoading(); parent = event.parent; workoutItem = event.item; if (workoutItem != null) { setAbility(workoutItem.nameEnglish); } final LinkedHashMap branch = menuTreeRepository.getBranch(event.parent); await getImages(branch); //await Future.delayed(Duration(seconds: 2)); yield MenuReady(); } else if (event is MenuTreeUp) { yield MenuLoading(); // get parent menus or exercises parent = event.parent; workoutItem = menuTreeRepository.getParentItem(parent); LinkedHashMap branch; if (workoutItem != null) { setAbility(workoutItem.nameEnglish); branch = menuTreeRepository.getBranch(workoutItem.parent); await getImages(branch); } yield MenuReady(); } else if (event is MenuTreeJump) { yield MenuLoading(); parent = event.parent; workoutItem = menuTreeRepository.getParentItem(parent); if (workoutItem != null) { setAbility(workoutItem.nameEnglish); } final LinkedHashMap branch = menuTreeRepository.getBranch(workoutItem.parent); if (branch != null) { await getImages(branch); } yield MenuReady(); } else if (event is MenuClickExercise) { yield MenuLoading(); // get exercise page yield MenuReady(); } else if (event is MenuFilterExerciseType) { yield MenuLoading(); final int deviceId = event.deviceId; if (selectedDevice(deviceId)) { listFilterDevice.add(deviceId); } else { listFilterDevice.remove(deviceId); } yield MenuReady(); } } on Exception catch (ex) { yield MenuError(message: ex.toString()); } } void setAbility(String name) { switch (name) { case "One Rep Max": ability = ExerciseAbility.oneRepMax; break; case "Endurance": ability = ExerciseAbility.endurance; break; case "Cardio": ability = ExerciseAbility.running; break; case "Test Center": ability = ExerciseAbility.mini_test; break; case "My Body": ability = ExerciseAbility.none; break; } log("Ability: " + ability.toString() + " name:" + name); } Future getImages(LinkedHashMap branch) async { wt.ImageCache().clearImageList(); await putBranchImageToHash(branch); log("downloaded image size in KB: " + wt.ImageCache().downloadSize.toString()); } Future putBranchImageToHash(LinkedHashMap branch) async { await Future.forEach(branch.keys, (key) async { final WorkoutMenuTree value = branch[key]; if (!value.imageName.contains("asset")) { await wt.ImageCache().putImageToList(value.id, value.imageName); } }); } String getImage(int id, String name) { String imageString; if (name.contains("http")) { imageString = wt.ImageCache().getImageString(id, name); } return imageString; } bool selectedDevice(int deviceId) { return !listFilterDevice.contains(deviceId); } LinkedHashMap getFilteredBranch(int parent) { if (parent == null) return LinkedHashMap(); LinkedHashMap branch = menuTreeRepository.getBranch(parent); if (!menuTreeRepository.isChild(parent) || ability.toString() == ExerciseAbility.none.toString() || listFilterDevice.isEmpty) { return branch; } LinkedHashMap filtered = LinkedHashMap(); branch.forEach((key, value) { final WorkoutMenuTree elem = value; if (elem.exerciseType != null) { for (int i = 0; i < elem.exerciseType.devices.length; i++) { if (listFilterDevice.contains(elem.exerciseType.devices[i])) { filtered[elem.name] = elem; } } } }); return filtered; } }