From 22f1d127e4579e3bb6d5963b52160ba6650bb476 Mon Sep 17 00:00:00 2001
From: Mark Watkins <jedimark@users.sourceforge.net>
Date: Thu, 9 Jun 2011 23:49:13 +1000
Subject: [PATCH] MachineLoader Data Version PURGE Dialogs. Warning: This added
 file deletion code. Needs Reviewing.

---
 Projects/CodeBlocks/SleepyHead.depend         | 39 ++++++++--------
 src/GUIFrame.cpp                              |  5 +++
 src/GUIFrame.h                                |  2 +
 src/SleepyHeadMain.cpp                        | 40 ++++++++++++++---
 src/SleepyHeadMain.h                          |  1 +
 src/WxWizFrame.fbp                            | 15 +++++++
 src/graphs/graph.cpp                          | 41 +++++++++++------
 src/libs/sleeplib/binary_file.cpp             |  2 +-
 .../sleeplib/loader_plugins/cms50_loader.cpp  | 13 ++++--
 .../sleeplib/loader_plugins/cms50_loader.h    |  8 ++++
 .../sleeplib/loader_plugins/zeo_loader.cpp    | 13 +++++-
 src/libs/sleeplib/loader_plugins/zeo_loader.h |  7 +++
 src/libs/sleeplib/machine.cpp                 | 40 +++++++++++++++++
 src/libs/sleeplib/machine.h                   |  1 +
 src/libs/sleeplib/machine_loader.h            |  5 ++-
 src/libs/sleeplib/profiles.cpp                | 45 +++++++++++++++++--
 src/libs/sleeplib/profiles.h                  |  4 ++
 src/libs/sleeplib/prs1_loader.cpp             | 10 ++++-
 src/libs/sleeplib/prs1_loader.h               |  8 +++-
 src/version.h                                 | 12 ++---
 20 files changed, 255 insertions(+), 56 deletions(-)

diff --git a/Projects/CodeBlocks/SleepyHead.depend b/Projects/CodeBlocks/SleepyHead.depend
index 0054f070..53a075a1 100644
--- a/Projects/CodeBlocks/SleepyHead.depend
+++ b/Projects/CodeBlocks/SleepyHead.depend
@@ -8210,12 +8210,12 @@
 	"wx/treebase.h"
 	"wx/hashmap.h"
 
-1307521170 source:/home/mark/projects/git/sleepyhead/src/GUIFrame.cpp
+1307618682 source:/home/mark/projects/git/sleepyhead/src/GUIFrame.cpp
 	"wx/wxprec.h"
 	<wx/wx.h>
 	"GUIFrame.h"
 
-1307470075 /home/mark/projects/git/sleepyhead/src/GUIFrame.h
+1307618682 /home/mark/projects/git/sleepyhead/src/GUIFrame.h
 	<wx/intl.h>
 	<wx/string.h>
 	<wx/bitmap.h>
@@ -8258,7 +8258,7 @@
 1307418393 /home/mark/projects/git/sleepyhead/src/SleepyHeadApp.h
 	<wx/app.h>
 
-1307477974 /home/mark/projects/git/sleepyhead/src/SleepyHeadMain.h
+1307618623 /home/mark/projects/git/sleepyhead/src/SleepyHeadMain.h
 	<wx/listbox.h>
 	<wx/treectrl.h>
 	"SleepyHeadApp.h"
@@ -8266,7 +8266,7 @@
 	"sleeplib/machine.h"
 	"graphs/graph.h"
 
-1307479645 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/machine.h
+1307624470 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/machine.h
 	<wx/string.h>
 	<wx/variant.h>
 	<wx/dir.h>
@@ -8304,24 +8304,25 @@
 	<sleeplib/machine.h>
 	<list>
 
-1307616952 /home/mark/projects/git/sleepyhead/src/version.h
+1307627183 /home/mark/projects/git/sleepyhead/src/version.h
 
-1307418393 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/prs1_loader.h
+1307623481 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/prs1_loader.h
 	"machine.h"
 	"machine_loader.h"
 	"profiles.h"
 
-1307418393 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/machine_loader.h
+1307620763 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/machine_loader.h
 	"profiles.h"
 
-1307418393 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/profiles.h
+1307620828 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/profiles.h
 	<wx/string.h>
 	<map>
 	"machine.h"
+	"machine_loader.h"
 	"preferences.h"
 	"tinyxml/tinyxml.h"
 
-1307615758 source:/home/mark/projects/git/sleepyhead/src/SleepyHeadMain.cpp
+1307627009 source:/home/mark/projects/git/sleepyhead/src/SleepyHeadMain.cpp
 	"wx_pch.h"
 	"version.h"
 	<wx/app.h>
