// Copyright (C) Stichting Deltares 2022. All rights reserved.
//
// This file is part of Riskeer.
//
// Riskeer 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.Linq;
using Riskeer.MacroStabilityInwards.Primitives.Properties;
namespace Riskeer.MacroStabilityInwards.Data.SoilProfile
{
///
/// This class represents a soil profile, which was imported for use in a macro stability inwards calculation.
///
public sealed class MacroStabilityInwardsSoilProfile1D : IMacroStabilityInwardsSoilProfile
{
private MacroStabilityInwardsSoilLayer1D[] layers;
private string name;
///
/// Creates a new instance of , with the given ,
/// and .
/// A new collection is created for and used in the .
///
/// The name of the profile.
/// The bottom level of the profile.
/// The collection of layers that should be part of the profile.
/// Thrown when
///
/// - contains no layers
/// - contains a layer with the less than
///
///
///
/// Thrown when or
/// is null.
/// The in this soil profile are ordered by
/// in descending order.
public MacroStabilityInwardsSoilProfile1D(string name, double bottom, IEnumerable layers)
{
Name = name;
Bottom = bottom;
ValidateLayersCollection(layers);
Layers = layers.OrderByDescending(l => l.Top);
}
///
/// Gets the bottom level of the .
///
public double Bottom { get; }
public IEnumerable Layers
{
get
{
return layers;
}
private set
{
layers = value.ToArray();
}
}
///
/// Gets the name of .
///
/// Thrown when the value is null.
public string Name
{
get
{
return name;
}
private set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
name = value;
}
}
///
/// Gets the thickness of the given layer in the .
/// Thickness of a layer is determined by its top and the top of the layer below it.
///
/// The to determine the thickness of.
/// The thickness of the .
/// does not contain .
public double GetLayerThickness(MacroStabilityInwardsSoilLayer1D layer)
{
IEnumerable layersOrderedByTopAscending = layers.Reverse();
double previousLevel = Bottom;
foreach (MacroStabilityInwardsSoilLayer1D oLayer in layersOrderedByTopAscending)
{
if (ReferenceEquals(layer, oLayer))
{
return layer.Top - previousLevel;
}
previousLevel = oLayer.Top;
}
throw new ArgumentException("Layer not found in profile.");
}
public override string ToString()
{
return Name;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != GetType())
{
return false;
}
return Equals((MacroStabilityInwardsSoilProfile1D) obj);
}
public override int GetHashCode()
{
unchecked
{
int hashCode = Bottom.GetHashCode();
hashCode = (hashCode * 397) ^ Name.GetHashCode();
return hashCode;
}
}
private bool Equals(MacroStabilityInwardsSoilProfile1D other)
{
return AreLayersEqual(other.layers)
&& Bottom.Equals(other.Bottom)
&& string.Equals(Name, other.Name);
}
private bool AreLayersEqual(MacroStabilityInwardsSoilLayer1D[] otherLayers)
{
int layerCount = layers.Length;
if (layerCount != otherLayers.Length)
{
return false;
}
for (var i = 0; i < layerCount; i++)
{
if (!layers[i].Equals(otherLayers[i]))
{
return false;
}
}
return true;
}
///
/// Validates the given . A valid has layers which
/// all have values for which are greater than or equal to .
///
/// The collection of to validate.
/// Thrown when is null.
/// Thrown when:
///
/// - contains no layers
/// - contains a layer with the less than
///
///
///
private void ValidateLayersCollection(IEnumerable collection)
{
if (collection == null)
{
throw new ArgumentNullException(nameof(collection), string.Format(Resources.Error_Cannot_Construct_MacroStabilityInwardsSoilProfile_Without_Layers));
}
if (!collection.Any())
{
throw new ArgumentException(Resources.Error_Cannot_Construct_MacroStabilityInwardsSoilProfile_Without_Layers);
}
if (collection.Any(l => l.Top < Bottom))
{
throw new ArgumentException(Resources.MacroStabilityInwardsSoilProfile_Layers_Layer_top_below_profile_bottom);
}
}
}
}