using System;
using System.Collections.Generic;
using System.Linq;
using Deltares.Geometry;
using Deltares.Geotechnics;
using Deltares.Geotechnics.GeotechnicalGeometry;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard;
using Deltares.Standard.Extensions;
using Deltares.Standard.IO.Xml;
namespace Deltares.Stability
{
///
/// Repairs stability dike locations which had a 2D profile only
///
public class StabilitySurfaceLineXmlHandler : IXmlHandler
{
public bool CanHandle(Type type, string property)
{
return (type == typeof(StabilityModel) || type == typeof(UniformLoad)) &&
(property == "SurfaceLine" || property == "PreConsolidationStressList");
}
public bool CanHandle(Type type)
{
return type == typeof(StabilityModel);
}
public Type GetFormerPropertyType(Type type, string property)
{
switch (property)
{
case "SurfaceLine":
return typeof(SurfaceLine);
case "PreConsolidationStressList":
return typeof(List);
default:
return null;
}
}
public void Handle(object target, string property, object value, object[] objects)
{
if ((target is StabilityModel || target is UniformLoad) &&
(property == "SurfaceLine" || property == "PreConsolidationStressList"))
{
if (value is SurfaceLine)
{
var surfaceLine = (SurfaceLine) value;
var surfaceLine2 = CreateSurfaceLine(surfaceLine, false);
foreach (var geometryPoint in surfaceLine.Points)
{
surfaceLine2.Geometry.Points.Add(geometryPoint);
}
foreach (var keyValuePair in surfaceLine.CharacteristicPoints.Where(kvp => kvp.Value != null && kvp.Key != CharacteristicPointType.None))
{
surfaceLine2.AddCharacteristicPoint(keyValuePair.Value, keyValuePair.Key);
}
if (target is StabilityModel)
{
var model = (StabilityModel) target;
// Fix data consistency that is broken during backwards compatibility conversion:
foreach (var uniformLoad in model.UniformLoads.Where(ul => !ReferenceEquals(ul.SurfaceLine2, surfaceLine2)))
{
if (uniformLoad.SurfaceLine2 != null)
{
uniformLoad.SurfaceLine2.Dispose();
}
uniformLoad.SurfaceLine2 = surfaceLine2;
}
model.SurfaceLine2 = surfaceLine2;
}
else if (target is UniformLoad)
{
var uniformLoad = (UniformLoad) target;
uniformLoad.SurfaceLine2 = surfaceLine2;
}
}
else if (value is List)
{
var stresses = (List) value;
if (target is StabilityModel)
{
var model = (StabilityModel) target;
model.SoilProfile.PreconsolidationStresses.AddRange(stresses);
}
}
}
}
public void HandleObject(object target, object value) {}
public void SetVersion(string version) {}
public void Upgrade(object[] target)
{
foreach (var obj in target)
{
if (obj is StabilityDikeLocationInfo)
{
var dikeLocationInfo = (StabilityDikeLocationInfo) obj;
if (dikeLocationInfo.StabilityModel != null && dikeLocationInfo.StabilityModel.SurfaceLine2 != null)
{
if (dikeLocationInfo.SchematizedSurfaceLine.Geometry.Points.Count == 0)
{
dikeLocationInfo.SchematizedSurfaceLine = dikeLocationInfo.StabilityModel.SurfaceLine2;
}
if (dikeLocationInfo.SurfaceLine.Points.Count == 0)
{
dikeLocationInfo.SurfaceLine = dikeLocationInfo.StabilityModel.SurfaceLine2.Geometry;
}
}
}
if (obj is StabilityModel)
{
var model = (StabilityModel) obj;
if (RequiresConversion(model.SurfaceLine2))
{
UpdateSurfaceLine(model.SurfaceLine2, model);
}
RemoveCharacteristicNoneType(model.SurfaceLine2);
}
}
}
private static bool RequiresConversion(SurfaceLine2 surfaceLine2)
{
foreach (var characteristicPoint in surfaceLine2.CharacteristicPoints)
{
if (surfaceLine2.Geometry.Points.Contains(characteristicPoint.GeometryPoint))
{
return true;
}
}
return false;
}
private static void UpdateSurfaceLine(SurfaceLine2 surfaceLine2, StabilityModel model)
{
CharacteristicPoint[] characteristicPoints = surfaceLine2.CharacteristicPoints.ToArray();
surfaceLine2.CharacteristicPoints.GeometryMustContainPoint = false;
// Make the surface line equal to the top of the geometry
surfaceLine2.Geometry.Points.Clear();
surfaceLine2.Geometry.Points.AddRange(model.GeometryData.SurfaceLine.Points);
// Make sure that the points of the surface line are not part of the geometry
foreach (var characteristicPoint in characteristicPoints)
{
surfaceLine2.AddCharacteristicPoint((GeometryPoint) characteristicPoint.GeometryPoint.Clone(), characteristicPoint.CharacteristicPointType);
}
}
private static SurfaceLine2 CreateSurfaceLine(BaseSurfaceLine value, bool geometryMustContainPoint)
{
var surfaceLine2 = new SurfaceLine2
{
Name = value.Name,
CharacteristicPoints =
{
GeometryMustContainPoint = geometryMustContainPoint
},
Geometry = new LocalizedGeometryPointString
{
FromTime = value.FromTime,
UntilTime = value.UntilTime,
IsTimeDependent = value.IsTimeDependent,
LatitudeAngle = value.LatitudeAngle,
Offset = value.Offset,
OriginalXy = value.OriginalXy
}
};
return surfaceLine2;
}
private void RemoveCharacteristicNoneType(SurfaceLine2 surfaceLine2)
{
// Make sure that the points of the surface line are not part of the geometry
foreach (var characteristicPoint in surfaceLine2.CharacteristicPoints.ToArray())
{
if (characteristicPoint.CharacteristicPointType == CharacteristicPointType.None)
{
surfaceLine2.CharacteristicPoints.Remove(characteristicPoint);
}
}
}
}
}