using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml.Serialization;
using Deltares.Geotechnics;
using Deltares.Geotechnics.Soils;
using Deltares.Standard;
using Deltares.Standard.Attributes;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Reflection;
using Deltares.Standard.Scenarios;
using Deltares.Standard.Units;
using Deltares.Standard.Validation;
namespace Deltares.AssessmentMechanism
{
///
/// An object to be used for
/// to hold scenario dependent data, based on a .
///
public class AssessmentScenario : Scenario, IDomain, IVisibleEnabled
{
private AssessmentCalculationResult assessmentCalculationResult = new AssessmentCalculationResult();
private double probability;
///
/// Initializes a new instance of the class without
/// any definitions.
///
public AssessmentScenario()
{
Name = String.Empty;
Description = String.Empty;
}
///
/// Indicates the probability of the scenario
///
[Clearable]
[Unit(UnitType.Probability, ProbabilityUnit.Fraction)]
[Format("F2", true)]
[PropertyOrder(3, 0)]
[Minimum(0)]
[Maximum(1)]
public double Probability
{
get
{
return probability;
}
set
{
this.SetAndNotify2(out probability, value, s => s.Probability);
}
}
///
/// Gets or sets the name of the scenario.
///
[PropertyOrder(1, 0)]
[ReadOnly(true)]
public string Name { get; set; }
///
/// Gets or sets the description of the scenario.
///
[PropertyOrder(1, 1)]
public string Description { get; set; }
[PropertyOrder(2, 0)]
public bool Calculated
{
get
{
return assessmentCalculationResult.Calculated;
}
}
///
/// Gets or sets the soil profile of the scenario from the
/// on which this scenario is based. If you set a different value, the corresponding
/// will replace the value for that
///
/// When setting a new value while there
/// is no available as
/// or is not set.
[XmlIgnore]
[PropertyOrder(4, 0)]
public SoilProfile SoilProfile
{
get
{
return Values.OfType().Select(ssp => ssp.Profile).FirstOrDefault();
}
set
{
if (GetAvailableStochasticSoilProfiles == null)
{
throw new InvalidOperationException("AssessmentScenario requires to have GetAvailableStochasticSoilProfiles set.");
}
ScenarioItem soilProfileItem = ScenarioItems.FirstOrDefault(si => si.Value is StochasticSoilProfile);
if (soilProfileItem == null)
{
throw new InvalidOperationException("AssessmentScenario requires to have a ScenarioItem with a StochasticSoilProfile.");
}
soilProfileItem.Value = GetStochasticSoilProfile(value);
// Updating SoilProfile in scenario should update target -> Send event to notify this action:
DataEventPublisher.AfterChange(this, s => s.SoilProfile);
}
}
///
/// Gets or sets the result from an .
///
public AssessmentCalculationResult AssessmentCalculationResult
{
get
{
return assessmentCalculationResult;
}
set
{
assessmentCalculationResult = value;
}
}
///
/// Injection point for method to retrieve all available stochastic soil profiles
/// for this scenario to be based upon.
///
public Func GetAvailableStochasticSoilProfiles { get; set; }
[DynamicProperties]
[PropertyOrder(4, 1)]
public override List Values
{
get
{
return base.Values;
}
}
public override string ToString()
{
return Name ?? string.Empty;
}
#region IDomain
public ICollection GetDomain(string property)
{
switch (property)
{
case "SoilProfile":
return GetAvailableStochasticSoilProfiles != null ?
GetAvailableStochasticSoilProfiles().Select(ssp => ssp.Profile).ToArray() :
null;
default:
return null;
}
}
#endregion
private StochasticSoilProfile GetStochasticSoilProfile(SoilProfile value)
{
StochasticSoilProfile scenarioItemStochasticSoilProfile = null;
DataEventPublisher.InvokeWithoutPublishingEvents(() =>
{
var stochasticSoilProfile = GetAvailableStochasticSoilProfiles().FirstOrDefault(si => ReferenceEquals(si.Profile, value));
if (stochasticSoilProfile != null)
{
scenarioItemStochasticSoilProfile = (StochasticSoilProfile)stochasticSoilProfile.Clone();
}
});
return scenarioItemStochasticSoilProfile;
}
#region IVisibleEnabled
public bool IsVisible(string property)
{
return true;
}
public bool IsEnabled(string property)
{
var enabled = true;
if (this.GetMemberName(s => s.SoilProfile) == property)
{
enabled = GetAvailableStochasticSoilProfiles != null;
}
return enabled;
}
#endregion
}
}