// Copyright (C) Stichting Deltares 2016. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq.Expressions;
using Core.Common.Base;
using Core.Common.Base.Data;
using Core.Common.Base.Geometry;
using Core.Common.Gui.Attributes;
using Core.Common.Gui.PropertyBag;
using Core.Common.Utils.Attributes;
using Core.Common.Utils.Reflection;
using Ringtoets.Common.Data;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.DikeProfiles;
using Ringtoets.Common.Data.FailureMechanism;
using Ringtoets.Common.Data.Structures;
using Ringtoets.Common.Forms.Helpers;
using Ringtoets.Common.Forms.PresentationObjects;
using Ringtoets.Common.Forms.Properties;
using Ringtoets.Common.Forms.UITypeEditors;
using Ringtoets.HydraRing.Data;
namespace Ringtoets.Common.Forms.PropertyClasses
{
///
/// ViewModel of structure calculation input for properties panel.
///
/// The type of structures at stake.
/// The type of structures calculation input.
/// The type of the calculation containing the structures calculation input.
/// The type of the failure mechanism.
public abstract class StructuresInputBaseProperties :
ObjectProperties>,
IHasHydraulicBoundaryLocationProperty,
IHasStructureProperty,
IHasForeshoreProfileProperty
where TStructure : StructureBase
where TStructureInput : StructuresInputBase
where TCalculation : ICalculation
where TFailureMechanism : IFailureMechanism
{
private readonly Dictionary propertyIndexLookup;
///
/// Creates a new instance of the class.
///
/// The property values required to create an instance of .
/// Thrown when is null.
protected StructuresInputBaseProperties(ConstructionProperties constructionProperties)
{
if (constructionProperties == null)
{
throw new ArgumentNullException("constructionProperties");
}
propertyIndexLookup = new Dictionary
{
{
GetMemberName(p => p.ModelFactorSuperCriticalFlow), constructionProperties.ModelFactorSuperCriticalFlowPropertyIndex
},
{
GetMemberName(p => p.Structure), constructionProperties.StructurePropertyIndex
},
{
GetMemberName(p => p.StructureLocation), constructionProperties.StructureLocationPropertyIndex
},
{
GetMemberName(p => p.StructureNormalOrientation), constructionProperties.StructureNormalOrientationPropertyIndex
},
{
GetMemberName(p => p.FlowWidthAtBottomProtection), constructionProperties.FlowWidthAtBottomProtectionPropertyIndex
},
{
GetMemberName(p => p.WidthFlowApertures), constructionProperties.WidthFlowAperturesPropertyIndex
},
{
GetMemberName(p => p.StorageStructureArea), constructionProperties.StorageStructureAreaPropertyIndex
},
{
GetMemberName(p => p.AllowedLevelIncreaseStorage), constructionProperties.AllowedLevelIncreaseStoragePropertyIndex
},
{
GetMemberName(p => p.CriticalOvertoppingDischarge), constructionProperties.CriticalOvertoppingDischargePropertyIndex
},
{
GetMemberName(p => p.FailureProbabilityStructureWithErosion), constructionProperties.FailureProbabilityStructureWithErosionPropertyIndex
},
{
GetMemberName(p => p.ForeshoreProfile), constructionProperties.ForeshoreProfilePropertyIndex
},
{
GetMemberName(p => p.UseBreakWater), constructionProperties.UseBreakWaterPropertyIndex
},
{
GetMemberName(p => p.UseForeshore), constructionProperties.UseForeshorePropertyIndex
},
{
GetMemberName(p => p.SelectedHydraulicBoundaryLocation), constructionProperties.HydraulicBoundaryLocationPropertyIndex
},
{
GetMemberName(p => p.StormDuration), constructionProperties.StormDurationPropertyIndex
}
};
}
#region Model factors
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_ModelSettings")]
[ResourcesDisplayName(typeof(Resources), "Structure_ModelFactorSuperCriticalFlow_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_ModelFactorSuperCriticalFlow_Description")]
public virtual NormalDistributionProperties ModelFactorSuperCriticalFlow
{
get
{
return new NormalDistributionProperties(DistributionPropertiesReadOnly.StandardDeviation, data.WrappedData)
{
Data = data.WrappedData.ModelFactorSuperCriticalFlow
};
}
}
#endregion
[DynamicPropertyOrderEvaluationMethod]
public int DynamicPropertyOrderEvaluationMethod(string propertyName)
{
int propertyIndex;
propertyIndexLookup.TryGetValue(propertyName, out propertyIndex);
return propertyIndex;
}
public abstract IEnumerable GetAvailableForeshoreProfiles();
public Point2D GetReferenceLocation()
{
return StructureLocation;
}
public IEnumerable GetHydraulicBoundaryLocations()
{
return data.AvailableHydraulicBoundaryLocations;
}
public abstract IEnumerable GetAvailableStructures();
///
/// The action to perform after setting the property.
///
protected abstract void AfterSettingStructure();
///
/// Sets a probability value to one of the properties of a wrapped data object.
///
/// The type of the wrapped data to set a probability value for.
/// The probability value to set.
/// The wrapped data to set a probability value for.
/// The action that sets the probability value to a specific property of the wrapped data.
/// Thrown when equals null.
/// Thrown when cannot be parsed into a double.
/// After correctly setting the to the wrapped data, observers will be notified.
protected static void SetProbabilityValue(string value,
T wrappedData,
Action setValueAction)
where T : IObservable
{
if (value == null)
{
throw new ArgumentNullException("value", Resources.FailureProbability_Value_cannot_be_null);
}
try
{
setValueAction(wrappedData, (RoundedDouble) double.Parse(value));
}
catch (OverflowException)
{
throw new ArgumentException(Resources.FailureProbability_Value_too_large);
}
catch (FormatException)
{
throw new ArgumentException(Resources.FailureProbability_Could_not_parse_string_to_double_value);
}
wrappedData.NotifyObservers();
}
private static string GetMemberName(Expression, object>> expression)
{
return TypeUtils.GetMemberName(expression);
}
///
/// Class holding the various construction parameters for .
///
public class ConstructionProperties
{
#region Model factors
///
/// Gets or sets the property index for .
///
public int ModelFactorSuperCriticalFlowPropertyIndex { get; set; }
#endregion
#region Schematization
///
/// Gets or sets the property index for .
///
public int StructurePropertyIndex { get; set; }
///
/// Gets or sets the property index for the location of .
///
public int StructureLocationPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int StructureNormalOrientationPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int FlowWidthAtBottomProtectionPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int WidthFlowAperturesPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int StorageStructureAreaPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int AllowedLevelIncreaseStoragePropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int CriticalOvertoppingDischargePropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int FailureProbabilityStructureWithErosionPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int ForeshoreProfilePropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int UseBreakWaterPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int UseForeshorePropertyIndex { get; set; }
#endregion
#region Hydraulic data
///
/// Gets or sets the property index for .
///
public int HydraulicBoundaryLocationPropertyIndex { get; set; }
///
/// Gets or sets the property index for .
///
public int StormDurationPropertyIndex { get; set; }
#endregion
}
#region Schematization
[DynamicPropertyOrder]
[Editor(typeof(StructureEditor), typeof(UITypeEditor))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_Description")]
public TStructure Structure
{
get
{
return data.WrappedData.Structure;
}
set
{
data.WrappedData.Structure = value;
AfterSettingStructure();
data.WrappedData.NotifyObservers();
}
}
[DynamicPropertyOrder]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_Location_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_Location_Description")]
public Point2D StructureLocation
{
get
{
return data.WrappedData.Structure == null ? null :
new Point2D(
new RoundedDouble(0, data.WrappedData.Structure.Location.X),
new RoundedDouble(0, data.WrappedData.Structure.Location.Y));
}
}
[DynamicPropertyOrder]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_StructureNormalOrientation_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_StructureNormalOrientation_Description")]
public virtual RoundedDouble StructureNormalOrientation
{
get
{
return data.WrappedData.StructureNormalOrientation;
}
set
{
data.WrappedData.StructureNormalOrientation = value;
data.WrappedData.NotifyObservers();
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_FlowWidthAtBottomProtection_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_FlowWidthAtBottomProtection_Description")]
public LogNormalDistributionProperties FlowWidthAtBottomProtection
{
get
{
return new LogNormalDistributionProperties(DistributionPropertiesReadOnly.None, data.WrappedData)
{
Data = data.WrappedData.FlowWidthAtBottomProtection
};
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_WidthFlowApertures_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_WidthFlowApertures_Description")]
public virtual VariationCoefficientNormalDistributionProperties WidthFlowApertures
{
get
{
return new VariationCoefficientNormalDistributionProperties(VariationCoefficientDistributionPropertiesReadOnly.None, data.WrappedData)
{
Data = data.WrappedData.WidthFlowApertures
};
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_StorageStructureArea_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_StorageStructureArea_Description")]
public VariationCoefficientLogNormalDistributionProperties StorageStructureArea
{
get
{
return new VariationCoefficientLogNormalDistributionProperties(VariationCoefficientDistributionPropertiesReadOnly.None, data.WrappedData)
{
Data = data.WrappedData.StorageStructureArea
};
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_AllowedLevelIncreaseStorage_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_AllowedLevelIncreaseStorage_Description")]
public LogNormalDistributionProperties AllowedLevelIncreaseStorage
{
get
{
return new LogNormalDistributionProperties(DistributionPropertiesReadOnly.None, data.WrappedData)
{
Data = data.WrappedData.AllowedLevelIncreaseStorage
};
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_CriticalOvertoppingDischarge_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_CriticalOvertoppingDischarge_Description")]
public VariationCoefficientLogNormalDistributionProperties CriticalOvertoppingDischarge
{
get
{
return new VariationCoefficientLogNormalDistributionProperties(VariationCoefficientDistributionPropertiesReadOnly.None, data.WrappedData)
{
Data = data.WrappedData.CriticalOvertoppingDischarge
};
}
}
[DynamicPropertyOrder]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_FailureProbabilityStructureWithErosion_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_FailureProbabilityStructureWithErosion_Description")]
public string FailureProbabilityStructureWithErosion
{
get
{
return ProbabilityFormattingHelper.Format(data.WrappedData.FailureProbabilityStructureWithErosion);
}
set
{
SetProbabilityValue(value, data.WrappedData, (wrappedData, parsedValue) => wrappedData.FailureProbabilityStructureWithErosion = parsedValue);
}
}
[DynamicPropertyOrder]
[Editor(typeof(ForeshoreProfileEditor), typeof(UITypeEditor))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "Structure_ForeshoreProfile_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_ForeshoreProfile_Description")]
public ForeshoreProfile ForeshoreProfile
{
get
{
return data.WrappedData.ForeshoreProfile;
}
set
{
data.WrappedData.ForeshoreProfile = value;
data.WrappedData.NotifyObservers();
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "BreakWaterProperties_DisplayName")]
[ResourcesDescription(typeof(Resources), "BreakWaterProperties_Description")]
public UseBreakWaterProperties UseBreakWater
{
get
{
return data.WrappedData.ForeshoreProfile == null ?
new UseBreakWaterProperties(null) :
new UseBreakWaterProperties(data.WrappedData);
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_Schematization")]
[ResourcesDisplayName(typeof(Resources), "ForeshoreProperties_DisplayName")]
[ResourcesDescription(typeof(Resources), "ForeshoreProperties_Description")]
public UseForeshoreProperties UseForeshore
{
get
{
return new UseForeshoreProperties(data.WrappedData);
}
}
#endregion
#region Hydraulic data
[DynamicPropertyOrder]
[Editor(typeof(HydraulicBoundaryLocationEditor), typeof(UITypeEditor))]
[ResourcesCategory(typeof(Resources), "Categories_HydraulicData")]
[ResourcesDisplayName(typeof(Resources), "HydraulicBoundaryLocation_DisplayName")]
[ResourcesDescription(typeof(Resources), "HydraulicBoundaryLocation_Description")]
public HydraulicBoundaryLocation SelectedHydraulicBoundaryLocation
{
get
{
return data.WrappedData.HydraulicBoundaryLocation;
}
set
{
data.WrappedData.HydraulicBoundaryLocation = value;
data.WrappedData.NotifyObservers();
}
}
[DynamicPropertyOrder]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ResourcesCategory(typeof(Resources), "Categories_HydraulicData")]
[ResourcesDisplayName(typeof(Resources), "Structure_StormDuration_DisplayName")]
[ResourcesDescription(typeof(Resources), "Structure_StormDuration_Description")]
public VariationCoefficientLogNormalDistributionProperties StormDuration
{
get
{
return new VariationCoefficientLogNormalDistributionProperties(VariationCoefficientDistributionPropertiesReadOnly.CoefficientOfVariation, data.WrappedData)
{
Data = data.WrappedData.StormDuration
};
}
}
#endregion
}
}