using parkMonitor.model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace parkMonitor.server {
	/// <summary>异步命令服务</summary>
	public class AsyncCmdServer {
		public static readonly AsyncCmdServer ins = new AsyncCmdServer();
		public static AsyncCmdServer getInstance() { return ins; }

		object syncObj = new object();
		Dictionary<AsyncCmdType, List<Action>> mapFun = new Dictionary<AsyncCmdType, List<Action>>();
		Dictionary<AsyncCmdType, List<Delegate>> mapFunArgs = new Dictionary<AsyncCmdType, List<Delegate>>();

		public void listen(AsyncCmdType type, Action fun) {
			lock(syncObj) {
				if(!mapFun.ContainsKey(type)) {
					mapFun[type] = new List<Action>();
				}
				mapFun[type].Add(fun);
			}
		}

		public void listen<T>(AsyncCmdType type, Action<T> fun) {
			lock(syncObj) {
				if(!mapFunArgs.ContainsKey(type)) {
					mapFunArgs[type] = new List<Delegate>();
				}
				mapFunArgs[type].Add(fun);
			}
		}

		public void send(AsyncCmdType type) {

			List<Action> lstFun = new List<Action>();
			lock(syncObj) {
				if(!mapFun.ContainsKey(type)) {
					return;
				}

				//lstFun = mapFun[type];
				lstFun = new List<Action>(mapFun[type]);
			}

			Task.Run(() => {
				for(int i = 0; i < lstFun.Count; ++i) {
					lstFun[i].Invoke();
				}
			});
		}

		public void send<T>(AsyncCmdType type, T data) {
			List<Delegate> lstFun = new List<Delegate>();
			lock(syncObj) {
				if(!mapFunArgs.ContainsKey(type)) {
					return;
				}

				lstFun = new List<Delegate>(mapFunArgs[type]);
			}

			Task.Run(() => {
				for(int i = 0; i < lstFun.Count; ++i) {
					Action<T> fun = lstFun[i] as Action<T>;
					if(fun == null) {
						continue;
					}
					fun.Invoke(data);
				}
			});
		}
	}

	/// <summary>命令类型</summary>
	public enum AsyncCmdType {
		/// <summary>
		/// 总状态改变
		/// 参数：AlarmStatus status
		/// </summary>
		TotalStatusChanged,

		/// <summary>
		/// PLC离线
		/// 参数:无
		/// </summary>
		PLCOffline,
		/// <summary>
		/// PLC上线
		/// 参数:无
		/// </summary>
		PLCOnline,
        /// <summary>PLC读异常</summary>
        PLCReadException,
        /// <summary>PLC写异常</summary>
        PLCWriteException,

        /// <summary>号牌机离线</summary>
        //NumMachineOffline,
		/// <summary>号牌机上线</summary>
		//NumMachineOnline,

        /// <summary>Laser1离线</summary>
        Laser1Offline,
        /// <summary>Laser1上线</summary>
        Laser1Online,
        /// <summary>Laser1结算异常</summary>
        Laser1CalcException,
        /// <summary>Laser1系统异常</summary>
        Laser1SystemException,

        /// <summary>Laser2离线</summary>
        Laser2Offline,
        /// <summary>Laser2上线</summary>
        Laser2Online,
        /// <summary>Laser2结算异常</summary>
        Laser2CalcException,
        /// <summary>Laser2系统异常</summary>
        Laser2SystemException
    }
}
