using System;
using System.Collections.Generic;
using System.ComponentModel;
using Deltares.Geographic;
using Deltares.Geotechnics;
using Deltares.Geotechnics.Mechanisms;
using Deltares.Standard;
using Deltares.Standard.Attributes;
using Deltares.Standard.Data;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Units;
using Deltares.Standard.Validation;
namespace Deltares.DeltaModel
{
///
/// HydraulicBoundary
/// TODO: Comment
///
[Label("HydraulicBoundary")]
public class HydraulicBoundary : IGeographicPoint, IVisibleEnabled, IName, IComparable, IComparable
{
private const double EPSILON = 0.001;
private readonly DelegatedList windHydraulicBoundaries = new DelegatedList();
private int id;
private string name = string.Empty;
private Region region = new Region();
private double swellHeight;
private double swellPeriod;
private double waterLevelSetupHeight;
private double x;
private double y;
///
/// Default constructor
///
public HydraulicBoundary()
{
windHydraulicBoundaries.AddMethod = AddFetch;
}
///
/// Constructor with id
///
/// Identification of the hydraulic boundary
public HydraulicBoundary(int id)
{
this.id = id;
}
///
/// Identification of the hydraulic boundary as defined in the hydraulic databases
///
[ReadOnly(true)]
[Label("Id")]
[PropertyOrder(0, 0)]
public int Id
{
get
{
return id;
}
set
{
id = value;
}
}
///
/// RegionId -> Hydraulic Boundary are grouped by region
///
[Label("RegionId")]
[ReadOnly(true)]
[PropertyOrder(1)]
[Group]
public Region Region
{
get
{
return region;
}
set
{
region = value;
}
}
///
/// Gets or sets the height of the WaterLevelSetup.
///
///
/// The height.
///
[Unit(UnitType.Length)]
[Minimum(-1.000e+06)]
[Maximum(1.000e+06)]
[Format("F2")]
[Label("Waterlevel setup height")]
[Description("Waterlevel setup height")]
[PropertyOrder(3)]
[Browsable(false)]
public double WaterLevelSetupHeight
{
get
{
return waterLevelSetupHeight;
}
set
{
DataEventPublisher.BeforeChange(this, "WaterLevelSetupHeight");
waterLevelSetupHeight = value;
DataEventPublisher.AfterChange(this, "WaterLevelSetupHeight");
}
}
///
/// Gets or sets the period of the Swell.
///
///
/// The period.
///
[Unit(UnitType.Time)]
[Format("F2")]
[Label("Swell period")]
[Description("Swell period")]
[PropertyOrder(4, 0)]
[ReadOnly(true)]
[Browsable(false)]
public double SwellPeriod
{
get
{
return swellPeriod;
}
set
{
DataEventPublisher.BeforeChange(this, "SwellPeriod");
swellPeriod = value;
DataEventPublisher.AfterChange(this, "SwellPeriod");
}
}
///
/// Gets or sets the height of the Swell.
///
///
/// The height.
///
[Unit(UnitType.Length)]
[Format("F2")]
[Label("Swell height")]
[Description("Swell height")]
[PropertyOrder(4, 1)]
[ReadOnly(true)]
[Browsable(false)]
public double SwellHeight
{
get
{
return swellHeight;
}
set
{
DataEventPublisher.BeforeChange(this, "SwellHeight");
swellHeight = value;
DataEventPublisher.AfterChange(this, "SwellHeight");
}
}
///
/// List of hydraulic boundary data per wind direction
///
[PropertyOrder(10, 0)]
[Category("WindParameters")]
[ReadOnly(true)]
[Browsable(false)]
[Mechanism(Mechanism.Overtopping, Mechanism.BlockRevetment, Mechanism.AsphaltRevetment)]
public IList WindHydraulicBoundaries
{
get
{
if (!DataEventPublisher.IsDataEventPublishStopped && windHydraulicBoundaries.Count == 0)
{
GenerateWindDirections();
}
return windHydraulicBoundaries;
}
}
///
/// Gets or sets the X of a Fetch location.
///
///
/// The X.
///
[Label("X")]
[Description("X")]
[PropertyOrder(2, 0)]
[Format("N2")]
[ReadOnly(true)]
[Unit(UnitType.Length)]
public double X
{
get
{
return x;
}
set
{
if (Math.Abs(value - x) > EPSILON)
{
DataEventPublisher.BeforeChange(this, "X");
x = value;
DataEventPublisher.AfterChange(this, "X");
}
}
}
///
/// Gets or sets the X of a Fetch location.
///
///
/// The X.
///
[Label("Y")]
[Description("Y")]
[PropertyOrder(2, 1)]
[Format("N2")]
[ReadOnly(true)]
[Unit(UnitType.Length)]
public double Y
{
get
{
return y;
}
set
{
if (Math.Abs(value - y) > EPSILON)
{
DataEventPublisher.BeforeChange(this, "Y");
y = value;
DataEventPublisher.AfterChange(this, "Y");
}
}
}
///
/// Name
///
[Label("Name")]
[ReadOnly(true)]
[PropertyOrder(0, 1)]
[Data]
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
///
/// Generates wind fetch data based on the region wind directions
///
public void GenerateWindDirections()
{
for (int i = 0; i < Region.WindDirections.Count; i++)
{
windHydraulicBoundaries.Add(new WindHydraulicBoundary(Region.WindDirections[i].Direction));
}
}
///
/// Gets the wind hydraulic boundary with a certain angle.
///
/// The angle.
/// wind hydraulic boundary
public WindHydraulicBoundary GetWindHydraulicBoundary(double angle)
{
while (angle >= 360)
{
angle -= 360;
}
foreach (var windHydraulicBoundary in WindHydraulicBoundaries)
{
if (Math.Abs(windHydraulicBoundary.Angle - angle) < 0.01)
{
return windHydraulicBoundary;
}
}
return null;
}
///
/// Gets the fetches count.
///
/// the amount of fetches for the hydraulic boundary
public int GetFetchesCount()
{
int count = 0;
foreach (var windHydraulicBoundary in WindHydraulicBoundaries)
{
if (!double.IsNaN(windHydraulicBoundary.FetchLength))
{
count++;
}
}
return count;
}
///
/// Returns a that represents this instance.
///
///
/// A that represents this instance.
///
public override string ToString()
{
if (string.IsNullOrEmpty(name) && Math.Abs(X - 0.0) < EPSILON && Math.Abs(Y - 0.0) < EPSILON)
{
return string.Empty;
}
return id + " (" + name + ")";
}
public int CompareTo(object obj)
{
if (obj is HydraulicBoundary)
{
return CompareTo((HydraulicBoundary) obj);
}
else
{
return 0;
}
}
public int CompareTo(HydraulicBoundary other)
{
return Id.CompareTo(other.Id);
}
public bool IsVisible(string property)
{
if (!MechanismSupport.IsMechanismVisible(typeof(DikeLocation), property))
{
return false;
}
switch (property)
{
case "WindHydraulicBoundaries":
return Region.NeedsFetches;
case "WaterLevelSetupHeight":
return false;
case "SwellPeriod":
return false;
case "SwellHeight":
return false;
default:
return true;
}
}
public bool IsEnabled(string property)
{
return true;
}
private void AddFetch(WindHydraulicBoundary fetch)
{
fetch.StartPoint = this;
}
}
}