// lib/editor/input/pressure_curve.dart
//
// Configurable pen-pressure response (F5 — the user's repeated "可配置笔" ask).
// Raw normalized stylus pressure [0,1] is pre-shaped here before it reaches
// perfect_freehand, giving two user-facing knobs:
//   - [floor]: a minimum output (the plan's marker "min-width floor" — a fixed-
//     pressure marker uses floor≈1.0; a pen uses 0.0).
//   - [gamma]: the response exponent — γ<1 makes light touches register more
//     width (more sensitive), γ>1 requires firmer pressure (less sensitive).
//
// Pure value type (widget-free, storage-free) so the full mapping is unit
// tested; PenConfig / the canvas wire it later (the wiring touches the live
// draw path and is validated on-device).

import 'dart:math' as math;

/// Maps raw normalized pressure to a shaped response in `[floor, 1]`.
class PressureCurve {
  const PressureCurve({this.floor = 0.0, this.gamma = 1.0})
      : assert(floor >= 0.0 && floor < 1.0),
        assert(gamma > 0.0);

  /// Minimum output (>=0, <1). 0 = full dynamic range; raise toward 1 for a
  /// fixed-pressure feel (marker).
  final double floor;

  /// Response exponent (>0). 1 = linear; <1 = more sensitive at light pressure;
  /// >1 = firmer.
  final double gamma;

  /// Linear, full-range pen response (identity).
  static const PressureCurve linear = PressureCurve();

  /// Shape [pressure] (clamped to [0,1]) into `[floor, 1]`.
  double apply(double pressure) {
    final p = pressure.isNaN ? 0.0 : pressure.clamp(0.0, 1.0);
    final shaped = gamma == 1.0 ? p : math.pow(p, gamma).toDouble();
    return floor + (1.0 - floor) * shaped;
  }
}
