using System.Windows;
namespace ytLive.Models;
///
/// The vertical (9:16) tier's camera rules — TASK 57, the "vv" feature.
///
/// The vertical tier is a centred band crop of the SAME 1920×1080 master the
/// 16:9 tiers use, so a camera placed for 16:9 lands outside the cropped
/// window and vanishes from the vertical output. The vertical tier therefore
/// keeps its OWN placement per scene: a small tile inside the band, snapped to
/// one of six spots — the band splits into a top and a bottom half, each with
/// a left, a centre and a right slot.
///
/// Geometry only: the preview and the compositor both read the element's own
/// X/Y/W/H + ClipShape, so the placement is resolved by swapping those values
/// when the tier changes. No render-path change.
///
public static class VerticalCameraLayout
{
/// The vertical tier's camera tile over the master frame —
/// 270×152 master px = 480×270 in the 1080×1920 output.
public const double TileWidth = 270;
public const double TileHeight = 152;
/// How far the tile keeps from the band's outer edge — the app's
/// own placement margin (32 master px) used by the default webcam spot.
public const double Inset = 32;
/// True for the portrait tier (the vertical 1080×1920 one).
public static bool IsVerticalTier(QualityOption quality) => quality.Height > quality.Width;
/// The half of the band a tile lives in — top or bottom.
public static Rect AreaFor(Rect band, bool bottom)
=> new(band.Left, bottom ? band.Top + band.Height / 2 : band.Top, band.Width, band.Height / 2);
/// The largest a camera may be inside the band: one whole area.
public static (double Width, double Height) MaxSizeFor(Rect band)
=> (band.Width, band.Height / 2);
///
/// The spot a tile snaps to: the area (top/bottom) and the column
/// (left/centre/right) its centre falls in, then the tile's top-left for
/// that spot — inset from the band's outer edge, and never outside the band
/// (a tile wider than the inset eats it).
///
public static (double X, double Y) SpotFor(Rect band, double width, double height, double centreX, double centreY)
{
var bottom = centreY >= band.Top + band.Height / 2;
var area = AreaFor(band, bottom);
var third = area.Width / 3;
double x;
if (centreX < area.Left + third) x = area.Left + Inset;
else if (centreX < area.Left + 2 * third) x = area.Left + (area.Width - width) / 2;
else x = area.Right - Inset - width;
var y = bottom ? area.Bottom - Inset - height : area.Top + Inset;
x = Math.Clamp(x, band.Left, Math.Max(band.Left, band.Right - width));
y = Math.Clamp(y, band.Top, Math.Max(band.Top, band.Bottom - height));
return (x, y);
}
/// The default tile spot: the bottom-right corner of the band —
/// the same corner the 16:9 default webcam placement uses.
public static (double X, double Y) DefaultSpot(Rect band, double width, double height)
=> SpotFor(band, width, height, band.Right, band.Bottom);
}