using System.Runtime.InteropServices;
using System.Text;

namespace B24SiemensPlugin;

[StructLayout(LayoutKind.Explicit, Size = 19)]
public struct PLCPacket
{
    [FieldOffset(0)] private byte LifebitAndKamera;
    [FieldOffset(2)] public int Materialnummer;
    [FieldOffset(6)] public int ArtikelnummerBall;
    [FieldOffset(10)] public int MaterialnummerFoil;
    [FieldOffset(14)] private byte Chargennummer0;
    [FieldOffset(15)] private byte Chargennummer1;
    [FieldOffset(16)] private byte Chargennummer2;
    [FieldOffset(17)] private byte Chargennummer3;
    [FieldOffset(18)] private byte Chargennummer4;

    public string Chargennummer
    {
        get => Encoding.ASCII.GetString(new[]
            {Chargennummer0, Chargennummer1, Chargennummer2, Chargennummer3, Chargennummer4});
        set
        {
            var bytes = Encoding.ASCII.GetBytes(value);
            var fill = new byte[5];
            for (int i = 0; i < bytes.Length; i++)
            {
                fill[i] = bytes[i];
            }
            Chargennummer0 = fill[0];
            Chargennummer1 = fill[1];
            Chargennummer2 = fill[2];
            Chargennummer3 = fill[3];
            Chargennummer4 = fill[4];
        }
    }
     




public bool Lifebit
    {
        get => (LifebitAndKamera & 1) > 0;
        set
        {
            if (value)
                LifebitAndKamera |= 1;
            else
                LifebitAndKamera &= 0xFE;
        }
    }

    public bool KameraStart
    {
        get => (LifebitAndKamera & 2) > 0;
        set
        {
            if (value)
                LifebitAndKamera |= 2;
            else
                LifebitAndKamera &= 0xFD;
        }
    }

    public byte[] Serialize()
    {
        int size = Marshal.SizeOf(this);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.StructureToPtr(this, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);

        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(arr, 2, 4); // Materialnummer
            Array.Reverse(arr, 6, 4); // ArtikelnummerBall
            Array.Reverse(arr, 10, 4); // MaterialnummerFoil
        }

        return arr;
    }

    public static PLCPacket Deserialize(byte[] arr)
    {
        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(arr, 2, 4); // Materialnummer
            Array.Reverse(arr, 6, 4); // ArtikelnummerBall
            Array.Reverse(arr, 10, 4); // MaterialnummerFoil
        }

        PLCPacket ds;
        int size = Marshal.SizeOf(typeof(PLCPacket));
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.Copy(arr, 0, ptr, size);

        ds = (PLCPacket)Marshal.PtrToStructure(ptr, typeof(PLCPacket));
        Marshal.FreeHGlobal(ptr);

        return ds;
    }

    override public string ToString()
    {
        return $"Lifebit: {(Lifebit?'1':'0')}, KameraStart: {KameraStart}, Materialnummer: {Materialnummer}, ArtikelnummerBall: {ArtikelnummerBall}, MaterialnummerFoil: {MaterialnummerFoil}, Chargennummer: {Chargennummer}";
    }
}