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

/// <summary>
/// 单值同步
/// </summary>
public class OneValueSyncObject : SyncBase
{
    public static Dictionary<string, OneValueSyncObject> OneAxisSyncObjectList = new Dictionary<string, OneValueSyncObject>();

    [HideInInspector]
    [SerializeField]
    public ValueType valueType;
    /// <summary>
    /// 同步回调 <id,是否为进房间>
    /// </summary>
    [HideInInspector]
    public Action<string,bool> callbackInmono;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public bool mybool;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public byte mybyte;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public short myshort;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public int myint;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public float myfloat;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public double mydouble;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public string mystring;

    [SerializeField]
    [HideInInspector]
    [DisplayOnly]
    public Vector3 myvector3;

    public bool 自定义回调 = false;

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

    /// <summary>
    /// 打分回调
    /// </summary>
    public Action action_apprisedetail;
    private void OnDestroy()
    {
        if(OneAxisSyncObjectList.ContainsKey(Id))
        {
            OneAxisSyncObjectList.Remove(Id);
        }
    }
    public void InitDynamic(string id = "", Action<string,bool> callbackInMono = null, ValueType TmpvalueType = ValueType.Null)
    {
        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(TmpvalueType!= ValueType.Null)
        {
            this.valueType = TmpvalueType;
        }
        else if(valueType== ValueType.Null)
        {
            Debug.LogError("类型为空:"+gameObject.name);
            return;
        }

        this.callbackInmono= callbackInMono;
        st_Motions.area = LoadManage.Instance.currentRoomArea;

        List<byte> tmpbytes = new List<byte>();
        //syncId
        tmpbytes.AddRange(BitConverter.GetBytes(LoadManage.Instance.SyncId));
        //id
        byte[] data=Encoding.UTF8.GetBytes(Id);
        tmpbytes.AddRange(BitConverter.GetBytes(data.Length));
        tmpbytes.AddRange(data);
        //类型
        tmpbytes.Add((byte)valueType);
        //回调
        tmpbytes.Add(callbackInmono == null?(byte)0:(byte)1);
        switch (valueType)
        {
            case ValueType.Null:
                Debug.LogError("类型不能为空");
                return;
            case ValueType.Bool:
                tmpbytes.Add(new byte());
                lastindex = tmpbytes.Count - 1;
                break;
            case ValueType.Byte:
                tmpbytes.Add(new byte());
                lastindex = tmpbytes.Count - 1;
                break;
            case ValueType.Short:
                tmpbytes.AddRange(new byte[2]);
                lastindex = tmpbytes.Count - 2;
                break;
            case ValueType.Int:
                tmpbytes.AddRange(new byte[4]);
                lastindex = tmpbytes.Count - 4;
                break;
            case ValueType.Float:
                tmpbytes.AddRange(new byte[4]);
                lastindex = tmpbytes.Count - 4;
                break;
            case ValueType.Double:
                tmpbytes.AddRange(new byte[8]);
                lastindex = tmpbytes.Count - 8;
                break;
            case ValueType.String:
                tmpbytes.AddRange(new byte[4]);
                lastindex = tmpbytes.Count - 4;
                break;
            case ValueType.Vector3:
                tmpbytes.AddRange(new byte[12]);
                lastindex = tmpbytes.Count - 12;
                break;
        }
        st_Motions.m_sOperaData = tmpbytes.ToArray();

        OneAxisSyncObjectList.Add(Id, this);
        hasInit = true;
    }

    /// <summary>
    /// 发送同步
    /// </summary>
    public void SendSync()
    {
        if (!GameManage.Instance.is单机模式)
        {
            switch (valueType)
            {
                case ValueType.Null:
                    Debug.LogError("类型不能为空");
                    return;
                case ValueType.Bool:
                    st_Motions.m_sOperaData[lastindex] = mybool ? (byte)1 : (byte)0;
                    break;
                case ValueType.Byte:
                    st_Motions.m_sOperaData[lastindex] = mybyte;
                    break;
                case ValueType.Short:
                    Array.Copy(BitConverter.GetBytes(myshort), 0, st_Motions.m_sOperaData, lastindex, 2);
                    break;
                case ValueType.Int:
                    Array.Copy(BitConverter.GetBytes(myint), 0, st_Motions.m_sOperaData, lastindex, 4);
                    break;
                case ValueType.Float:
                    Array.Copy(BitConverter.GetBytes(myfloat), 0, st_Motions.m_sOperaData, lastindex, 4);
                    break;
                case ValueType.Double:
                    Array.Copy(BitConverter.GetBytes(mydouble), 0, st_Motions.m_sOperaData, lastindex, 8);
                    break;
                case ValueType.String:
                    byte[] tmpstring = Encoding.UTF8.GetBytes(mystring);
                    Array.Copy(BitConverter.GetBytes(tmpstring.Length), 0, st_Motions.m_sOperaData, lastindex, 4);
                    byte[] data = new byte[lastindex + 4 + tmpstring.Length];
                    Array.Copy(st_Motions.m_sOperaData, 0, data, 0, lastindex + 4);
                    Array.Copy(tmpstring, 0, data, lastindex + 4, tmpstring.Length);
                    st_Motions.m_sOperaData = data;
                    break;
                case ValueType.Vector3:
                    Array.Copy(BitConverter.GetBytes(myvector3.x), 0, st_Motions.m_sOperaData, lastindex, 4);
                    Array.Copy(BitConverter.GetBytes(myvector3.y), 0, st_Motions.m_sOperaData, lastindex + 4, 4);
                    Array.Copy(BitConverter.GetBytes(myvector3.z), 0, st_Motions.m_sOperaData, lastindex + 8, 4);
                    break;
            }
            LoadManage.Instance.RSclient.Send(st_Motions);
        }
    }

    /// <summary>
    /// 设置值
    /// </summary>
    public void SetValue(int start,byte[] data)
    {
        switch ((ValueType)(data[start]))
        {
            case ValueType.Null:
                Debug.LogError("类型不能为空");
                return ;
            case ValueType.Bool:
                mybool = (data[start + 2] == 1 ? true : false);
                break;
            case ValueType.Byte:
                mybyte = data[start+2];
                break;
            case ValueType.Short:
                myshort = BitConverter.ToInt16(data, start+2);
                break;
            case ValueType.Int:
                myint = BitConverter.ToInt32(data, start + 2);
                break;
            case ValueType.Float:
                myfloat = BitConverter.ToSingle(data, start + 2);
                break;
            case ValueType.Double:
                mydouble = BitConverter.ToDouble(data, start + 2);
                break;
            case ValueType.String:
                int length = BitConverter.ToInt32(data, start + 2);
                mystring = Encoding.UTF8.GetString(data, start + 6, length);
                break;
            case ValueType.Vector3:
                myvector3.x = BitConverter.ToSingle(data, start + 2);
                myvector3.y= BitConverter.ToSingle(data, start + 6);
                myvector3.z = BitConverter.ToSingle(data, start + 10);
                break;
        }
    }
}
public enum ValueType
{
    Null,
    Bool,
    Byte,
    Short,
    Int,
    Float,
    Double,
    String,
    Vector3
}