using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace Inspectron.HawkEye
{
    public class FragmentedPacket
    {
        private readonly uint _packetSize;
        private readonly EPacketType _packetType;
        private readonly uint _sequnceId;

        public FragmentedPacket(uint packetSize,EPacketType packetType,uint sequnceId)
        {
            _packetSize = packetSize;
            _packetType = packetType;
            _sequnceId = sequnceId;
        }
        public IEnumerable<byte[]> Fragment(byte[] packetData)
        {
            

            
            uint dataPtr = 0;

            int packetNumber = 0;
            uint headerSize = 20;
            uint payloadSize = (_packetSize - headerSize);
            var totalPackets = (uint)Math.Ceiling(((double)packetData.Length / payloadSize));
            do
            {
                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write((uint) 114455); //packetStart    //4
                bw.Write((uint) _packetType); //8
                bw.Write((uint) _sequnceId); //12
                bw.Write((uint) packetNumber); //16
                //total packets?


                bw.Write(totalPackets); //20

                byte[] data = new byte[payloadSize];
                uint dataSize = Math.Min((uint)(packetData.Length-dataPtr), payloadSize);
                Array.Copy(packetData, dataPtr, data, 0, dataSize);
                dataPtr += dataSize;
                bw.Write(dataSize);
                bw.Write(data);

                packetNumber += 1;
                yield return ms.ToArray();

            } while (packetNumber < totalPackets);






        }
        public IEnumerable<byte[]> FragmentTo(byte[] packetData,UDPSocket socket)
        {



            uint dataPtr = 0;

            int packetNumber = 0;
            uint headerSize = 20;
            uint payloadSize = (_packetSize - headerSize);
            var totalPackets = (uint)Math.Ceiling(((double)packetData.Length / payloadSize));
            do
            {
                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write((uint)114455); //packetStart    //4
                bw.Write((uint)_packetType); //8
                bw.Write((uint)_sequnceId); //12
                bw.Write((uint)packetNumber); //16
                //total packets?


                bw.Write(totalPackets); //20

                byte[] data = new byte[payloadSize];
                uint dataSize = Math.Min((uint)(packetData.Length - dataPtr), payloadSize);
                Array.Copy(packetData, dataPtr, data, 0, dataSize);
                dataPtr += dataSize;
                bw.Write(dataSize);
                bw.Write(data);

                packetNumber += 1;
                yield return ms.ToArray();

            } while (packetNumber < totalPackets);






        }
    }
}