// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets 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; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using Core.Common.Base.Data; using Core.Common.Controls.TreeView; using Core.Common.Gui.ContextMenu; using Core.Common.Gui.Plugin; using Ringtoets.Common.Data; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Forms.Helpers; using Ringtoets.Common.Forms.PresentationObjects; using Ringtoets.Common.Forms.TreeNodeInfos; using Ringtoets.GrassCoverErosionInwards.Data; using Ringtoets.GrassCoverErosionInwards.Forms.PresentationObjects; using Ringtoets.GrassCoverErosionInwards.Forms.PropertyClasses; using Ringtoets.GrassCoverErosionInwards.Plugin.Properties; using Ringtoets.HydraRing.Calculation.Activities; using Ringtoets.HydraRing.Calculation.Data; using Ringtoets.HydraRing.Calculation.Data.Input.Overtopping; using Ringtoets.HydraRing.Calculation.Data.Output; using Ringtoets.HydraRing.Data; using GrassCoverErosionInwardsDataResources = Ringtoets.GrassCoverErosionInwards.Data.Properties.Resources; using GrassCoverErosionInwardsFormsResources = Ringtoets.GrassCoverErosionInwards.Forms.Properties.Resources; using RingtoetsCommonDataResources = Ringtoets.Common.Data.Properties.Resources; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; namespace Ringtoets.GrassCoverErosionInwards.Plugin { /// /// The GUI plug-in for the . /// public class GrassCoverErosionInwardsGuiPlugin : GuiPlugin { public override IEnumerable GetPropertyInfos() { yield return new PropertyInfo(); yield return new PropertyInfo(); yield return new PropertyInfo(); } public override IEnumerable GetTreeNodeInfos() { yield return new DefaultFailureMechanismTreeNodeInfo( FailureMechanismChildNodeObjects, FailureMechanismContextMenuStrip, Gui); yield return CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo( CalculationGroupContextChildNodeObjects, CalculationGroupContextContextMenuStrip, CalculationGroupContextOnNodeRemoved); yield return CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo( GrassCoverErosionInwardsFormsResources.CalculationIcon, CalculationContextChildNodeObjects, null); yield return new TreeNodeInfo { Text = pipingInputContext => GrassCoverErosionInwardsFormsResources.GrassCoverErosionInwardsInputContext_NodeDisplayName, Image = pipingInputContext => RingtoetsCommonFormsResources.GenericInputOutputIcon, ContextMenuStrip = (nodeData, parentData, treeViewControl) => Gui.Get(nodeData, treeViewControl) .AddImportItem() .AddExportItem() .AddSeparator() .AddPropertiesItem() .Build() }; yield return new TreeNodeInfo { Text = emptyPipingOutput => RingtoetsCommonFormsResources.CalculationOutput_DisplayName, Image = emptyPipingOutput => RingtoetsCommonFormsResources.GenericInputOutputIcon, ForeColor = emptyPipingOutput => Color.FromKnownColor(KnownColor.GrayText), ContextMenuStrip = (nodeData, parentData, treeViewControl) => Gui.Get(nodeData, treeViewControl) .AddExportItem() .AddSeparator() .AddPropertiesItem() .Build() }; } private static object[] CalculationContextChildNodeObjects(GrassCoverErosionInwardsCalculationContext calculationContext) { var childNodes = new List { new CommentContext(calculationContext.WrappedData), new GrassCoverErosionInwardsInputContext(calculationContext.WrappedData.InputParameters, calculationContext.WrappedData, calculationContext.FailureMechanism, calculationContext.AssessmentSection) }; if (!calculationContext.WrappedData.HasOutput) { childNodes.Add(new EmptyGrassCoverErosionInwardsOutput()); } return childNodes.ToArray(); } private static ExceedanceProbabilityCalculationActivity CreateHydraRingTargetProbabilityCalculationActivity(HydraulicBoundaryLocation hydraulicBoundaryLocation, string hlcdDirectory, GrassCoverErosionInwardsInput inwardsInput, GrassCoverErosionInwardsOutput inwardsOutput ) { var hydraulicBoundaryLocationId = (int) hydraulicBoundaryLocation.Id; return HydraRingActivityFactory.Create( string.Format(Resources.GrassCoverErosionInwardsGuiPlugin_Calculate_overtopping_for_location_0_, hydraulicBoundaryLocationId), hlcdDirectory, hydraulicBoundaryLocationId.ToString(), HydraRingTimeIntegrationSchemeType.FBC, HydraRingUncertaintiesType.All, new OvertoppingCalculationInput(hydraulicBoundaryLocationId, new HydraRingSection(hydraulicBoundaryLocationId, hydraulicBoundaryLocationId.ToString(), double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN), inwardsInput.DikeHeight, inwardsInput.CriticalOvertoppingModelFactor, inwardsInput.FbFactor.Mean, inwardsInput.FbFactor.StandardDeviation, inwardsInput.FnFactor.Mean, inwardsInput.FnFactor.StandardDeviation, inwardsInput.OvertoppingModelFactor, inwardsInput.CriticalFlowRate.StandardDeviation, inwardsInput.CriticalFlowRate.Mean, inwardsInput.FrunupModelFactor.Mean, inwardsInput.FrunupModelFactor.StandardDeviation, inwardsInput.FshallowModelFactor.Mean, inwardsInput.FshallowModelFactor.StandardDeviation, ParseProfilePoints(inwardsInput.DikeGeometry), ParseForeshore(inwardsInput), ParseBreakWater(inwardsInput) ), output => { ParseHydraRingOutput(inwardsOutput, output); }); } private static HydraRingBreakWater ParseBreakWater(GrassCoverErosionInwardsInput input) { return input.UseBreakWater ? new HydraRingBreakWater((int) input.BreakWater.Type, input.BreakWater.Height) : null; } private static IEnumerable ParseForeshore(GrassCoverErosionInwardsInput input) { if (!input.UseForeshore) { yield break; } if (input.ForeshoreGeometry.Any()) { var first = input.ForeshoreGeometry.First(); yield return new HydraRingForelandPoint(first.StartingPoint.X, first.StartingPoint.Y); } foreach (var foreshore in input.ForeshoreGeometry) { yield return new HydraRingForelandPoint(foreshore.EndingPoint.X, foreshore.EndingPoint.Y); } } private static IEnumerable ParseProfilePoints(IEnumerable profileSections) { if (profileSections.Any()) { var first = profileSections.First(); yield return new HydraRingRoughnessProfilePoint(first.StartingPoint.X, first.StartingPoint.Y, 0); } foreach (var profileSection in profileSections) { yield return new HydraRingRoughnessProfilePoint(profileSection.EndingPoint.X, profileSection.EndingPoint.Y, profileSection.Roughness); } } private static void ParseHydraRingOutput(GrassCoverErosionInwardsOutput grassCoverErosionInwardsOutput, ExceedanceProbabilityCalculationOutput output) { if (output != null) { grassCoverErosionInwardsOutput.Probability = (RoundedDouble) output.Beta; } else { throw new InvalidOperationException(Resources.GrassCoverErosionInwardsGuiPlugin_Error_during_overtopping_calculation); } } #region GrassCoverErosionInwards TreeNodeInfo private object[] FailureMechanismChildNodeObjects(GrassCoverErosionInwardsFailureMechanismContext grassCoverErosionInwardsFailureMechanismContext) { GrassCoverErosionInwardsFailureMechanism wrappedData = grassCoverErosionInwardsFailureMechanismContext.WrappedData; return new object[] { new CategoryTreeFolder(RingtoetsCommonFormsResources.FailureMechanism_Inputs_DisplayName, GetInputs(wrappedData, grassCoverErosionInwardsFailureMechanismContext.Parent), TreeFolderCategory.Input), new GrassCoverErosionInwardsCalculationGroupContext(wrappedData.CalculationsGroup, wrappedData, grassCoverErosionInwardsFailureMechanismContext.Parent), new CategoryTreeFolder(RingtoetsCommonFormsResources.FailureMechanism_Outputs_DisplayName, GetOutputs(wrappedData), TreeFolderCategory.Output) }; } private static IList GetInputs(GrassCoverErosionInwardsFailureMechanism failureMechanism, IAssessmentSection assessmentSection) { return new ArrayList { new FailureMechanismSectionsContext(failureMechanism, assessmentSection), new CommentContext(failureMechanism) }; } private static IList GetOutputs(GrassCoverErosionInwardsFailureMechanism failureMechanism) { return new ArrayList { new FailureMechanismSectionResultContext(failureMechanism.SectionResults, failureMechanism) }; } private ContextMenuStrip FailureMechanismContextMenuStrip(GrassCoverErosionInwardsFailureMechanismContext grassCoverErosionInwardsFailureMechanismContext, object parentData, TreeViewControl treeViewControl) { var changeRelevancyItem = new StrictContextMenuItem( RingtoetsCommonFormsResources.FailureMechanismContextMenuStrip_Is_relevant, RingtoetsCommonFormsResources.FailureMechanismContextMenuStrip_Is_relevant_Tooltip, RingtoetsCommonFormsResources.Checkbox_ticked, (sender, args) => { Gui.ViewCommands.RemoveAllViewsForItem(grassCoverErosionInwardsFailureMechanismContext); grassCoverErosionInwardsFailureMechanismContext.WrappedData.IsRelevant = false; grassCoverErosionInwardsFailureMechanismContext.WrappedData.NotifyObservers(); } ); return Gui.Get(grassCoverErosionInwardsFailureMechanismContext, treeViewControl) .AddOpenItem() .AddSeparator() .AddCustomItem(changeRelevancyItem) .AddSeparator() .AddImportItem() .AddExportItem() .AddSeparator() .AddExpandAllItem() .AddCollapseAllItem() .Build(); } private static void AddCalculation(GrassCoverErosionInwardsCalculationGroupContext context) { var calculation = new GrassCoverErosionInwardsCalculation(context.FailureMechanism.GeneralInput) { Name = NamingHelper.GetUniqueName(context.WrappedData.Children, GrassCoverErosionInwardsDataResources.GrassCoverErosionInwardsCalculation_DefaultName, c => c.Name) }; context.WrappedData.Children.Add(calculation); context.WrappedData.NotifyObservers(); } #endregion #region CalculationGroupContext TreeNodeInfo private static object[] CalculationGroupContextChildNodeObjects(GrassCoverErosionInwardsCalculationGroupContext nodeData) { var childNodeObjects = new List(); foreach (ICalculationBase calculationItem in nodeData.WrappedData.Children) { var calculation = calculationItem as GrassCoverErosionInwardsCalculation; var group = calculationItem as CalculationGroup; if (calculation != null) { childNodeObjects.Add(new GrassCoverErosionInwardsCalculationContext(calculation, nodeData.FailureMechanism, nodeData.AssessmentSection)); } else if (group != null) { childNodeObjects.Add(new GrassCoverErosionInwardsCalculationGroupContext(group, nodeData.FailureMechanism, nodeData.AssessmentSection)); } else { childNodeObjects.Add(calculationItem); } } return childNodeObjects.ToArray(); } private ContextMenuStrip CalculationGroupContextContextMenuStrip(GrassCoverErosionInwardsCalculationGroupContext nodeData, object parentData, TreeViewControl treeViewControl) { var group = nodeData.WrappedData; var builder = Gui.Get(nodeData, treeViewControl); var isNestedGroup = parentData is GrassCoverErosionInwardsCalculationGroupContext; if (!isNestedGroup) { builder .AddOpenItem() .AddSeparator(); } CalculationTreeNodeInfoFactory.AddCreateCalculationGroupItem(builder, group); CalculationTreeNodeInfoFactory.AddCreateCalculationItem(builder, nodeData, AddCalculation); builder.AddSeparator(); CalculationTreeNodeInfoFactory.AddPerformAllCalculationsInGroupItem(builder, group, context => { }); // TODO: Actualy connect the calculation CalculationTreeNodeInfoFactory.AddClearAllCalculationOutputInGroupItem(builder, group); builder.AddSeparator(); if (isNestedGroup) { builder.AddRenameItem(); builder.AddDeleteItem(); builder.AddSeparator(); } return builder .AddImportItem() .AddExportItem() .AddSeparator() .AddExpandAllItem() .AddCollapseAllItem() .AddSeparator() .AddPropertiesItem() .Build(); } private void CalculationGroupContextOnNodeRemoved(GrassCoverErosionInwardsCalculationGroupContext nodeData, object parentNodeData) { var parentGroupContext = (GrassCoverErosionInwardsCalculationGroupContext) parentNodeData; parentGroupContext.WrappedData.Children.Remove(nodeData.WrappedData); parentGroupContext.NotifyObservers(); } #endregion } }