using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using Wayne.FDCPOSLibrary;
using Wayne.ForecourtControl.Fusion.ReadDeviceStatus;
using Wayne.Lib;
using Wayne.Lib.Log;

namespace Wayne.ForecourtControl.Fusion
{
    public class FUSIONForecourtControl : IForecourtControl, IConnectable, IIdentifiableEntity, IDisposable
    {
        // Fields

        private string clientName;
        private string connectionString;

        private DeviceConnectionState connectionState = DeviceConnectionState.Disconnected;

        private List<IFuelPrice> fuelPriceList = new List<IFuelPrice>();
        private int id;
        private FUSIONManager _manager;

        public FUSIONManager manager
        {
            get { return _manager; }
        }

        private List<IPricePole> pricePoleList = new List<IPricePole>();
        private List<IPumpEx> pumpList = new List<IPumpEx>();
        private List<ITankGroup> tankGroupList = new List<ITankGroup>();
        private List<IFuelProduct> fuelProducts = new List<IFuelProduct>();


        private int siteMode;
        private bool siteOpened;
        public ServiceRequestChangeFuelMode srChangeMode = null;
        public bool fuelPriceReserved;
        public ReadDeviceStatusController DeviceStatusController { get; private set; }

        // Events
        public event EventHandler<AlarmEventArgs> OnAlarm;
        public event EventHandler<ConnectionChangedEventArgs> OnConnectionStateChange;
        public event EventHandler<ConfigurationChangeEventArgs> OnConfigurationChange;
        public event EventHandler<FuelPriceChangeEventArgs> OnFuelPriceChange;
        public event EventHandler<SiteModeChangeEventArgs> OnSiteModeChange;

        private readonly DebugLogger debugLogger;

        #region Methods

        public FUSIONForecourtControl(int deviceId, ForecourtEntityTypes managedEntityTypes, int[] managedPumpIds,
            IPumpAuthorizationIdGenerator authorizationIdGenerator)
            : this(deviceId, managedEntityTypes, managedPumpIds, null, authorizationIdGenerator)
        {
        }

        public FUSIONForecourtControl(int deviceId, ForecourtEntityTypes managedEntityTypes, int[] managedPumpIds,
            IForecourtConfiguration config, IPumpAuthorizationIdGenerator authorizationIdGenerator)
        {
            this.id = deviceId;
            debugLogger = new DebugLogger(this, true);

            ForecourtConfiguration = config;
            DebugLog("Creating FUSIONManager");
            DeviceStatusController = new ReadDeviceStatusController(this, this);
            DeviceStatusController.Initialize();

            this._manager = new FUSIONManager(this, managedEntityTypes, managedPumpIds, authorizationIdGenerator, DeviceStatusController);
            fuelPriceReserved = false;

            siteOpened = true;

            DebugLog("Creating ReadDeviceStatusController");
        }

        private void DebugLog(string s)
        {
            if (debugLogger.IsActive())
                debugLogger.Add(s);
        }

