From 4efd408c14cb7edbfe2df131a7c64f4a8860a0cc Mon Sep 17 00:00:00 2001
From: Doug Junkins <junkins@foghead.com>
Date: Tue, 5 Mar 2019 23:50:16 +0000
Subject: [PATCH] Add statistics by dive depth

Added statistics by dive depth in 10m increments. Labels are currently
hard coded in meters. Need to figure out how to use the units
preferences to change the labels to feed when necessary.

Signed-off-by: Doug Junkins <junkins@foghead.com>
---
 core/statistics.c                   | 33 ++++++++++++++++++++++++++++-
 core/statistics.h                   |  2 ++
 qt-models/yearlystatisticsmodel.cpp | 15 +++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 core/statistics.c
 mode change 100644 => 100755 core/statistics.h
 mode change 100644 => 100755 qt-models/yearlystatisticsmodel.cpp

diff --git a/core/statistics.c b/core/statistics.c
old mode 100644
new mode 100755
index d6d9418d7..bcf3dd4e9
--- a/core/statistics.c
+++ b/core/statistics.c
@@ -15,6 +15,8 @@
 #include "divelist.h"
 #include "statistics.h"
 
+#include <stdio.h>
+
 static void process_temperatures(struct dive *dp, stats_t *stats)
 {
 	temperature_t min_temp, mean_temp, max_temp = {.mkelvin = 0};
@@ -95,6 +97,8 @@ char *get_minutes(int seconds)
 void calculate_stats_summary(struct stats_summary *out, bool selected_only)
 {
 	int idx;
+	int dr;
+	char *label;
 	struct dive *dp;
 	struct tm tm;
 	int current_year = 0;
@@ -124,12 +128,17 @@ void calculate_stats_summary(struct stats_summary *out, bool selected_only)
 	out->stats_monthly = malloc(size);
 	out->stats_by_trip = malloc(size);
 	out->stats_by_type = malloc(tsize);
-	if (!out->stats_yearly || !out->stats_monthly || !out->stats_by_trip || !out->stats_by_type)
+	out->stats_by_depth = malloc(tsize);
+	out->stats_by_temp = malloc(tsize);
+	if (!out->stats_yearly || !out->stats_monthly || !out->stats_by_trip ||
+		  !out->stats_by_type || !out->stats_by_depth || !out->stats_by_temp)
 		return;
 	memset(out->stats_yearly, 0, size);
 	memset(out->stats_monthly, 0, size);
 	memset(out->stats_by_trip, 0, size);
 	memset(out->stats_by_type, 0, tsize);
+	memset(out->stats_by_depth, 0, tsize);
+	memset(out->stats_by_temp, 0, tsize);
 	out->stats_yearly[0].is_year = true;
 
 	/* Setting the is_trip to true to show the location as first
@@ -145,6 +154,9 @@ void calculate_stats_summary(struct stats_summary *out, bool selected_only)
 	out->stats_by_type[4].location = strdup(translate("gettextFromC", divemode_text_ui[FREEDIVE]));
 	out->stats_by_type[4].is_trip = true;
 
+  out->stats_by_depth[0].location = strdup(translate("gettextFromC", "All (by depth stats)"));
+	out->stats_by_depth[0].is_trip = true;
+
 	/* this relies on the fact that the dives in the dive_table
 	 * are in chronological order */
 	for_each_dive (idx, dp) {
@@ -174,6 +186,13 @@ void calculate_stats_summary(struct stats_summary *out, bool selected_only)
 		process_dive(dp, &(out->stats_by_type[dp->dc.divemode + 1]));
 		out->stats_by_type[dp->dc.divemode + 1].selection_size++;
 
+    /* stats_by_depth[0] is all the dives combined */
+		out->stats_by_depth[0].selection_size++;
+		process_dive(dp, &(out->stats_by_depth[0]));
+
+		process_dive(dp, &(out->stats_by_depth[(dp->maxdepth.mm / 10000) + 1]));
+		out->stats_by_depth[(dp->maxdepth.mm / 10000) + 1].selection_size++;
+
 		if (dp->divetrip != NULL) {
 			if (trip_ptr != dp->divetrip) {
 				trip_ptr = dp->divetrip;
@@ -207,6 +226,14 @@ void calculate_stats_summary(struct stats_summary *out, bool selected_only)
 		prev_month = current_month;
 		prev_year = current_year;
 	}
+
+	/* add labels for depth ranges up to maximum depth seen */
+	for (dr=0; dr * 10000 <= out->stats_by_depth[0].max_depth.mm; ++dr)
+	{
+		asprintf(&label, "%dm - %dm", dr * 10, (dr+1) * 10);
+		out->stats_by_depth[dr+1].location = label;
+		out->stats_by_depth[dr+1].is_trip = true;
+	}
 }
 
 void free_stats_summary(struct stats_summary *stats)
@@ -215,6 +242,8 @@ void free_stats_summary(struct stats_summary *stats)
 	free(stats->stats_monthly);
 	free(stats->stats_by_trip);
 	free(stats->stats_by_type);
+	free(stats->stats_by_depth);
+	free(stats->stats_by_temp);
 }
 
 void init_stats_summary(struct stats_summary *stats)
@@ -223,6 +252,8 @@ void init_stats_summary(struct stats_summary *stats)
 	stats->stats_monthly = NULL;
 	stats->stats_by_trip = NULL;
 	stats->stats_by_type = NULL;
+	stats->stats_by_depth = NULL;
+	stats->stats_by_temp = NULL;
 }
 
 /* make sure we skip the selected summary entries */
diff --git a/core/statistics.h b/core/statistics.h
old mode 100644
new mode 100755
index 6072f93b2..12e729343
--- a/core/statistics.h
+++ b/core/statistics.h
@@ -44,6 +44,8 @@ struct stats_summary {
 	stats_t *stats_monthly;
 	stats_t *stats_by_trip;
 	stats_t *stats_by_type;
+	stats_t *stats_by_depth;
+	stats_t *stats_by_temp;
 };
 
 #ifdef __cplusplus
diff --git a/qt-models/yearlystatisticsmodel.cpp b/qt-models/yearlystatisticsmodel.cpp
old mode 100644
new mode 100755
index fa86cffbe..028e5fc4e
--- a/qt-models/yearlystatisticsmodel.cpp
+++ b/qt-models/yearlystatisticsmodel.cpp
@@ -225,4 +225,19 @@ void YearlyStatisticsModel::update_yearly_stats()
 		rootItem->children.append(item);
 		item->parent = rootItem.get();
 	}
+
+	/* Show the statistic sorted by dive depth */
+	if (stats.stats_by_depth != NULL && stats.stats_by_depth[0].is_trip == true) {
+		YearStatisticsItem *item = new YearStatisticsItem(stats.stats_by_depth[0]);
+		for (i = 1; stats.stats_by_depth != NULL && stats.stats_by_depth[i].is_trip; ++i) {
+			if (stats.stats_by_depth[i].selection_size) {
+			  YearStatisticsItem *iChild = new YearStatisticsItem(stats.stats_by_depth[i]);
+			  item->children.append(iChild);
+			  iChild->parent = item;
+		  }
+		}
+		rootItem->children.append(item);
+		item->parent = rootItem.get();
+	}
+
 }
-- 
2.17.1

