/// <summary>
        /// Queues each line of g-code for printing.
        /// </summary>
        public void Print()
        {
            //Queue each line of GCode for printing.
            string modiPrintGCodeStr = _gCodeManagerViewModel.GetModiPrintGCode();

            string[]      modiPrintGCodeArr  = modiPrintGCodeStr.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
            List <string> modiPrintGCodeList = modiPrintGCodeArr.ToList <string>();

            _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(modiPrintGCodeList);
        }
        /// <summary>
        /// Sends outgoing commands that retracts all Z Axes and moves X and Y Axes to the limit switches.
        /// </summary>
        public void Home(double xCalibrationSpeed, double yCalibrationSpeed, double zCalibrationSpeed, double xDistanceFromCenter, double yDistanceFromCenter)
        {
            try
            {
                //Retract Z Axes.
                RetractAllZ(zCalibrationSpeed);

                //Z Axes should be in default positions.
                AxisModel zAxisModel = _printerModel.ZAxisModelList[_printerModel.ZAxisModelList.Count - 1];
                double    zPosition  = zAxisModel.MaxPosition - GlobalValues.LimitBuffer;
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(SerialMessageCharacters.SerialCommandSetCharacter + "SetMinMaxPos " + "Z" + zPosition);

                //Set X Axis to calibration speeds.
                AxisModel xAxis       = _printerModel.AxisModelList[0];
                int       xLimitPinID = (xAxis.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : xAxis.AttachedLimitSwitchGPIOPinModel.PinID;
                string    switchX     = _writeSetAxisModel.WriteSetAxis(xAxis.AxisID, xAxis.AttachedMotorStepGPIOPinModel.PinID, xAxis.AttachedMotorDirectionGPIOPinModel.PinID, xAxis.StepPulseTime,
                                                                        xLimitPinID, xCalibrationSpeed, xAxis.MaxAcceleration, xAxis.MmPerStep);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchX);

                //Set Y Axis to max speeds.
                AxisModel yAxis       = _printerModel.AxisModelList[1];
                int       yLimitPinID = (yAxis.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : yAxis.AttachedLimitSwitchGPIOPinModel.PinID;
                string    switchY     = _writeSetAxisModel.WriteSetAxis(yAxis.AxisID, yAxis.AttachedMotorStepGPIOPinModel.PinID, yAxis.AttachedMotorDirectionGPIOPinModel.PinID, yAxis.StepPulseTime,
                                                                        yLimitPinID, yCalibrationSpeed, yAxis.MaxAcceleration, yAxis.MmPerStep);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchY);

                //Hit the min and max limit switches on X.
                double unused    = 0;
                string xPositive = GCodeLinesConverter.GCodeLinesListToString(
                    WriteG00.WriteAxesMovement(
                        xAxis.MmPerStep, 0, 0,
                        5000, 0, 0,
                        xAxis.IsDirectionInverted, false, false,
                        ref unused, ref unused, ref unused));
                string xNegative = GCodeLinesConverter.GCodeLinesListToString(
                    WriteG00.WriteAxesMovement(
                        xAxis.MmPerStep, 0, 0,
                        -5000, 0, 0,
                        xAxis.IsDirectionInverted, false, false,
                        ref unused, ref unused, ref unused));
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(xPositive);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(xNegative);

                //Move away from the limit switch.
                string xMoveAwayFromLimit = GCodeLinesConverter.GCodeLinesListToString(
                    WriteG00.WriteAxesMovement(
                        xAxis.MmPerStep, 0, 0,
                        GlobalValues.LimitBuffer, 0, 0,
                        xAxis.IsDirectionInverted, false, false,
                        ref unused, ref unused, ref unused));
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(xMoveAwayFromLimit);

                //Hit the min and max limit switches on Y.
                string yPositive = GCodeLinesConverter.GCodeLinesListToString(
                    WriteG00.WriteAxesMovement(
                        0, yAxis.MmPerStep, 0,
                        0, 5000, 0,
                        yAxis.IsDirectionInverted, false, false,
                        ref unused, ref unused, ref unused));
                string yNegative = GCodeLinesConverter.GCodeLinesListToString(
                    WriteG00.WriteAxesMovement(
                        0, yAxis.MmPerStep, 0,
                        0, -5000, 0,
                        yAxis.IsDirectionInverted, false, false,
                        ref unused, ref unused, ref unused));
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(yPositive);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(yNegative);

                //Move away from the limit switch.
                string yMoveAwayFromLimit = GCodeLinesConverter.GCodeLinesListToString(
                    WriteG00.WriteAxesMovement(
                        0, yAxis.MmPerStep, 0,
                        0, GlobalValues.LimitBuffer, 0,
                        yAxis.IsDirectionInverted, false, false,
                        ref unused, ref unused, ref unused));
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(yMoveAwayFromLimit);

                //Set X Axis to max speeds.
                string switchXMax = _writeSetAxisModel.WriteSetAxis(xAxis);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchXMax);

                //Set Y Axis to max speeds.
                string switchYMax = _writeSetAxisModel.WriteSetAxis(yAxis);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchYMax);

                //Center the X and Y actuators.
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(SerialMessageCharacters.SerialCommandSetCharacter + "Center X" + xDistanceFromCenter + " Y" + yDistanceFromCenter);
                _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(SerialMessageCharacters.SerialCommandSetCharacter + "OriginXY");

                //At the end, switch the Z actuator to the Printhead used at the beginning of the print.
                if (_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name != "Unset")
                {
                    AxisModel zAxisFinalModel  = _printerModel.FindAxis(_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name);
                    int       zFinalLimitPinID = (zAxisFinalModel.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : zAxisFinalModel.AttachedLimitSwitchGPIOPinModel.PinID;
                    string    switchZFinal     = _writeSetAxisModel.WriteSetAxis(zAxisFinalModel.AxisID, zAxisFinalModel.AttachedMotorStepGPIOPinModel.PinID, zAxisFinalModel.AttachedMotorDirectionGPIOPinModel.PinID,
                                                                                 zAxisFinalModel.StepPulseTime, zFinalLimitPinID, zCalibrationSpeed, zAxisFinalModel.MaxAcceleration, zAxisFinalModel.MmPerStep);
                    _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchZFinal);
                }

                OnCalibrationBegun();
            }
            catch
            {
                _errorListViewModel.AddError("", "Unkown error when homing");
            }
        }