Flutter-Ernaehrungsapp/lib/android/config/statistics.dart

215 lines
7.3 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++){
addValuesToList(box, keys.elementAt(i), newFood[keys.elementAt(i)] ?? []);
}
}
void addValuesToList(Box box, String key, List<Food> newValues){
List<Food> existingList = castDynamicToListFood(box.get(key));
for(int i = 0; i < newValues.length;i++){
existingList.add(newValues[i]);
}
box.put(key, existingList);
}
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;
}
num getAllCaloriesByBoxAndTimestamp(Box box,DateTime date){
int timestamp = date.millisecondsSinceEpoch.toInt() ~/ 1000;
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));
}
}
}