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

/// <summary>
/// 注意:1.此脚本和动画共用时,需要注意动画激活时,位置会被锁死,无法移动。
///       2.有控制权才能移动,结束后需释放控制权(控制权专属除外)
/// </summary>
public class FunctionSync_PositionRoate : SyncBase
{
    public static Dictionary<string, FunctionSync_PositionRoate> positionRoateSyncObejctList = new Dictionary<string, FunctionSync_PositionRoate>();
    [Tooltip("同步坐标")]
    public bool isPositionSync;
    [HideInInspector]
    public bool isLocalPotion=true;
    [Tooltip("同步角度")]
    public bool isRoateSync;
    [HideInInspector]
    public bool isLocalRoate=true;
    /// <summary>
    /// 是否本地锁定
    /// </summary>
   [DisplayOnly]
    public bool isLock=true;

    //同步的位置
    [DisplayOnly]
    public float[] pos = new float[6];
    private Vector3 tmpPos = new Vector3();
    private Vector3 tmpRat = new Vector3();

    private st_Motions st_Motions = new st_Motions { m_iOperaType = 10007 };
    private int lastindex;


    private void OnDestroy()
    {
        if(positionRoateSyncObejctList.ContainsKey(Id))
        {
            positionRoateSyncObejctList.Remove(Id);
        }
    }
    public void Init()
    {
        if (!hasInit)
        {
            if (!positionRoateSyncObejctList.ContainsValue(this))
            {
                InitDynamic("move_" + gameObject.name);
            }
        }
    }
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="id"></param>
    /// <param name="Tmpislock">是否获取控制权</param>
    public void InitDynamic(string id,bool isControl=false)
    {
        if (GameManage.Instance.is单机模式)
        {
            return;
        }

        if (hasInit)
        {
            Debug.Log("已经初始化,不能重复初始化");
            return;
        }

        if (string.IsNullOrEmpty(id))
        {
            if (string.IsNullOrEmpty(Id))
            {
                Debug.LogError("Id为空");
                return;
            }
        }
        else
        {
            Id = id;
        }

        if (LoadManage.Instance != null)
        {
            st_Motions.area = LoadManage.Instance.currentRoomArea;
        }
        isLock = !isControl;
        //初始化缓存
        if(isPositionSync)
        {
            lastpos = isLocalPotion ? transform.localPosition : transform.position;
        }
        if(isRoateSync)
        {
            lastrot = isLocalRoate ? transform.localEulerAngles : transform.eulerAngles;
        }
        List<byte> tmpbytes = new List<byte>();
        //syncId
        if (LoadManage.Instance != null)
        {
            tmpbytes.AddRange(BitConverter.GetBytes(LoadManage.Instance.SyncId));
        }
        //id
        byte[] data = Encoding.UTF8.GetBytes(Id);
        tmpbytes.AddRange(BitConverter.GetBytes(data.Length));
        tmpbytes.AddRange(data);
        //类型
        if(isPositionSync&& !isRoateSync)
        {
            tmpbytes.Add(0);
            lastindex = tmpbytes.Count;
            //坐标系
            tmpbytes.Add(isLocalPotion ? (byte)1 : (byte)0);
            tmpbytes.AddRange(new byte[12]);
        }
        else if(!isPositionSync && isRoateSync)
        {
            tmpbytes.Add(1);
            lastindex = tmpbytes.Count;
            //坐标系
            tmpbytes.Add(isLocalRoate ? (byte)1 : (byte)0);
            tmpbytes.AddRange(new byte[12]);
        }
        else if(isPositionSync && isRoateSync)
        {
            tmpbytes.Add(2);
            lastindex = tmpbytes.Count;
            //坐标系
            tmpbytes.Add(isLocalPotion ? (byte)1 : (byte)0); 
            tmpbytes.AddRange(new byte[12]);
            tmpbytes.Add(isLocalRoate ? (byte)1 : (byte)0);
            tmpbytes.AddRange(new byte[12]);
        }
        else
        {
            tmpbytes.Add(3);
            lastindex = tmpbytes.Count;
            //坐标系
            tmpbytes.Add(isLocalPotion ? (byte)1 : (byte)0);
            tmpbytes.AddRange(new byte[12]);
            tmpbytes.Add(isLocalRoate ? (byte)1 : (byte)0);
            tmpbytes.AddRange(new byte[12]);
        }

        //初始化
        pos[0] = isLocalPotion ? transform.localPosition.x : transform.position.x;
        pos[1] = isLocalPotion ? transform.localPosition.y : transform.position.y;
        pos[2] = isLocalPotion ? transform.localPosition.z : transform.position.z;
        pos[3] = isLocalPotion ? transform.localEulerAngles.x : transform.eulerAngles.x;
        pos[4] = isLocalPotion ? transform.localEulerAngles.y : transform.eulerAngles.y;
        pos[5] = isLocalPotion ? transform.localEulerAngles.z : transform.eulerAngles.z;
        st_Motions.m_sOperaData = tmpbytes.ToArray();
        positionRoateSyncObejctList.Add(Id, this);

        hasInit = true;
    }

