using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Probabilistic;
using Deltares.Standard;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.IO;
using Deltares.Standard.Language;
using Deltares.Standard.Logging;
using Deltares.Standard.Reflection;
namespace Deltares.DeltaModel
{
///
/// Class responsible for populating the delta model
///
public class DeltaModelFactory : ITransactionDataFactory
{
private readonly DeltaModel deltaModel;
private readonly List modifiedLists = new List();
///
/// Default constructor
///
/// Delta model to be populated
public DeltaModelFactory(DeltaModel deltaModel)
{
this.deltaModel = deltaModel;
}
public void SetAquiferDictionary(Dictionary dict)
{
deltaModel.Soils.AquiferDictionary = dict;
}
///
/// Sends the modified lists to the data event publisher.
///
public void SendModifiedLists()
{
foreach (var modifiedList in modifiedLists)
{
DataEventPublisher.DataListModified(modifiedList);
}
}
///
/// Find an existing object or creates an object with a certain specification and populates the delta model with it
///
/// Unique identifier of the object to be find/created
/// Type of object to be find/created
///
/// The found/created object
public virtual object GetObject(string key, Type objectType, Enum subType)
{
var item = GetExistingObject(key, objectType, subType);
if (item == null)
{
item = CreateItem(key, subType, objectType);
var list = GetList(objectType, subType);
if (!modifiedLists.Contains(list))
{
DataEventPublisher.BeforeChange(list);
modifiedLists.Add(list);
}
list.Add(item);
}
return item;
}
///
/// Find an object with a certain specification
///
/// Unique identifier of the object to be found
/// Type of object to be found
///
/// The existing object
public virtual object GetExistingObject(string key, Type objectType, Enum subType)
{
var type = objectType;
// special case, SoilProfile can be either 1D or 2D
if (type == typeof(SoilProfile))
{
var profile = deltaModel.SoilProfiles1D.FirstOrDefault(p => p.Name == key) as SoilProfile;
profile = profile ?? deltaModel.SoilProfiles2D.FirstOrDefault(p => p.Name == key);
return profile;
}
var list = GetList(type, subType);
if (!string.IsNullOrEmpty(key))
{
if (typeof(IIdentifier).IsAssignableFrom(type))
{
return list.Cast().FirstOrDefault(item => item.Id.ToString().Equals(key));
}
if (typeof(IStringIdentifier).IsAssignableFrom(type))
{
return list.Cast().FirstOrDefault(item => item.Id.ToString().Equals(key));
}
if (typeof(IName).IsAssignableFrom(type))
{
return list.Cast().FirstOrDefault(item => item.Name.Equals(key));
}
if (type == typeof(ProbabilityDefinition))
{
return list.Cast().FirstOrDefault(item => item.Probability.Equals(Convert.ToDouble(key)));
}
}
return null;
}
///
/// Find an existing object or creates an object with a certain specification and populates the delta model with it
///
/// Unique identifier of the object to be found/created
///
/// The found/created object
public T GetObject(string key, Enum subType)
{
var returnObject = GetObject(key, typeof(T), subType);
if (returnObject is T)
{
return (T)returnObject;
}
return default(T);
}
///
/// Find an object with a certain specification
///
/// Unique identifier of the object to be found
///
/// The existing object
public T GetExistingObject(string key, Enum subType)
{
var returnObject = GetExistingObject(key, typeof(T), subType);
if (returnObject is T)
{
return (T)returnObject;
}
return default(T);
}
public bool ShouldRegister(RegisteredItem registeredItem)
{
// specific workaround: for Surfacelines imported in RD (absolute) coordinates, the additional information from crossections shapefile (angle offset etc.) needs to be ignored (RT-1270)
var dikeLocation = registeredItem.Subject as DikeLocation;
if (dikeLocation != null && registeredItem.PropertyName.StartsWith(dikeLocation.GetMemberName(cl => cl.SurfaceLine)))
{
var surfaceLine = dikeLocation.SurfaceLine;
if (surfaceLine != null)
{
if (surfaceLine.IsLocalized)
{
LogManager.Add(new LogMessage(LogMessageType.Warning, registeredItem.Subject,
String.Format(
(string) LocalizationManager.GetTranslatedText(typeof(DeltaModelFactory),
"SurfacelinePropertyNotset_propertyname"), (object) registeredItem.PropertyName)));
return false;
}
}
}
return true;
}
public virtual void ProcessImportedItems(ImporterProgressDelegate progress)
{
MapIsAquiferFromSoilToLayers();
foreach (var soil in deltaModel.Soils.Soils)
{
if (soil.Color.Name == "ffffffff")
{
soil.Color = DefaultSoilColor(soil.SoilType);
}
}
foreach (var schematizedSurfaceLine in deltaModel.SchematizedSurfaceLines)
{
schematizedSurfaceLine.CharacteristicPoints.RefreshHeight();
}
}
protected virtual object CreateItem(string key, Enum subType, Type type)
{
var newItem = Activator.CreateInstance(type);
if (newItem is IIdentifier)
{
((IIdentifier) newItem).Id = Convert.ToInt32(key);
}
else if (newItem is IStringIdentifier)
{
((IStringIdentifier) newItem).Id = key;
}
else if (newItem is IName)
{
((IName) newItem).Name = key;
}
if (newItem is CharacteristicLine)
{
((CharacteristicLine) newItem).PointType = (CharacteristicPointType) subType;
}
else if (newItem is ProbabilityDefinition)
{
((ProbabilityDefinition) newItem).Probability = Convert.ToDouble(key);
}
else if (newItem is BlockRevetmentCrossSection)
{
((BlockRevetmentCrossSection) newItem).DikeLine = deltaModel.DikeLines.First(); // No support for multiple dike lines yet
}
else if (newItem is DikeCrossSection)
{
var dikeCrossSection = (DikeCrossSection) newItem;
if (dikeCrossSection.DikeLine == null)
{
dikeCrossSection.DikeLine = deltaModel.DikeLines.First(); // No support for multiple dike lines yet
}
}
return newItem;
}
///
/// Gets the list in the delta model corresponding with the item type
///
/// Item type
/// The subtype of the item
/// List
protected virtual IList GetList(Type type, Enum subType)
{
return deltaModel.GetListForType(type);
}
private void MapIsAquiferFromSoilToLayers()
{
if (deltaModel.Soils.AquiferDictionary.Count > 0)
{
foreach (var soilProfile1D in deltaModel.SoilProfiles1D)
{
foreach (var soilLayer1D in soilProfile1D.Layers)
{
if (deltaModel.Soils.AquiferDictionary.ContainsKey(soilLayer1D.Soil))
{
soilLayer1D.IsAquifer = deltaModel.Soils.AquiferDictionary[soilLayer1D.Soil];
}
}
}
foreach (var soilProfile2D in deltaModel.SoilProfiles2D)
{
foreach (var soilLayer2D in soilProfile2D.Surfaces)
{
if (deltaModel.Soils.AquiferDictionary.ContainsKey(soilLayer2D.Soil))
{
soilLayer2D.IsAquifer = deltaModel.Soils.AquiferDictionary[soilLayer2D.Soil];
}
}
}
}
}
// default soil colors,
private static Color DefaultSoilColor(SoilType type)
{
switch (type)
{
case SoilType.Sand:
return Color.LightYellow;
case SoilType.Clay:
return Color.LightGray;
case SoilType.Gravel:
return Color.Gray;
case SoilType.Loam:
return Color.DarkKhaki;
case SoilType.Peat:
return Color.SaddleBrown;
default:
return Color.White;
}
}
public virtual void Start()
{
// nothing to do
}
public virtual void Commit()
{
// nothing to do
}
public virtual void Abort()
{
ClearAllLists();
}
protected virtual void ClearAllLists()
{
deltaModel.ClearAllLists();
}
}
}