# The geometry vocabulary every instrument UI module speaks (the Rect alias + contains())
# is header-only, hence INTERFACE.
add_library(editor_geometry INTERFACE)
target_include_directories(editor_geometry INTERFACE ${REASAMPLER_SRC_DIR})

reasampler_pure_library(sample_bands SOURCES sample_bands.cpp LINK PUBLIC editor_geometry)
reasampler_test(sample_bands LINK sample_bands)

reasampler_pure_library(sample_chrome SOURCES sample_chrome.cpp LINK PUBLIC sample_bands)
# knob_deck is linked for the test only: the knob size the shell hands chromeRects is
# kDeckKnobSize, and the test reads the real constant rather than copying its value.
reasampler_test(sample_chrome LINK sample_chrome knob_deck)

reasampler_pure_library(embed_strip SOURCES embed_strip.cpp LINK PUBLIC editor_geometry)
reasampler_test(embed_strip LINK embed_strip)

reasampler_pure_library(capture_browser SOURCES capture_browser.cpp LINK PUBLIC editor_geometry)
reasampler_test(capture_browser LINK capture_browser)

reasampler_pure_library(keyboard_strip SOURCES keyboard_strip.cpp LINK PUBLIC editor_geometry)
reasampler_test(keyboard_strip LINK keyboard_strip sample_bands sample_chrome)

# sample_bands is PUBLIC since resolveLaneSplit answers in its LaneSplit — the meter's bar
# count consumes that answer, so the type is part of this module's surface, not an internal.
# component_geometry is PRIVATE: the overlay area is DERIVED from the draw chain's own column
# count so the two cannot drift, but no type of it appears in this module's header.
reasampler_pure_library(waveform_view
    SOURCES waveform_view.cpp
    LINK PUBLIC editor_geometry peaks sample_bands PRIVATE component_geometry)
# component_geometry is linked for the test too: proving the overlay rides the drawn column
# band takes the real column count, not a copy of it.
reasampler_test(waveform_view LINK waveform_view sample_bands component_geometry)

# The loop enable's state machine. Links loop_span for the park bounds — the span the user is
# offered and the span the engine accepts stay one definition.
reasampler_pure_library(loop_marks SOURCES loop_marks.cpp LINK PUBLIC loop_span)
reasampler_test(loop_marks LINK loop_marks)

reasampler_pure_library(browser_scroll
    SOURCES browser_scroll.cpp
    LINK PUBLIC capture_browser sample_chrome)
reasampler_test(browser_scroll LINK browser_scroll)

reasampler_pure_library(param_slider
    SOURCES param_slider.cpp
    LINK PUBLIC editor_geometry param_taper)
reasampler_test(param_slider LINK param_slider)

reasampler_pure_library(envelope_overlay
    SOURCES envelope_overlay.cpp
    LINK PUBLIC editor_geometry curve_law param_taper)
# sample_bands is linked for the test only: the tapered-axis legibility assertion is judged at the
# editor's own floor width, read from the allocator rather than copied as a number.
reasampler_test(envelope_overlay LINK envelope_overlay sample_bands)

reasampler_pure_library(envelope_edit SOURCES envelope_edit.cpp LINK PUBLIC envelope_overlay)
reasampler_test(envelope_edit LINK envelope_edit)

reasampler_pure_library(knob_deck SOURCES knob_deck.cpp LINK PUBLIC editor_geometry)
reasampler_test(knob_deck LINK knob_deck)

# The spanning deck's meter column, split from knob_deck on the axis sample_chrome has to
# sample_bands: that says where the column is, this lays out inside it. sample_bands is PUBLIC
# for LaneSplit — the bar count is the SAME resolved decision the waveform's lane split is.
reasampler_pure_library(master_meter
    SOURCES master_meter.cpp
    LINK PUBLIC editor_geometry sample_bands meter_ballistics)
# waveform_view is linked for the test only: proving the bar count is not a second rule takes
# the real waveformSurface fold, over channel mode x source channel count.
reasampler_test(master_meter LINK master_meter waveform_view)

# The deck's group COMPOSITION, split from its layout: knob_deck stays engine-free (see
# core/instrument/CLAUDE.md's deck_groups entry for why this module, not knob_deck, reads
# PlayMode). velocity_curve is the filter's own curve field; peaks is play_params.h's
# AudioSample dependency. play_params.h also drags in filter/'s headers (FilterSettings,
# MorphLaw) for the v9 filter tail -- plain value types, no filter symbol linked.
# master_meter is PRIVATE: MASTER's descriptor reserves the meter column's own kMeterColumnW,
# but nothing in deck_groups.h names a meter type, so the edge stops at this TU.
reasampler_pure_library(deck_groups
    SOURCES deck_groups.cpp
    LINK PUBLIC knob_deck velocity_curve peaks curve_law PRIVATE master_meter)