        public void ActivateFuelPricesAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            DebugLog("ActivateFuelPricesAsync init");
            int iFuelGrade;
            decimal price;
            ServiceRequestChangeFuelPrice sr = new ServiceRequestChangeFuelPrice();
            foreach (FUSIONFuelPrice fuelprice in WritableFuelPriceList)
            {
                try
                {
                    Monitor.Enter(fuelprice.locker);
                    iFuelGrade = fuelprice.WritableFuelGrade;
                    DebugLog(string.Format("fuelGrade={0}, ((FUSIONFuelPrice)fuelprice).Changed={1}", fuelprice.WritableFuelGrade, fuelprice.Changed));
                    if (fuelprice.Changed)
                    {
                        for (int pg = PriceGroup.MinValue; pg <= PriceGroup.MaxValue; pg++)
                        {
                            FUSIONFuelPriceAddPricePerPriceGroup pgd = (FUSIONFuelPriceAddPricePerPriceGroup)(fuelprice.PriceGroupDelta);
                            DebugLog(string.Format("pg = {0}, pgd.getChanged(mode)={1}", pg, pgd.getChanged(pg)));
                            if (pgd.getChanged(pg))
                            {
                                price = fuelprice.BasePrice + fuelprice.GeneralPriceDelta +
                                        fuelprice.PriceGroupDelta[pg];
                                // Get Fuel Modes that use this price group
                                var fuelModes = manager.forecourtControl.ForecourtConfiguration.GetFuelModes(pg);
                                foreach (var mode in fuelModes)
                                {
                                    this._manager.ifsfManager.ChangeFuelPriceAdd(sr, fuelprice.WritableFuelGrade, price,
                                        mode);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    DebugLog("ActivateFuelPricesAsync Exception! " + ex);
                }
                finally
                {
                    Monitor.Exit(fuelprice.locker);
                }
            }
            this._manager.ifsfManager.ChangeFuelPriceSend(sr, null, null, null);

            foreach (IFuelPrice fuelprice in FuelPrices)
            {
                ((FUSIONFuelPrice)fuelprice).WritableReserved = false;
            }
            srChangeMode = null;
            fuelPriceReserved = false;

            if (requestCompleted != null)
                requestCompleted(this, new AsyncCompletedEventArgs(true, userToken));
            DebugLog("ActivateFuelPricesAsync end");
        }

        public void SetFuelPriceAsync(IList<IFuelPriceReading> newFuelPrices,
            EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            DebugLog("SetFuelPriceAsync init");
            var sr = new ServiceRequestChangeFuelPrice();
            foreach (var newFuelPrice in newFuelPrices.OfType<FuelPriceReading>())
            {
                try
                {
                    var fuelMode =
                        manager.forecourtControl.ForecourtConfiguration.GetDefaultFuelMode(newFuelPrice.PriceGroup);

                    DebugLog(string.Format("fuelGrade={0}, fuelprice={1}, mode={2}", newFuelPrice.Fuelgrade, newFuelPrice.Price, fuelMode));
                    this._manager.ifsfManager.ChangeFuelPriceAdd(sr, newFuelPrice.Fuelgrade, newFuelPrice.Price, fuelMode);
                }
                catch (Exception ex)
                {
                    DebugLog("SetFuelPriceAsync Exception! " + ex);
                }
            }
            this._manager.ifsfManager.ChangeFuelPriceSend(sr, requestCompleted, userToken, null);
            DebugLog("SetFuelPriceAsync end");
        }

        public void CloseReconciliationPeriodAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted,
            object userToken)
        {
            DebugLog("CloseReconciliationPeriodAsync init");
            this._manager.ifsfManager.CloseReconciliationPeriodAsyncSend(requestCompleted, userToken, null);
            DebugLog("CloseReconciliationPeriodAsync end");
        }

        public void Connect(string connectionString)
        {
            this.connectionString = connectionString;

            Thread runConnectThread = new Thread(ConnectThreadProc);
            runConnectThread.Start();
        }

        private void ConnectThreadProc()
        {
            this.manager.Connect(connectionString);
        }

        public void Disconnect()
        {
            this.WritableConnectionState = DeviceConnectionState.Disconnecting;
            this.manager.Disconnect();
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                DeviceStatusController.Dispose();
                FUSIONFactory.Remove(this);
                this.manager.Dispose();
                debugLogger.Dispose();
            }
        }

        ~FUSIONForecourtControl()
        {
            this.Dispose(false);
        }

        internal void FireAlarmEvent(AlarmEventArgs args)
        {
            if (this.OnAlarm != null)
            {
                this.OnAlarm(this, args);
            }
        }

        internal void FireConfigurationChangeEvent(ConfigurationChangeEventArgs args)
        {
            if (this.OnConfigurationChange != null)
            {
                this.OnConfigurationChange(this, args);
            }
        }

        public void ReserveFuelPricesAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            fuelPriceReserved = true;
            srChangeMode = new ServiceRequestChangeFuelMode();
            if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007)
                srChangeMode.RequestType = "ChangeFuelMode";
            else
                srChangeMode.RequestType = "ChangeFPFuelMode";

            foreach (IFuelPrice fuelprice in FuelPrices)
            {
                ((FUSIONFuelPrice)fuelprice).WritableReserved = true;
            }
            if (requestCompleted != null)
                requestCompleted(this, new AsyncCompletedEventArgs(true, userToken));
        }