@@ -8341,14 +8342,14 @@
 	"sleeplib/profiles.h"
 	"sleeplib/machine_loader.h"
 
-1307615111 source:/home/mark/projects/git/sleepyhead/src/graphs/graph.cpp
+1307618429 source:/home/mark/projects/git/sleepyhead/src/graphs/graph.cpp
 	<wx/settings.h>
 	<wx/dcbuffer.h>
 	<wx/log.h>
 	"graph.h"
 	"sleeplib/profiles.h"
 
-1307418393 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/binary_file.cpp
+1307623396 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/binary_file.cpp
 	<wx/filename.h>
 	"binary_file.h"
 
@@ -8356,11 +8357,12 @@
 	<wx/ffile.h>
 	<wx/utils.h>
 
-1307529366 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/machine.cpp
+1307626196 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/machine.cpp
 	<tr1/random>
 	<wx/colour.h>
 	<wx/log.h>
 	<wx/progdlg.h>
+	<wx/msgdlg.h>
 	"binary_file.h"
 	"machine.h"
 	"profiles.h"
@@ -8377,19 +8379,20 @@
 	<wx/stdpaths.h>
 	"preferences.h"
 
-1307527050 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/profiles.cpp
+1307626707 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/profiles.cpp
 	<wx/filefn.h>
 	<wx/filename.h>
 	<wx/utils.h>
 	<wx/dir.h>
 	<wx/log.h>
+	<wx/msgdlg.h>
 	"preferences.h"
 	"profiles.h"
 	"machine.h"
 	"machine_loader.h"
 	"tinyxml/tinyxml.h"
 
-1307585840 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/prs1_loader.cpp
+1307622945 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/prs1_loader.cpp
 	<wx/dir.h>
 	<wx/filename.h>
 	<wx/ffile.h>
@@ -8419,19 +8422,19 @@
 	"tinyxml.h"
 	<windows.h>
 
-1307418393 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/cms50_loader.h
+1307620082 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/cms50_loader.h
 	"sleeplib/machine_loader.h"
 
-1307529283 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/cms50_loader.cpp
+1307620453 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/cms50_loader.cpp
 	<wx/log.h>
 	<wx/progdlg.h>
 	"cms50_loader.h"
 	"sleeplib/machine.h"
 
-1307418393 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/zeo_loader.h
+1307620144 /home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/zeo_loader.h
 	"sleeplib/machine_loader.h"
 
-1307418393 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/zeo_loader.cpp
+1307620439 source:/home/mark/projects/git/sleepyhead/src/libs/sleeplib/loader_plugins/zeo_loader.cpp
 	<wx/log.h>
 	"zeo_loader.h"
 	"sleeplib/machine.h"
diff --git a/src/GUIFrame.cpp b/src/GUIFrame.cpp
index 88483944..0bdc8dac 100644
--- a/src/GUIFrame.cpp
+++ b/src/GUIFrame.cpp
@@ -58,6 +58,9 @@ GUIFrame::GUIFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
 	ViewMenuSerial = new wxMenuItem( ViewMenu, wxID_ANY, wxString( _("Show Serial Numbers") ) , wxEmptyString, wxITEM_CHECK );
 	ViewMenu->Append( ViewMenuSerial );
 	
+	ViewMenuLinkGraph = new wxMenuItem( ViewMenu, wxID_ANY, wxString( _("Link Graph Movement") ) , wxEmptyString, wxITEM_CHECK );
+	ViewMenu->Append( ViewMenuLinkGraph );
+	
 	ViewMenuFruitsalad = new wxMenuItem( ViewMenu, wxID_ANY, wxString( _("Fruit Salad") ) , wxEmptyString, wxITEM_CHECK );
 	ViewMenu->Append( ViewMenuFruitsalad );
 	
@@ -105,6 +108,7 @@ GUIFrame::GUIFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
 	this->Connect( ViewMenuSummary->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnViewMenuSummary ) );
 	this->Connect( ViewMenuDaily->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnViewMenuDaily ) );
 	this->Connect( ViewMenuSerial->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnShowSerial ) );
+	this->Connect( ViewMenuLinkGraph->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnLinkGraphs ) );
 	this->Connect( ViewMenuFruitsalad->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnFruitsalad ) );
 	this->Connect( ViewMenuFullscreen->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnFullscreen ) );
 	this->Connect( ToolsMenuScreenshot->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnScreenshot ) );
@@ -121,6 +125,7 @@ GUIFrame::~GUIFrame()
 	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnViewMenuSummary ) );
 	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnViewMenuDaily ) );
 	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnShowSerial ) );
+	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnLinkGraphs ) );
 	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnFruitsalad ) );
 	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnFullscreen ) );
 	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIFrame::OnScreenshot ) );
