using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using Wayne.Lib;
using Wayne.FDCPOSLibrary;

namespace Wayne.ForecourtControl.Fusion
{
    public class FUSIONPump : IPumpEx, IDisposable
    {
        // Fields
        private bool blocked;
        private bool capFuelGradeSelected;
        private bool capNozzleDetection;
        private bool capSetLight;
        private bool capSuspendFuelling;
        private bool connected;
        private IFuelling currentFuelling;
        private string entitySubType;
        private bool fuelGradeSelected;
        private List<IFuelling> fuellingList;
        private FUSIONManager manager;
        private int nfsPumpSymbol;
        private List<INozzle> nozzles;
        private bool open;
        private IIdentifiableEntity parerentDevice;
        private PriceGroup priceGroup;
        private int pumpId;
        private int reservedBy;
        private Timer runningFuellingDataTimer;
        private bool _runningFuellingUpdates;
        private PumpState state;
        private TankLevelSwitchStatus tankLevelSwitchStatus;

        // Events
        public event EventHandler<PumpEventOccuredEventArgs> OnEventOccured;

        public event EventHandler<FuellingDataChangeEventArgs> OnFuellingDataChange;

        public event EventHandler<FuellingStateChangeEventArgs> OnFuellingStateChange;

        public event EventHandler<NozzleStateChangeEventArgs> OnNozzleStateChange;

        public event EventHandler<PumpStateChangeEventArgs> OnStateChange;

        public event EventHandler<TankLevelSwitchStatusChangeEventArgs> OnTankLevelSwitchStatusChange;

        public event EventHandler<FuelModeChangeEventArgs> OnFuelModeChange;

        // Methods
        public FUSIONPump(FUSIONManager manager)
        {
            this.manager = manager;
            this.fuellingList = new List<IFuelling>();
            this.nozzles = new List<INozzle>();
            this.currentFuelling = new FUSIONFuelling(manager, this);
        }

        public void AuthorizeAsync(IAuthorizeParameters authorizeParams, EventHandler<AsyncCompletedEventArgs<long>> requestCompleted, object userToken)
        {
            //this.CheckDisposed();
            //if (authorizeParams == null)
            //{
            //    throw new ArgumentException("Must supply a valid IAuthorizeParams object");
            //}
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs<long>>(this, requestCompleted, userToken);
            //this.SendAuthorizationRequest(0xcd, operation.Id, authorizeParams);
            while (this.manager.forecourtControl.fuelPriceReserved)
            {
                Thread.Sleep(200);
                Trace.WriteLine(String.Format("FUSIONPump.AuthorizeAsync: pumpId={0} - fuel price running, wait ...", this.realId));
            }
            int transactionId = 0; // is generated on the server side // ++FUSIONFuelling.transactionId;
            FUSIONFuelling currentFuelling = null;
            currentFuelling = (FUSIONFuelling)(CurrentFuelling);
            currentFuelling.WritableFuellingSequenceNumber = 0;
            currentFuelling.WritableAuthorizationId = 0;
            currentFuelling.WritablePresetType = authorizeParams.PresetType;
            currentFuelling.WritablePresetValue = authorizeParams.PresetValue;

            //FG, OCT-13-10, Add PayType to show outdoor payment type on FM
            currentFuelling.PayType = authorizeParams.PayType;

            Trace.WriteLine(String.Format("FUSIONPump.AuthorizeAsync: pumpId={0}, presetAmount=[{1}, reservingDeviceId={2}, fuellingType={3}", this.realId, currentFuelling.PresetValue, currentFuelling.ReservingDeviceId, currentFuelling.Type));
            this.manager.ifsfManager.AuthoriseFuelPoint(this.realId, transactionId, currentFuelling.Type, currentFuelling.ReservingDeviceId, authorizeParams, requestCompleted, userToken, this);
        }

        public void AuthorizeUpdateAsync(IAuthorizeParameters authorizeParams, EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            //this.CheckDisposed();
            //if (authorizeParams == null)
            //{
            //    throw new ArgumentException("Must supply a valid IAuthorizeParams object");
            //}
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, requestCompleted, userToken);
            //this.SendAuthorizationRequest(0xd5, operation.Id, authorizeParams);
        }

