void ResetPlaybackEnd()
        {
            currentUpdate = loadedRecording.updates[loadedRecording.updates.Count - 1];
            nextUpdate    = loadedRecording.updates[loadedRecording.updates.Count - 2];

            updateCount = loadedRecording.updates.Count - 1;
            playerTime  = maxTime;

            ResetScene();
            ApplyUpdate();
        }
        void ResetPlaybackStart()
        {
            currentUpdate = loadedRecording.updates[0];
            nextUpdate    = loadedRecording.updates[1];

            updateCount = 1;
            playerTime  = 0;

            ResetScene();
            ApplyUpdate();
        }
        void UpdateRecording()
        {
            if (curTime >= nextTick)
            {
                nextTick = curTime + tick;

                Rec_Update update = new Rec_Update();
                update.objList = new List <Rec_Object>();
                update.time    = curTime;

                //recordText += "\t<update seconds=\"" + curTime + "\" >\n";

                foreach (GameObject obj in recordObjects)
                {
                    //recordText += "\t\t<object name=\"" + obj.name + "\" tag=\"" + obj.tag + "\" >\n";
                    //recordText += "\t\t\t<position x=\"" + obj.transform.position.x + "\" " + "y=\"" + obj.transform.position.y + "\" " + "z =\"" + obj.transform.position.z + "\" />\n";
                    //recordText += "\t\t\t<rotation x=\"" + obj.transform.rotation.eulerAngles.x + "\" " + "y=\"" + obj.transform.rotation.eulerAngles.y + "\" " + "z =\"" + obj.transform.rotation.eulerAngles.z + "\" />\n";
                    //recordText += "\t\t</object>\n";

                    Rec_Object rec_obj = new Rec_Object();
                    rec_obj.active   = obj.activeInHierarchy;
                    rec_obj.name     = obj.name;
                    rec_obj.tag      = obj.tag;
                    rec_obj.position = obj.transform.position;
                    rec_obj.rotation = obj.transform.rotation.eulerAngles;

                    update.objList.Add(rec_obj);
                }

                recording.updates.Add(update);
                //recordText += "\t</update>\n";

                //if(OVRInput.Get(OVRInput.RawButton.RIndexTrigger))
                //{
                //    recordText += "\t<action seconds=\"" + (curTime - startTime) + "\" type=\"r_grabbing\" />\n";
                //}
                //else if(OVRInput.Get(OVRInput.RawButton.LIndexTrigger))
                //{
                //    recordText += "\t<action seconds=\"" + (curTime - startTime) + "\" type=\"l_grabbing\" />\n";
                //}
            }

            curTime += Time.deltaTime;
        }
        public void ReversePlayback()
        {
            if (IsState(State.Playing) || IsState(State.Paused))
            {
                if (playbackSpeed >= 0)
                {
                    updateCount -= 2;
                    if (updateCount <= 0)
                    {
                        updateCount = 0;
                        playerTime  = 0;
                        SetState(State.Ended);
                    }
                }
                else if (playbackSpeed <= 0)
                {
                    updateCount += 2;
                    if (updateCount >= loadedRecording.updates.Count)
                    {
                        updateCount = loadedRecording.updates.Count - 1;
                        playerTime  = maxTime;
                        SetState(State.Ended);
                    }
                }

                playbackSpeed *= -1;

                nextUpdate = loadedRecording.updates[updateCount];
            }
            else if (IsPrevState(State.Ended))
            {
                playbackSpeed *= -1;

                if (playbackSpeed < 0)
                {
                    ResetPlaybackEnd();
                }
                else if (playbackSpeed >= 0)
                {
                    ResetPlaybackStart();
                }
            }
        }
        void UpdatePlaying()
        {
            if (playbackSpeed > 0.0f)
            {
                if (playerTime >= nextUpdate.time)
                {
                    if (++updateCount >= loadedRecording.updates.Count)
                    {
                        updateCount = 0;
                        playerTime  = 0;
                        SetState(State.Ended);
                        return;
                    }

                    currentUpdate = nextUpdate;
                    nextUpdate    = loadedRecording.updates[updateCount];
                }
            }
            else if (playbackSpeed < 0.0f)
            {
                if (playerTime <= nextUpdate.time)
                {
                    if (--updateCount <= 0)
                    {
                        updateCount = loadedRecording.updates.Count - 1;
                        playerTime  = maxTime;
                        SetState(State.Ended);
                        return;
                    }

                    currentUpdate = nextUpdate;
                    nextUpdate    = loadedRecording.updates[updateCount];
                }
            }
            else
            {
                return;
            }

            ApplyUpdate();

            playerTime += Time.deltaTime * playbackSpeed;
        }
        void UpdateLoad()
        {
            //LoadRecordingFromDisk(Application.persistentDataPath + "/" + fileName + ".xml");

            loadedRecording         = new Recording();
            loadedRecording.updates = new List <Rec_Update>();

            int child = 0;

            if (xmlDoc.FirstChild.Name == "xml")
            {
                child++;
            }

            // <start time="00:00:00" >
            recordingMetaData = "Start Time: " + xmlDoc.ChildNodes[child].FirstChild.Attributes.GetNamedItem("time").Value;
            // <start date="DD/MM/YYYY" >
            recordingMetaData += "\nStart Date: " + xmlDoc.ChildNodes[child].FirstChild.Attributes.GetNamedItem("date").Value;
            // <end time="00:00:00" >
            recordingMetaData += "\nEnd Time: " + xmlDoc.ChildNodes[child].LastChild.Attributes.GetNamedItem("time").Value;

            if (xmlDoc.ChildNodes[child].ChildNodes.Count > 2)
            {
                for (int i = 1; i < xmlDoc.ChildNodes[child].ChildNodes.Count - 1; ++i)
                {
                    if (xmlDoc.ChildNodes[child].ChildNodes[i].Name == "update")
                    {
                        Rec_Update update = new Rec_Update();

                        // <update seconds="0.0(s)" >
                        update.time    = float.Parse(xmlDoc.ChildNodes[child].ChildNodes[i].Attributes.GetNamedItem("seconds").Value, CultureInfo.InvariantCulture.NumberFormat);
                        update.objList = new List <Rec_Object>();

                        foreach (XmlNode obj in xmlDoc.ChildNodes[child].ChildNodes[i])
                        {
                            Rec_Object o = new Rec_Object();
                            // <object name="" >
                            o.name = obj.Attributes.GetNamedItem("name").Value;
                            // tag=""
                            XmlNode node = obj.Attributes.GetNamedItem("tag");
                            o.tag = (node != null) ? node.Value : "Untagged";
                            // active="true/false"
                            node = obj.Attributes.GetNamedItem("active");
                            if (node != null)
                            {
                                bool temp    = true;
                                bool success = bool.TryParse(node.Value, out temp);
                                o.active = success ? temp : true;
                                //o.active = bool.Parse(obj.Attributes.GetNamedItem("active").Value);
                            }
                            else
                            {
                                o.active = true;
                            }

                            //Debug.Log(o.name);

                            // <position x="0.0(m)" y="0.0(m)" z="0.0(m)" >
                            float x = float.Parse(obj.FirstChild.Attributes.GetNamedItem("x").Value, CultureInfo.InvariantCulture.NumberFormat);
                            float y = float.Parse(obj.FirstChild.Attributes.GetNamedItem("y").Value, CultureInfo.InvariantCulture.NumberFormat);
                            float z = float.Parse(obj.FirstChild.Attributes.GetNamedItem("z").Value, CultureInfo.InvariantCulture.NumberFormat);

                            o.position = new Vector3(x, y, z);

                            // <rotation x="0.0(degrees)" y="0.0(degrees)" z="0.0(degrees)" >
                            x = float.Parse(obj.ChildNodes[1].Attributes.GetNamedItem("x").Value, CultureInfo.InvariantCulture.NumberFormat);
                            y = float.Parse(obj.ChildNodes[1].Attributes.GetNamedItem("y").Value, CultureInfo.InvariantCulture.NumberFormat);
                            z = float.Parse(obj.ChildNodes[1].Attributes.GetNamedItem("z").Value, CultureInfo.InvariantCulture.NumberFormat);

                            o.rotation = new Vector3(x, y, z);

                            //Debug.Log(o.rotation);

                            update.objList.Add(o);
                        }

                        loadedRecording.updates.Add(update);
                    }
                }

                // last recorded update time
                maxTime = loadedRecording.updates[loadedRecording.updates.Count - 1].time;

                ResetPlaybackStart();
            }

            playbackSpeed = 1;

            OnLoadEvent(new LoadEventArgs(recordingMetaData));
        }