using System;
using System.Collections.Generic;

namespace Decal.Adapter.Messages;

/// <summary>
/// The base from which Adapter messages derive
/// </summary>
[CLSCompliant(true)]
public class AdapterMessageEventArgs : EventArgs
{
	private EventHandler<AdapterMessageResponseEventArgs> responder;

	private List<object> handlers;

	private bool canAddHandlers;

	internal bool CanAddHandlers
	{
		get
		{
			return canAddHandlers;
		}
		set
		{
			canAddHandlers = value;
		}
	}

	/// <summary>
	/// Fires for each handler that completes processing of the message
	/// </summary>
	public event EventHandler<AdapterMessageResponseEventArgs> MessageComplete
	{
		add
		{
			responder = (EventHandler<AdapterMessageResponseEventArgs>)Delegate.Combine(responder, value);
		}
		remove
		{
			responder = (EventHandler<AdapterMessageResponseEventArgs>)Delegate.Remove(responder, value);
		}
	}

	internal AdapterMessageEventArgs()
	{
		handlers = new List<object>();
	}

	/// <summary>
	/// Acknowledges that the object intends to process the message
	/// </summary>
	/// <param name="obj">The object that will do the processing</param>
	public void AddHandler(object obj)
	{
		if (!CanAddHandlers)
		{
			throw new InvalidOperationException("Unable to add handlers at this time");
		}
		if (obj != null)
		{
			handlers.Add(obj);
		}
	}

	/// <summary>
	/// Signals completion of message processing
	/// </summary>
	/// <param name="handler">The object that handled the message</param>
	/// <param name="e">The message response</param>
	public void SetComplete(object handler, AdapterMessageResponseEventArgs e)
	{
		handlers.Remove(handler);
		if (handlers.Count == 0)
		{
			e.Complete = true;
		}
		if (responder != null)
		{
			responder(this, e);
		}
	}
}
