/**********************************************************************************
* Blueprint Reality Inc. CONFIDENTIAL
* 2020 Blueprint Reality Inc.
* All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains, the property of
* Blueprint Reality Inc. and its suppliers, if any.  The intellectual and
* technical concepts contained herein are proprietary to Blueprint Reality Inc.
* and its suppliers and may be covered by Patents, pending patents, and are
* protected by trade secret or copyright law.
*
* Dissemination of this information or reproduction of this material is strictly
* forbidden unless prior written permission is obtained from Blueprint Reality Inc.
***********************************************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace BlueprintReality.MixCast.Shared
{
    public partial class TrackedObject
    {
        const float POSITION_UPDATE_PRECISION = 0.0001f;    //in meters
        const float POSITION_UPDATE_PRECISION_SQR = POSITION_UPDATE_PRECISION * POSITION_UPDATE_PRECISION;

        const float ROTATION_UPDATE_PRECISION = 0.01f;  //in degrees

        public bool CopyFromSource(TrackedObject src, bool conservative = false)
        {
            bool changed = false;

            if(!conservative || Identifier != src.Identifier)
            {
                Identifier = src.Identifier;
                changed = true;
            }

            if(src.__isset.name &&
                (!conservative || Name != src.Name))
            {
                Name = src.Name;
                changed = true;
            }
            if(src.__isset.source &&
                (!conservative || Source != src.Source))
            {
                Source = src.Source;
                changed = true;
            }
            if(src.__isset.objectType && 
                (!conservative || ObjectType != src.ObjectType))
            {
                ObjectType = src.ObjectType;
                changed = true;
            }
            if(src.__isset.assignedRole &&
                (!conservative || AssignedRole != src.AssignedRole))
            {
                AssignedRole = src.AssignedRole;
                changed = true;
            }
            if(src.__isset.hideFromUser &&
                (!conservative || HideFromUser != src.HideFromUser))
            {
                HideFromUser = src.HideFromUser;
                changed = true;
            }
            if(src.__isset.connected &&
                (!conservative || Connected != src.Connected))
            {
                Connected = src.Connected;
                changed = true;
            }

            if(src.__isset.position &&
                (!conservative || (Position.unity - src.Position.unity).sqrMagnitude > POSITION_UPDATE_PRECISION_SQR))
            {
                Position.unity = src.Position.unity;
                __isset.position = true;
                changed = true;
            }
            if(src.__isset.rotation &&
                (!conservative || Quaternion.Angle(Rotation.unity, src.Rotation.unity) >= ROTATION_UPDATE_PRECISION))
            {
                Rotation.unity = src.Rotation.unity;
                __isset.rotation = true;
                changed = true;
            }

            return changed;
        }

        public void ClearDirtyFlags()
        {
            __isset.name = false;
            __isset.source = false;
            __isset.objectType = false;
            __isset.assignedRole = false;
            __isset.hideFromUser = false;
            __isset.connected = false;
            __isset.position = false;
            __isset.rotation = false;
        }
        public static void ResizeList(List<TrackedObject> list, int newSize)
        {
            while (list.Count < newSize)
            {
                TrackedObject newTrackedObject = new TrackedObject()
                {
                    Position = new BlueprintReality.Thrift.Vector3() { unity = Vector3.zero },
                    Rotation = new BlueprintReality.Thrift.Quaternion() { unity = Quaternion.identity },
                };
                newTrackedObject.__isset.position = false;
                newTrackedObject.__isset.rotation = false;

                list.Add(newTrackedObject);
            }
            while (list.Count > newSize)
            {
                list.RemoveAt(list.Count - 1);
            }
        }
    }
}
