summaryrefslogtreecommitdiff
path: root/src/c/fastforge_logic.c
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-13 08:01:10 +0300
committerPaul Buetow <paul@buetow.org>2026-04-13 08:01:10 +0300
commit2a5855992e96940fdcba90e66132fdf0db1b41a2 (patch)
tree95fcf1d74939d62b79618d8011f19c521c8944aa /src/c/fastforge_logic.c
parent63c33d373eedd6a6974438250f183a0828aa6794 (diff)
n2: extract Pebble-free fasting logic module
Diffstat (limited to 'src/c/fastforge_logic.c')
-rw-r--r--src/c/fastforge_logic.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/c/fastforge_logic.c b/src/c/fastforge_logic.c
new file mode 100644
index 0000000..64fe776
--- /dev/null
+++ b/src/c/fastforge_logic.c
@@ -0,0 +1,88 @@
+#include "fastforge_logic.h"
+
+#if defined(__has_include)
+#if __has_include(<pebble.h>)
+#include <pebble.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+time_t entry_duration_seconds(const FastEntry *entry) {
+ if (!entry || entry->start_time == 0 || entry->end_time <= entry->start_time) {
+ return 0;
+ }
+ return entry->end_time - entry->start_time;
+}
+
+uint8_t stage_level_for_elapsed(time_t elapsed_seconds) {
+ if (elapsed_seconds >= 24 * 3600) {
+ return 3;
+ }
+ if (elapsed_seconds >= 18 * 3600) {
+ return 2;
+ }
+ if (elapsed_seconds >= 12 * 3600) {
+ return 1;
+ }
+ return 0;
+}
+
+const char *stage_text_for_elapsed(time_t elapsed_seconds) {
+ if (elapsed_seconds >= 24 * 3600) {
+ return "DEEP KETOSIS";
+ }
+ if (elapsed_seconds >= 18 * 3600) {
+ return "EARLY KETOSIS";
+ }
+ if (elapsed_seconds >= 12 * 3600) {
+ return "FAT BURN";
+ }
+ return "GLYCOGEN";
+}
+
+void format_hhmmss(time_t seconds, char *buffer, size_t size) {
+ if (seconds < 0) {
+ seconds = 0;
+ }
+ snprintf(buffer, size, "%02d:%02d:%02d",
+ (int)(seconds / 3600),
+ (int)((seconds % 3600) / 60),
+ (int)(seconds % 60));
+}
+
+void format_duration_hours_minutes(time_t seconds, char *buffer, size_t size) {
+ if (seconds < 0) {
+ seconds = 0;
+ }
+ int hours = (int)(seconds / 3600);
+ int minutes = (int)((seconds % 3600) / 60);
+ snprintf(buffer, size, "%dh %02dm", hours, minutes);
+}
+
+time_t local_day_start(time_t timestamp) {
+ if (timestamp <= 0) {
+ return 0;
+ }
+
+ struct tm tm_copy;
+ struct tm *tm_info = localtime(&timestamp);
+ if (!tm_info) {
+ return 0;
+ }
+
+ tm_copy = *tm_info;
+ tm_copy.tm_hour = 0;
+ tm_copy.tm_min = 0;
+ tm_copy.tm_sec = 0;
+ tm_copy.tm_isdst = -1;
+ return mktime(&tm_copy);
+}
+
+bool running_fast_is_at_target(const FastEntry *entry, time_t now) {
+ if (!entry || entry->start_time == 0 || entry->end_time != 0 || entry->target_minutes == 0) {
+ return false;
+ }
+ return now >= entry->start_time + (time_t)entry->target_minutes * 60;
+}