using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { public class PipeJoin : INode { public const double SIZE = 3.6; public const double POINT = 0.8; public double CenterX { get; set; } public double CenterY { get; set; } public string Label => ""; public ISet Inputs { get; init; } public ISet Outputs { get; init; } private Polygon? _rect; public PipeJoin(double x, double y) { CenterX = x; CenterY = y; Inputs = new HashSet(); Outputs = new HashSet(); } public void Draw(Canvas canvas) { _rect = new Polygon() { Fill = Brushes.Black, Stroke = Brushes.Black, }; canvas.Children.Add(_rect); } public void Scale(double scale) { var it = Inputs.Any(e => (e.Start.CenterY < CenterY && (!e.Orientation || e.Start.CenterX == CenterX)) || (e.IsTwoWay && e.End.CenterY < CenterY && (!e.Orientation || e.End.CenterX == CenterX))); var ot = Outputs.Any(e => (e.End.CenterY < CenterY && (e.Orientation || e.End.CenterX == CenterX)) || (e.IsTwoWay && e.Start.CenterY < CenterY && (e.Orientation || e.Start.CenterX == CenterX))); var ir = Inputs.Any(e => (e.Start.CenterX > CenterX && (e.Orientation || e.Start.CenterY == CenterY)) || (e.IsTwoWay && e.End.CenterX > CenterX && (e.Orientation || e.End.CenterY == CenterY))); var or = Outputs.Any(e => (e.End.CenterX > CenterX && (!e.Orientation || e.End.CenterY == CenterY)) || (e.IsTwoWay && e.Start.CenterX > CenterX && (!e.Orientation || e.Start.CenterY == CenterY))); var ib = Inputs.Any(e => (e.Start.CenterY > CenterY && (!e.Orientation || e.Start.CenterX == CenterX)) || (e.IsTwoWay && e.End.CenterY > CenterY && (!e.Orientation || e.End.CenterX == CenterX))); var ob = Outputs.Any(e => (e.End.CenterY > CenterY && (e.Orientation || e.End.CenterX == CenterX)) || (e.IsTwoWay && e.Start.CenterY > CenterY && (e.Orientation || e.Start.CenterX == CenterX))); var il = Inputs.Any(e => (e.Start.CenterX < CenterX && (e.Orientation || e.Start.CenterY == CenterY)) || (e.IsTwoWay && e.End.CenterX < CenterX && (e.Orientation || e.End.CenterY == CenterY))); var ol = Outputs.Any(e => (e.End.CenterX < CenterX && (!e.Orientation || e.End.CenterY == CenterY)) || (e.IsTwoWay && e.Start.CenterX < CenterX && (!e.Orientation || e.Start.CenterY == CenterY))); var points = new List { new(0, 0) }; if (ot && it) { points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, -POINT / 2), new(SIZE / 2, POINT / 2), new(SIZE / 2 + POINT, 0)]); } else if (ot) { points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, -POINT), new(SIZE / 2 + POINT, 0)]); } else if (it) { points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, POINT), new(SIZE / 2 + POINT, 0)]); } points.Add(new(SIZE, 0)); if (or && ir) { points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT / 2, SIZE / 2), new(SIZE - POINT / 2, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); } else if (or) { points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); } else if (ir) { points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE - POINT, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); } points.Add(new(SIZE, SIZE)); if (ob && ib) { points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT / 2), new(SIZE / 2, SIZE - POINT / 2), new(SIZE / 2 - POINT, SIZE)]); } else if (ob) { points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT), new(SIZE / 2 - POINT, SIZE)]); } else if (ib) { points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE - POINT), new(SIZE / 2 - POINT, SIZE)]); } points.Add(new(0, SIZE)); if (ol && il) { points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT / 2, SIZE / 2), new(POINT / 2, SIZE / 2), new(0, SIZE / 2 - POINT)]); } else if (ol) { points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT, SIZE / 2), new(0, SIZE / 2 - POINT)]); } else if (il) { points.AddRange([new(0, SIZE / 2 + POINT), new(POINT, SIZE / 2), new(0, SIZE / 2 - POINT)]); } _rect?.Points = [.. points.Select(p => new Point(p.X * scale, p.Y * scale))]; _rect?.StrokeThickness = 2; _rect?.SetValue(Canvas.LeftProperty, (CenterX - SIZE / 2) * scale); _rect?.SetValue(Canvas.TopProperty, (CenterY - SIZE / 2) * scale); } public bool IsInside(double x, double y) { return Math.Abs(x - CenterX) <= SIZE / 2 && Math.Abs(y - CenterY) <= SIZE / 2; } public void Update(bool isHovering, bool isPressed) { _rect?.Stroke = isHovering ? Brushes.Black : Brushes.Black; } } }