/// <summary>
        /// Deletes an existing simulator assignment and saves the changes to the simulatorAssignments.csv file.
        /// </summary>
        /// <returns>True if deletion was successful (or if the specified assignment wasn't found), false otherwise.</returns>
        public static bool DeleteAssignment(SimulatorAssignment assignment)
        {
            SimulatorAssignment existingAssignment = simulatorAssignments.Where(a => a.SimulatorId == assignment.SimulatorId).FirstOrDefault();

            if (existingAssignment == null)
            {
                return(true);
            }

            simulatorAssignments.Remove(existingAssignment);

            //load and update the csv file
            Exception ex;
            DataTable dtAssignments = Logging.CsvHandler.ReadCSVFile(myPathToSimulatorAssignments, out ex);

            if (dtAssignments == null || ex != null)
            {
                MessageBox.Show("Interner Fehler beim Löschen der Simulatorzuweisung. Die Zuweisungen werden nicht angewendet.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            dtAssignments.PrimaryKey = new DataColumn[] { dtAssignments.Columns[0] }; //set a primary key on the "simulatorId" column for easier searching

            //remove existing row if possible
            DataRow existingRow = dtAssignments.Rows.Find(assignment.SimulatorId);

            if (existingRow != null)
            {
                dtAssignments.Rows.Remove(existingRow);
                return(Logging.CsvHandler.WriteDataTable(dtAssignments, ';', myPathToSimulatorAssignments) == null);
            }

            return(true);
        }
        /// <summary>
        /// Loads all known assignments from the *csv file and adds them to the assignedSimulators-dictionary.
        /// </summary>
        private static Exception LoadAssignments()
        {
            if (simulatorAssignments == null)
            {
                #region Load assignments
                simulatorAssignments = new List <SimulatorAssignment>();

                Exception ex;
                DataTable dtAssignments = Logging.CsvHandler.ReadCSVFile(myPathToSimulatorAssignments, out ex);

                if (dtAssignments == null || ex != null)
                {
                    return(new Exception("Interner Fehler beim Laden der Simulatorzuweisungen."));
                }

                if ((string)dtAssignments.Columns[1].ColumnName != "simulatorAssignments" || dtAssignments.Columns.Count != assignmentsFileHeader.Split(';').Count()) //the file is outdated --> delete all assignments and notify the user that they have to be made again
                {
                    ResetAssignments();
                    simulatorAssignments.Clear();
                }

                try
                {
                    foreach (DataRow row in dtAssignments.Rows) //parse all assignments (there can be only one assignment per simulator id)
                    {
                        string simId = row[0].ToString();
                        SimulatorAssignmentsManager.SimulatorAssignments assignment = (SimulatorAssignmentsManager.SimulatorAssignments)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorAssignments), row[1].ToString());
                        SimulatorAssignmentsManager.SimulatorPositions   position   = (SimulatorAssignmentsManager.SimulatorPositions)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorPositions), row[2].ToString());
                        SimulatorAssignmentsManager.SimulationMattresses mattress   = (SimulatorAssignmentsManager.SimulationMattresses)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulationMattresses), row[3].ToString());
                        string customName = row[4].ToString();

                        if (simulatorAssignments.Where(a => a.SimulatorId == simId).Count() > 0)
                        {
                            return(new Exception("Fehler beim Lesen der Simulatorzuweisungen: der Simulator mit der Seriennummer " + simId + " kommt mehrfach vor!"));
                        }

                        SimulatorAssignment newAssignment = new SimulatorAssignment(simId, assignment, position, mattress, customName);
                        simulatorAssignments.Add(newAssignment);
                    }
                }
                catch (Exception exc)
                {
                    simulatorAssignments.Clear();
                    ResetAssignments();
                    return(exc);
                }
                #endregion
            }

            return(null);
        }
        /// <summary>
        /// Returns the corresponding simulator object for the specified assignment, position and mattress type. The last two parameters can be ommited.
        /// Special case: if the required assignment is "Simulation" and no object can be found, the assignment "Druckmessung_und_Simulation" is also checked.
        /// </summary>
        /// <returns>The correct simulator object or null if no simulator was specified for the assignment.</returns>
        public static CBaseSimulator GetSimulatorObject(SimulatorAssignments assignment, SimulatorPositions position = (SimulatorPositions)(-1), SimulationMattresses mattress = (SimulationMattresses)(-1)) //optional parameters
        {
            //get the id of the simulator that is assigned to the specified assignment
            string id = "";
            SimulatorAssignment existingAssignment = null;

QueryStart:
            var result = simulatorAssignments.Where(a => a.Assignment == assignment);

            if ((int)position > -1)
            {
                result = result.Where(r => r.Position == position);
            }

            if ((int)mattress > -1)
            {
                result = result.Where(r => r.Mattress == mattress);
            }

            existingAssignment = result.FirstOrDefault();

            if (existingAssignment != null)
            {
                id = existingAssignment.SimulatorId;
            }
            else if (assignment == SimulatorAssignments.Simulation)
            {
                assignment = SimulatorAssignments.Druckmessung_und_Simulation_Kaltschaum; //re-attempt the query with a slightly different assignment that includes the "Simulation" assignment
                goto QueryStart;
            }
            else if (assignment == SimulatorAssignments.Druckmessung_und_Simulation_Kaltschaum)
            {
                assignment = SimulatorAssignments.Druckmessung_und_Simulation_NaturLatex; //re-attempt the query with a slightly different assignment that also includes the "Simulation" assignment
                goto QueryStart;
            }

            if (string.IsNullOrEmpty(id)) //no simulator available
            {
                return(null);
            }

            return(SimulatorController.MultiSimulatorMode.SimulatorControl.Instance.GetSimulatorById(id));
        }
        /// <summary>
        /// Adds a simulator assignment and saves it in the simulatorAssignments.csv file.
        /// There can be multiple assignments with the same simulator, but an assignment cannot have multiple simulators assigned to it.
        /// </summary>
        /// <param name="assignmentName">The name of the form to where the simulator is assigned to.</param>
        /// <param name="simulatorID">The hardware ID of the simulator.</param>
        /// <returns>True if the adding was successful (or if the assignment was already existing); false otherwise.</returns>
        public static bool AddOrUpdateAssignment(SimulatorAssignment assignment)
        {
            if (simulatorAssignments.Count(a => a.SimulatorId == assignment.SimulatorId) != 0) //update existing assigment (remove the old one and add the new one)
            {
                simulatorAssignments.Remove(simulatorAssignments.Where(a => a.SimulatorId == assignment.SimulatorId).FirstOrDefault());
            }

            simulatorAssignments.Add(assignment);

            //load and update the csv file
            Exception ex;
            DataTable dtAssignments = Logging.CsvHandler.ReadCSVFile(myPathToSimulatorAssignments, out ex);

            if (dtAssignments == null || ex != null)
            {
                MessageBox.Show("Interner Fehler beim Speichern der Simulatorzuweisungen. Die Zuweisungen werden nicht angewendet.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            dtAssignments.PrimaryKey = new DataColumn[] { dtAssignments.Columns[0] }; //set a primary key on the "simulatorId" column for easier searching

            //remove existing row if possible
            DataRow existingRow = dtAssignments.Rows.Find(assignment.SimulatorId);

            if (existingRow != null)
            {
                dtAssignments.Rows.Remove(existingRow);
            }

            //add a new row
            DataRow newRow = dtAssignments.NewRow();

            newRow[0] = assignment.SimulatorId;
            newRow[1] = assignment.Assignment;
            newRow[2] = assignment.Position;
            newRow[3] = assignment.Mattress;
            newRow[4] = assignment.CustomAssignmentName;
            dtAssignments.Rows.Add(newRow);

            return(Logging.CsvHandler.WriteDataTable(dtAssignments, ';', myPathToSimulatorAssignments) == null);
        }
        /// <summary>
        /// Validates and saves the assignments.
        /// </summary>
        private void bSave_Click(object sender, EventArgs e)
        {
            #region Validation
            //only 1 simulator may have the pressure mapping assignment
            int pressureMappingCnt = 0;
            if ((string)cbDeviceAssignment1.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung.ToString() || (string)cbDeviceAssignment1.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_Kaltschaum.ToString() || (string)cbDeviceAssignment1.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_NaturLatex.ToString())
            {
                pressureMappingCnt++;
            }
            if ((string)cbDeviceAssignment2.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung.ToString() || (string)cbDeviceAssignment2.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_Kaltschaum.ToString() || (string)cbDeviceAssignment2.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_NaturLatex.ToString())
            {
                pressureMappingCnt++;
            }
            if ((string)cbDeviceAssignment3.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung.ToString() || (string)cbDeviceAssignment3.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_Kaltschaum.ToString() || (string)cbDeviceAssignment3.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_NaturLatex.ToString())
            {
                pressureMappingCnt++;
            }
            if ((string)cbDeviceAssignment4.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung.ToString() || (string)cbDeviceAssignment4.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_Kaltschaum.ToString() || (string)cbDeviceAssignment4.Text == SimulatorAssignmentsManager.SimulatorAssignments.Druckmessung_und_Simulation_NaturLatex.ToString())
            {
                pressureMappingCnt++;
            }

            if (pressureMappingCnt != 1 && pressureMappingCnt != 2)
            {
                MessageBox.Show("Bitte weisen Sie maximal zwei Simulatoren die Funktion \"Druckmessung\" bzw. \"Druckmessung_und_Simulation_Kaltschaum\" und \"Druckmessung_und_Simulation_NaturLatex\" zu!", "Zuweisungen nicht korrekt", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            //check if a simulator has been assigned multiple times
            List <string> simulatorSerialNbrs = new List <string>()
            {
                (string)cbSerialNbr1.Text, (string)cbSerialNbr2.Text, (string)cbSerialNbr3.Text, (string)cbSerialNbr4.Text
            };

            //delete any "Nicht verwendet" selections
            simulatorSerialNbrs = simulatorSerialNbrs.Where(s => s != COMBOBOX_ITEM_NOT_USED).ToList();

            if (simulatorSerialNbrs.Count != simulatorSerialNbrs.Distinct().Count())
            {
                MessageBox.Show("Es wurde mindestens ein Simulator doppelt eingerichtet. Bitte stellen Sie sicher, dass jede Seriennummer nur einmal verwendet wird!", "Simulator doppelt", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            //if a serial number was selected, all other settings have to be made as well
            #endregion

            #region Save assignments
            bool success = true;

            List <SimulatorAssignment> unchangedAssignments = SimulatorAssignmentsManager.GetSimulatorAssignments();

            if (cbSerialNbr1.SelectedIndex > 0)
            {
                string simId = cbSerialNbr1.Text;
                SimulatorAssignmentsManager.SimulatorAssignments assignment = (SimulatorAssignmentsManager.SimulatorAssignments)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorAssignments), cbDeviceAssignment1.Text);
                SimulatorAssignmentsManager.SimulatorPositions   position   = (SimulatorAssignmentsManager.SimulatorPositions)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorPositions), cbPosition1.Text);
                SimulatorAssignmentsManager.SimulationMattresses mattress   = (SimulatorAssignmentsManager.SimulationMattresses)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulationMattresses), cbMattress1.Text);
                string customName = tbCustomName1.Text;

                SimulatorAssignment newAssignment = new SimulatorAssignment(simId, assignment, position, mattress, customName);

                success &= SimulatorAssignmentsManager.AddOrUpdateAssignment(newAssignment);

                if (unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr1.Text).Count() == 1) //remove the assignment from the list if it was existing before
                {
                    unchangedAssignments.Remove(unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr1.Text).FirstOrDefault());
                }
            }

            if (cbSerialNbr2.SelectedIndex > 0)
            {
                string simId = cbSerialNbr2.Text;
                SimulatorAssignmentsManager.SimulatorAssignments assignment = (SimulatorAssignmentsManager.SimulatorAssignments)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorAssignments), cbDeviceAssignment2.Text);
                SimulatorAssignmentsManager.SimulatorPositions   position   = (SimulatorAssignmentsManager.SimulatorPositions)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorPositions), cbPosition2.Text);
                SimulatorAssignmentsManager.SimulationMattresses mattress   = (SimulatorAssignmentsManager.SimulationMattresses)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulationMattresses), cbMattress2.Text);
                string customName = tbCustomName2.Text;

                SimulatorAssignment newAssignment = new SimulatorAssignment(simId, assignment, position, mattress, customName);

                success &= SimulatorAssignmentsManager.AddOrUpdateAssignment(newAssignment);

                if (unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr2.Text).Count() == 1) //remove the assignment from the list if it was existing before
                {
                    unchangedAssignments.Remove(unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr2.Text).FirstOrDefault());
                }
            }

            if (cbSerialNbr3.SelectedIndex > 0)
            {
                string simId = cbSerialNbr3.Text;
                SimulatorAssignmentsManager.SimulatorAssignments assignment = (SimulatorAssignmentsManager.SimulatorAssignments)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorAssignments), cbDeviceAssignment3.Text);
                SimulatorAssignmentsManager.SimulatorPositions   position   = (SimulatorAssignmentsManager.SimulatorPositions)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorPositions), cbPosition3.Text);
                SimulatorAssignmentsManager.SimulationMattresses mattress   = (SimulatorAssignmentsManager.SimulationMattresses)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulationMattresses), cbMattress3.Text);
                string customName = tbCustomName3.Text;

                SimulatorAssignment newAssignment = new SimulatorAssignment(simId, assignment, position, mattress, customName);

                success &= SimulatorAssignmentsManager.AddOrUpdateAssignment(newAssignment);

                if (unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr3.Text).Count() == 1) //remove the assignment from the list if it was existing before
                {
                    unchangedAssignments.Remove(unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr3.Text).FirstOrDefault());
                }
            }

            if (cbSerialNbr4.SelectedIndex > 0)
            {
                string simId = cbSerialNbr4.Text;
                SimulatorAssignmentsManager.SimulatorAssignments assignment = (SimulatorAssignmentsManager.SimulatorAssignments)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorAssignments), cbDeviceAssignment4.Text);
                SimulatorAssignmentsManager.SimulatorPositions   position   = (SimulatorAssignmentsManager.SimulatorPositions)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulatorPositions), cbPosition4.Text);
                SimulatorAssignmentsManager.SimulationMattresses mattress   = (SimulatorAssignmentsManager.SimulationMattresses)Enum.Parse(typeof(SimulatorAssignmentsManager.SimulationMattresses), cbMattress4.Text);
                string customName = tbCustomName4.Text;

                SimulatorAssignment newAssignment = new SimulatorAssignment(simId, assignment, position, mattress, customName);

                success &= SimulatorAssignmentsManager.AddOrUpdateAssignment(newAssignment);

                if (unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr4.Text).Count() == 1) //remove the assignment from the list if it was existing before
                {
                    unchangedAssignments.Remove(unchangedAssignments.Where(a => a.SimulatorId == cbSerialNbr4.Text).FirstOrDefault());
                }
            }

            if (success)
            {
                //check if an assignment has been deleted
                if (unchangedAssignments.Count > 0) //if there are assignments left in this list it means that the user selected "Nicht verwendet" combobox item --> delete these assignments
                {
                    foreach (var assignment in unchangedAssignments)
                    {
                        SimulatorAssignmentsManager.DeleteAssignment(assignment);
                    }
                }

                MessageBox.Show("Die Simulatorzuweisungen wurden erfolgreich übernommen.", "Erfolg", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Fehler beim Speichern der Simulatorzuweisungen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            #endregion
        }