diff --git a/src/GUIFrame.h b/src/GUIFrame.h
index d58b0610..79a9388c 100644
--- a/src/GUIFrame.h
+++ b/src/GUIFrame.h
@@ -48,6 +48,7 @@ class GUIFrame : public wxFrame
 		wxMenu* FileMenu;
 		wxMenu* ViewMenu;
 		wxMenuItem* ViewMenuSerial;
+		wxMenuItem* ViewMenuLinkGraph;
 		wxMenuItem* ViewMenuFruitsalad;
 		wxMenu* ProfileMenu;
 		wxMenu* ToolsMenu;
@@ -62,6 +63,7 @@ class GUIFrame : public wxFrame
 		virtual void OnViewMenuSummary( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnViewMenuDaily( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnShowSerial( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnLinkGraphs( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnFruitsalad( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnFullscreen( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnScreenshot( wxCommandEvent& event ) { event.Skip(); }
diff --git a/src/SleepyHeadMain.cpp b/src/SleepyHeadMain.cpp
index 430025c0..65e617b6 100644
--- a/src/SleepyHeadMain.cpp
+++ b/src/SleepyHeadMain.cpp
@@ -66,6 +66,7 @@ wxString wxbuildinfo(wxbuildinfoformat format)
     return wxbuild;
 }
 
+const long profile_version=0;
 
 SleepyHeadFrame::SleepyHeadFrame(wxFrame *frame)
     : GUIFrame(frame)
@@ -83,10 +84,22 @@ SleepyHeadFrame::SleepyHeadFrame(wxFrame *frame)
 
     if (!pref.Exists("ShowSerialNumbers")) pref["ShowSerialNumbers"]=false;
     if (!pref.Exists("fruitsalad")) pref["fruitsalad"]=true;
+    if (!pref.Exists("LinkGraphMovement")) pref["LinkGraphMovement"]=true;
+    if (!pref.Exists("ProfileVersion")) pref["ProfileVersion"]=(long)0;
+
+    if (pref["ProfileVersion"].GetInteger()<profile_version) {
+        if (wxMessageBox(title+wxT("\n\nChanges have been made that require the profiles database to be recreated\n\nWould you like to do this right now?"),wxT("Profile Database Changes"),wxYES_NO,this)==wxYES) {
+            // Delete all machines from memory.
+            pref["ProfileVersion"]=profile_version;
+
+
+           // assert(1==0);
+        }
+    }
 
     ViewMenuSerial->Check(pref["ShowSerialNumbers"]);
     ViewMenuFruitsalad->Check(pref["fruitsalad"]);
-
+    ViewMenuLinkGraph->Check(pref["LinkGraphMovement"]);
 
     // wxDisableAsserts();
 
@@ -244,6 +257,10 @@ void SleepyHeadFrame::DoScreenshot( wxCommandEvent &event )
     }
 #endif
 }
+void SleepyHeadFrame::OnLinkGraphs( wxCommandEvent& event )
+{
+    pref["LinkGraphMovement"]=event.IsChecked();
+}
 void SleepyHeadFrame::OnShowSerial(wxCommandEvent& event)
 {
     pref["ShowSerialNumbers"]=event.IsChecked();
@@ -647,7 +664,7 @@ Daily::Daily(wxWindow *win,Profile *p)
     LEAK->AddLayer(new gXAxis(wxBLACK));
     LEAK->AddLayer(new gYAxis(wxBLACK));
     LEAK->AddLayer(new gFooBar());
-    LEAK->AddLayer(new gLineChart(leakdata,wxPURPLE,4096,false,false,false));
+    LEAK->AddLayer(new gLineChart(leakdata,wxPURPLE,4096,false,false,true));
 
     AddCPAPData(pressure_iap=new EventData(CPAP_IAP));
     AddCPAPData(pressure_eap=new EventData(CPAP_EAP));
@@ -695,16 +712,29 @@ Daily::Daily(wxWindow *win,Profile *p)
     SF=new gGraphWindow(ScrolledWindow,-1,wxT("Event Flags"),wxPoint(0,0), wxSize(600,180), wxNO_BORDER);
   //  SF->SetMargins(10,15,20,80);
 
-    SF->LinkZoom(FRW);
+//    #if defined(__UNIX__)
     FRW->LinkZoom(SF);
-    #if defined(__UNIX__)
     FRW->LinkZoom(PRD);
     FRW->LinkZoom(LEAK);
     FRW->LinkZoom(SNORE);
+    SF->LinkZoom(FRW);
     SF->LinkZoom(PRD); // Uncomment to link in more graphs.. Too slow on windows.
     SF->LinkZoom(LEAK);
     SF->LinkZoom(SNORE);
-    #endif
+    PRD->LinkZoom(SF);
+    PRD->LinkZoom(FRW);
+    PRD->LinkZoom(LEAK);
+    PRD->LinkZoom(SNORE);
+    LEAK->LinkZoom(SF);
+    LEAK->LinkZoom(FRW);
+    LEAK->LinkZoom(PRD);
+    LEAK->LinkZoom(SNORE);
+    SNORE->LinkZoom(SF);
+    SNORE->LinkZoom(FRW);
+    SNORE->LinkZoom(PRD);
+    SNORE->LinkZoom(LEAK);
+
+  //  #endif
 
     const int sfc=9;
 
diff --git a/src/SleepyHeadMain.h b/src/SleepyHeadMain.h
index 7c7099d3..8a0359a6 100644
--- a/src/SleepyHeadMain.h
+++ b/src/SleepyHeadMain.h
@@ -110,6 +110,7 @@ class SleepyHeadFrame: public GUIFrame
         virtual void OnShowSerial(wxCommandEvent& event);
         virtual void OnProfileSelected(wxCommandEvent& event);
         virtual void OnFruitsalad(wxCommandEvent& event);
+		virtual void OnLinkGraphs( wxCommandEvent& event );
 
 
         virtual void UpdateProfiles();
diff --git a/src/WxWizFrame.fbp b/src/WxWizFrame.fbp
index 57172dc9..4fb47c8f 100644
--- a/src/WxWizFrame.fbp
+++ b/src/WxWizFrame.fbp
@@ -305,6 +305,21 @@
                         <event name="OnMenuSelection">OnShowSerial</event>
                         <event name="OnUpdateUI"></event>
                     </object>
+                    <object class="wxMenuItem" expanded="1">
+                        <property name="bitmap"></property>
+                        <property name="checked">0</property>
+                        <property name="enabled">1</property>
+                        <property name="help"></property>
+                        <property name="id">wxID_ANY</property>
+                        <property name="kind">wxITEM_CHECK</property>
+                        <property name="label">Link Graph Movement</property>
+                        <property name="name">ViewMenuLinkGraph</property>
+                        <property name="permission">protected</property>
+                        <property name="shortcut"></property>
+                        <property name="unchecked_bitmap"></property>
+                        <event name="OnMenuSelection">OnLinkGraphs</event>
+                        <event name="OnUpdateUI"></event>
+                    </object>
                     <object class="wxMenuItem" expanded="1">
                         <property name="bitmap"></property>
                         <property name="checked">0</property>
diff --git a/src/graphs/graph.cpp b/src/graphs/graph.cpp
index 336ab1c2..92b04439 100644
--- a/src/graphs/graph.cpp
+++ b/src/graphs/graph.cpp
@@ -380,11 +380,22 @@ void gGraphWindow::OnMouseMove(wxMouseEvent &event)
         }
         m_foobar_moved+=fabs((qx-minx))+fabs((m_mouseLClick.x-x))+fabs((m_mouseLClick.y-y));
         SetXBounds(qx,ex);
-
+        if (pref["LinkGraphMovement"]) {
+            for (list<gGraphWindow *>::iterator g=link_zoom.begin();g!=link_zoom.end();g++) {
+                (*g)->SetXBounds(qx,ex);
+            }
+        }
     } else
     if (event.m_rightDown) {
         MoveX(event.GetX() - m_mouseRClick.x);
         m_mouseRClick.x=event.GetX();
+        double min=MinX();
+        double max=MaxX();
+        if (pref["LinkGraphMovement"]) {
+            for (list<gGraphWindow *>::iterator g=link_zoom.begin();g!=link_zoom.end();g++) {
+                (*g)->SetXBounds(min,max);
+            }
+        }
     } else
     if (event.m_leftDown) {
 
@@ -530,24 +541,20 @@ void gGraphWindow::OnMouseLeftRelease(wxMouseEvent &event)
         }
     }
 
-    if (!did_draw && !zoom_in && m_mouseLDown) { // && !m_drag_foobar)  {
+    if (!did_draw && !zoom_in && m_mouseLDown) {
         wxPoint release(event.GetX(), m_scrY-m_marginBottom);
         wxPoint press(m_mouseLClick.x, m_marginTop);
         int x1=m_mouseRBrect.x;
         int x2=x1+m_mouseRBrect.width;
+        int t1=MIN(x1,x2);
+        int t2=MAX(x1,x2);
 
-        //if (m_mouseLDown && !m_drag_foobar) { //hot1.Contains(x,y) &&
-            int t1=MIN(x1,x2);
-            int t2=MAX(x1,x2);
+        if ((t2-t1)>4) {
+            // Range Selected
+            ZoomXPixels(t1,t2);
+            did_draw=true;
+        }
 
-            if ((t2-t1)>4) {
-                // Range Selected
-                ZoomXPixels(t1,t2);
-                did_draw=true;
-            }
-
-        //}
-        //goto end;
     }
 
 
@@ -563,7 +570,6 @@ void gGraphWindow::OnMouseLeftRelease(wxMouseEvent &event)
             ZoomX(zoom_fact,xp); //event.GetX()); // adds origin to zoom in.. Doesn't look that cool.
         }
         did_draw=true;
-        //goto end;
     }
 
     m_drag_foobar=false;
