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);
}
}
}