using System;
using Chernobyl.Collections.Generic;
namespace Chernobyl.StateMachine
{
///
/// An interface for a state machine
/// (http://en.wikipedia.org/wiki/Finite-state_machine). This interface
/// defines both a state and a state machine in one type; this allows for
/// states to have sub-states which also have sub-states and so on and so
/// forth. Types implement this interface when they want to make it aware
/// that they have a state or can be a state of another state machine.
///
public interface IState : ILinkedEnumerable
{
///
/// This event is raised when this state has become the active state.
/// This can happen if this instances' has been
/// set and the has had
/// its set to this instance. It can also
/// happen if this instance has decided to activate itself. This event
/// will only be raised once when the state has become active. It will not be
/// invoked a second time unless it is deactivated first.
///
event EventHandler Entered;
///
/// This event is raised when this state is no longer an active state.
/// This can happen if this instances' has
/// been set and the has
/// had its set to this instance. It can also
/// happen if this instance has decided to deactivate itself. This event
/// will only be raised once when the state has been deactivated. It will
/// not be raised a second time unless it was previously in an active
/// state.
///
event EventHandler Left;
///
/// The that this is a
/// sub-state of or null if this is not sub-state
/// of another state. When set this property will set the incoming
/// instances property
/// to this instance (unless the value set is null of course). If this
/// property is set to null (or in other words, this state is
/// deactivated), two things will occur: (1) the event
/// will be raised and (2), immediately prior to raising the
/// event, this state will deactivate its child state
/// (or sub-state) which will deactivate its child states and so and so
/// forth. Deactivating sub-states is done prior to invoking the
/// event so that sub-states will be deactivated from
/// the lowest sub-state to the highest sub-state. For example, in a
/// state machine setup like so: state1 -> state2 -> state3 -> state4
/// If state2 was deactivated, then state4 would be deactivated first
/// (i.e., its event would be raised first),
/// then state3, and finally state2.
///
IState ParentState { get; set; }
///
/// The currently active sub-state of this or null
/// if this doesn't currently have an active
/// sub-state. When set this property will set the incoming
/// instances property
/// to this instance (unless the value set is null, in which case, the
/// this instances
/// is set to null).
///
IState ChildState { get; set; }
}
///
/// An interface used to "mark" an type as being an
/// or a state used during the initial
/// configuration of the application. This is the first state to be applied.
///
public interface IConfigurationState : IState
{ }
///
/// An interface used to "mark" an type as being an
/// or a state that is applied immediately after
/// the configuration state (see ) when
/// it is now safe to load content and handle other tasks that are dependent
/// on a fully configured Chernobyl.
///
public interface ILoadingState : IState
{ }
///
/// An interface used to "mark" an type as being an
/// or a state used when the application is
/// started and running. This state is applied immediately after the loading
/// state (see ).
///
public interface IRunningState : IState
{ }
}