@@ -574,7 +580,14 @@ void gGraphWindow::OnMouseLeftRelease(wxMouseEvent &event)
     if (!did_draw) { // Should never happen.
         if (r!=m_mouseRBrect)
             Refresh();
+    //} else { // Update any linked graphs..
     }
+        double min=MinX();
+        double max=MaxX();
+        for (list<gGraphWindow *>::iterator g=link_zoom.begin();g!=link_zoom.end();g++) {
+            (*g)->SetXBounds(min,max);
+        }
+    //}
     LastGraphLDown=NULL;
     event.Skip();
 }
diff --git a/src/libs/sleeplib/binary_file.cpp b/src/libs/sleeplib/binary_file.cpp
index 93b66219..3c8daef2 100644
--- a/src/libs/sleeplib/binary_file.cpp
+++ b/src/libs/sleeplib/binary_file.cpp
@@ -40,7 +40,7 @@ bool BinaryFile::Open(wxString filename,BFOpenMode mode)
     if (wxFileExists(filename)) {
         if (mode==BF_WRITE) {
             // hmm.. file exists. unsure of best course of action here..
-            return false;
+          //  return false;
         }
         size=wxFileName::GetSize(filename).GetLo();
     }
diff --git a/src/libs/sleeplib/loader_plugins/cms50_loader.cpp b/src/libs/sleeplib/loader_plugins/cms50_loader.cpp
index 46b89865..07179c88 100644
--- a/src/libs/sleeplib/loader_plugins/cms50_loader.cpp
+++ b/src/libs/sleeplib/loader_plugins/cms50_loader.cpp
@@ -5,6 +5,13 @@ Author: Mark Watkins <jedimark64@users.sourceforge.net>
 License: GPL
 */
 
