﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using ProtoBuf;

[DisallowMultipleComponent]
public sealed class NettedIdentity : MonoBehaviour
{
    // Start is called before the first frame update
    public int objID;
    public Connection owner { get; set; }
    public string prefabName;
    //[HideInInspector]
    public List<NettedBehavior> netteds=new List<NettedBehavior>();
    public bool PackObject(out byte[] bytes)
    {
        bytes = null;
        int count = 0, c = 0;
        MemoryStream ms = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(ms);
        if (netteds.Count == 0) return false;
        bw.Write(objID);
        foreach (var i in netteds)
        {
            byte[] bs;
            if (((INetted)i).Send(out bs))
            {
                bw.Write((byte)c);
                bw.Write(bs.Length);
                bw.Write(bs);
                c++;
            }
            count++;
        }
        bw.Seek(4, SeekOrigin.Begin);
        bw.Write(c);
        bytes = ms.ToArray();
        ms.Dispose();
        bw.Dispose();
        return c !=0;
    }   
    public void PackObject(out byte[] bytes,bool full)
    {
        bytes = null;
        int count = 0, c = 0;
        MemoryStream ms = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(ms);
        bw.Write(objID);
        foreach (var i in netteds)
        {
            byte[] bs;
            MemoryStream m = new MemoryStream();
            i.OnSendPrep(full);
            ProtoBuf.Meta.RuntimeTypeModel.Default.Serialize(m,i);
            i.OnSendPost(full);
            bs = m.ToArray();
            m.Dispose();
            bw.Write((byte)c);
            bw.Write(bs.Length);
            bw.Write(bs);
            c++;
            count++;
        }
        bw.Seek(4, SeekOrigin.Begin);
        bw.Write(c);
        bytes = ms.ToArray();
        ms.Dispose();
        bw.Dispose();
        return;
    }
    public void PackNettedInfo(out byte[] bytes)
    {
        MemoryStream ms = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(ms);
        Component[] coms = gameObject.GetComponents(typeof(Component));
        bw.Write(coms.Length);
        foreach (var i in coms)
        {
            string netName = i.GetType().FullName;
            if (i is Transform || i is NettedIdentity) continue;
            bw.Write(netName.Length);
            bw.Write(netName);
            //Debug.Log(netName);
        }
        bytes = ms.ToArray();
        bw.Dispose();
        ms.Dispose();
    }
    public string[] PackNettedInfo()
    {
        List<string> lsn = new List<string>();
        Component[] coms = gameObject.GetComponents(typeof(Component));
        foreach (var i in coms)
        {
            string netName = i.GetType().FullName;
            if (i is Transform || i is NettedIdentity) continue;
            lsn.Add(netName);
        }
        return lsn.ToArray();

    }

    private void Start()
    {
        NettedManager.current.gObjPool.Add(this);
        byte[] a;
        PackNettedInfo(out a);
    }
}

