using System.Runtime.InteropServices;
using Decal.Interop.Net;

namespace Decal.Adapter.NetParser;

/// <summary>
/// IMessage2 Implementation
/// </summary>
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IMessage2))]
[ProgId("DecalAdapter.MessageWrapper")]
[Guid("76142307-98E3-494d-8320-3C801010221D")]
public class MessageWrapper : IMessage2, IMessage
{
	private Message msg;

	internal Message Wrapped => msg;

	/// <summary>
	/// Return an IMessageIterator instance for this packet
	/// </summary>
	public MessageRoot Begin => new MessageRootWrapper(this);

	/// <summary>
	/// Return the number of items within this structure
	/// </summary>
	public int Count => msg.Count;

	/// <summary>
	/// Return the raw bytes of this structure
	/// </summary>
	public byte[] RawData => msg.RawData;

	/// <summary>
	/// Return the message type
	/// </summary>
	public int Type => msg.Type;

	/// <summary>
	/// Public constructor...
	/// </summary>
	public MessageWrapper()
	{
	}

	/// <summary>
	/// Internal constructor to wrap the Adapter parser
	/// </summary>
	/// <param name="msg">Adapter Message instance</param>
	internal MessageWrapper(Message msg)
	{
		this.msg = msg;
		if (!this.msg.mStruct.mParsed)
		{
			this.msg.mStruct.Parse();
		}
	}

	/// <summary>
	/// Get the field name for the specified index
	/// </summary>
	/// <param name="Index">message member index</param>
	/// <returns>field name</returns>
	public string get_FieldName(int Index)
	{
		return msg.Name(Index);
	}

	/// <summary>
	/// Return the raw bytes for the specified member
	/// </summary>
	/// <param name="vElement">Member index (string or int)</param>
	/// <returns>Byte array containing the member data</returns>
	public byte[] get_RawValue(object vElement)
	{
		return msg.RawValue(msg.mStruct.ObjectToIndex(vElement));
	}

	/// <summary>
	/// Return the specified member struct
	/// </summary>
	/// <param name="vElement">Member index (string or int)</param>
	/// <returns>Member data</returns>
	public IMessageMember get_Struct(object vElement)
	{
		int num = msg.mStruct.ObjectToIndex(vElement);
		if (num < 0)
		{
			throw new COMHResultException((HResults)1);
		}
		return new MessageMemberWrapper(msg.Struct(num), this);
	}

	/// <summary>
	/// Return the specified member data
	/// </summary>
	/// <param name="vElement">Member index (string or int)</param>
	/// <returns>Member data</returns>
	public object get_Value(object vElement)
	{
		int num = msg.mStruct.ObjectToIndex(vElement);
		if (num >= 0)
		{
			return msg.Value<object>(num);
		}
		return null;
	}
}
