public MITesDataCollectionForm()
        {

            //Initialize the UNIX QueryPerformanceCounter
            UnixTime.InitializeTime();

            //intialize the mode of the software
            this.collectDataMode = false;
            this.isCollectingDetailedData = false;
            this.isPlotting = false;
            this.isExtracting = false;

            //initialize the progress thread
            progressMessage = null;
            aProgressThread = new Thread(new ThreadStart(ProgressThread));
            aProgressThread.Start();

            //initialize the interface components
            InitializeComponent();

            //Initialize where the data will be stored and where the configuration
            //files exist
            this.dataDirectory = Constants.DEFAULT_DATA_STORAGE_DIRECTORY;


            //load the activity and sensor configuration files
            progressMessage = "Loading XML protocol and sensors ...";
            AXML.Reader reader = new AXML.Reader(Constants.MASTER_DIRECTORY, Constants.DEFAULT_DATA_STORAGE_DIRECTORY);
            this.annotation = reader.parse();
            this.annotation.DataDirectory = Constants.DEFAULT_DATA_STORAGE_DIRECTORY;

            SXML.Reader sreader = new SXML.Reader(Constants.MASTER_DIRECTORY, Constants.DEFAULT_DATA_STORAGE_DIRECTORY);
            this.sensors = sreader.parse(Constants.MAX_CONTROLLERS);

            progressMessage += " Completed\r\n";

            progressMessage += "Loading configuration file ...";
            MITesFeatures.core.conf.ConfigurationReader creader = new MITesFeatures.core.conf.ConfigurationReader(Constants.DEFAULT_DATA_STORAGE_DIRECTORY);
            this.configuration = creader.parse();
            progressMessage += " Completed\r\n";

            //calculate how many plots to be drawn
            if (this.sensors.IsHR)
                this.maxPlots = this.sensors.Sensors.Count - 1;
            else
                this.maxPlots = this.sensors.Sensors.Count;


            //Initialize the timers
            progressMessage += "Initializing Timers ...";
            InitializeTimers();
            progressMessage += " Completed\r\n";

            //Initialize different GUI components
            progressMessage += "Initializing GUI ...";
            InitializeInterface();
            progressMessage += " Completed\r\n";

#if (PocketPC)
            this.tabControl1.TabPages.RemoveAt(4);
            this.tabControl1.TabPages.RemoveAt(3);
            this.tabControl1.TabPages.RemoveAt(2);
            this.tabControl1.TabPages.RemoveAt(0);                       
            this.tabControl1.SelectedIndex = 0;
#endif
            progressThreadQuit = true;
        }
        public MITesDataCollectionForm(string dataDirectory)
        {

           //where data is being stored
            this.dataDirectory = dataDirectory;

            //Initialize high resolution unix timer
            UnixTime.InitializeTime();

            //Initialize and start GUI progress thread
            progressMessage = null;
            aProgressThread = new Thread(new ThreadStart(ProgressThread));
            aProgressThread.Start();


            #region Load Configuration files
            //load the activity and sensor configuration files
            progressMessage = "Loading XML protocol and sensors ...";
            AXML.Reader reader = new AXML.Reader(Constants.MASTER_DIRECTORY, dataDirectory);
#if (!PocketPC)
            if (reader.validate() == false)
            {
                throw new Exception("Error Code 0: XML format error - activities.xml does not match activities.xsd!");
            }
            else
            {
#endif
            this.annotation = reader.parse();
            this.annotation.DataDirectory = dataDirectory;
            SXML.Reader sreader = new SXML.Reader(Constants.MASTER_DIRECTORY, dataDirectory);
#if (!PocketPC)

                if (sreader.validate() == false)
                {
                    throw new Exception("Error Code 0: XML format error - sensors.xml does not match sensors.xsd!");
                }
                else
                {
#endif
            this.sensors = sreader.parse(Constants.MAX_CONTROLLERS);
            progressMessage += " Completed\r\n";

            //TODO: remove BT components
            progressMessage += "Loading configuration file ...";
            MITesFeatures.core.conf.ConfigurationReader creader = new MITesFeatures.core.conf.ConfigurationReader(dataDirectory);
            this.configuration = creader.parse();
            progressMessage += " Completed\r\n";
#if (!PocketPC)
                }
            }
#endif
            #endregion Load Configuration files

            //Initialize 1 master decoder
            this.masterDecoder = new MITesDecoder();


            #region Initialize External Data Reception Channels
            //Initialize Data reception for Bluetooth and USB
            if ((this.sensors.TotalReceivers > 0) && (this.sensors.TotalReceivers <= Constants.MAX_CONTROLLERS))
            {

                //Initialize arrays to store USB and Bluetooth controllers
                this.mitesControllers = new MITesReceiverController[this.sensors.TotalWiredReceivers];
#if (PocketPC)
                this.bluetoothControllers = new BluetoothController[this.sensors.TotalBluetoothReceivers];
               // this.ts = new Thread[this.sensors.TotalBluetoothReceivers];
#endif

                //Initialize array to store Bluetooth connection status
                //this.bluetoothConnectionStatus = new bool[this.sensors.TotalBluetoothReceivers];

                //Initialize a decoder for each sensor
                this.mitesDecoders = new MITesDecoder[this.sensors.TotalReceivers];
                
                this.aMITesActivityCounters = new Hashtable();

#if (PocketPC)
                #region Bluetooth reception channels initialization
                //Initialize and search for wockets connections
                progressMessage += "Initializing Bluetooth receivers ... searching " + this.sensors.TotalBluetoothReceivers+ " BT receivers\r\n";                
                //Try to initialize all Bluetooth receivers 10 times then exit
                int initializationAttempt = 0;
                while (initializationAttempt <= 10)
                {
                    if (InitializeBluetoothReceivers() == false)
                    {
                        initializationAttempt++;

                        if (initializationAttempt == 10)
                        {
                            MessageBox.Show("Exiting: Some Bluetooth receivers in your configuration were not initialized.");

                            Application.Exit();
                            System.Diagnostics.Process.GetCurrentProcess().Kill();
                        }
                        else
                            progressMessage += "Failed to initialize all BT connections. Retrying (" + initializationAttempt + ")...\r\n";

                    }
                    else
                        break;
                    Thread.Sleep(2000);
                }
                #endregion Bluetooth reception channels initialization
#endif

                #region USB reception channels initialization

                if (InitializeUSBReceivers() == false)
                {
                    MessageBox.Show("Exiting: Some USB receivers in your configuration were not initialized.");
#if (PocketPC)
                    Application.Exit();
                    System.Diagnostics.Process.GetCurrentProcess().Kill();
#else
                    Environment.Exit(0);
#endif

                }
                #endregion USB reception channels initialization
            }
            #endregion Initialize External Data Reception Channels

#if (PocketPC)
            #region Initialize Builtin Data Reception Channels
            if (InitializeBuiltinReceivers() == false)
            {
                MessageBox.Show("Exiting: A built in receiver channel was not found.");

                Application.Exit();
                System.Diagnostics.Process.GetCurrentProcess().Kill();


            }
            #endregion Initialize Builtin Data Reception Channels
#endif


            #region Initialize GUI Components
            //initialize the interface components
            InitializeComponent();
            //Initialize GUI timers
            progressMessage += "Initializing Timers ...";
            InitializeTimers();
            progressMessage += " Completed\r\n";

            //Initialize different GUI components
            progressMessage += "Initializing GUI ...";
            InitializeInterface();
            progressMessage += " Completed\r\n";

            this.isPlotting = true;
            //count the number of accelerometers
            if (this.sensors.IsHR)
                this.maxPlots = this.sensors.Sensors.Count - 1;
            else
                this.maxPlots = this.sensors.Sensors.Count;
            SetFormPositions();
            if (this.sensors.TotalReceivers > 0)
                aMITesPlotter = new MITesScalablePlotter(this.panel1, MITesScalablePlotter.DeviceTypes.IPAQ, maxPlots, this.masterDecoder, GetGraphSize(false));
            else
                aMITesPlotter = new MITesScalablePlotter(this.panel1, MITesScalablePlotter.DeviceTypes.IPAQ, maxPlots, this.masterDecoder, GetGraphSize(false));

            //Override the resize event
#if (PocketPC)
            this.Resize += new EventHandler(OnResize);
#else
            this.form1.Resize += new EventHandler(OnResizeForm1);
            this.form1.FormClosing += new FormClosingEventHandler(form_FormClosing);
            this.form2.Resize += new EventHandler(OnResizeForm2);
            this.form2.FormClosing += new FormClosingEventHandler(form_FormClosing);
            this.form3.Resize += new EventHandler(OnResizeForm3);
            this.form3.FormClosing += new FormClosingEventHandler(form_FormClosing);
            this.form4.Resize += new EventHandler(OnResizeForm4);
            this.form4.FormClosing += new FormClosingEventHandler(form_FormClosing);
#endif

            //Initialize the quality interface
            progressMessage += "Initializing MITes Quality GUI ...";
            InitializeQualityInterface();
            progressMessage += " Completed\r\n";

            //Remove classifier tabs
#if (PocketPC)

            this.tabControl1.TabPages.RemoveAt(4);
            this.tabControl1.SelectedIndex = 0;
#else
            this.ShowForms();
#endif


            #endregion Initialize GUI Components

            #region Initialize Feature Extraction
            this.isExtracting = false;
            if (this.sensors.TotalReceivers > 0) // if there is at least 1 MIT
                //Extractor.Initialize(this.mitesDecoders[0], dataDirectory, this.annotation, this.sensors, this.configuration);
                Extractor.Initialize(this.masterDecoder, dataDirectory, this.annotation, this.sensors, this.configuration);
            else if (this.sensors.Sensors.Count > 0) // only built in
                Extractor.Initialize(new MITesDecoder(), dataDirectory, this.annotation, this.sensors, this.configuration);
            #endregion Initialize Feature Extraction

            #region Initialize Quality Tracking variables
            InitializeQuality();
            #endregion Initialize Quality Tracking variables

            #region Initialize Logging
            InitializeLogging(dataDirectory);
            #endregion Initialize Logging

            #region Initialize CSV Storage (PC Only)
#if (!PocketPC)

            //create some counters for activity counts
            averageX = new int[this.sensors.MaximumSensorID + 1];
            averageY = new int[this.sensors.MaximumSensorID + 1];
            averageZ = new int[this.sensors.MaximumSensorID + 1];

            averageRawX = new int[this.sensors.MaximumSensorID + 1];
            averageRawY = new int[this.sensors.MaximumSensorID + 1];
            averageRawZ = new int[this.sensors.MaximumSensorID + 1];

            prevX = new int[this.sensors.MaximumSensorID + 1];
            prevY = new int[this.sensors.MaximumSensorID + 1];
            prevZ = new int[this.sensors.MaximumSensorID + 1];
            acCounters = new int[this.sensors.MaximumSensorID + 1];
            activityCountWindowSize = 0;

            activityCountCSVs = new StreamWriter[this.sensors.MaximumSensorID + 1];
            samplingCSVs = new StreamWriter[this.sensors.MaximumSensorID + 1];
            averagedRaw = new StreamWriter[this.sensors.MaximumSensorID + 1];
            masterCSV = new StreamWriter(dataDirectory + "\\MITesSummaryData.csv");
            hrCSV = new StreamWriter(dataDirectory + "\\HeartRate_MITes.csv");

            string csv_line1 = "UnixTimeStamp,TimeStamp,X,Y,Z";
            string csv_line2 = "UnixTimeStamp,TimeStamp,Sampling";
            string hr_csv_header = "UnixTimeStamp,TimeStamp,HR";
            string master_csv_header = "UnixTimeStamp,TimeStamp";
            foreach (Category category in this.annotation.Categories)
                master_csv_header += "," + category.Name;


            foreach (Sensor sensor in this.sensors.Sensors)
            {
                int sensor_id = Convert.ToInt32(sensor.ID);
                string location = sensor.Location.Replace(' ', '-');
                if (sensor_id > 0) //exclude HR
                {
                    activityCountCSVs[sensor_id] = new StreamWriter(dataDirectory + "\\MITes_" + sensor_id.ToString("00") + "_ActivityCount_" + location + ".csv");
                    activityCountCSVs[sensor_id].WriteLine(csv_line1);
                    averagedRaw[sensor_id] = new StreamWriter(dataDirectory + "\\MITes_" + sensor_id.ToString("00") + "_1s-RawMean_" + location + ".csv");
                    averagedRaw[sensor_id].WriteLine(csv_line1);
                    samplingCSVs[sensor_id] = new StreamWriter(dataDirectory + "\\MITes_" + sensor_id.ToString("00") + "_SampleRate_" + location + ".csv");
                    samplingCSVs[sensor_id].WriteLine(csv_line2);
                    master_csv_header += ",MITes" + sensor_id.ToString("00") + "_SR," + "MITes" + sensor_id.ToString("00") + "_AVRaw_X," +
                        "MITes" + sensor_id.ToString("00") + "_AVRaw_Y," + "MITes" + sensor_id.ToString("00") + "_AVRaw_Z," + "MITes" + sensor_id.ToString("00") + "_AC_X," +
                        "MITes" + sensor_id.ToString("00") + "_AC_Y," + "MITes" + sensor_id.ToString("00") + "_AC_Z";

                }
            }

            master_csv_header += ",HR";
            this.masterCSV.WriteLine(master_csv_header);
            this.hrCSV.WriteLine(hr_csv_header);
#endif

            #endregion Initialize CSV Storage (PC Only)

            #region Start Collecting Data
            this.collectDataMode = true;
#if (PocketPC)
            this.isCollectingDetailedData = false;
#else
            this.isCollectingDetailedData = true;
#endif

            //if (this.sensors.TotalReceivers > 0)
            //    isStartedReceiver = true;
            //Start the built in polling thread            
#if (PocketPC)
            if (this.sensors.HasBuiltinSensors)
            {
                this.pollingThread = new Thread(new ThreadStart(this.pollingData));
                this.pollingThread.Priority = ThreadPriority.Lowest;
                this.pollingThread.Start();
            }
#endif

            //Terminate the progress thread
            progressThreadQuit = true;

           
            //Enable all timer functions
            this.readDataTimer.Enabled = true;
            this.qualityTimer.Enabled = true;
            if (this.sensors.IsHR)
                this.HRTimer.Enabled = true;

            #endregion Start Collecting Data

        }
        //This constructor initializes the software for calibration of a list
        //of sensors
        public MITesDataCollectionForm(SensorAnnotation uncalibratedSensors, string dataDirectory)
        {
            //Initialize the UNIX timer to use QueryPerformanceCounter
            UnixTime.InitializeTime();

            //Setup the initial state of the calibration variables
            this.sensors = uncalibratedSensors;
            this.currentCalibrationSensorIndex = 0;
            this.calCounter = 0;

#if (PocketPC)
            this.horizontalMITes = (System.Drawing.Image)new System.Drawing.Bitmap(Constants.MITES_HORIZONTAL_96_96);
            this.verticalMITes = (System.Drawing.Image)new System.Drawing.Bitmap(Constants.MITES_VERTICAL_96_96);
#else
            this.horizontalMITes = (System.Drawing.Image)new System.Drawing.Bitmap(Constants.MITES_HORIZONTAL_288_288);
            this.verticalMITes = (System.Drawing.Image)new System.Drawing.Bitmap(Constants.MITES_VERTICAL_288_288);
#endif

            //create a dummy annotation
            this.annotation = new Annotation();

            //make sure the software will not collect or extract features
            this.collectDataMode = false;
            this.isClassifying = false;
            this.isExtracting = false;
            this.isCollectingDetailedData = false;

            //setup where the sensordata file will be stored
            this.dataDirectory = dataDirectory;

            //setup plotting parameters
            isPlotting = true;
            this.maxPlots = this.sensors.Sensors.Count;

            //Spawn the progress thread
            progressMessage = null;
            aProgressThread = new Thread(new ThreadStart(ProgressThread));
            aProgressThread.Start();





            //Intialize the interface of the forms
            InitializeComponent();
            progressMessage += "Initializing Timers ...";
            InitializeTimers();
            progressMessage += " Completed\r\n";
            progressMessage += "Initializing GUI ...";
            InitializeInterface();
            progressMessage += " Completed\r\n";

            progressMessage += "Loading configuration file ...";
            MITesFeatures.core.conf.ConfigurationReader confreader = new MITesFeatures.core.conf.ConfigurationReader(dataDirectory);
            this.configuration = confreader.parse();
            progressMessage += " Completed\r\n";

#if (PocketPC)

            //setup the Bluetooth if needed
            if (this.configuration.Connection == MITesFeatures.core.conf.Constants.SOFTWARE_CONNECTION_BLUETOOTH)
            {
                progressMessage += "Initializing Bluetooth ...";
                /*
                this.bt = new BluetoothController();
                try
                {
                    this.bluetoothPort = bt.initialize(this.configuration.MacAddress, this.configuration.Passkey);
                }
                catch (Exception e)
                {
                   
                    progressMessage += " Failed\r\n";
                    MessageBox.Show("Failed to find Bluetooth Device... exiting!");
                    bt.close();
                    Application.Exit();
                    System.Diagnostics.Process.GetCurrentProcess().Kill();    
                }
                 */
                progressMessage += " Completed\r\n";
            }
#endif
            //Intialize the MITes Receivers, decoders and counters based
            //on the chosen sensors
            if ((this.sensors.TotalReceivers > 0) && (this.sensors.TotalReceivers <= Constants.MAX_CONTROLLERS))
            {
                this.mitesControllers = new MITesReceiverController[this.sensors.TotalReceivers];
                this.mitesDecoders = new MITesDecoder[this.sensors.TotalReceivers];
                //this.aMITesActivityCounters = new Hashtable();
                progressMessage += "Initializing MITes ... searching " + this.sensors.TotalReceivers + " receivers\r\n";
                if (InitializeMITes(dataDirectory) == false)
                {
                    MessageBox.Show("Exiting: You picked a configuration with " + this.sensors.TotalReceivers + " receivers. Please make sure they are attached to the computer.");
#if (PocketPC)
                    /*
                    bt.close();
                     */
                    Application.Exit();
                    System.Diagnostics.Process.GetCurrentProcess().Kill();    
#else

                    Environment.Exit(0);
                    Application.Exit();
#endif
                }
            }


            //Setup the resize event for each different form
#if (PocketPC)
            this.Resize += new EventHandler(OnResize);
#else
            this.form1.Resize += new EventHandler(OnResizeForm1);
            this.form1.FormClosing += new FormClosingEventHandler(form_FormClosing);
            this.form2.Resize += new EventHandler(OnResizeForm2);
            this.form2.FormClosing += new FormClosingEventHandler(form_FormClosing);
            this.form3.Resize += new EventHandler(OnResizeForm3);
            this.form3.FormClosing += new FormClosingEventHandler(form_FormClosing);
            this.form4.Resize += new EventHandler(OnResizeForm4);
            this.form4.FormClosing += new FormClosingEventHandler(form_FormClosing);
#endif

            //Initialize the interface for reporting the quality of the MITes
            //transmission
            progressMessage += "Initializing MITes Quality GUI ...";
            InitializeQualityInterface();
            progressMessage += " Completed\r\n";

            //Intialize the MITes performance tracking objects
            for (int i = 0; i < MITesData.MAX_MITES_CHANNELS; i++)
                MITesDataFilterer.MITesPerformanceTracker[i] = new MITesPerformanceStats(0);
            foreach (Sensor sensor in this.sensors.Sensors)
            {
                int sensor_id = Convert.ToInt32(sensor.ID);
                int receiver_id = Convert.ToInt32(sensor.Receiver);
                if (sensor_id == 0) //HR sensor
                {
                    MITesDataFilterer.MITesPerformanceTracker[sensor_id].GoodRate = (int)(Constants.HR_SAMPLING_RATE * 0.8);
                    MITesDataFilterer.MITesPerformanceTracker[sensor_id].PerfectRate = Constants.HR_SAMPLING_RATE;
                }
                else
                {
                    int goodSamplingRate = 150;
                    MITesDataFilterer.MITesPerformanceTracker[sensor_id].GoodRate = goodSamplingRate;
                    MITesDataFilterer.MITesPerformanceTracker[sensor_id].PerfectRate = 180;
                }
            }


#if (PocketPC)
            this.tabControl1.SelectedIndex = 0;
#endif


            progressThreadQuit = true;
            //remove unnecessary forms or pages
#if (PocketPC)
            this.tabControl1.TabPages.RemoveAt(1);
            this.tabControl1.TabPages.RemoveAt(2);
            //this.tabControl1.TabPages.RemoveAt(3);
#else
            this.ShowForms();
#endif


            //Only enable the read data time since we are just calibrating
            this.readDataTimer.Enabled = true;

        }