using System; namespace TINK.Model.State { /// /// Types of rent states /// public enum InUseStateEnum { /// /// 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 m_oInUseState; /// /// Constructs a state info object when state is available. /// /// Provider for current date time to calculate remainig time on demand for state of type reserved. public StateInfo() { m_oInUseState = 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 p_oDateTimeNowProvider, DateTime p_oRequestedAt, string p_strMailAddress, string p_strCode) { // Todo: Handle p_oFrom == null here. // Todo: Handle p_oDuration == null here. m_oInUseState = new StateRequestedInfo( p_oDateTimeNowProvider ?? (() => DateTime.Now), p_oRequestedAt, p_strMailAddress, p_strCode); } /// /// 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. m_oInUseState = new StateOccupiedInfo( p_oBookedAt, p_strMailAddress, p_strCode); } /// /// Gets the state value of object. /// public InUseStateEnum Value { get { return m_oInUseState.Value; } } /// /// Member for serialization purposes. /// internal BaseState StateInfoObject { get { return m_oInUseState; } } /// Transforms object to string. /// /// public new string ToString() { return m_oInUseState.Value.ToString("g"); } /// /// Date of request/ bookeing action. /// public DateTime? From { get { var l_oNotDisposableInfo = m_oInUseState as INotAvailableState; return l_oNotDisposableInfo != null ? l_oNotDisposableInfo.From : (DateTime?)null; } } /// /// Mail address. /// public string MailAddress { get { var l_oNotDisposableInfo = m_oInUseState as INotAvailableState; return l_oNotDisposableInfo?.MailAddress; } } /// /// Reservation code. /// public string Code { get { var l_oNotDisposableInfo = m_oInUseState 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 = m_oInUseState as StateRequestedInfo; if (l_oReservedInfo == null) { p_oRemainingTime = null; return false; } return l_oReservedInfo.GetIsStillReserved(out p_oRemainingTime); } } }