using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Appccelerate.StateMachine;
using Appccelerate.StateMachine.AsyncMachine;
using StatementMachineService.Events;
using StatementMachineService.Model;

namespace StatementMachineService.Service
{
    internal class SignalStateService:ISignalStateService
    {
        private AsyncPassiveStateMachine<SignalState,SingalEvent> _machine;
        public event StateEventHandler UpExecuteEvent;
        public event StateEventHandler DownExecuteEvent;
        public SignalStateService()
        {
        }

        private void OnUpEvent()
        {
            UpExecuteEvent?.Invoke(this, new StateEventArgs(_id));

        }

        private void OnDownEvent()
        {
            DownExecuteEvent?.Invoke(this, new StateEventArgs(_id));
        }

        private static readonly List<int> SignalList=new List<int>();
        private int _id;
        public void CreateService(int id)
        {
            _id = id;
            if (SignalList.Exists(p=>p==id))
            {
               throw new Exception("已经存在");
            }

           
            var signal1=new SignalState(Guid.NewGuid().ToString());
            var signal2= new SignalState(Guid.NewGuid().ToString());
            var builder = new StateMachineDefinitionBuilder<SignalState, SingalEvent>();
            builder.In(signal1)
                .On(new SingalEvent(1))
                .Goto(signal2).Execute(OnUpEvent);
            builder.In(signal2).On(new SingalEvent(0)).Goto(signal1).Execute(OnDownEvent);

            _machine = builder.WithInitialState(signal1)
                  .Build().CreatePassiveStateMachine();
           
            _machine.Start();
            SignalList.Add(id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="state">
        ///     <状态></状态>
        /// </param>
        public void ExecuteSate(ushort state)
        {
            _machine.Fire(new SingalEvent(Convert.ToInt32(state)));
        }

    }

    [ComVisible(true)]
    [Serializable]
    public delegate void StateEventHandler(object sender, StateEventArgs e);
}