    /// <summary>
    /// 获取控制权
    /// </summary>
    public void GetControl()
    {
        isLock = false;
        Debug.Log("获取控制权:" + Id);
    }
    /// <summary>
    /// 释放控制权
    /// </summary>
    public void ReleaseControl()
    {
        isLock = true;
        SendSync();
        Debug.Log("释放控制权:" + Id);
    }

    [DisplayOnly]
    public float PostionOnceTime = 0.06f;
    [DisplayOnly]
    public float RoateOneTime = 1;
    Vector3 lastpos = new Vector3();
    Vector3 lastrot = new Vector3();
    public virtual void LateUpdate()
    {
        if (!GameManage.Instance.is单机模式)
        {
            //发同步
            if (!isLock)
            {
                bool isAlreadySend = false;
                if (isPositionSync)
                {
                    if (isLocalPotion)
                    {
                        if (Vector3.Distance(lastpos, transform.localPosition) >= PostionOnceTime)
                        {
                            SendSync();
                            isAlreadySend = true;
                        }
                    }
                    else
                    {
                        if (Vector3.Distance(lastpos, transform.position) >= PostionOnceTime)
                        {
                            if (!isLock)
                            {
                                SendSync();
                                isAlreadySend = true;
                            }
                        }
                    }
                }
                //位置没法同步时判断角度是否发
                if (isRoateSync && !isAlreadySend)
                {
                    if (isLocalRoate)
                    {
                        if (Vector3.Distance(lastrot, transform.localEulerAngles) >= RoateOneTime)
                        {
                            SendSync();
                        }
                    }
                    else
                    {
                        if (Vector3.Distance(lastrot, transform.eulerAngles) >= RoateOneTime)
                        {
                                SendSync();
                        }
                    }
                }
            }
            else
            {
                //锁定位置
                if (isPositionSync)
                {
                    tmpPos.x = pos[0];
                    tmpPos.y = pos[1];
                    tmpPos.z = pos[2];
                    if (!isLocalPotion)
                    {
                        transform.position = tmpPos;
                        lastpos = transform.position;
                    }
                    else
                    {
                        transform.localPosition = tmpPos;
                        lastpos = transform.localPosition;
                    }
                }
                if (isRoateSync)
                {
                    tmpRat.x = pos[3];
                    tmpRat.y = pos[4];
                    tmpRat.z = pos[5];
                    if (!isLocalRoate)
                    {
                        transform.eulerAngles = tmpRat;
                        lastrot = transform.eulerAngles;
                    }
                    else
                    {
                        transform.localEulerAngles = tmpRat;
                        lastrot = transform.localEulerAngles;
                    }
                }
            }
        }
    }
    public void SendSync()
    {
        if (!GameManage.Instance.is单机模式)
        {
            if (isPositionSync)
            {
                Vector3 tmp;
                if (isLocalPotion)
                {
                    tmp = transform.localPosition;
                    lastpos = transform.localPosition;
                }
                else
                {
                    tmp = transform.position;
                    lastpos = transform.position;
                }
                SetPos(isLocalPotion, tmp.x, tmp.y, tmp.z);
            }

            if (isRoateSync)
            {
                Vector3 tmp;
                if (isLocalRoate)
                {
                    tmp = transform.localEulerAngles;
                    lastrot = transform.localEulerAngles;
                }
                else
                {
                    tmp = transform.eulerAngles;
                    lastrot = transform.eulerAngles;
                }
                SetRot(isLocalRoate, tmp.x, tmp.y, tmp.z);
            }


            if (isPositionSync && !isRoateSync)
            {
                st_Motions.m_sOperaData[lastindex] = (isLocalPotion ? (byte)1 : (byte)0);
                Array.Copy(BitConverter.GetBytes(pos[0]), 0, st_Motions.m_sOperaData, lastindex + 1, 4);
                Array.Copy(BitConverter.GetBytes(pos[1]), 0, st_Motions.m_sOperaData, lastindex + 5, 4);
                Array.Copy(BitConverter.GetBytes(pos[2]), 0, st_Motions.m_sOperaData, lastindex + 9, 4);
            }
            else if (!isPositionSync && isRoateSync)
            {
                st_Motions.m_sOperaData[lastindex] = (isLocalRoate ? (byte)1 : (byte)0);
                Array.Copy(BitConverter.GetBytes(pos[3]), 0, st_Motions.m_sOperaData, lastindex + 1, 4);
                Array.Copy(BitConverter.GetBytes(pos[4]), 0, st_Motions.m_sOperaData, lastindex + 5, 4);
                Array.Copy(BitConverter.GetBytes(pos[5]), 0, st_Motions.m_sOperaData, lastindex + 9, 4);
            }
            else if (isPositionSync && isRoateSync)
            {
                st_Motions.m_sOperaData[lastindex] = (isLocalPotion ? (byte)1 : (byte)0);
                Array.Copy(BitConverter.GetBytes(pos[0]), 0, st_Motions.m_sOperaData, lastindex + 1, 4);
                Array.Copy(BitConverter.GetBytes(pos[1]), 0, st_Motions.m_sOperaData, lastindex + 5, 4);
                Array.Copy(BitConverter.GetBytes(pos[2]), 0, st_Motions.m_sOperaData, lastindex + 9, 4);
                st_Motions.m_sOperaData[lastindex + 13] = (isLocalPotion ? (byte)1 : (byte)0);
                Array.Copy(BitConverter.GetBytes(pos[3]), 0, st_Motions.m_sOperaData, lastindex + 14, 4);
                Array.Copy(BitConverter.GetBytes(pos[4]), 0, st_Motions.m_sOperaData, lastindex + 18, 4);
                Array.Copy(BitConverter.GetBytes(pos[5]), 0, st_Motions.m_sOperaData, lastindex + 22, 4);
            }
            LoadManage.Instance.RSclient.Send(st_Motions);
        }
    }