# WHICH descriptors the deck carries, and how they resolve to a layout — no window-floor budget
# assertion here, so this target needs neither sample_bands nor master_meter.
reasampler_test(deck_groups LINK deck_groups)
# The width-BUDGET half, split out on the same seam PRIVATE master_meter already draws above:
# the deck-fits-the-floor-window assertion needs the band allocator, and the MASTER-reserve
# identity needs the column width the PRIVATE edge on deck_groups does not re-export.
reasampler_test(deck_groups_measured LINK deck_groups sample_bands master_meter)
# The commit-tier + overlay-selection state machine, split out of deck_groups_tests on the seam
# those fixtures already had: deckParamCommit/liveCommitFor and the overlay predicates are pure
# control-id/enum logic that touches no layout, so this target needs no sample_bands/master_meter.
reasampler_test(deck_groups_state LINK deck_groups)

# The point-editing grammar both spline consumers share, so it links the curve itself (unlike
# envelope_overlay/envelope_edit, which stay engine-free — the staged envelopes touch no curve).
reasampler_pure_library(spline_edit
    SOURCES spline_edit.cpp
    LINK PUBLIC editor_geometry velocity_curve)
# waveform_view and sample_bands are linked for the test only: resolveWaveformClaim's
# smallest-target-first tests build the real node/tab/marker geometry
# editor_input_waveform.cpp's mouseDownWaveform composes (the shell that calls it has no test
# target of its own), which needs waveform_view's marker/tab primitives and sample_bands'
# kWaveformMinHeight floor.
reasampler_test(spline_edit LINK spline_edit waveform_view sample_bands)

# The deck's VALUE binding, split from its composition on the same axis deck_groups was split
# from knob_deck. Links the header-only play_seconds, NOT sample_map: PlaySeconds is all a deck
# knob edits, and sample_map would drag the bank model and the WAV codec in behind it. Same for
# the filter's MorphLaw — an enum, so no filter symbol is linked.
# time_stretch carries Rate's range — the stretcher's own measured bounds, aliased here rather
# than restated so the knob's ends and the engine's clamp cannot disagree.
reasampler_pure_library(deck_values
    SOURCES deck_values.cpp
    LINK PUBLIC deck_groups play_seconds envelope_overlay param_taper master_gain time_stretch)
reasampler_test(deck_values LINK deck_values)

# The bake Hold knob's value domain. Links the ladder alone — it computes no geometry, so it
# does not even take editor_geometry.
reasampler_pure_library(bake_hold SOURCES bake_hold.cpp LINK PUBLIC musical_division)
reasampler_test(bake_hold LINK bake_hold)

reasampler_pure_library(curve_popup SOURCES curve_popup.cpp LINK PUBLIC editor_geometry)
# velocity_curve is linked for the test only: the sheet's geometry is domain-agnostic, and
# proving that takes a curve of each domain mapped through the one curveBox.
reasampler_test(curve_popup LINK curve_popup velocity_curve)

# The ONE norm<->value taper and modifier vocabulary every variable control shares. Declared
# last, but it sits at the BOTTOM of this directory's dependency order: param_slider,
# envelope_overlay and deck_values all read it — which is exactly why it could not stay inside
# deck_values, which sits above envelope_overlay.
reasampler_pure_library(param_taper SOURCES param_taper.cpp LINK PUBLIC curve_law)
# envelope_overlay and sample_bands are linked for the test only: the finest-drag-step assertion
# is judged against the envelope node drag at the editor's own floor width (the sharper of the
# taper's two consumers), read from the allocator/overlay rather than copied as a number.
reasampler_test(param_taper LINK param_taper envelope_overlay sample_bands)

# The staged trace, split from envelope_overlay's vertex model. stroke_aa is the trace-point
# vocabulary, filled in place so the shell's scratch buffer is reused rather than a fresh
# vector returned per paint; curve_law arrives through envelope_overlay but is named here
# because this module evaluates the law rather than merely carrying its exponents.
reasampler_pure_library(curve_tessellate
    SOURCES curve_tessellate.cpp
    LINK PUBLIC envelope_overlay stroke_aa curve_law)
reasampler_test(curve_tessellate LINK curve_tessellate)