        public void SetSiteModeAsync(int siteMode, EventHandler<AsyncCompletedEventArgs> requestCompleted,
            object userToken)
        {
            WritableSiteMode = siteMode;
            if (requestCompleted != null)
                requestCompleted(this, new AsyncCompletedEventArgs(true, userToken));

            string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Test", "Operation");
            if (sValue != "")
            {
                Test();
            }
        }

        public void SetSiteOpenedAsync(bool opened, EventHandler<AsyncCompletedEventArgs> requestCompleted,
            object userToken)
        {

            if (opened)
            {
                this.manager.ifsfManager.StartForecourt(requestCompleted, userToken, this);
            }
            else
                this.manager.ifsfManager.StopForecourt(requestCompleted, userToken, this);
        }

        public void Test()
        {
            int par1 = -1, par2 = -1;
            int id = -1;
            int trid = -1;
            int nozzleId = -1;
            string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Test", "Operation");
            string[] sElems;

            StreamReader sr = new StreamReader(ConfigurationParams.getSINPPath("ini\\") + sValue);
            while (sr.Peek() != -1)
            {
                sValue = sr.ReadLine();
                sElems = sValue.Split(',');
                try
                {
                    if (sElems.GetLength(0) > 1)
                    {
                        try
                        {
                            par1 = Convert.ToInt32(sElems[1]);
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                    if (sElems.GetLength(0) > 2)
                    {
                        try
                        {
                            par2 = Convert.ToInt32(sElems[2]);
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                    sValue = sElems[0];
                    id = par1;
                    trid = par2;
                }
                catch (Exception ex)
                {
                }
                if (sValue == "StartFuelPointTest")
                {
                    manager.ifsfManager.StartFuelPointTest(id, null, null, null);
                }
                else if (sValue == "EndFuelPointTest")
                {
                    this.manager.ifsfManager.EndFuelPointTest(id, null, null, null);
                }
                else if (sValue == "CloseFuelPoint")
                {
                    this.manager.ifsfManager.CloseFuelPoint(id, null, null, null);
                }
                else if (sValue == "OpenFuelPoint")
                {
                    this.manager.ifsfManager.OpenFuelPoint(id, null, null, null);
                }
                else if (sValue == "AuthoriseFuelPoint")
                {
                    AuthorizeParameters authParams = new AuthorizeParameters();
                    authParams.PresetType = PresetType.Amount;
                    authParams.PresetValue = 50;
                    this.manager.ifsfManager.AuthoriseFuelPoint(id, trid, FuellingType.Unknown, 0, authParams, null,
                        null, null);
                }
                else if (sValue == "SuspendFuelling")
                {
                    FUSIONPump pump = this.manager.GetPumpById(id);
                    if (pump != null)
                        pump.SuspendAsync(new EventHandler<Wayne.Lib.AsyncCompletedEventArgs>(Test_SuspendResult), null);
                    //this.manager.ifsfManager.SuspendFuelling(id, null, null);
                }
                else if (sValue == "ResumeFuelling")
                {
                    FUSIONPump pump = this.manager.GetPumpById(id);
                    if (pump != null)
                        pump.ResumeAsync(new EventHandler<Wayne.Lib.AsyncCompletedEventArgs>(Test_ResumeResult), null);
                    //this.manager.ifsfManager.ResumeFuelling(id, null, null);
                }
                else if (sValue == "TerminateFuelling")
                {
                    this.manager.ifsfManager.TerminateFuelling(id, null, null, null);
                }
                else if (sValue == "LogOff")
                {
                    this.manager.ifsfManager.LogOff();
                }
                else if (sValue == "LogOn")
                {
                    this.manager.ifsfManager.LogOn("", "");
                }
                else if (sValue == "GetFuelMode")
                {
                    this.manager.ifsfManager.GetFuelMode(id, null, null, null);
                }
                else if (sValue == "GetModeTable")
                {
                    this.manager.ifsfManager.GetModeTable(null, null, null);
                }
                else if (sValue == "ClearFuelSaleTrx")
                {
                    this.manager.ifsfManager.ClearFuelSaleTrx(id, trid, 0, "", null, null, null);
                }
                else if (sValue == "LockFuelSaleTrx")
                {
                    this.manager.ifsfManager.LockFuelSaleTrx(id, trid, 0, null, null, null);
                }
                else if (sValue == "UnlockFuelSaleTrx")
                {
                    this.manager.ifsfManager.UnlockFuelSaleTrx(id, trid, 0, null, null, null);
                }
                else if (sValue == "getCountrySetting")
                {
                    this.manager.ifsfManager.GetCountrySettings(null, null, null);
                }
                else if (sValue == "GetCurrentFuellingStatus")
                {
                    this.manager.ifsfManager.GetCurrentFuellingStatus(id, null, null, null);
                }
                else if (sValue == "LockNozzle")
                {
                    this.manager.ifsfManager.LockNozzle(id, nozzleId, null, null, null);
                }
                else if (sValue == "UnlockNozzle")
                {
                    this.manager.ifsfManager.UnlockNozzle(id, nozzleId, null, null, null);
                }
                else if (sValue == "GetDeviceState")
                {
                    this.manager.ifsfManager.GetDeviceState(Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser, id, null,
                        null, null);
                }
                else if (sValue == "GetFuelPointTotals")
                {
                    nozzleId = par2;
                    this.manager.ifsfManager.GetFuelPointTotals(id, nozzleId, null, null, null);
                }
                else if (sValue == "CloseFuelPoint")
                {
                    this.manager.ifsfManager.CloseFuelPoint(id, null, null, null);
                }
                else if (sValue == "OpenFuelPoint")
                {
                    this.manager.ifsfManager.OpenFuelPoint(id, null, null, null);
                }
                else if (sValue == "ReserveFuelPoint")
                {
                    FUSIONPump pump = this.manager.GetPumpById(id);
                    if (pump != null)
                        pump.ReserveAsync(FuellingType.Unknown, 0,
                            new EventHandler<Wayne.Lib.AsyncCompletedEventArgs>(Test_ReserveResult), null);
                    //this.manager.ifsfManager.ReserveFuelPoint(id, null, null);
                }
                else if (sValue == "FreeFuelPoint")
                {
                    FUSIONPump pump = this.manager.GetPumpById(id);
                    if (pump != null)
                        pump.UnreserveAsync(new EventHandler<Wayne.Lib.AsyncCompletedEventArgs>(Test_UnreserveResult),
                            null);
                    //this.manager.ifsfManager.FreeFuelPoint(id, null, null);
                }
                else if (sValue == "GetFuelSaleTrxDetails")
                {
                    this.manager.ifsfManager.GetFuelSaleTrxDetails(id, trid, 0, null, null, null);
                }
                else if (sValue == "GetAvailableFuelSaleTrxs")
                {
                    this.manager.ifsfManager.GetAvailableFuelSaleTrxs(id, null, null, null);
                }
                else if (sValue == "ChangeFuelMode")
                {
                    int priceGroup = par2;

                    this.manager.ifsfManager.ChangeFuelMode(id, priceGroup, 0, null, null, null);
                }
                else if (sValue == "SendConfig")
                {
                    this.manager.ifsfManager.SendConfig(sElems[1], null, null, null);
                }
                else
                {

                }
            }
            sr.Close();
        }

        private void Test_SuspendResult(Object src, Wayne.Lib.AsyncCompletedEventArgs completed)
        {
            try
            {
                IPump pump = (IPump)completed.UserToken;
                if (pump != null)
                {
                    DebugLog(string.Format("pump={0}, result={1}", ((FUSIONPump)(pump)).realId, completed.Success));
                }
            }
            catch (Exception ex)
            {
                DebugLog(string.Format("EXCEPTION! {0}", ex));
            }
        }

        private void Test_ResumeResult(Object src, Wayne.Lib.AsyncCompletedEventArgs completed)
        {
            try
            {
                IPump pump = (IPump)completed.UserToken;
                if (pump != null)
                {
                    DebugLog(string.Format("pump={0}, result={1}", ((FUSIONPump)(pump)).realId, completed.Success));
                }
            }
            catch (Exception ex)
            {
                DebugLog(string.Format("EXCEPTION! {0}", ex));
            }
        }

        private void Test_ReserveResult(Object src, Wayne.Lib.AsyncCompletedEventArgs completed)
        {
            try
            {
                IPump pump = (IPump)completed.UserToken;
                if (pump != null)
                {
                    DebugLog(string.Format("pump={0}, result={1}", ((FUSIONPump)(pump)).realId, completed.Success));
                }
            }
            catch (Exception ex)
            {
                DebugLog(string.Format("EXCEPTION! {0}", ex));
            }
        }

        private void Test_UnreserveResult(Object src, Wayne.Lib.AsyncCompletedEventArgs completed)
        {
            try
            {
                IPump pump = (IPump)completed.UserToken;
                if (pump != null)
                {
                    DebugLog(string.Format("pump={0}, result={1}", ((FUSIONPump)(pump)).realId, completed.Success));
                }
            }
            catch (Exception ex)
            {
                DebugLog(string.Format("EXCEPTION! {0}", ex));
            }
        }



        public override string ToString()
        {
            return ("Forecourt Control ClientId=" + this.ClientId.ToString(CultureInfo.InvariantCulture));
        }

        public void UnreserveFuelPricesAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            //if (this.manager.forecourtControl.fuelPriceReserved)
            //    this.manager.ifsfManager.ChangeFuelModeSend(this.manager.forecourtControl.srChangeMode, requestCompleted,
            //        userToken, this);
            foreach (IFuelPrice fuelprice in FuelPrices)
            {
                ((FUSIONFuelPrice)fuelprice).WritableReserved = false;
            }
            if (requestCompleted != null && !this.manager.forecourtControl.fuelPriceReserved)
                requestCompleted(this, new AsyncCompletedEventArgs(true, userToken));
            srChangeMode = null;
            fuelPriceReserved = false;
        }


        #endregion

        /// <summary>
        /// Get Fuel prices. 
        /// </summary>
        /// <param name="requestCompleted">Delegate that will be called on completion.</param>
        /// <param name="userToken">A user supplied object that will be returned in the requestCompleted callback</param>
        public void GetFuelPricesAsync(
            EventHandler<Wayne.Lib.AsyncCompletedEventArgs<IList<IFuelPriceReading>>> requestCompleted, object userToken)
        {
            DebugLog("GetFuelPricesAsync init");
            this.manager.ifsfManager.GetFuelPrices(requestCompleted, userToken, this);
        }

        /// <summary>
        /// Get Pump Totals. 
        /// </summary>
        /// <param name="requestCompleted">Delegate that will be called on completion.</param>
        /// <param name="userToken">A user supplied object that will be returned in the requestCompleted callback</param>
        public void GetPumpTotalsAsync(FuelTotalReading totalReading,
            EventHandler<AsyncCompletedEventArgs<PumpAccumulatorReading>> requestCompleted, object userToken)
        {
            DebugLog("GetPumpTotalsAsync init");
            this._manager.ifsfManager.GetPumpTotals(totalReading.DeviceClass, requestCompleted, userToken, this);
        }

        /// <summary>
        /// Get Tank reconciliation 
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="requestCompleted">Delegate that will be called on completion.</param>
        /// <param name="userToken">A user supplied object that will be returned in the requestCompleted callback</param>
        public void GetTankReconciliationAsync(int deviceId,
            EventHandler<Wayne.Lib.AsyncCompletedEventArgs<ITankReconciliation>> requestCompleted, object userToken)
        {
            DebugLog("GetTankReconciliationAsync init");
            this.manager.ifsfManager.GetTankReconciliation(deviceId, requestCompleted, userToken, this);
        }

        /// <summary>
        /// Get Tank delivery 
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="requestCompleted">Delegate that will be called on completion.</param>
        /// <param name="userToken">A user supplied object that will be returned in the requestCompleted callback</param>
        public void GetTankDeliveryAsync(int deviceId,
            EventHandler<Wayne.Lib.AsyncCompletedEventArgs<ITankDelivery>> requestCompleted, object userToken)
        {
            DebugLog("GetTankDeliveryAsync init");
            this.manager.ifsfManager.GetTankDelivery(deviceId, requestCompleted, userToken, this);
        }

        #region Properties

        public int ClientId
        {
            get { return int.Parse(this.manager.ifsfManager.clientSocket.applicationSender); }
        }

        public string ClientName
        {
            get { return this.clientName; }
        }

        public DeviceConnectionState ConnectionState
        {
            get { return this.connectionState; }
        }

        public string EntitySubType
        {
            get { return ""; }
        }

        public string EntityType
        {
            get { return "FUSIONForecourtControl"; }
        }

        /// <summary>
        /// This is used by the logger and should never be set by inheriting classes
        /// </summary>
        public string FullEntityName { get; set; }

        public ReadOnlyCollection<IFuelPrice> FuelPrices
        {
            get { return new ReadOnlyCollection<IFuelPrice>(new List<IFuelPrice>(this.fuelPriceList)); }
        }

        public ReadOnlyCollection<IFuelPriceReading> FuelPriceReadings
        {
            get { return this.manager.FuelPriceReadings.AsReadOnly(); }
        }



        public int Id
        {
            get { return this.id; }
            set { id = value; }
        }

        public IIdentifiableEntity ParentEntity
        {
            get { return null; }
        }

        public ReadOnlyCollection<IPricePole> PricePoles
        {
            get { return this.pricePoleList.AsReadOnly(); }
        }

        public ReadOnlyCollection<IPumpEx> Pumps
        {
            get { return this.pumpList.AsReadOnly(); }
        }

        public ReadOnlyCollection<IFuelProduct> FuelProducts
        {
            get { return this.WritableFuelProducts.AsReadOnly(); }
        }



        public int SiteMode
        {
            get { return this.siteMode; }
        }

        public bool SiteOpened
        {
            get { return this.siteOpened; }
        }

        public ReadOnlyCollection<ITankGroup> TankGroups
        {
            get { return this.tankGroupList.AsReadOnly(); }
        }

        internal DeviceConnectionState WritableConnectionState
        {
            get { return this.connectionState; }
            set
            {
                DebugLog(string.Format("old connectionState={0}, new connectionState={1}", this.connectionState, value));
                if (this.connectionState != value)
                {
                    this.connectionState = value;

                    if (this.OnConnectionStateChange != null)
                    {
                        this.OnConnectionStateChange(this, new ConnectionChangedEventArgs(value));
                    }
                }
            }
        }

        internal List<IFuelPrice> WritableFuelPriceList
        {
            get { return this.fuelPriceList; }
        }

        internal List<IPricePole> WritablePricePoleList
        {
            get { return this.pricePoleList; }
        }

        internal List<IPumpEx> WritablePumpList
        {
            get { return this.pumpList; }
        }

        internal List<IFuelProduct> WritableFuelProducts
        {
            get { return fuelProducts; }
        }

        internal int WritableSiteMode
        {
            get
            {
                return this.siteMode;
            }
            set
            {
                if (this.siteMode != value)
                {
                    this.siteMode = value;
                    if (this.OnSiteModeChange != null)
                    {
                        this.OnSiteModeChange(this, new SiteModeChangeEventArgs(this.siteMode, this.siteOpened));
                    }
                }
            }
        }

        internal List<ITankGroup> WritableTankGroupList
        {
            get { return this.tankGroupList; }
        }

        public IFuelPrice getFuelPriceByProductId(int productId)
        {
            foreach (FUSIONFuelPrice fuelprice in WritableFuelPriceList)
            {
                if (productId == fuelprice.WritableFuelGrade)
                    return fuelprice;
            }
            return null;
        }

        public IForecourtConfiguration ForecourtConfiguration { get; internal set; }

        #endregion

        #region IForecourtControl Members


        public void ReservePumpClusterAsync(int terminalDeviceId, EventHandler<AsyncCompletedEventArgs> requestCompleted,
            object userToken)
        {
            throw new NotImplementedException();
        }

        public void UnreservePumpClusterAsync(int terminalDeviceId,
            EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            throw new NotImplementedException();
        }


        public void SendDeviceAlarmAsync(int terminalDeviceId, string deviceClassType, IEnumerable<int> alarmIds,
            IEnumerable<string> messages,
            EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            manager.ifsfManager.SetDeviceAlarm(deviceClassType, terminalDeviceId, alarmIds, messages, requestCompleted,
                userToken, this);
        }

        #endregion

        public void ReadStatusBeforeSetConnectionState(DeviceConnectionState deviceConnectionState)
        {
            if (deviceConnectionState == DeviceConnectionState.Connected)
            {
                DeviceStatusController.Start();
            }
            else
            {
                WritableConnectionState = deviceConnectionState;
            }
        }
    }
}