using System; namespace TINK.Model.State { /// /// Types of rent states /// public enum InUseStateEnum { /// /// Bike was returned but no feedback given. /// This applies to COPRI locks only because returning of bike is not done using app (Status: Supported locks are ILockIt and COPRI). /// FeedbackPending, /// /// Bike is not in use. Corresponding COPRI state is "available". /// Disposable, /// /// Bike is reserved. Corresponding COPRI state is "requested". /// Reserved, /// /// Bike is booked. Corresponding COPRI statie is "occupied". /// Booked } /// /// Manages the state of a bike. /// public class StateInfo : IStateInfo { // Holds the current disposable state value. private readonly BaseState _InUseState; /// /// Constructs a state info object when state is available. /// /// Specifieds whether feedback is pending or not. public StateInfo(bool isFeedbackPending = false) { _InUseState = isFeedbackPending ? (BaseState)new StateFeedbackPendingInfo() : new StateAvailableInfo(); } /// /// Constructs a state info object when state is requested. /// /// Date time when bike was requested /// Mail address of user which requested bike. /// Booking code. /// Date time provider to calculate reaining time. public StateInfo( Func dateTimeNowProvider, DateTime requestedAt, string mailAddress, string code) { // Todo: Handle p_oFrom == null here. // Todo: Handle p_oDuration == null here. _InUseState = new StateRequestedInfo( dateTimeNowProvider ?? (() => DateTime.Now), requestedAt, mailAddress, code); } /// /// Constructs a state info object when state is booked. /// /// Date time when bike was booked /// Mail address of user which booked bike. /// Booking code. public StateInfo( DateTime p_oBookedAt, string p_strMailAddress, string p_strCode) { // Todo: Handle p_oFrom == null here. // Todo: Clearify question: What to do if code changes form one value to another? This should never happen. // Todo: Clearify question: What to do if from time changes form one value to another? This should never happen. _InUseState = new StateOccupiedInfo( p_oBookedAt, p_strMailAddress, p_strCode); } /// /// Gets the state value of object. /// public InUseStateEnum Value { get { return _InUseState.Value; } } /// /// Member for serialization purposes. /// internal BaseState StateInfoObject { get { return _InUseState; } } /// Transforms object to string. /// /// public new string ToString() { return _InUseState.Value.ToString("g"); } /// /// Date of request/ bookeing action. /// public DateTime? From { get { var l_oNotDisposableInfo = _InUseState as INotAvailableState; return l_oNotDisposableInfo != null ? l_oNotDisposableInfo.From : (DateTime?)null; } } /// /// Mail address. /// public string MailAddress { get { var l_oNotDisposableInfo = _InUseState as INotAvailableState; return l_oNotDisposableInfo?.MailAddress; } } /// /// Reservation code. /// public string Code { get { var l_oNotDisposableInfo = _InUseState as INotAvailableState; return l_oNotDisposableInfo?.Code; } } /// /// Tries update /// /// True if reservation span has not exeeded and state remains reserved, false otherwise. /// Implement logging of time stamps. public bool GetIsStillReserved(out TimeSpan? p_oRemainingTime) { var l_oReservedInfo = _InUseState as StateRequestedInfo; if (l_oReservedInfo == null) { p_oRemainingTime = null; return false; } return l_oReservedInfo.GetIsStillReserved(out p_oRemainingTime); } } }