namespace AIStudio.Tools.PowerPoint;
///
/// Where a placeholder sits on the slide, in English Metric Units (EMU).
///
/// The distance of the left edge from the left edge of the slide.
/// The distance of the top edge from the top edge of the slide.
/// The width.
/// The height.
internal readonly record struct SlotBounds(long X, long Y, long Width, long Height)
{
public long Right => this.X + this.Width;
public long Bottom => this.Y + this.Height;
public long CenterX => this.X + this.Width / 2;
public long CenterY => this.Y + this.Height / 2;
public double Area => (double)this.Width * this.Height;
///
/// Whether the two areas share a part of their horizontal extent.
///
public bool OverlapsHorizontally(SlotBounds other) => this.X < other.Right && other.X < this.Right;
///
/// The area both share; 0 when they do not overlap.
///
public double IntersectionArea(SlotBounds other)
{
var width = Math.Min(this.Right, other.Right) - Math.Max(this.X, other.X);
var height = Math.Min(this.Bottom, other.Bottom) - Math.Max(this.Y, other.Y);
return width > 0 && height > 0 ? (double)width * height : 0;
}
///
/// Whether the other area lies within this one, give or take the given tolerance on each edge.
///
public bool Contains(SlotBounds other, long horizontalTolerance, long verticalTolerance) =>
other.X >= this.X - horizontalTolerance &&
other.Right <= this.Right + horizontalTolerance &&
other.Y >= this.Y - verticalTolerance &&
other.Bottom <= this.Bottom + verticalTolerance;
///
/// Whether both areas are the same, give or take the given tolerance on each edge.
///
public bool IsCloseTo(SlotBounds other, long horizontalTolerance, long verticalTolerance) =>
Math.Abs(this.X - other.X) <= horizontalTolerance &&
Math.Abs(this.Width - other.Width) <= horizontalTolerance &&
Math.Abs(this.Y - other.Y) <= verticalTolerance &&
Math.Abs(this.Height - other.Height) <= verticalTolerance;
}