using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Serialization;
using Deltares.Geographic;
using Deltares.Standard;
using Deltares.Standard.Attributes;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Language;
using Deltares.Standard.Reflection;
using Deltares.Standard.Units;
using Deltares.Standard.Validation;
namespace Deltares.DeltaModel
{
///
/// Wind Hydraulic Boundary Object
/// TODO: Comment
///
public class WindHydraulicBoundary : IGeographicString
{
private const double deg2rad = Math.PI/180.0;
private double angle;
private BindPropertyInfo angleProperty = PropertyInfoSupport.GetPropertyInfo(typeof(WindHydraulicBoundary), "Angle");
private IGeographicPoint endPoint = null;
private double fetchBottom = double.NaN;
private double fetchLength = double.NaN;
private List points = null;
private IGeographicPoint startPoint = new GeographicPoint(0, 0);
///
/// Initializes a new instance of the class.
///
public WindHydraulicBoundary()
{
DataEventPublisher.OnAfterChange += DataEventPublisher_OnAfterChange;
}
///
/// Initializes a new instance of the class.
///
/// The angle.
public WindHydraulicBoundary(double angle)
: this()
{
this.angle = angle;
}
///
/// Gets or sets the incoming angle of the wind.
///
///
/// The angle.
///
[Unit(UnitType.Angle)]
[Minimum(0)]
[Maximum(360)]
[Format("F2")]
[Label("WindDirection")]
[Description("WindDirection")]
[PropertyOrder(0, 0)]
[ReadOnly(true)]
public double Angle
{
get
{
return angle;
}
set
{
DataEventPublisher.BeforeChange(this, "Angle");
angle = value;
UpdateEndPoint();
DataEventPublisher.AfterChange(this, "Angle");
}
}
///
/// Gets or sets the length of the fetch.
///
///
/// The length of the fetch.
///
[Unit(UnitType.Length)]
[Minimum(0)]
[Maximum(1.000e+06)]
[Format("F2")]
[Label("Length")]
[Description("Length")]
[PropertyOrder(1, 0)]
[Clearable]
public double FetchLength
{
get
{
return fetchLength;
}
set
{
DataEventPublisher.BeforeChange(this, "FetchLength");
if (value == 0.0)
{
fetchLength = double.NaN;
fetchBottom = double.NaN;
}
else
{
fetchLength = value;
}
UpdateEndPoint();
DataEventPublisher.AfterChange(this, "FetchLength");
}
}
///
/// Gets or sets the fetch bottom.
///
///
/// The fetch bottom.
///
[Unit(UnitType.Depth)]
[Minimum(-1.000e+06)]
[Maximum(1.000e+06)]
[Format("F2")]
[Label("Bottom")]
[Description("Bottom")]
[PropertyOrder(1, 1)]
[Clearable]
public double FetchBottom
{
get
{
return fetchBottom;
}
set
{
DataEventPublisher.BeforeChange(this, "FetchBottom");
fetchBottom = value;
DataEventPublisher.AfterChange(this, "FetchBottom");
}
}
///
/// Indicates the starting point of the wind arrow
///
[Browsable(false)]
[XmlIgnore]
public IGeographicPoint StartPoint
{
get
{
return startPoint;
}
set
{
startPoint = value;
UpdateEndPoint();
}
}
[Browsable(false)]
[XmlIgnore]
public IList Points
{
get
{
if (points == null)
{
endPoint = new GeographicPoint(StartPoint.X, StartPoint.Y);
points = new List()
{
StartPoint, endPoint
};
UpdateEndPoint();
}
return points;
}
}
public override string ToString()
{
return LocalizationManager.GetTranslatedText(GetType(), "Fetch at") + angleProperty.GetUserValue(this) + " " + angleProperty.GetUnitString(this);
}
private void UpdateEndPoint()
{
if (endPoint == null)
{
return;
}
if (double.IsNaN(FetchLength))
{
endPoint.X = startPoint.X;
endPoint.Y = startPoint.Y;
}
else
{
endPoint.X = startPoint.X + Math.Sin(Angle*deg2rad)*FetchLength;
endPoint.Y = startPoint.Y + Math.Cos(Angle*deg2rad)*FetchLength;
}
}
private void DataEventPublisher_OnAfterChange(object sender, PublishEventArgs e)
{
if (sender == StartPoint)
{
UpdateEndPoint();
DataEventPublisher.AfterChange(this);
}
}
}
}