//    public void SetFromBody(EnableBody body, ReplayEventData data, float speed = 1.0f, bool usePositionData = false)
    /// <summary>
    /// Sets the Avatar's joints using EnableBody as relative-to-Tpose rotation data.
    /// </summary>
    /// <param name="body">T-pose offset rotation data</param>
    /// <param name="duration">How quickly to get to final pose</param>
    /// <param name="speed">Multiplier to duration</param>
    /// <param name="usePositionData">Whether to use or ignore joint positions (and only use orientations)</param>
    public void SetFromBody(EnableBody body, float duration, float speed = 1.0f, bool usePositionData = false, bool mirror = false)
    {
        Dictionary <string, EnableJoint> joints = body.Joints;

        //estimatedRootOffset = newEstimatedRootOffset;
        //print("SetFromBody: duration=" + duration + ", speed = " + speed);
        foreach (string jointName in joints.Keys)
        {
            //print ("======================SetFromBody jointName = " + jointName);
            //Transform bp = bodyDict[jointName];

            /*
             *          Transform bp;
             *          //lookup if JSON data is one of the joints we are tracking
             *          if (bodyDict.TryGetValue(jointName, out bp))
             *          {
             *          }
             *          else
             *          {
             *              continue;
             *          }
             */
            string jn = jointName;
            //print("jn=" + jn);
            if (mirror == true)
            {
                if (jointName.Contains("Left"))
                {
                    //print("replacing " + jn);
                    jn = jointName.Replace("Left", "Right");
                }
                else if (jointName.Contains("Right"))
                {
                    jn = jointName.Replace("Right", "Left");
                }
            }


            EnableJoint j = joints[jn];
            //if (j.orientation == null) {
            //	print ("NULL+++++++++++++++++++++");
            //}
            JointSet(j, jointName, duration / speed, usePositionData, mirror);
        }

        /*
         *      footPositionCurrent = (leftFootPosition.y < rightFootPosition.y ? leftFootPosition : rightFootPosition);
         *      leftFootDown = (leftFootPosition.y < rightFootPosition.y);
         *      int footDown = (leftFootDown ? 1 : 0);
         *      if (lastFootDown != footDown) {  //switched feet
         *              footPositionInit = (leftFootDown ? leftFootPosition : rightFootPosition) ;
         *              //print ("switched feet, leftdown=" + leftFootDown + ", l=" + leftFootPosition + ", r=" + rightFootPosition);
         *              if (lastFootDown == -1) {  //get offset to move foot position to startPosition
         *                      startOffset = startPosition - footPositionInit;
         *              }
         *              lastFootDown = footDown;
         *      }
         *      newEstimatedRootOffset = footPositionCurrent - footPositionInit ; //move body
         */
    }
    /// <summary>
    /// Gets avatar's joint positions and orientations relative to initial T-Pose.
    /// Needs to cache ebody so only calculated if needed.
    /// </summary>
    /// <param name="global">Only global is currently supported</param>
    /// <returns></returns>
    public EnableBody GetSkeletonData(bool global)
    {
        //Debug.Log("AvatarSkeleton:GetSkeletonData");
        EnableBody ebody = new EnableBody();

        for (int i = 0; i < bones.Length; i++)
        {
            var bone = bones[i];
            if (!bone)
            {
                continue;
            }
            // position
            Vector3 jointPosition;
            if (globalData)
            {
                jointPosition = bone.position;
            }
            else
            {
                jointPosition = bone.localPosition;
            }

            //            writer.Write(jointPosition);
            Quaternion jointRotation;

            if (global)
            {
                jointRotation = bone.rotation * Quaternion.Inverse(initialRotations[i]);
                //                jointRotation = Quaternion.Inverse(initialRotations[i]) * bone.rotation;
            }
            else
            {
                jointRotation = bone.localRotation * Quaternion.Inverse(initialLocalRotations[i]);
                //intRotation = Quaternion.Inverse(initialLocalRotations[i]) * bone.localRotation;
            }

            //var name = boneNames[i];
            //var jointName = name;
            //Debug.Log("avatar bone [" + i + "]=" + name);

            /*
             * if (name == "aLeftShoulder")
             * {
             *  print("GET ROTATIONS[" + jointName + "]bi=" + name);
             *  print("GET ROTATIONS[" + jointName + "]lrot=" + bone.localRotation.eulerAngles);
             *  print("GET ROTATIONS[" + jointName + "]init=" + initialLocalRotations[i].eulerAngles);
             *  print("GET ROTATIONS[" + jointName + "]targ= " + jointRotation.eulerAngles);
             *  print("GET ROTATIONS[" + jointName + "]trans=" + bone.name);
             * }
             */
            //            Debug.Log("AvatarSkeleton:bn=" + boneNames[i] + ",jp=" +  jointPosition + ", jr=" + jointRotation);

            ebody.AddJoint(boneNames[i], jointPosition, jointRotation);
        }
        //        Debug.Log("AvatarSkeleton:returning SkeletonData");
        return(ebody);
    }
    void HandleOnReplayTransition(ReplayEventData data)
    {
        TrackerMessage bodyMessage = SessionAnalyzer.LookupMessage(data.To.messages, "Player Skeleton");

        if (bodyMessage != null)
        {
            EnableBody body = bodyMessage.Value as EnableBody;
            SetFromBody(body, data);
        }
    }
    /*    string jointString(KinectInterop.JointType j, Vector3 position, Quaternion rotation)
     *  {
     *      print(string.Format("{0} : [ Position . {1} ] [ Rotation . {2} ]", j.ToString(), position.ToString(), rotation.ToString()));
     *      return string.Format("{0} : [ Position . {1} ] [ Rotation . {2} ]", j.ToString(), position.ToString(), rotation.ToString());
     *  }
     */

    //    Array allJoints = Enum.GetValues(typeof(KinectInterop.JointType));
    public EnableSerializableValue skeletonData()
    {
        //        EnableBody ebody = new EnableBody();
        //        return ebody;
        //print("TrackAvatar:skeletonData");
        EnableBody ebody = avatarSkeleton.GetSkeletonData(true);

        //print("TrackAvatar:GetSkeletonData returned: " + ebody);
        return(ebody);
    }
    void SetFromBody(EnableBody body, ReplayEventData data)
    {
        Dictionary <string, EnableJoint> joints = body.Joints;
//		foreach(string jointName in joints.Keys) {
//			Transform bp = bodyDict[jointName];
//			EnableJoint j = joints[jointName];
//			bp.DOLocalRotate(j.orientation.eulerAngles, data.Duration);
//			bp.DOMove(j.position, data.Duration);
//		}
    }
 void SetFromBody(EnableBody body, ReplayEventData data)
 {
     Dictionary<string, EnableJoint> joints = body.Joints;
     //		foreach(string jointName in joints.Keys) {
     //			Transform bp = bodyDict[jointName];
     //			EnableJoint j = joints[jointName];
     //			bp.DOLocalRotate(j.orientation.eulerAngles, data.Duration);
     //			bp.DOMove(j.position, data.Duration);
     //		}
 }
    /// <summary>
    /// </summary>
    void CopySkeletonData()
    {
        //print("getSkelData");
        EnableBody ebody = avatarSkeleton.GetSkeletonData(true);
        Dictionary <string, EnableJoint> joints = ebody.Joints;
        //estimatedRootOffset = newEstimatedRootOffset;

        float duration = 0.0f;
        float speed    = 1.0f;     //SessionReplay.timeScale;

        if (Ghost)
        {
//            print("\n--GHOST1--\n");
            Ghost.SetFromBody(ebody, duration, speed, usePositionData, mirror);
        }
    }