+//********************************************************************************************
+/// IMPORTANT!!!
+//********************************************************************************************
+// Please INCREMENT the cms50_data_version in cms50_loader.h when making changes to this loader
+// that change loader behaviour or modify channels.
+//********************************************************************************************
+
 #include <wx/log.h>
 #include <wx/progdlg.h>
 #include "cms50_loader.h"
@@ -249,7 +256,7 @@ Machine *CMS50Loader::CreateMachine(Profile *profile)
     vector<Machine *> ml=profile->GetMachines(MT_OXIMETER);
 
     for (vector<Machine *>::iterator i=ml.begin(); i!=ml.end(); i++) {
-        if ((*i)->GetClass()==wxT("CMS50"))  {
+        if ((*i)->GetClass()==cms50_class_name)  {
             return (*i);
             break;
         }
@@ -258,10 +265,10 @@ Machine *CMS50Loader::CreateMachine(Profile *profile)
     wxLogDebug(wxT("Create CMS50 Machine Record"));
 
     Machine *m=new Oximeter(profile,0);
-    m->SetClass(wxT("CMS50"));
+    m->SetClass(cms50_class_name);
     m->properties[wxT("Brand")]=wxT("Contec");
     m->properties[wxT("Model")]=wxT("CMS50X");
-
+    m->properties[wxT("DataVersion")]=wxString::Format("%li",cms50_data_version);
     profile->AddMachine(m);
 
     return m;
diff --git a/src/libs/sleeplib/loader_plugins/cms50_loader.h b/src/libs/sleeplib/loader_plugins/cms50_loader.h
index 084be58e..12a62068 100644
--- a/src/libs/sleeplib/loader_plugins/cms50_loader.h
+++ b/src/libs/sleeplib/loader_plugins/cms50_loader.h
@@ -10,17 +10,25 @@ License: GPL
 
 #include "sleeplib/machine_loader.h"
 
+const wxString cms50_class_name=wxT("CMS50");
+const int cms50_data_version=1;
 
 class CMS50Loader : public MachineLoader
 {
     public:
+
+
         CMS50Loader();
         virtual ~CMS50Loader();
         virtual bool Open(wxString & path,Profile *profile);
         static void Register();
 
+        virtual int Version() { return cms50_data_version; };
+        virtual const wxString & ClassName() { return cms50_class_name; };
+
         Machine *CreateMachine(Profile *profile);
 
+
     protected:
         bool OpenCMS50(wxString & path, Profile *profile);
         bool OpenSPORFile(wxString path, Machine * machine,Profile *profile);
diff --git a/src/libs/sleeplib/loader_plugins/zeo_loader.cpp b/src/libs/sleeplib/loader_plugins/zeo_loader.cpp
index af75d23a..a5772217 100644
--- a/src/libs/sleeplib/loader_plugins/zeo_loader.cpp
+++ b/src/libs/sleeplib/loader_plugins/zeo_loader.cpp
@@ -5,6 +5,14 @@ Author: Mark Watkins <jedimark64@users.sourceforge.net>
 License: GPL
 */
 
+//********************************************************************************************
+/// IMPORTANT!!!
+//********************************************************************************************
+// Please INCREMENT the zeo_data_version in zel_loader.h when making changes to this loader
+// that change loader behaviour or modify channels.
+//********************************************************************************************
+
+
 #include <wx/log.h>
 #include "zeo_loader.h"
 #include "sleeplib/machine.h"
@@ -37,7 +45,7 @@ Machine *ZEOLoader::CreateMachine(Profile *profile)
     vector<Machine *> ml=profile->GetMachines(MT_SLEEPSTAGE);
 
     for (vector<Machine *>::iterator i=ml.begin(); i!=ml.end(); i++) {
-        if ((*i)->GetClass()==wxT("ZEO"))  {
+        if ((*i)->GetClass()==zeo_class_name)  {
             return (*i);
             break;
         }
@@ -46,9 +54,10 @@ Machine *ZEOLoader::CreateMachine(Profile *profile)
     wxLogDebug(wxT("Create ZEO Machine Record"));
 
     Machine *m=new SleepStage(profile,0);
-    m->SetClass(wxT("ZEO"));
+    m->SetClass(zeo_class_name);
     m->properties[wxT("Brand")]=wxT("ZEO");
     m->properties[wxT("Model")]=wxT("Personal Sleep Coach");
+    m->properties[wxT("DataVersion")]=wxString::Format("%li",zeo_data_version);
 
     profile->AddMachine(m);
 
diff --git a/src/libs/sleeplib/loader_plugins/zeo_loader.h b/src/libs/sleeplib/loader_plugins/zeo_loader.h
index ed992a0d..1d70136c 100644
--- a/src/libs/sleeplib/loader_plugins/zeo_loader.h
+++ b/src/libs/sleeplib/loader_plugins/zeo_loader.h
@@ -10,6 +10,9 @@ License: GPL
 
 #include "sleeplib/machine_loader.h"
 
+const wxString zeo_class_name=wxT("CMS50");
+const int zeo_data_version=1;
+
 
 class ZEOLoader : public MachineLoader
 {
@@ -19,6 +22,10 @@ class ZEOLoader : public MachineLoader
         virtual bool Open(wxString & path,Profile *profile);
         static void Register();
 
+        virtual int Version() { return zeo_data_version; };
+        virtual const wxString & ClassName() { return zeo_class_name; };
+
+
         Machine *CreateMachine(Profile *profile);
 
     protected:
diff --git a/src/libs/sleeplib/machine.cpp b/src/libs/sleeplib/machine.cpp
index cd03b311..b329d627 100644
--- a/src/libs/sleeplib/machine.cpp
+++ b/src/libs/sleeplib/machine.cpp
@@ -2,6 +2,7 @@
 #include <wx/colour.h>
 #include <wx/log.h>
 #include <wx/progdlg.h>
+#include <wx/msgdlg.h>
 #include "binary_file.h"
 #include "machine.h"
 #include "profiles.h"
@@ -273,6 +274,45 @@ Day *Machine::AddSession(Session *s,Profile *p)
     return day[date];
 }
 
+// This functions purpose is murder and mayhem... It deletes all of a machines data.
+// Therefore this is the most dangerous function in this software..
+bool Machine::Purge(int secret)
+{
+    // Boring api key to stop this function getting called by accident :)
+    if (secret!=3478216) return false;
+
+
+    // It would be joyous if this function screwed up..
+    wxString path=profile->Get("DataFolder")+wxFileName::GetPathSeparator()+hexid();
+
+    wxDir dir;
+    wxLogDebug(wxT("Purging ")+path);
+    dir.Open(path);
+    if (!dir.IsOpened()) return false;
+
+    wxString filename;
+    bool cont=dir.GetFirst(&filename);
+
+    int could_not_kill=0;
+    while (cont) {
+        // KILL KILL KILL..
+        wxString fullpath=path+wxFileName::GetPathSeparator()+filename;
+        wxString ext_s=filename.AfterLast(wxChar('.'));
+        long ext;
+        // But only files with numerical extensions.
+        if (ext_s.ToLong(&ext)) {
+            if (!wxRemoveFile(fullpath)) could_not_kill++;
+        }
+
+        cont=dir.GetNext(&filename);
+    }
+    if (could_not_kill>0) {
+        wxMessageBox(wxT("Could not purge path\n")+path+wxT("\n\n")+wxString::Format(wxT("%i"),could_not_kill)+wxT(" file(s) remain.. Suggest manually deleting this path"),wxT("Purge Error"),wxOK,NULL);
+        return false;
+    }
+
+    return true;
+}
 bool Machine::Load()
 {
     wxString path=profile->Get("DataFolder")+wxFileName::GetPathSeparator()+hexid();
diff --git a/src/libs/sleeplib/machine.h b/src/libs/sleeplib/machine.h
index fc41694f..4d55aae9 100644
--- a/src/libs/sleeplib/machine.h
+++ b/src/libs/sleeplib/machine.h
@@ -162,6 +162,7 @@ public:
 
     bool Load();
     bool Save();
+    bool Purge(int secret);
 
     map<wxDateTime,Day *> day;
     map<SessionID,Session *> sessionlist;
diff --git a/src/libs/sleeplib/machine_loader.h b/src/libs/sleeplib/machine_loader.h
index 6ca0851c..e3d1679c 100644
--- a/src/libs/sleeplib/machine_loader.h
+++ b/src/libs/sleeplib/machine_loader.h
@@ -16,7 +16,10 @@ class MachineLoader
 public:
     MachineLoader();
     virtual ~MachineLoader();
-    virtual bool Open(wxString &,Profile *profile)=0;
+    virtual bool Open(wxString &,Profile *profile){};
+    virtual int Version(){};
+    virtual const wxString & ClassName(){};
+
 };
 
 void RegisterLoader(MachineLoader *loader);
diff --git a/src/libs/sleeplib/profiles.cpp b/src/libs/sleeplib/profiles.cpp
index f4c97578..7e236974 100644
--- a/src/libs/sleeplib/profiles.cpp
+++ b/src/libs/sleeplib/profiles.cpp
@@ -11,6 +11,7 @@ License: GPL
 #include <wx/utils.h>
 #include <wx/dir.h>
 #include <wx/log.h>
+#include <wx/msgdlg.h>
 
 #include "preferences.h"
 #include "profiles.h"
@@ -53,7 +54,30 @@ Profile::~Profile()
 void Profile::LoadMachineData()
 {
     for (map<MachineID,Machine *>::iterator i=machlist.begin(); i!=machlist.end(); i++) {
-        i->second->Load();
+        Machine *m=i->second;
+
+        MachineLoader *loader=GetLoader(m->GetClass());
+        if (loader) {
+            long v=loader->Version();
+            long cv=0;
+            if (m->properties.find(wxT("DataVersion"))==m->properties.end())
+                m->properties[wxT("DataVersion")]=wxString::Format("%i",0);
+            m->properties["DataVersion"].ToLong(&cv);
+            if (cv<v) {
+                wxString msg=wxT("Software changes have been made that require the reimporting of the following machines data:\n\n");
+                msg=msg+m->properties[wxT("Brand")]+wxT(" ")+m->properties[wxT("Model")]+wxT(" ")+m->properties[wxT("Serial")];
+                msg=msg+wxT("\n\nNo attempt will be made to load previous data.\n\n");
+                msg=msg+wxT("Importing ALL of your data for this machine again will rectify this problem.\n\n");
+                msg=msg+wxT("However, if you have more than one seperate datacard/stash for this machine, it would be best if the machine data was purged first.\n\nWould you like me to do this for you?");
+
+                if (wxMessageBox(msg,wxT("Machine Database Changes"),wxYES_NO,NULL)==wxYES) {
+
+                    if (m->Purge(3478216)) { // Do not copy this line without thinking.. You will be eaten by a Grue if you do
+                        m->properties["DataVersion"]=wxString::Format("%li",v); // Dont need to nag again if they are too lazy.
+                    }
+                }
+            } else  m->Load();
+        }
     }
 }
 
@@ -175,6 +199,19 @@ void Profile::Import(wxString path)
     }
 }
 
+MachineLoader * GetLoader(wxString name)
+{
+    MachineLoader *l=NULL;
+    list<MachineLoader *>loaders=GetLoaders();
+    for (list<MachineLoader *>::iterator i=loaders.begin(); i!=loaders.end(); i++) {
+        if ((*i)->ClassName()==name) {
+            l=*i;
+            break;
+        }
+    }
+    return l;
+}
+
 
 vector<Machine *> Profile::GetMachines(MachineType t)
 // Returns a vector containing all machine objects regisered of type t
@@ -240,12 +277,12 @@ Profile *Get()
 {
     return profile;
 }
+
+
+
 /**
  * @brief Scan Profile directory loading user profiles
  */
-
-
-
 void Scan()
 {
     InitMapsWithoutAwesomeInitializerLists();
diff --git a/src/libs/sleeplib/profiles.h b/src/libs/sleeplib/profiles.h
index a22e40f3..98fa5a89 100644
--- a/src/libs/sleeplib/profiles.h
+++ b/src/libs/sleeplib/profiles.h
@@ -13,6 +13,7 @@ License: GPL
 #include <wx/string.h>
 #include <map>
 #include "machine.h"
+#include "machine_loader.h"
 #include "preferences.h"
 #include "tinyxml/tinyxml.h"
 
@@ -55,6 +56,9 @@ protected:
 
 };
 
+class MachineLoader;
+extern MachineLoader * GetLoader(wxString name);
+
 extern Preferences *p_pref;
 extern Preferences *p_layout;
 #define pref (*p_pref)
diff --git a/src/libs/sleeplib/prs1_loader.cpp b/src/libs/sleeplib/prs1_loader.cpp
index aec043b0..efc53fcb 100644
--- a/src/libs/sleeplib/prs1_loader.cpp
+++ b/src/libs/sleeplib/prs1_loader.cpp
@@ -18,6 +18,13 @@ License: GPL
 
 #include "prs1_loader.h"
 
+//********************************************************************************************
+/// IMPORTANT!!!
+//********************************************************************************************
+// Please INCREMENT the prs1_data_version in prs1_loader.h when making changes to this loader
+// that change loader behaviour or modify channels.
+//********************************************************************************************
+
 
 extern wxProgressDialog *loader_progress;
 
@@ -26,7 +33,7 @@ map<int,wxString> ModelMap;
 // This class technically isn't needed now.. as long as m_class, Brand & Model is set, things should be fine.
 PRS1::PRS1(Profile *p,MachineID id):CPAP(p,id)
 {
-    m_class=wxT("PRS1");
+    m_class=prs1_class_name;
     properties[wxT("Brand")]=wxT("Philips Respironics");
     properties[wxT("Model")]=wxT("System One");
 
@@ -353,6 +360,7 @@ int PRS1Loader::OpenMachine(Machine *m,wxString path,Profile *profile)
         //wxPrintf(sess->start().Format()+wxT(" avgsummary=%.3f avgmine=%.3f\n"),sess->summary[CPAP_PressureAverage].GetDouble(),sess->weighted_avg_event_field(CPAP_Pressure,0));
         sess->SetChanged(true);
     }
+    m->properties["DataVersion"]=wxString::Format("%i",prs1_data_version);
     m->Save(); // Save any new sessions to disk in our format
     if (loader_progress) loader_progress->Update(100);
     return true;
diff --git a/src/libs/sleeplib/prs1_loader.h b/src/libs/sleeplib/prs1_loader.h
index d1b144d7..0e8e34cd 100644
--- a/src/libs/sleeplib/prs1_loader.h
+++ b/src/libs/sleeplib/prs1_loader.h
@@ -22,15 +22,21 @@ public:
     virtual ~PRS1();
 };
 
+
 const int max_load_buffer_size=384*1024;
 
+const int prs1_data_version=1;
+
+const wxString prs1_class_name=wxT("PRS1");
+
 class PRS1Loader : public MachineLoader
 {
 public:
     PRS1Loader();
     virtual ~PRS1Loader();
     virtual bool Open(wxString & path,Profile *profile);
-
+    virtual int Version() { return prs1_data_version; };
+    virtual const wxString & ClassName() { return prs1_class_name; };
     Machine *CreateMachine(wxString serial,Profile *profile);
 
     static void Register();
diff --git a/src/version.h b/src/version.h
index 8f689c68..b7a114f2 100644
--- a/src/version.h
+++ b/src/version.h
@@ -16,14 +16,14 @@ namespace AutoVersion{
 	//Standard Version Type
 	static const long MAJOR = 0;
 	static const long MINOR = 7;
-	static const long BUILD = 4132;
-	static const long REVISION = 5787;
+	static const long BUILD = 4224;
+	static const long REVISION = 6281;
 	
 	//Miscellaneous Version Types
-	static const long BUILDS_COUNT = 2515;
-	#define RC_FILEVERSION 0,7,4132,5787
-	#define RC_FILEVERSION_STRING "0, 7, 4132, 5787\0"
-	static const char FULLVERSION_STRING[] = "0.7.4132.5787";
+	static const long BUILDS_COUNT = 2704;
+	#define RC_FILEVERSION 0,7,4224,6281
+	#define RC_FILEVERSION_STRING "0, 7, 4224, 6281\0"
+	static const char FULLVERSION_STRING[] = "0.7.4224.6281";
 	
 	//These values are to keep track of your versioning state, don't modify them.
 	static const long BUILD_HISTORY = 0;