/// <summary>
 /// Merge object right into left recursively
 /// </summary>
 /// <param name="left">The left (base) object</param>
 /// <param name="right">The right (new) object</param>
 static void MergeRecur(JSONObject left, JSONObject right)
 {
     if (left.type == Type.NULL)
     {
         left.Absorb(right);
     }
     else if (left.type == Type.OBJECT && right.type == Type.OBJECT)
     {
         for (int i = 0; i < right.list.Count; i++)
         {
             string key = right.keys[i];
             if (right[i].isContainer)
             {
                 if (left.HasField(key))
                 {
                     MergeRecur(left[key], right[i]);
                 }
                 else
                 {
                     left.AddField(key, right[i]);
                 }
             }
             else
             {
                 if (left.HasField(key))
                 {
                     left.SetField(key, right[i]);
                 }
                 else
                 {
                     left.AddField(key, right[i]);
                 }
             }
         }
     }
     else if (left.type == Type.ARRAY && right.type == Type.ARRAY)
     {
         if (right.Count > left.Count)
         {
             Debug.LogError("Cannot merge arrays when right object has more elements");
             return;
         }
         for (int i = 0; i < right.list.Count; i++)
         {
             if (left[i].type == right[i].type)                                          //Only overwrite with the same type
             {
                 if (left[i].isContainer)
                 {
                     MergeRecur(left[i], right[i]);
                 }
                 else
                 {
                     left[i] = right[i];
                 }
             }
         }
     }
 }
        public static Keyframe ToKeyframe(JSONObject obj)
        {
            Keyframe k = new Keyframe(obj.HasField("time")? obj.GetField("time").f : 0, obj.HasField("value")? obj.GetField("value").f : 0);

            if (obj.HasField("inTangent"))
            {
                k.inTangent = obj.GetField("inTangent").f;
            }
            if (obj.HasField("outTangent"))
            {
                k.outTangent = obj.GetField("outTangent").f;
            }
            if (obj.HasField("tangentMode"))
            {
                k.tangentMode = (int)obj.GetField("tangentMode").f;
            }

            return(k);
        }
        public static AnimationCurve ToAnimationCurve(JSONObject obj)
        {
            AnimationCurve a = new AnimationCurve();

            if (obj.HasField("keys"))
            {
                JSONObject keys = obj.GetField("keys");
                for (int i = 0; i < keys.list.Count; i++)
                {
                    a.AddKey(ToKeyframe(keys[i]));
                }
            }
            if (obj.HasField("preWrapMode"))
            {
                a.preWrapMode = (WrapMode)((int)obj.GetField("preWrapMode").n);
            }
            if (obj.HasField("postWrapMode"))
            {
                a.postWrapMode = (WrapMode)((int)obj.GetField("postWrapMode").n);
            }
            return(a);
        }
		public static Keyframe ToKeyframe(JSONObject obj){
			Keyframe k = new Keyframe(obj.HasField("time")? obj.GetField("time").f : 0, obj.HasField("value")? obj.GetField("value").f : 0);
			if(obj.HasField("inTangent")) k.inTangent = obj.GetField("inTangent").f;
			if(obj.HasField("outTangent")) k.outTangent = obj.GetField("outTangent").f;
			if(obj.HasField("tangentMode")) k.tangentMode = (int)obj.GetField("tangentMode").f;
			
			return k;
		}
		public static AnimationCurve ToAnimationCurve(JSONObject obj){
			AnimationCurve a = new AnimationCurve();
			if(obj.HasField("keys")){
				JSONObject keys = obj.GetField("keys");
				for(int i =0; i < keys.list.Count;i++){
					a.AddKey(ToKeyframe(keys[i]));
				}
			}
			if(obj.HasField("preWrapMode"))
				a.preWrapMode = (WrapMode)((int)obj.GetField("preWrapMode").n);
			if(obj.HasField("postWrapMode"))
				a.postWrapMode = (WrapMode)((int)obj.GetField("postWrapMode").n);
			return a;
		}
		/// <summary>
		/// Merge object right into left recursively
		/// </summary>
		/// <param name="left">The left (base) object</param>
		/// <param name="right">The right (new) object</param>
		static void MergeRecur(JSONObject left, JSONObject right) {
			if(left.type == Type.NULL)
				left.Absorb(right);
			else if(left.type == Type.OBJECT && right.type == Type.OBJECT) {
				for(int i = 0; i < right.list.Count; i++) {
					string key = right.keys[i];
					if(right[i].isContainer) {
						if(left.HasField(key))
							MergeRecur(left[key], right[i]);
						else
							left.AddField(key, right[i]);
					} else {
						if(left.HasField(key))
							left.SetField(key, right[i]);
						else
							left.AddField(key, right[i]);
					}
				}
			} else if(left.type == Type.ARRAY && right.type == Type.ARRAY) {
				if(right.Count > left.Count) {
					Debug.LogError("Cannot merge arrays when right object has more elements");
					return;
				}
				for(int i = 0; i < right.list.Count; i++) {
					if(left[i].type == right[i].type) {			//Only overwrite with the same type
						if(left[i].isContainer)
							MergeRecur(left[i], right[i]);
						else {
							left[i] = right[i];
						}
					}
				}
			}
		}