236 lines
7.8 KiB
Dart
236 lines
7.8 KiB
Dart
import 'dart:math';
|
|
import 'package:ernaehrung/android/components/meal_page_text/days_component.dart';
|
|
import 'package:ernaehrung/android/config/cast_helper.dart';
|
|
import 'package:hive/hive.dart';
|
|
import '../models/food.dart';
|
|
|
|
class StatisticsService {
|
|
final String reducedStatisticsBoxName = 'STATISTICS_REDUCED';
|
|
final String mainStatisticsBoxName = 'STATISTICS_MAIN';
|
|
|
|
StatisticsService() {
|
|
initBoxes();
|
|
}
|
|
|
|
initBoxes()async{
|
|
Box reducedBox = Hive.box(reducedStatisticsBoxName);
|
|
putIfKeyNotExists(reducedBox, 'FRÜHSTÜCK', []);
|
|
putIfKeyNotExists(reducedBox, 'MITTAGESSEN', []);
|
|
putIfKeyNotExists(reducedBox, 'ABENDESSEN', []);
|
|
updateReducedBoxByTimespan(TimeSpan.day);
|
|
}
|
|
|
|
void putIfKeyNotExists(Box box, String key, dynamic value) {
|
|
if (!box.containsKey(key)) {
|
|
box.put(key, value);
|
|
}
|
|
}
|
|
|
|
updateReducedBoxByTimespan(TimeSpan timeSpan){
|
|
clearReducedBoxBeforeUpdate();
|
|
DateTime now = DateTime.now();
|
|
int timestamp = now.millisecondsSinceEpoch.toInt() ~/ 1000;
|
|
switch(timeSpan){
|
|
case TimeSpan.day:
|
|
getNewFoodAndUpdateReducedBoxByTimestamp(timestamp);
|
|
break;
|
|
case TimeSpan.week:
|
|
List<int> currentWeek = getTimestampsByTimestampAndTimespan(TimeSpan.week,timestamp);
|
|
for(int i = 0;i < currentWeek.length;i++){
|
|
getNewFoodAndUpdateReducedBoxByTimestamp(currentWeek[i]);
|
|
}
|
|
break;
|
|
case TimeSpan.month:
|
|
List<int> currentMonth = getTimestampsByTimestampAndTimespan(TimeSpan.month,timestamp);
|
|
for(int i = 0;i < currentMonth.length;i++){
|
|
getNewFoodAndUpdateReducedBoxByTimestamp(currentMonth[i]);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void getNewFoodAndUpdateReducedBoxByTimestamp(int timestamp){
|
|
Map<String,List<Food>> newFood = getFoodMapForGivenTimestampFromMainBox(timestamp);
|
|
if(newFood.keys.isNotEmpty){
|
|
setElementsOfReducedBox(newFood);
|
|
}
|
|
}
|
|
|
|
List<int> getTimestampsByTimestampAndTimespan(TimeSpan timespan, int timestamp) {
|
|
int range = timespan == TimeSpan.week ? 7 : 31;
|
|
int targetWeekday = DateTime.monday; // Example target weekday (Monday)
|
|
DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
|
int currentWeekday = currentDateTime.weekday;
|
|
int daysToAdd = targetWeekday - currentWeekday;
|
|
DateTime targetDateTime = currentDateTime.add(Duration(days: daysToAdd));
|
|
|
|
List<int> timestampsForWeekdays = [];
|
|
for (int i = 0; i < range; i++) {
|
|
timestampsForWeekdays.add(targetDateTime.millisecondsSinceEpoch ~/ 1000);
|
|
targetDateTime = targetDateTime.add(const Duration(days: 1));
|
|
}
|
|
return timestampsForWeekdays;
|
|
}
|
|
|
|
clearReducedBoxBeforeUpdate(){
|
|
Box box = Hive.box(reducedStatisticsBoxName);
|
|
for(int i = 0; i < box.keys.length;i++){
|
|
box.put(box.keys.elementAt(i), []);
|
|
}
|
|
}
|
|
setElementsOfReducedBox(Map<String,List<Food>> newFood){
|
|
Box box = Hive.box(reducedStatisticsBoxName);
|
|
Iterable<String> keys = newFood.keys;
|
|
for(int i = 0; i < keys.length;i++){
|
|
List<Food> alreadyExisting = castDynamicToListFood(box.get(keys.elementAt(i)));
|
|
alreadyExisting.addAll(newFood[keys.elementAt(i)] as Iterable<Food>);
|
|
box.put(keys.elementAt(i), alreadyExisting);
|
|
}
|
|
}
|
|
|
|
getDayAsIntFromTimestamp(int timestamp){
|
|
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
|
return dateTime.day;
|
|
}
|
|
|
|
Map<String,List<Food>> getFoodMapForGivenTimestampFromMainBox(int timestamp){
|
|
Box box = Hive.box(mainStatisticsBoxName);
|
|
dynamic matchingTimestamp = getMatchingTimeStamp(box, timestamp);
|
|
if(matchingTimestamp != null){
|
|
return castDynamicMap(box.get(matchingTimestamp));
|
|
}
|
|
return <String,List<Food>>{};
|
|
}
|
|
|
|
getMatchingTimeStamp(Box box,int newTimestamp){
|
|
if(box.keys.isNotEmpty){
|
|
for(int i = 0; i < box.keys.length;i++){
|
|
int timestamp = box.keys.elementAt(i);
|
|
if(isDateEqual(newTimestamp, timestamp)){
|
|
return timestamp;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
getMonthAsIntFromTimestamp(int timestamp){
|
|
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
|
return dateTime.month;
|
|
}
|
|
|
|
getYearAsIntFromTimestamp(int timestamp){
|
|
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
|
return dateTime.year;
|
|
}
|
|
|
|
isDateEqual(int timestamp1, int timestamp2){
|
|
return
|
|
getDayAsIntFromTimestamp(timestamp1) == getDayAsIntFromTimestamp(timestamp2) &&
|
|
getMonthAsIntFromTimestamp(timestamp1) == getMonthAsIntFromTimestamp(timestamp2) &&
|
|
getYearAsIntFromTimestamp(timestamp1) == getYearAsIntFromTimestamp(timestamp2);
|
|
}
|
|
|
|
addItemToMainBox(Food value, String mealType){
|
|
// Hive.deleteFromDisk();
|
|
Box box = Hive.box(mainStatisticsBoxName);
|
|
DateTime dateTime = DateTime.now();
|
|
|
|
// DEBUG
|
|
//DateTime dateTime = getRandomTimestampForTesting();
|
|
|
|
int newTimestamp = dateTime.millisecondsSinceEpoch.toInt() ~/ 1000;
|
|
|
|
dynamic matchingTimestamp = getMatchingTimeStamp(box, newTimestamp);
|
|
if(matchingTimestamp != null){
|
|
newTimestamp = matchingTimestamp;
|
|
}
|
|
Map<String, List<Food>> valueMap = castDynamicMap(box.get(newTimestamp));
|
|
List<Food> values = [];
|
|
if(valueMap.containsKey(mealType)){
|
|
values = valueMap[mealType]!;
|
|
}
|
|
values.add(value);
|
|
valueMap[mealType] = values;
|
|
box.put(newTimestamp, valueMap);
|
|
}
|
|
|
|
getRandomTimestampForTesting(){
|
|
DateTime now = DateTime.now();
|
|
DateTime startOfWeek = now.subtract(Duration(days: now.weekday - 1));
|
|
DateTime endOfWeek = startOfWeek.add(const Duration(days: 6));
|
|
|
|
Random random = Random();
|
|
int randomMilliseconds = random.nextInt(endOfWeek.millisecondsSinceEpoch - startOfWeek.millisecondsSinceEpoch);
|
|
DateTime randomTimestamp = startOfWeek.add(Duration(milliseconds: randomMilliseconds));
|
|
|
|
return randomTimestamp;
|
|
}
|
|
|
|
int getAllEatenCaloriesForTodayStatistics(){
|
|
Box box = Hive.box(reducedStatisticsBoxName);
|
|
num sum = 0;
|
|
for(int i = 0; i < box.keys.length;i++){
|
|
for(Food food in box.get(box.keys.elementAt(i))){
|
|
sum += food.calories;
|
|
}
|
|
}
|
|
return sum as int;
|
|
}
|
|
|
|
List<double> getAllEatenIngredientsForTodayStatistics(){
|
|
Box box = Hive.box(reducedStatisticsBoxName);
|
|
num fat = 0;
|
|
num protein = 0;
|
|
num carbs = 0;
|
|
for(int i = 0; i < box.keys.length;i++){
|
|
for(Food food in box.get(box.keys.elementAt(i))){
|
|
fat += food.fatg;
|
|
protein = food.proteing;
|
|
carbs = food.carbohydrateg;
|
|
}
|
|
}
|
|
return [fat as double,protein as double,carbs as double];
|
|
}
|
|
|
|
num getAllCaloriesByBoxAndTimestamp(Box box,int timestamp){
|
|
Map<String, List<Food>> valueMap = castDynamicMap(box.get(timestamp));
|
|
num sum = 0;
|
|
for(var mealType in valueMap.keys){
|
|
if(valueMap.containsKey(mealType)){
|
|
List<Food> values = valueMap[mealType]!;
|
|
for(var value in values){
|
|
sum += value.calories;
|
|
}
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
num getCaloriesByTimestampAndMealTypeAndBox(Box box,DateTime date, String mealType){
|
|
int timestamp = date.millisecondsSinceEpoch.toInt() ~/ 1000;
|
|
Map<String, List<Food>> valueMap = castDynamicMap(box.get(timestamp));
|
|
num sum = 0;
|
|
if(valueMap.containsKey(mealType)){
|
|
List<Food> values = valueMap[mealType]!;
|
|
for(var value in values){
|
|
sum += value.calories;
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
|
|
|
|
showItems(){
|
|
print("Statistics.dart - showItems() - ITEMS");
|
|
//Hive.box(boxName).clear();
|
|
print(Hive.box(mainStatisticsBoxName).keys.length);
|
|
for(int i = 0; i < Hive.box(mainStatisticsBoxName).keys.length; i++){
|
|
print(Hive.box(mainStatisticsBoxName).keys.elementAt(i));
|
|
print(Hive.box(mainStatisticsBoxName).values.elementAt(i));
|
|
//print(Hive.box(boxName).keys.elementAt(i) + " " + Hive.box(boxName).values.elementAt(i));
|
|
}
|
|
}
|
|
|
|
} |