namespace Passer.RoboidControl {

    /// <summary>
    /// A message containing binary data for custom communication
    /// </summary>
    public class BinaryMsg : IMessage {
        /// <summary>
        /// The message ID
        /// </summary>
        public const byte Id = 0xB1;
        /// <summary>
        /// The length of the message, excluding the binary data
        /// </summary>
        /// For the total size of the message this.bytes.Length should be added to this value.
        public const byte length = 2;
        /// <summary>
        /// The network ID identifying the thing
        /// </summary>
        public byte networkId;
        /// <summary>
        /// The ID of the thing
        /// </summary>
        public byte thingId;
        /// <summary>
        /// The binary data
        /// </summary>
        public byte[] bytes;

        /// <summary>
        /// Create a new message for sending
        /// </summary>
        /// <param name="networkId">The netowork ID of the thing</param>
        /// <param name="thingId">The ID of the thing</param>
        /// <param name="bytes">The binary data for the thing</param>
        public BinaryMsg(byte networkId, byte thingId, byte[] bytes) : base() {
            this.networkId = networkId;
            this.thingId = thingId;
            this.bytes = bytes;
        }
        /// <summary>
        /// Create an empty message for sending
        /// </summary>
        /// <param name="networkId">The netowork ID of the thing</param>
        /// <param name="thingId">The ID of the thing</param>
        public BinaryMsg(byte networkId, Thing thing) : base() {
            this.networkId = networkId;
            this.thingId = thing.id;
            this.bytes = System.Array.Empty<byte>();
        }
        /// @copydoc Passer::RoboidControl::IMessage::IMessage(byte[] buffer)
        public BinaryMsg(byte[] buffer) {
            byte ix = 1;
            this.networkId = buffer[ix++];
            this.thingId = buffer[ix++];
            byte length = (byte)(buffer.Length - ix);
            this.bytes = new byte[length];
            for (uint bytesIx = 0; bytesIx < length; bytesIx++)
                this.bytes[bytesIx] = buffer[ix++];
        }

        /// @copydoc Passer::RoboidControl::IMessage::Serialize
        public override byte Serialize(ref byte[] buffer) {
            if (buffer.Length < BinaryMsg.length + this.bytes.Length || this.bytes.Length == 0)
                return 0;
                
            byte ix = 0;
            buffer[ix++] = BinaryMsg.Id;
            buffer[ix++] = this.networkId;
            buffer[ix++] = this.thingId;
            foreach (byte b in bytes)
                buffer[ix++] = b;

            return ix;
        }
    }

}