        private void CheckDisposed()
        {
            if (this.manager == null)
            {
                throw new ObjectDisposedException("", "The pump object is not available anymore.");
            }
        }

        public void Dispose()
        {
            //if (this.runningFuellingDataTimer != null)
            //{
            //    this.runningFuellingDataTimer.Dispose();
            //}
            this.manager = null;
            foreach (FUSIONNozzle nozzle in this.nozzles)
            {
                nozzle.Dispose();
            }
            foreach (FUSIONFuelling fuelling in this.fuellingList)
            {
                fuelling.Dispose();
            }
            ((FUSIONFuelling)this.currentFuelling).Dispose();
        }

        internal void FireFuellingDataChange(IFuelling fuelling, decimal amount, decimal quantity)
        {
            if (this.OnFuellingDataChange != null)
            {
                this.OnFuellingDataChange.BeginInvoke(this, new FuellingDataChangeEventArgs(fuelling, amount, quantity), null, null);
            }
        }

        internal void FireFuellingStateChange(IFuelling fuelling, FuellingState state)
        {
            if (this.OnFuellingStateChange != null)
            {
                this.OnFuellingStateChange.BeginInvoke(this, new FuellingStateChangeEventArgs(fuelling, state), null, null);
            }
        }

        internal void FireNozzleStateChange(INozzle nozzle, NozzleState nozzleState)
        {
            if (this.OnNozzleStateChange != null)
            {
                this.OnNozzleStateChange.BeginInvoke(this, new NozzleStateChangeEventArgs(nozzle, nozzleState), null, null);
            }
        }

        internal void FirePumpEventOccured(PumpEventType pumpEventType)
        {
            if (this.OnEventOccured != null)
            {
                this.OnEventOccured.BeginInvoke(this, new PumpEventOccuredEventArgs(pumpEventType), null, null);
            }
        }

        internal void FireFuelModeChange(int mode)
        {
            if (this.OnFuelModeChange != null)
            {
                this.OnFuelModeChange.BeginInvoke(this, new FuelModeChangeEventArgs(this, mode), null, null);
            }
        }

        private void PerformStopPump(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            //FUSIONAsyncOperation<ushort, AsyncCompletedEventArgs> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, requestCompleted, userToken);
            //Function function = new Function(0xc9, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x17, PrimitiveType.Byte, this.pumpId) });
            //this.manager.Send(function);
            //AsyncCompletedEventArgs resultEventArgs = new AsyncCompletedEventArgs(true, operation.UserToken);
            //operation.Complete(resultEventArgs);

            this.manager.ifsfManager.TerminateFuelling(this.realId, requestCompleted, userToken, this);
        }

        public void ReserveAsync(FuellingType fuellingType, byte DeviceId, EventHandler<AsyncCompletedEventArgs> reservedCompleted, object userToken)
        {
            //this.CheckDisposed();
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, reservedCompleted, userToken);
            //Function function = new Function(0xcc, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, operation.Id), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.pumpId), new PrimitiveParameter(5, PrimitiveType.Byte, DeviceId), new PrimitiveParameter(7, PrimitiveType.Int16, NfsConvert.DecodeFillingType(fuellingType)) });
            //this.manager.Send(function);

