/// <summary>
        ///     See <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_get_reference.html">GetReference</a>.
        ///     <para />
        ///     From the documentation: Tracking results are reported relative to a predefined right-handed Cartesian coordinate
        ///     system, called the reference system. The default reference system is located at 1 meter from the PST Tracker. It is
        ///     oriented such that the Z-axis points away from the PST tracker and the X-axis is parallel to the PST tracker. The
        ///     transformation matrix defining the reference system is a row-major 4x4 homogeneous transformation matrix.
        /// </summary>
        public Matrix4x4 GetReference()
        {
            RestRequest   request  = new RestRequest("GetReference");
            IRestResponse response = m_client.Get(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.Log(PstUtility.GetPstLogMessage(MSG_EMPTY_RESP));
                return(Matrix4x4.identity);
            }

            if (m_logSingleResponses)
            {
                Debug.Log(PstUtility.GetPstLogMessage(response.Content));
            }

            Matrix4x4 referenceMatrix =
                Array.ConvertAll(
                    ValuesBetweenBrackets(response.Content),
                    x => { return(float.Parse(x, NumberFormatInfo.InvariantInfo)); })
                .FromRowMajor();

            // the identity matrix represents the default PST reference system, which is located at 1 meter away from the tracker
            // meaning whenever we get an identity matrix, we need to return a matrix that accurately represents this 1 meter offset!
            if (referenceMatrix.isIdentity)
            {
                referenceMatrix.SetPosition(new Vector3(0, 0, 1));
            }

            return(referenceMatrix);
        }
        public void ProcessTrackerDataString(string restResponseContent)
        {
            string[] trackerData = restResponseContent.Split(
                new[] { "\r\n", "data: " }, StringSplitOptions.RemoveEmptyEntries);

            //trackerData.PrintElements();
            for (int i = 0; i < trackerData.Length; i++)
            {
                // sanity check
                if (!trackerData[i].StartsWith(@"{""TrackerData"":"))
                {
                    continue;
                }

                try
                {
                    TrackerData td = JsonConvert.DeserializeObject <TrackerDataWrapper>(trackerData[i]).trackerData;
                    CacheData(td);
                }
                catch (JsonException e)
                {
                    Debug.LogWarning(
                        PstUtility.GetPstLogMessage(
                            "Consider adjusting the stream's polling interval or buffer size if this happens more often. " +
                            $"Error: {e.Message}."));
                }
                catch (Exception e)
                {
                    Debug.LogWarning(PstUtility.GetPstLogMessage($"An error occured: {e.Message}."));
                }
            }
        }
        /// <summary>
        ///     See
        ///     <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_set_reference.html">SetReference</a>
        ///     .
        /// </summary>
        public void SetReference(Matrix4x4 newReference)
        {
            if (!newReference.ValidTRS())
            {
                Debug.LogWarning(PstUtility.GetPstLogMessage("No valid TRS matrix given. Not setting reference!"));
                return;
            }

            RestRequest request = new RestRequest("SetReference");
            var         tmp     = new { ReferenceMatrix = newReference.ToRowMajor() };

            request.AddJsonBody(tmp);

            IRestResponse response = m_client.Post(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.Log(PstUtility.GetPstLogMessage(MSG_EMPTY_RESP));
                return;
            }

            if (m_logSingleResponses)
            {
                Debug.Log(PstUtility.GetPstLogMessage(response.Content));
            }
        }
        /// <summary>
        ///     See
        ///     <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_get_framerate.html">GetFramerate</a>.
        /// </summary>
        public double GetFramerate()
        {
            RestRequest   request  = new RestRequest("GetFramerate");
            IRestResponse response = m_client.Get(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.Log(PstUtility.GetPstLogMessage(MSG_EMPTY_RESP));
                return(default);
        /// <summary>
        ///     See
        ///     <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_start_tracker_data_stream.html">
        ///         StartTrackerDataStream
        ///     </a>
        ///     .
        /// </summary>
        public void StartTrackerDataStream()
        {
            if (s_processingContinuousTrackerData)
            {
                Debug.Log(PstUtility.GetPstLogMessage("PST TrackerData is already being processed."));
                return;
            }

            s_processingContinuousTrackerData = true;

            RestRequest request = new RestRequest("StartTrackerDataStream");

            request.ResponseWriter = stream =>
            {
                Task.Run(
                    () =>
                {
                    using (stream)
                    {
                        if (!stream.CanRead)
                        {
                            Debug.LogError(PstUtility.GetPstLogMessage("Cannot 'Read' stream!"));
                            s_processingContinuousTrackerData = false;
                            return;
                        }

                        // making buffer sufficiently large s.t. only complete 'TrackerData' is read from the stream
                        // --> no chunk, which has to be put together later on
                        byte[] buffer = new byte[m_trackerDataStreamBufferSize];
                        int readSize  = 0;
                        while (s_processingContinuousTrackerData)
                        {
                            Array.Clear(buffer, 0, m_trackerDataStreamBufferSize);
                            if ((readSize = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                // cutting the zero bytes of the buffer before converting them to string
                                string contentAsString =
                                    Encoding.UTF8.GetString(buffer, 0, readSize);

                                if (m_logContinuousResponses)
                                {
                                    Debug.Log($"{readSize}; {contentAsString}");
                                }

                                OnNewTrackerData?.Invoke(contentAsString);
                            }

                            Thread.Sleep(m_pollInterval);
                        }
                    }
                }).Start();
            };

            m_client.ExecuteAsync(request, null);
        }
        /// <summary>
        ///     See
        ///     <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_set_default_reference.html">SetDefaultReference</a>
        ///     .
        /// </summary>
        public void SetDefaultReference()
        {
            RestRequest   request  = new RestRequest("SetDefaultReference");
            IRestResponse response = m_client.Post(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.Log(PstUtility.GetPstLogMessage(MSG_EMPTY_RESP));
                return;
            }

            if (m_logSingleResponses)
            {
                Debug.Log(PstUtility.GetPstLogMessage(response.Content));
            }
        }
        /// <summary>
        ///     See <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_pause.html">Pause</a>.
        /// </summary>
        public void Pause()
        {
            s_processingContinuousTrackerData = false;

            RestRequest   request  = new RestRequest("Pause");
            IRestResponse response = m_client.Post(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.Log(PstUtility.GetPstLogMessage(MSG_EMPTY_RESP));
                return;
            }

            if (m_logSingleResponses)
            {
                Debug.Log(PstUtility.GetPstLogMessage(response.Content));
            }
        }
        /// <summary>
        ///     See
        ///     <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_get_target_list.html">GetTargetList</a>.
        /// </summary>
        public string GetTargetList()
        {
            RestRequest   request  = new RestRequest("GetTargetList");
            IRestResponse response = m_client.Get(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.Log(PstUtility.GetPstLogMessage(MSG_EMPTY_RESP));
                return(string.Empty);
            }

            if (m_logSingleResponses)
            {
                Debug.Log(PstUtility.GetPstLogMessage(response.Content));
            }

            return(response.Content);
        }
        /// <summary>
        ///     See <a href="file:///C:/Program%20Files%20(x86)/PS-Tech/PST/Development/docs/_start.html">Start</a>.
        /// </summary>
        public void Start()
        {
            RestRequest   request  = new RestRequest("Start");
            IRestResponse response = m_client.Post(request);

            request  = new RestRequest("Start");
            response = m_client.Post(request);

            if (string.IsNullOrEmpty(response.Content))
            {
                Debug.LogError(PstUtility.GetPstLogMessage("REST Server not running."));
                s_serverIsOnline = false;
                return;
            }

            if (m_logSingleResponses)
            {
                Debug.Log(PstUtility.GetPstLogMessage(response.Content));
            }

            s_serverIsOnline = true;
        }