    public void SetPos(bool islocalPos,float x,float y,float z)
    {
        this.isLocalPotion = islocalPos;
        pos[0] = x;
        pos[1] = y;
        pos[2] = z;

    }
    public void SetRot(bool islocalRoate,float x,float y,float z)
    {
        this.isLocalRoate = islocalRoate;
        pos[3] = x;
        pos[4] = y;
        pos[5] = z;
    }

    public void SetValue(int start,byte[] data)
    {
        if(data[start]==0)
        {
            //只同步坐标
            if (data[start+1]==1)
            {
                //local
                isLocalPotion = true;
            }
            else
            {
                //世界
                isLocalPotion = false;
            }

            pos[0] = BitConverter.ToSingle(data, start + 2);
            pos[1] = BitConverter.ToSingle(data, start + 6);
            pos[2] = BitConverter.ToSingle(data, start + 10);
        }
        else if(data[start]==1)
        {
            //只同步角度
            if (data[start + 1] == 1)
            {
                //local
                isLocalRoate = true;
            }
            else
            {
                //世界
                isLocalRoate = false;
            }

            pos[3] = BitConverter.ToSingle(data, start + 2);
            pos[4] = BitConverter.ToSingle(data, start + 6);
            pos[5] = BitConverter.ToSingle(data, start + 10);
        }
        else if(data[start]==2)
        {
            //同步位置和角度
            if (data[start + 1] == 1)
            {
                //local
                isLocalPotion = true;
            }
            else
            {
                //世界
                isLocalPotion = false;
            }
            pos[0] = BitConverter.ToSingle(data, start + 2);
            pos[1] = BitConverter.ToSingle(data, start + 6);
            pos[2] = BitConverter.ToSingle(data, start + 10);

            if (data[start + 14] == 1)
            {
                //local
                isLocalRoate = true;
            }
            else
            {
                //世界
                isLocalRoate = false;
            }

            pos[3] = BitConverter.ToSingle(data, start + 15);
            pos[4] = BitConverter.ToSingle(data, start + 19);
            pos[5] = BitConverter.ToSingle(data, start + 23);
        }
    }
}

public class DisplayOnly : PropertyAttribute
{

}