            FUSIONFuelling currentFuelling = null;
            currentFuelling = (FUSIONFuelling)(CurrentFuelling);
            Trace.WriteLine(String.Format("FUSIONPump.ReserveAsync: pumpId={0}, reservingDeviceId={1}, fuellingType={2}", this.realId, currentFuelling.ReservingDeviceId, currentFuelling.Type));
            if (currentFuelling.Type == fuellingType && currentFuelling.ReservingDeviceId == DeviceId && reservedCompleted != null)
            {
                Trace.WriteLine(String.Format("FUSIONPump.ReserveAsync: pumpId={0}, reservingDeviceId={1}, fuellingType={2} ALREADY RESERVED by the same DeviceId!", this.realId, currentFuelling.ReservingDeviceId, currentFuelling.Type));
                reservedCompleted.BeginInvoke(this, new AsyncCompletedEventArgs(true, userToken), null, null);
            }
            else
            {
                currentFuelling.WritableType = fuellingType;
                currentFuelling.WritableReservingDeviceId = DeviceId;
                this.manager.ifsfManager.ReserveFuelPoint(this.realId, reservedCompleted, userToken, this);
            }
            //if (reservedCompleted != null)
            //    reservedCompleted.Invoke(this, new AsyncCompletedEventArgs(true, userToken));
        }

        public void ResumeAsync(EventHandler<AsyncCompletedEventArgs> resumeCompleted, object userToken)
        {
            //this.CheckDisposed();
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, resumeCompleted, userToken);
            //this.manager.Send(new Function(0xcb, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, operation), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.Id) }));

            this.manager.ifsfManager.ResumeFuelling(this.realId, resumeCompleted, userToken, this);
            //if (resumeCompleted != null)
            //    resumeCompleted.Invoke(this, new AsyncCompletedEventArgs(true, userToken));
        }

        private void RunningFuellingTimerProc(object state)
        {
            if (this.RunningFuellingUpdates && (this.manager != null))
            {
                this.manager.RequestFillingData(this.pumpId, true);
            }
        }

        private void SendAuthorizationRequest(ushort fid, int sequenceNumber, IAuthorizeParameters authorizeParams)
        {
            //this.CheckDisposed();
            //Function function = new Function(fid, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, sequenceNumber), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.pumpId), new PrimitiveParameter(0x16, PrimitiveType.Byte, NfsConvert.DecodePresetType(authorizeParams.PresetType)), new PrimitiveParameter(0x10, PrimitiveType.Decimal, authorizeParams.PresetValue), new PrimitiveParameter(0x27, PrimitiveType.Byte, NfsConvert.DecodePriceGroup(authorizeParams.PriceGroup)), new PrimitiveParameter(0x25, PrimitiveType.Byte, 0), new PrimitiveParameter(120, PrimitiveType.Byte, Convert.ToInt32(authorizeParams.LockToReleaseClient)) });
            //ArrayParameter parameter = new ArrayParameter(14);
            //for (int i = 0; i < authorizeParams.AllowedFuelGrade.Count; i++)
            //{
            //    if (!authorizeParams.AllowedFuelGrade[i])
            //    {
            //        parameter.Add(new PrimitiveParameter(0x1c, PrimitiveType.Byte, i));
            //    }
            //}
            //function.Add(parameter);
            //this.manager.Send(function);
        }

        public void SetBlockedAsync(bool blocked, EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            //if (blocked)
            //    this.manager.ifsfManager.LockNozzle(this.Id, -1, requestCompleted, userToken);
            //else
            //    this.manager.ifsfManager.UnlockNozzle(this.Id, -1, requestCompleted, userToken);
            if (blocked)
                this.manager.ifsfManager.CloseDevice(this.realId, requestCompleted, userToken, this);
            else
                this.manager.ifsfManager.OpenDevice(this.realId, requestCompleted, userToken, this);

            //if (requestCompleted != null)
            //    requestCompleted.Invoke(this, new AsyncCompletedEventArgs(true, userToken));
        }

        public void SetPriceGroupAsync(PriceGroup priceGroup, EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            //this.CheckDisposed();
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, requestCompleted, userToken);
            //Function function = new Function(0xd6, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, operation.Id), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.pumpId), new PrimitiveParameter(0x27, PrimitiveType.Byte, NfsConvert.DecodePriceGroup(priceGroup)) });
            //this.manager.Send(function);

            if (this.manager.forecourtControl.fuelPriceReserved)
                this.manager.ifsfManager.ChangeFuelModeAdd(this.manager.forecourtControl.srChangeMode, this.realId, (int)priceGroup, requestCompleted, userToken, this);
                //this.manager.ifsfManager.ChangeFuelMode(this.Id, (int)priceGroup, requestCompleted, userToken);
            else
                this.manager.ifsfManager.ChangeFuelMode(this.realId, (int)priceGroup, requestCompleted, userToken, this);
        }

        public void SignalEventAsync(PumpEventType eventType, EventHandler<AsyncCompletedEventArgs> signalEventCompleted, object userToken)
        {
            //this.CheckDisposed();
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, signalEventCompleted, userToken);
            //Function function = new Function(0xd8, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, operation.Id), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.Id), new PrimitiveParameter(0x7a, PrimitiveType.UInt16, eventType) });
            //this.manager.Send(function);
        }

        public void StopAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            this.CheckDisposed();
            this.PerformStopPump(requestCompleted, userToken);
        }

        public void SuspendAsync(EventHandler<AsyncCompletedEventArgs> suspendCompleted, object userToken)
        {
            this.CheckDisposed();
        //    FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, suspendCompleted, userToken);
        //    this.manager.Send(new Function(0xca, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, operation), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.Id) }));

            this.manager.ifsfManager.SuspendFuelling(this.realId, suspendCompleted, userToken, this);
        }

        public override string ToString()
        {
            return this.ToString("", CultureInfo.InvariantCulture);
        }

        public string ToString(IFormatProvider provider)
        {
            return this.ToString("", provider);
        }

        public string ToString(string format)
        {
            return this.ToString(format, CultureInfo.InvariantCulture);
        }

        public string ToString(string format, IFormatProvider provider)
        {
            return ("Pump DeviceId=" + this.pumpId.ToString(format, provider));
        }

        public void UnauthorizeAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            this.CheckDisposed();
            this.PerformStopPump(requestCompleted, userToken);
        }

        public void UnreserveAsync(EventHandler<AsyncCompletedEventArgs> requestCompleted, object userToken)
        {
            //this.CheckDisposed();
            //FUSIONAsyncOperation<ushort> operation = this.manager.AsyncManager.RegisterOperation<AsyncCompletedEventArgs>(this, requestCompleted, userToken);
            //Function function = new Function(210, ParserDomain.FillingServer, new Parameter[] { new PrimitiveParameter(0x66, PrimitiveType.UInt16, operation.Id), new PrimitiveParameter(0x17, PrimitiveType.Byte, this.pumpId) });
            //this.manager.Send(function);

            FUSIONFuelling currentFuelling = null;
            currentFuelling = (FUSIONFuelling)(CurrentFuelling);
            currentFuelling.WritableReservingDeviceId = 0;
            Trace.WriteLine(String.Format("FUSIONPump.UnreserveAsync: pumpId={0}, reservingDeviceId={1}, fuellingType={2}", this.realId, currentFuelling.ReservingDeviceId, currentFuelling.Type));

            this.manager.ifsfManager.FreeFuelPoint(this.realId, requestCompleted, userToken, this);
            //if (requestCompleted != null)
            //    requestCompleted.Invoke(this, new AsyncCompletedEventArgs(true, userToken));
        }

        public PumpState convertPumpState(LogicalDeviceState fdcState)
        {
            if (fdcState == LogicalDeviceState.FDC_REQUESTED) return PumpState.Authorized;
            else if (fdcState == LogicalDeviceState.FDC_AUTHORISED) return PumpState.Authorized;
            else if (fdcState == LogicalDeviceState.FDC_CALLING) return PumpState.Calling;
            //else if (fdcState == LogicalDeviceState.FDC_INACTIVATED) return PumpState.Closed;
            else if (fdcState == LogicalDeviceState.FDC_DISABLED) return PumpState.Closed;
            else if (fdcState == LogicalDeviceState.FDC_CLOSED) return PumpState.Closed;
            else if (fdcState == LogicalDeviceState.FDC_FUELLING) return PumpState.Fuelling;
            else if (fdcState == LogicalDeviceState.FDC_STARTED) return PumpState.Fuelling;
            else if (fdcState == LogicalDeviceState.FDC_READY) return PumpState.Idle;
            else if (fdcState == LogicalDeviceState.FDC_OUTOFORDER) return PumpState.Inoperative;
            else if (fdcState == LogicalDeviceState.FDC_OFFLINE) return PumpState.Inoperative;
            else if (fdcState == LogicalDeviceState.FDC_SUSPENDED) return PumpState.Suspended;
            else if (fdcState == LogicalDeviceState.FDC_SUSPENDED_STARTED) return PumpState.Suspended;
            else if (fdcState == LogicalDeviceState.FDC_SUSPENDED_FUELLING) return PumpState.Suspended;
            else if (fdcState == LogicalDeviceState.FDC_INVALIDSTATE) return PumpState.Unknown;
            else if (fdcState == LogicalDeviceState.FDC_UNDEFINED) return PumpState.Unknown;
            else if (fdcState == LogicalDeviceState.FDC_CONFIGURE) return PumpState.Closed;
#if !_USE_OLD_FCONTROL_
            else if (fdcState == LogicalDeviceState.FDC_ERRORSTATE) return PumpState.Error;
#else
            else if (fdcState == LogicalDeviceState.FDC_ERRORSTATE) return PumpState.Inoperative;
#endif
            //else if (fdcState == LogicalDeviceState.FDC_LOCKED) return PumpState.Closed;
            else return PumpState.Unknown;
        }

        public IFuelling getFuellingByTransactionId(int transactionId, int releaseToken)
        {
            // first look for transactionId or for the authorizationId
            foreach (IFuelling fuelling in fuellingList)
            {
                if (transactionId > 0 && fuelling.FuellingSequenceNumber == transactionId ||
                    transactionId == 0 && fuelling.AuthorizationId == releaseToken)
                    return fuelling;
            }
            return null;
        }

        #region Properties
        public bool Blocked
        {
            get
            {
                return this.blocked;
            }
        }

        public bool CapFuelGradeSelected
        {
            get
            {
                return this.capFuelGradeSelected;
            }
        }

        public bool CapNozzleDetection
        {
            get
            {
                return this.capNozzleDetection;
            }
        }

        public bool CapSetLight
        {
            get
            {
                return this.capSetLight;
            }
        }

        public bool CapSuspendFuelling
        {
            get
            {
                return this.capSuspendFuelling;
            }
        }

        public bool Connected
        {
            get
            {
                return this.connected;
            }
        }

        public IFuelling CurrentFuelling
        {
            get
            {
                return this.currentFuelling;
            }
        }

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

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

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

        public FUSIONManager Manager
        {
            get
            {
                return this.manager;
            }
        }

        public bool FuelGradeSelected
        {
            get
            {
                return this.fuelGradeSelected;
            }
        }

        public ReadOnlyCollection<IFuelling> Fuellings
        {
            get
            {
                return this.fuellingList.AsReadOnly();
            }
        }

        public int Id
        {
            get
            {
                if (manager.IdPumpShift > 0)
                    return this.pumpId + manager.IdPumpShift;
                else
                    return this.pumpId + manager.IdShift;
            }
        }

        public int realId
        {
            get
            {
                return this.pumpId;
            }
        }

        internal int NfsPumpSymbol
        {
            get
            {
                return this.nfsPumpSymbol;
            }
            set
            {
                this.nfsPumpSymbol = value;
            }
        }

        public ReadOnlyCollection<INozzle> Nozzles
        {
            get
            {
                return this.nozzles.AsReadOnly();
            }
        }

        public bool Open
        {
            get
            {
                return this.open;
            }
        }

        public IIdentifiableEntity ParentEntity
        {
            get
            {
                return this.parerentDevice;
            }
        }

        public PriceGroup PriceGroup
        {
            get
            {
                return priceGroup;
            }
        }

        public int ReservedBy
        {
            get
            {
                return this.reservedBy;
            }
        }

        public bool RunningFuellingUpdates
        {
            get
            {
                //return (this.runningFuellingDataTimer != null);
                return _runningFuellingUpdates;
            }
            set
            {
                this.CheckDisposed();
                if (this.runningFuellingDataTimer != null)
                {
                    Trace.WriteLine("RunningFuellingTimer disposed on Pump: " + this.pumpId);
                    this.runningFuellingDataTimer.Dispose();
                    this.runningFuellingDataTimer = null;
                }
                if (value)
                {
                    // TODO read timeout from ini file
                    Trace.WriteLine("RunningFuellingTimer create on Pump: " + this.pumpId);
                    this.runningFuellingDataTimer = new Timer(new TimerCallback(this.RunningFuellingTimerProc), null,
                        manager.forecourtControl.ConfigParam.ReadRunningFuelling, manager.forecourtControl.ConfigParam.ReadRunningFuelling);
                }


                //if (value && !_runningFuellingUpdates)
                //{
                //    // send GetCurrentFuellingUpdates command
                //    this.manager.ifsfManager.GetCurrentFuellingStatus(this.Id);
                //}
                //else if (!value && _runningFuellingUpdates)
                //{

                //}
                _runningFuellingUpdates = value;
            }
        }

        public PumpState State
        {
            get
            {
                return this.state;
            }
        }

        public void NozzleStateChange(INozzle nozzle, NozzleState nozzleState)
        {
            if (this.OnNozzleStateChange != null)
            {
                Trace.WriteLine("OnNozzleStateChange.Invoke");
                this.OnNozzleStateChange.BeginInvoke(this, new NozzleStateChangeEventArgs(nozzle, nozzleState), null, null);
            }
        }

        public TankLevelSwitchStatus TankLevelSwitchStatus
        {
            get
            {
                return this.tankLevelSwitchStatus;
            }
        }

        internal bool WritableBlocked
        {
            get
            {
                return this.blocked;
            }
            set
            {
                this.blocked = value;
            }
        }

        internal bool WritableCapFuelGradeSelected
        {
            get
            {
                return this.capFuelGradeSelected;
            }
            set
            {
                this.capFuelGradeSelected = value;
            }
        }

        internal bool WritableCapNozzleDetection
        {
            get
            {
                return this.capNozzleDetection;
            }
            set
            {
                this.capNozzleDetection = value;
            }
        }

        internal bool WritableCapSetLight
        {
            get
            {
                return this.capSetLight;
            }
            set
            {
                this.capSetLight = value;
            }
        }

        internal bool WritableCapSuspendFuelling
        {
            get
            {
                return this.capSuspendFuelling;
            }
            set
            {
                this.capSuspendFuelling = value;
            }
        }

        internal bool WritableConnected
        {
            get
            {
                return this.connected;
            }
            set
            {
                this.connected = value;
            }
        }

        internal IFuelling WritableCurrentFuelling
        {
            get
            {
                return this.currentFuelling;
            }
        }

        internal string WritableDeviceName
        {
            get
            {
                return this.entitySubType;
            }
            set
            {
                this.entitySubType = value;
            }
        }

        internal bool WritableFuelGradeSelected
        {
            get
            {
                return this.fuelGradeSelected;
            }
            set
            {
                this.fuelGradeSelected = value;
            }
        }

        internal List<IFuelling> WritableFuellingList
        {
            get
            {
                return this.fuellingList;
            }
        }

        internal List<INozzle> WritableNozzleList
        {
            get
            {
                return this.nozzles;
            }
        }

        internal bool WritableOpen
        {
            get
            {
                return this.open;
            }
            set
            {
                this.open = value;
            }
        }

        internal IIdentifiableEntity WritableParentDevice
        {
            get
            {
                return this.parerentDevice;
            }
            set
            {
                this.parerentDevice = value;
            }
        }

        internal PriceGroup WritablePriceGroup
        {
            get
            {
                return this.priceGroup;
            }
            set
            {
                this.priceGroup = value;
            }
        }

        internal int WritablePumpId
        {
            get
            {
                return this.pumpId;
            }
            set
            {
                this.pumpId = value;
            }
        }

        internal int WritableReservedBy
        {
            get
            {
                return this.reservedBy;
            }
            set
            {
                this.reservedBy = value;
            }
        }

        internal PumpState WritableState
        {
            get
            {
                return this.state;
            }
            set
            {
                if (this.state != value)
                {
                    this.state = value;
                    Trace.WriteLine("state is different");
                    if (this.OnStateChange != null)
                    {
                        Trace.WriteLine("OnStateChange.Invoke");
                        this.OnStateChange.BeginInvoke(this, new PumpStateChangeEventArgs(this, this.state), null, null);
                    }
                }
            }
        }

        internal TankLevelSwitchStatus WritableTankLevelSwitchStatus
        {
            get
            {
                return this.tankLevelSwitchStatus;
            }
            set
            {
                if (this.tankLevelSwitchStatus != value)
                {
                    this.tankLevelSwitchStatus = value;
                    if (this.OnTankLevelSwitchStatusChange != null)
                    {
                        this.OnTankLevelSwitchStatusChange.BeginInvoke(this, new TankLevelSwitchStatusChangeEventArgs(this, this.tankLevelSwitchStatus), null, null);
                    }
                }
            }
        }
        #endregion // properties
    }


}