<!-- Copyright © Northwoods Software Corporation, 2008-2026. All Rights Reserved. -->

<UserControl x:Class="Piping.Piping"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:go="http://schemas.nwoods.com/GoXam"
    xmlns:local="clr-namespace:Piping">
  <UserControl.Resources>
    <!-- this converter produces the stroke brush for links -->
    <go:BooleanBrushConverter x:Key="theStrokeChooser"
                              TrueBrush="Magenta" FalseBrush="Black" />
    <!-- this converter positions the text near the valve shape -->
    <local:ValveOrientationConverter x:Key="theValveOrienter" />

    <!-- For the text of each node -->
    <Style TargetType="TextBlock" x:Key="TextBlockStyle">
      <Setter Property="TextWrapping" Value="Wrap" />
      <Setter Property="VerticalAlignment" Value="Center" />
      <Setter Property="HorizontalAlignment" Value="Center" />
      <Setter Property="Margin" Value="5" />
      <Setter Property="go:Part.TextEditable" Value="True" />
    </Style>

    <!-- The DataTemplateDictionary used to store all the
         DataTemplates for the Node categories. -->
    <go:DataTemplateDictionary x:Key="NodeTemplateDictionary">

      <DataTemplate x:Key="Process">
        <go:NodePanel Sizing="Fixed"
                      go:Part.SelectionElementName="Shape"
                      go:Part.SelectionAdorned="True"
                      go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
                      go:Part.Resizable="True">
          <Rectangle x:Name="Shape"
                     Width="{Binding Path=Data.Width, Mode=TwoWay}"
                     Height="{Binding Path=Data.Height, Mode=TwoWay}"
                     RadiusX="30" RadiusY="30"
                     Stroke="Black" StrokeThickness="2"
                     go:Node.PortId="" Cursor="Hand"
                     go:Node.FromSpot="AllSides" go:Node.ToSpot="AllSides"
                     go:Node.LinkableFrom="True" go:Node.LinkableTo="True">
            <Shape.Fill>
              <RadialGradientBrush GradientOrigin="-0.2,-0.2">
                <GradientStop Color="White" Offset="0.35" />
                <GradientStop Color="SkyBlue" Offset="1" />
              </RadialGradientBrush>
            </Shape.Fill>
          </Rectangle>
          <!-- this Rectangle hides the link-drawing mouse behavior over most of
               the area of the main Shape, except for an 8-pixel border area -->
          <Rectangle Fill="Transparent" Margin="8" />
          <TextBlock Style="{StaticResource TextBlockStyle}"
                     Text="{Binding Path=Data.Text, Mode=TwoWay}" />
        </go:NodePanel>
      </DataTemplate>

      <DataTemplate x:Key="Valve">
        <StackPanel go:Part.SelectionElementName="Shape"
                    go:Part.SelectionAdorned="True"
                    go:Node.RotationAngle="{Binding Path=Data.Angle, Mode=TwoWay}"
                    go:Node.Rotatable="True"
                    Orientation="{Binding Path=Data.Angle, Converter={StaticResource theValveOrienter}}"
                    go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
                    go:Node.LocationElementName="Shape"
                    go:Node.LocationSpot="0.5 0.35">
          <TextBlock Style="{StaticResource TextBlockStyle}"
                     Text="{Binding Path=Data.Text, Mode=TwoWay}"
                     HorizontalAlignment="Center" VerticalAlignment="Center" />
          <go:NodePanel x:Name="Shape"
                        HorizontalAlignment="Center" VerticalAlignment="Center">
            <!-- an example of a non-predefined figure -->
            <Path Stroke="Black" StrokeThickness="2"
                  Data="M20 10 L0 20 0 0 20 10 M20 10 L40 0 40 20 20 10 M20 10 L20 30 M15 30 L25 30"
                  go:Node.PortId="" Cursor="Hand"
                  go:Node.ToSpot="0 0.35" go:Node.FromSpot="1 0.35"
                  go:Node.LinkableFrom="True" go:Node.LinkableTo="True">
              <Path.Fill>
                <LinearGradientBrush StartPoint="0 0" EndPoint="0 1">
                  <GradientStop Color="Gray" Offset="0" />
                  <GradientStop Color="White" Offset="0.35" />
                  <GradientStop Color="Gray" Offset="0.7" />
                </LinearGradientBrush>
              </Path.Fill>
            </Path>
            <!-- this Rectangle hides the link-drawing mouse behavior over most of
               the area of the main Shape, except for an 5-pixel border area -->
            <Rectangle Fill="Transparent" Margin="5" />
          </go:NodePanel>
        </StackPanel>
      </DataTemplate>

      <DataTemplate x:Key="Instrument">
        <go:NodePanel Sizing="Fixed"
                      go:Part.LayerName="Foreground"
                      go:Part.SelectionElementName="Shape"
                      go:Part.SelectionAdorned="True"
                      go:Node.LocationSpot="Center"
                      go:Part.Resizable="True"
                      go:Node.Avoidable="False"
                      go:LinkPanel.Index="{Binding Path=Data.Index, Mode=TwoWay}"
                      go:LinkPanel.Fraction="{Binding Path=Data.Fraction, Mode=TwoWay}"
                      go:LinkPanel.Offset="{Binding Path=Data.Location, Mode=TwoWay}"
                      go:LinkPanel.Alignment="Center">
          <Ellipse x:Name="Shape"
                   Width="{Binding Path=Data.Width, Mode=TwoWay}"
                   Height="{Binding Path=Data.Height, Mode=TwoWay}"
                   Stroke="Black" StrokeThickness="1" Fill="White" />
          <TextBlock Style="{StaticResource TextBlockStyle}"
                     Text="{Binding Path=Data.Text, Mode=TwoWay}" />
        </go:NodePanel>
      </DataTemplate>
      
    </go:DataTemplateDictionary>

    <DataTemplate x:Key="PipeTemplate">
      <go:LinkPanel go:Part.Reshapable="True"
                    go:Part.DropOntoBehavior="SplicesIntoLink">
        <go:Link.Route>
          <go:Route Routing="AvoidsNodes" Curve="JumpOver" Corner="5"
                    FromEndSegmentDirection="RotatedNodeOrthogonal"
                    ToEndSegmentDirection="RotatedNodeOrthogonal"
                    RelinkableFrom="True" RelinkableTo="True"
                    ToShortLength="5" />
        </go:Link.Route>
        <!-- in order to simulate a gradient across the breadth of the pipe, regardless of the pipe's direction,
             use multiple superimposed link shapes, each narrower and lighter than the previous one -->
        <go:LinkShape 
              Stroke="{Binding Path=Link.IsDropOntoAccepted, Converter={StaticResource theStrokeChooser}}"
              StrokeThickness="5" />
        <go:LinkShape Stroke="Gray" StrokeThickness="3" />
        <go:LinkShape Stroke="WhiteSmoke" StrokeThickness="1" />
        <Path go:LinkPanel.ToArrow="Triangle" Fill="Black" />
      </go:LinkPanel>
    </DataTemplate>

    <go:DataTemplateDictionary x:Key="GroupTemplateDictionary">
      <DataTemplate x:Key="Instrument">
      </DataTemplate>
    </go:DataTemplateDictionary>
  </UserControl.Resources>

  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="100" />
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <go:Palette x:Name="myPalette" Grid.Row="0" Padding="10"
                NodeTemplateDictionary="{StaticResource NodeTemplateDictionary}"
                MaximumSelectionCount="1">
        <go:Palette.Layout>
          <go:GridLayout Alignment="Position" CellSize="5 5" />
        </go:Palette.Layout>
      </go:Palette>
      <StackPanel Grid.Row="1">
        <Button Content="Save" Click="Save_Click" />
        <Button Content="Load" Click="Load_Click" x:Name="LoadButton" IsEnabled="False" />
      </StackPanel>
    </Grid>
    <GridSplitter Grid.Column="1" Width="5"
                  HorizontalAlignment="Center" VerticalAlignment="Stretch" />
    <go:Diagram x:Name="myDiagram" Grid.Column="2" Padding="10"
                HorizontalContentAlignment="Stretch"
                VerticalContentAlignment="Stretch"
                NodeTemplateDictionary="{StaticResource NodeTemplateDictionary}"
                GroupTemplateDictionary="{StaticResource GroupTemplateDictionary}"
                LinkTemplate="{StaticResource PipeTemplate}"
                AllowDrop="True"
                GridVisible="True" GridSnapEnabled="True">
      <go:Diagram.DraggingTool>
        <local:CustomDraggingTool DropOntoEnabled="True" FromPortId="Out" ToPortId="In" />
      </go:Diagram.DraggingTool>
      <go:Diagram.RotatingTool>
        <go:RotatingTool SnapAngleMultiple="90" SnapAngleEpsilon="45" />
      </go:Diagram.RotatingTool>
      <go:Diagram.GridPattern>
        <go:GridPattern CellSize="10 10">
          <Path Stroke="WhiteSmoke" StrokeThickness="1" go:GridPattern.Figure="HorizontalLine" />
          <Path Stroke="WhiteSmoke" StrokeThickness="1" go:GridPattern.Figure="VerticalLine" />
        </go:GridPattern>
      </go:Diagram.GridPattern>
    </go:Diagram>
  </Grid>
</UserControl>
