using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Framework.Sharing
{
    /// <summary>
    /// Represents an object that losely couples objects by transmitting 
    /// messages between subscribers, messages must inherit from the generic
    /// MessageType.
    /// </summary>
    /// <typeparam name="MessageType">The base type of the message to transmit to subscribers</typeparam>
    /// <typeparam name="SubscriberType">The type of object to subscribe to the mediator</typeparam>
    /// TODO: Update in normal framework because of error with not allowing multiple subscribers for different actions
    public interface Mediatorlike<MessageType, SubscriberType>
    {
        /// <summary>
        /// Broadcasts a message to all subscribers. This implementation
        /// must be defined in a no abstract base class. The subscriber type
        /// must implement a method that receives the message type.
        /// </summary>
        /// <param name="message">The message to transmit.</param>
        /// <returns>
        /// Whether or not any subscriber received it.
        /// </returns>
        bool Broadcast(MessageType message);

        /// <summary>
        /// Subscribes an object to this mediator like instance. The
        /// subscribed instance should now receive messages via the
        /// broadcast method.
        /// </summary>
        /// <typeparam name="ConcreteMessageType">The message type to transmit</typeparam>
        /// <param name="subscriber">The instance to subscribe</param>
        void Subscribe<ConcreteMessageType>(SubscriberType subscriber) where ConcreteMessageType : MessageType;

        /// <summary>
        /// Unsubscribes an object from this mediator like instance.
        /// The object will no longer recieve messages via the broadcast
        /// method.
        /// </summary>
        /// <param name="subscriber">The instance to unsubscribe</param>
        void Unsubscribe<ConcreteMessageType>(SubscriberType subscriber) where ConcreteMessageType : MessageType;

        /// <summary>
        /// Determines whether or not this mediator like instance has a
        /// given subscriber.
        /// </summary>
        /// <param name="subscriber">The subscriber to check for</param>
        /// <returns></returns>
        bool HasSubscriber<ConcreteMessageType>(SubscriberType subscriber) where ConcreteMessageType : MessageType;
    }
}
