zaaReloaded2/zaaReloaded2/LabModel/LabItem.cs

263 lines
7.2 KiB
C#
Executable File

/* LabItem.cs
* part of zaaReloaded2
*
* Copyright 2015-2017 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Globalization;
using System.Text.RegularExpressions;
namespace zaaReloaded2.LabModel
{
/// <summary>
/// Represents a single laboratory item (e.g., sodium or creatinine).
/// </summary>
public class LabItem
{
#region Properties
/// <summary>
/// Gets or sets the original name of the item (as known by Lauris).
/// </summary>
public string Name { get; protected set; }
/// <summary>
/// Gets or sets the unit of the item (as known by Lauris).
/// </summary>
public string Unit { get; protected set; }
/// <summary>
/// Gets or sets the value of the item. This may be a number or a string.
/// </summary>
public string Value { get; protected set; }
public double NumericalValue
{
get
{
if (IsNumerical)
{
return _numericalValue;
}
else
{
throw new InvalidOperationException(
String.Format("Value '{0}' is not numerical.", Value));
}
}
private set
{
_numericalValue = value;
}
}
public bool IsNumerical
{
get
{
return (Double.TryParse(Value,
NumberStyles.Any,
CultureInfo.InvariantCulture,
out _numericalValue));
}
}
/// <summary>
/// Returns whether or not the value is an 'extreme' value,
/// i.e. marked with "&gt;" or "&lt;". These values are not
/// strictly numeric, and IsNumerical returns false for them.
/// </summary>
public bool IsExtreme
{
get
{
return "<>".Contains(Value.Substring(0, 1));
}
}
/// <summary>
/// Gets the normal value of the item. Need not be set. This is
/// used for items with nominal values (as opposed to numbers).
/// </summary>
public string Normal { get; protected set; }
/// <summary>
/// Gets or sets the lower limit of normal.
/// </summary>
public double LowerLimit
{
get
{
return _lowerLimit;
}
protected set
{
_lowerLimit = value;
HasLowerLimit = true;
}
}
/// <summary>
/// Is true if the item has a lower limit of normal.
/// </summary>
public bool HasLowerLimit { get; protected set; }
/// <summary>
/// Gets or sets the upper limit of normal.
/// </summary>
public double UpperLimit
{
get
{
return _upperLimit;
}
set
{
_upperLimit = value;
HasUpperLimit = true;
}
}
/// <summary>
/// Is true if the item has an upper limit of normal.
/// </summary>
public bool HasUpperLimit { get; protected set; }
/// <summary>
/// Is true if <see cref="Value"/> is normal. Returns true
/// if no limits and no normal value are known.
/// </summary>
public bool IsNormal
{
get
{
if (IsExtreme) return false;
if (HasLimits)
{
if (HasLowerLimit && HasUpperLimit)
{
return (LowerLimit <= NumericalValue &&
NumericalValue <= UpperLimit);
}
else
{
if (HasLowerLimit)
{
return (LowerLimit <= NumericalValue);
}
return (NumericalValue <= UpperLimit);
}
}
else
{
return String.IsNullOrEmpty(Normal) || (Value == Normal);
}
}
}
/// <summary>
/// Is true if the item has lower and/or upper limits. Is false if the
/// item does not have limits but a <see cref="Normal"/> value.
/// </summary>
public bool HasLimits
{
get { return (HasLowerLimit || HasUpperLimit); }
}
/// <summary>
/// Is true if the item has numerical limits or a categorical normal
/// value.
/// </summary>
public bool HasLimitsOrNormal
{
get
{
return HasLimits || !String.IsNullOrEmpty(Normal);
}
}
public bool HasUnit
{
get
{
return !String.IsNullOrEmpty(Unit);
}
}
/// <summary>
/// Returns the canonical name prefixed with the abbreviation
/// for the material, e.g. "U-Na" for sodium in the spot urine,
/// but only if the material is not blood.
/// </summary>
public string QualifiedName
{
get
{
switch (Material)
{
case Material.S:
case Material.E:
case Material.B:
return Name;
default:
return String.Format("{0}-{1}", Material.ToString(), Name);
}
}
}
public int PreferredPrecision { get; protected set; }
public bool AlwaysPrintLimits { get; protected set; }
public Material Material { get; protected set; }
/// <summary>
/// Gets whether the LabItem is marked as blacklisted
/// in the thesaurus.
/// </summary>
public bool IsBlacklisted { get; protected set; }
#endregion
#region Constructors
public LabItem() { }
/// <summary>
/// Creates a new LabItem object that has a normal value, but
/// no upper or lower limits. This is constructor is used for
/// testing purposes.
/// </summary>
public LabItem(string name, string value, string normal)
: this()
{
Name = name;
Value = value;
Normal = normal;
}
#endregion
#region Fields
double _numericalValue;
double _lowerLimit;
double _upperLimit;
#endregion
}
}