using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace IndianHealthService.BMXNet
{
    /// <summary>
    /// All async communications with RPMS is performed through the RemoteEventService which
    /// is found by calling aRemoteSession.EventServices.  
    /// </summary>
    /// <remarks>
    /// <list>
    /// <para>By default remote events are asynchronous and are not on the UI thread.  The development
    /// must handed the events propertly and if interacting with a user interface control must use
    /// Invoke().  As a convinenence, InvokedControl can be set to any non-disposed Control and the
    /// event service is use Invoke() so that the event is triggered on the UI thread</para>
    /// <para>The Event timer, IsEventPollingEnabled and EventPollingInterval, is used by the Async RPC calls
    /// and is automattically turned on with IsEventPollingEnabled.  If the developer turns on polling or
    /// changes the EventPollingInterval to be a long period, then the Async RPC calls will not respond in
    /// a timely manner if at all. 
    /// </para>
    /// </list>
    /// </remarks>
    public interface RemoteEventService
    {
        /// <summary>
        /// This event is triggered when an event named anEventType is published and the
        /// receiver has a subscription.  Remember that this event is not on the UI-thread unless InvokedControl is properly set.
        /// </summary>
        event EventHandler<RemoteEventArgs> RpmsEvent;

        /// <summary>
        /// This event is triggered every time the event timer is triggered, based on the EventPollingInterval.
        /// Remember that this event is not on the UI-thread unless InvokedControl is properly set.
        /// </summary>
        /// <remarks>
        /// Respond quickly to this event.
        /// </remarks>
        event EventHandler TimerEvent;

        /// <summary>
        /// Set InvokedControl to a form or control of your WinForm application or EHR/VueCentric component that
        /// will live the lifetime of your RemoteSession.  The RemoteEventServices will Invoke() on the InvokedControl
        /// to ensure all events are triggered on the UI thread.
        /// </summary>
        Control InvokedControl { get; set; }     

        
        /// <summary>
        /// Subscribe to an event named anEventType.  These events are trigger exclusivley by other BMXNet remote services and
        /// travel from client-to-server-to-client.  Once subscribed, the RemoteSession will poll based on the EventPollingInterval to
        /// see if a server-side event is waiting to be triggered on the client.
        /// </summary>
        /// <param name="anEventType">The name of the event to subscribe to</param>
        /// <returns>1 if successful, otherwise it's an error.  Refer to KIDS source for error codes.</returns>
        int Subscribe(String anEventType);

        /// <summary>
        /// Unsubscribe from an event named anEventType.  Once unsubscribed, published events named anEventType will no longer
        /// trigger an event for this RemoteSession.
        /// </summary>
        /// <param name="anEventType">The name of the event to unsubscribe from</param>
        /// <returns>1 if successful, otherwise it's an error.  Refer to KIDS source for error codes.</returns>
        int Unsubscribe(String anEventType);
     
        /// <summary>
        /// Access to a RemoteEventService also allows you to publish your own events. Publishing is done through design and
        /// documentation to notify other developers what events you will trigger.  An event is published, or triggered, by using TriggerEvent
        /// with the name of the event, an optional event specific string with data, and whether or not the publisher, if subsubscribed,
        /// wants the event published to them.
        /// </summary>
        /// <param name="anEventType">Name of the event to publish</param>
        /// <param name="aParameter">An optional string with event specific data</param>
        /// <param name="raiseBack">Set to True if the publisher of anEventType, that is also a subscriber to anEventType,
        /// also wants the event to be triggered back to them</param>
        /// <returns></returns>
        int TriggerEvent(String anEventType, String aParameter,bool raiseBack);
          
        /// <summary>
        /// EventPolling is used for RemoteService events and Async RPC calls.  IsEventPollingEnabled is used
        /// to turn polling on and off: True for on and False for off.  The Async RPC framework and remote event service
        /// needs polling to be turned on.  
        /// </summary>
        /// <remarks>
        /// If Async RPC's or remote events are not working debug the RemoteEventService to verify polling is enabled
        /// and configured.
        /// </remarks>
        /// <example>
        /// If using Async RPC or remote service events activate and configure the timer when your applications starts
        /// <code>
        /// ... //Poll every 10000 ms, or 10 seconds
        ///     this.RemoteSession.EventServices.EventPollingInterval=10000;
        ///     this.RemoteSession.EventServices.IsEventPollingEnabled=True;
        /// ...
        /// ... //Perhaps in another part of your application you have a small active Chat Window
        /// ... //Increase the frequency of polling by decreasing the EventPollingInterval to every 2 seconds
        ///     this.RemoteSession.EventServices.EventPollingInterval=2000;
        /// </code>
        /// </example>
        bool IsEventPollingEnabled { get; set; }

        /// <summary>
        /// The number of milliseconds (ms) to wait before polling.  If a polling event is currently being processed
        /// when a second event is trigger, the second event is skipped.  It's recommended to keep this interval at
        /// 5000 (5 seconds) or higher.
        /// </summary>
        int EventPollingInterval { get; set; }
    }
}
