From ae8af7569206cb1c410c29a4aa2e92975c189d6b Mon Sep 17 00:00:00 2001
From: Mark Watkins <jedimark@users.sourceforge.net>
Date: Wed, 28 Dec 2011 22:36:40 +1000
Subject: [PATCH] Change Day First/Last to reflect hidden sessions.

---
 Graphs/gLineChart.cpp |   1 +
 SleepLib/day.cpp      |  42 ++++++++++++++-
 SleepLib/day.h        |   4 +-
 SleepLib/profiles.cpp | 118 +++++++++++++++++++++++++++++++-----------
 SleepLib/profiles.h   |   7 +++
 mainwindow.cpp        |  20 +++----
 6 files changed, 148 insertions(+), 44 deletions(-)

diff --git a/Graphs/gLineChart.cpp b/Graphs/gLineChart.cpp
index 28a71c7f..71ed5e3d 100644
--- a/Graphs/gLineChart.cpp
+++ b/Graphs/gLineChart.cpp
@@ -651,6 +651,7 @@ void AHIChart::SetDay(Day *d)
 
         bool fnd=false;
         for (s=d->begin();s!=d->end();s++) {
+            if (!(*s)->enabled()) continue;
             Session *sess=*s;
             if ((ti<sess->first()) || (f>sess->last())) continue;
 
diff --git a/SleepLib/day.cpp b/SleepLib/day.cpp
index 770f3b9e..3b5eccc8 100644
--- a/SleepLib/day.cpp
+++ b/SleepLib/day.cpp
@@ -329,8 +329,9 @@ EventDataType Day::Min(ChannelID code)
     EventDataType tmp;
     bool first=true;
     for (QVector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
+        if (!(*s)->enabled()) continue;
 
-        if ((!(*s)->m_min.contains(code)) || (!(*s)->enabled()))
+        if (!(*s)->m_min.contains(code))
             continue;
         tmp=(*s)->Min(code);
         if (first) {
@@ -522,3 +523,42 @@ void Day::CloseEvents()
         (*s)->TrashEvents();
     }
 }
+
+qint64 Day::first()
+{
+    qint64 date=0;
+    qint64 tmp;
+
+    for (QVector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
+        if (!(*s)->enabled()) continue;
+        tmp=(*s)->first();
+        if (!tmp) continue;
+        if (!date) {
+            date=tmp;
+        } else {
+            if (tmp<date) date=tmp;
+        }
+    }
+    return date;
+//    return d_first;
+}
+
+//! \brief Returns the last session time of this day
+qint64 Day::last()
+{
+    qint64 date=0;
+    qint64 tmp;
+
+    for (QVector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
+        if (!(*s)->enabled()) continue;
+        tmp=(*s)->last();
+        if (!tmp) continue;
+        if (!date) {
+            date=tmp;
+        } else {
+            if (tmp>date) date=tmp;
+        }
+    }
+    return date;
+//    return d_last;
+}
diff --git a/SleepLib/day.h b/SleepLib/day.h
index b632699b..036840bb 100644
--- a/SleepLib/day.h
+++ b/SleepLib/day.h
@@ -87,10 +87,10 @@ public:
     EventDataType settings_max(ChannelID code);
 
     //! \brief Returns the first session time of this day
-    qint64 first() { return d_first; }
+    qint64 first();
 
     //! \brief Returns the last session time of this day
-    qint64 last() { return d_last; }
+    qint64 last();
 
     //! \brief Sets the first session time of this day
     void setFirst(qint64 val) { d_first=val; }
diff --git a/SleepLib/profiles.cpp b/SleepLib/profiles.cpp
index 34efbe79..57284439 100644
--- a/SleepLib/profiles.cpp
+++ b/SleepLib/profiles.cpp
@@ -249,12 +249,42 @@ void Profile::AddDay(QDate date,Day *day,MachineType mt) {
     daylist[date].push_back(day);
 }
 
+Day * Profile::GetGoodDay(QDate date,MachineType type)
+{
+    Day *day=NULL;
+    // profile->     why did I d that??
+    if (daylist.find(date)!=daylist.end()) {
+        for (QList<Day *>::iterator di=daylist[date].begin();di!=daylist[date].end();di++) {
+
+            if (type==MT_UNKNOWN) { // Who cares.. We just want to know there is data available.
+                day=(*di);
+                break;
+            }
+            if ((*di)->machine_type()==type) {
+                bool b=false;
+                for (int i=0;i<(*di)->size();i++) {
+                    if ((*(*di))[i]->enabled()) {
+                        b=true;
+                        break;
+                    }
+                }
+                if (b) {
+                    day=(*di);
+                    break;
+                }
+            }
+        }
+    }
+    return day;
+}
+
 Day * Profile::GetDay(QDate date,MachineType type)
 {
     Day *day=NULL;
     // profile->     why did I d that??
     if (daylist.find(date)!=daylist.end()) {
         for (QList<Day *>::iterator di=daylist[date].begin();di!=daylist[date].end();di++) {
+
             if (type==MT_UNKNOWN) { // Who cares.. We just want to know there is data available.
                 day=(*di);
                 break;
@@ -556,7 +586,7 @@ int Profile::countDays(MachineType mt, QDate start, QDate end)
     QDate date=start;
     int days=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             if ((mt==MT_UNKNOWN) || (day->machine->GetType()==mt)) days++;
         }
@@ -568,13 +598,13 @@ int Profile::countDays(MachineType mt, QDate start, QDate end)
 
 EventDataType Profile::calcCount(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double val=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             val+=day->count(code);
         }
@@ -584,13 +614,13 @@ EventDataType Profile::calcCount(ChannelID code, MachineType mt, QDate start, QD
 }
 double Profile::calcSum(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double val=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             val+=day->sum(code);
         }
@@ -600,13 +630,13 @@ double Profile::calcSum(ChannelID code, MachineType mt, QDate start, QDate end)
 }
 EventDataType Profile::calcHours(MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double val=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             val+=day->hours();
         }
@@ -616,14 +646,14 @@ EventDataType Profile::calcHours(MachineType mt, QDate start, QDate end)
 }
 EventDataType Profile::calcAvg(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double val=0;
     int cnt=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             val+=day->sum(code);
             cnt++;
@@ -636,14 +666,14 @@ EventDataType Profile::calcAvg(ChannelID code, MachineType mt, QDate start, QDat
 EventDataType Profile::calcWavg(ChannelID code, MachineType mt, QDate start, QDate end)
 {
     if (!start.isValid())
-        start=LastDay(mt);
+        start=LastGoodDay(mt);
     if (!end.isValid())
-        end=LastDay(mt);
+        end=LastGoodDay(mt);
     QDate date=start;
 
     double val=0,tmp,tmph,hours=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             tmph=day->hours();
             tmp=day->wavg(code);
@@ -658,13 +688,13 @@ EventDataType Profile::calcWavg(ChannelID code, MachineType mt, QDate start, QDa
 }
 EventDataType Profile::calcMin(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double min=99999999,tmp;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             tmp=day->Min(code);
             if (min>tmp) min=tmp;
@@ -676,13 +706,13 @@ EventDataType Profile::calcMin(ChannelID code, MachineType mt, QDate start, QDat
 }
 EventDataType Profile::calcMax(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double max=-99999999,tmp;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             tmp=day->Max(code);
             if (max<tmp) max=tmp;
@@ -694,13 +724,13 @@ EventDataType Profile::calcMax(ChannelID code, MachineType mt, QDate start, QDat
 }
 EventDataType Profile::calcSettingsMin(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double min=99999999,tmp;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             tmp=day->settings_min(code);
             if (min>tmp) min=tmp;
@@ -712,13 +742,13 @@ EventDataType Profile::calcSettingsMin(ChannelID code, MachineType mt, QDate sta
 }
 EventDataType Profile::calcSettingsMax(ChannelID code, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
     QDate date=start;
 
     double max=-99999999,tmp;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             tmp=day->settings_max(code);
             if (max<tmp) max=tmp;
@@ -738,8 +768,8 @@ struct CountSummary {
 
 EventDataType Profile::calcPercentile(ChannelID code, EventDataType percent, MachineType mt, QDate start, QDate end)
 {
-    if (!start.isValid()) start=LastDay(mt);
-    if (!end.isValid()) end=LastDay(mt);
+    if (!start.isValid()) start=LastGoodDay(mt);
+    if (!end.isValid()) end=LastGoodDay(mt);
 
     QDate date=start;
 
@@ -754,7 +784,7 @@ EventDataType Profile::calcPercentile(ChannelID code, EventDataType percent, Mac
     bool setgain=false;
     //double val=0,tmp,hours=0;
     do {
-        Day * day=GetDay(date,mt);
+        Day * day=GetGoodDay(date,mt);
         if (day) {
             for (int i=0;i<day->size();i++) {
                 for (QVector<Session *>::iterator s=day->begin();s!=day->end();s++) {
@@ -854,3 +884,29 @@ QDate Profile::LastDay(MachineType mt)
     } while (d>=m_first);
     return m_first;
 }
+
+QDate Profile::FirstGoodDay(MachineType mt)
+{
+    if (mt==MT_UNKNOWN) //|| (!m_last.isValid()) || (!m_first.isValid()))
+        return FirstDay();
+
+    QDate d=FirstDay(mt);
+    QDate l=LastDay(mt);
+    do {
+        if (GetGoodDay(d,mt)!=NULL) return d;
+        d=d.addDays(1);
+    } while (d<=l);
+    return l; //m_last;
+}
+QDate Profile::LastGoodDay(MachineType mt)
+{
+    if (mt==MT_UNKNOWN) //|| (!m_last.isValid()) || (!m_first.isValid()))
+        return FirstDay();
+    QDate d=LastDay(mt);
+    QDate f=FirstDay(mt);
+    do {
+        if (GetGoodDay(d,mt)!=NULL) return d;
+        d=d.addDays(-1);
+    } while (d>=f);
+    return f; //m_first;
+}
diff --git a/SleepLib/profiles.h b/SleepLib/profiles.h
index 7b74ac1c..3bfaca94 100644
--- a/SleepLib/profiles.h
+++ b/SleepLib/profiles.h
@@ -84,6 +84,10 @@ public:
     //! \brief Get Day record if data available for date and machine type, else return NULL
     Day * GetDay(QDate date,MachineType type=MT_UNKNOWN);
 
+    //! \brief Get Day record if data available for date and machine type, and has enabled session data, else return NULL
+    Day * GetGoodDay(QDate date,MachineType type);
+
+
     //! \brief Returns a list of all machines of type t
     QList<Machine *> GetMachines(MachineType t=MT_UNKNOWN);
 
@@ -116,6 +120,9 @@ public:
     QDate FirstDay(MachineType mt=MT_UNKNOWN);
     QDate LastDay(MachineType mt=MT_UNKNOWN);
 
+    QDate FirstGoodDay(MachineType mt=MT_UNKNOWN);
+    QDate LastGoodDay(MachineType mt=MT_UNKNOWN);
+
     QString dataFolder() { return (*this).Get("{DataFolder}"); }
 
     UserInfo *user;
diff --git a/mainwindow.cpp b/mainwindow.cpp
index fbf4a051..77cb4713 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -526,8 +526,8 @@ void MainWindow::on_summaryButton_clicked()
 {
     QString html=htmlHeader();
 
-    QDate lastcpap=p_profile->LastDay(MT_CPAP);
-    QDate firstcpap=p_profile->FirstDay(MT_CPAP);
+    QDate lastcpap=p_profile->LastGoodDay(MT_CPAP);
+    QDate firstcpap=p_profile->FirstGoodDay(MT_CPAP);
     QDate cpapweek=lastcpap.addDays(-7);
     QDate cpapmonth=lastcpap.addDays(-30);
     QDate cpap6month=lastcpap.addMonths(-6);
@@ -706,8 +706,8 @@ void MainWindow::on_summaryButton_clicked()
     }
     int oxisize=oximeters.size();
     if (oxisize>0) {
-        QDate lastoxi=p_profile->LastDay(MT_OXIMETER);
-        QDate firstoxi=p_profile->FirstDay(MT_OXIMETER);
+        QDate lastoxi=p_profile->LastGoodDay(MT_OXIMETER);
+        QDate firstoxi=p_profile->FirstGoodDay(MT_OXIMETER);
         int days=PROFILE.countDays(MT_OXIMETER,firstoxi,lastoxi);
         if (days>0) {
             html+=QString("<tr><td colspan=6 align=center><b>%1</b></td></tr>").arg(tr("Oximetry Summary"));
@@ -803,7 +803,7 @@ void MainWindow::on_summaryButton_clicked()
         int cnt=0;
         QVector<RXChange> rxchange;
         do {
-            day=PROFILE.GetDay(date,MT_CPAP);
+            day=PROFILE.GetGoodDay(date,MT_CPAP);
 
             if (day) {
                 lastchanged=false;
@@ -1077,12 +1077,12 @@ void MainWindow::updateFavourites()
     ui->favouritesList->blockSignals(true);
     ui->favouritesList->clear();
 
-    QDate date=PROFILE.LastDay();
+    QDate date=PROFILE.LastGoodDay();
     if (!date.isValid())
         return;
 
     do {
-        Day * journal=PROFILE.GetDay(date,MT_JOURNAL);
+        Day * journal=PROFILE.GetGoodDay(date,MT_JOURNAL);
         if (journal) {
             if (journal->size()>0) {
                 Session *sess=(*journal)[0];
@@ -1107,7 +1107,7 @@ void MainWindow::updateFavourites()
         }
 
         date=date.addDays(-1);
-    } while (date>=PROFILE.FirstDay());
+    } while (date>=PROFILE.FirstGoodDay());
     ui->favouritesList->blockSignals(false);
 }
 
@@ -1525,8 +1525,8 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
 
     int graph_slots=0;
     if (name==STR_TR_Daily) {
-        cpap=PROFILE.GetDay(date,MT_CPAP);
-        oxi=PROFILE.GetDay(date,MT_OXIMETER);
+        cpap=PROFILE.GetGoodDay(date,MT_CPAP);
+        oxi=PROFILE.GetGoodDay(date,MT_OXIMETER);
         QString cpapinfo=date.toString(Qt::SystemLocaleLongDate)+"\n\n";
         if (cpap) {
             time_t f=cpap->first()/1000L;