"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const S = require("../static/scrub.js");

test("clamp01 bounds to [0,1]", () => {
  assert.equal(S.clamp01(-0.2), 0);
  assert.equal(S.clamp01(0.4), 0.4);
  assert.equal(S.clamp01(1.5), 1);
});

test("wrapIndex wraps both directions", () => {
  assert.equal(S.wrapIndex(0, 5), 0);
  assert.equal(S.wrapIndex(5, 5), 0);
  assert.equal(S.wrapIndex(-1, 5), 4);
  assert.equal(S.wrapIndex(7, 5), 2);
});

test("segmentOf splits floor and fraction", () => {
  assert.deepEqual(S.segmentOf(2), { lo: 2, frac: 0 });
  const s = S.segmentOf(2.4);
  assert.equal(s.lo, 2);
  assert.ok(Math.abs(s.frac - 0.4) < 1e-9);
});

test("accumToPos maps knob degrees to position", () => {
  assert.equal(S.accumToPos(2, 0, 72), 2);
  assert.equal(S.accumToPos(2, 72, 72), 3);
  assert.equal(S.accumToPos(2, -36, 72), 1.5);
});

test("fracToTime clamps and scales by duration", () => {
  assert.equal(S.fracToTime(0, 1.5), 0);
  assert.equal(S.fracToTime(0.5, 1.5), 0.75);
  assert.equal(S.fracToTime(1.2, 1.5), 1.5);
  assert.equal(S.fracToTime(0.5, 0), 0);
});

test("crossfadeGains splits energy by fraction", () => {
  assert.deepEqual(S.crossfadeGains(0), { from: 1, to: 0 });
  assert.deepEqual(S.crossfadeGains(1), { from: 0, to: 1 });
  assert.deepEqual(S.crossfadeGains(0.25), { from: 0.75, to: 0.25 });
});

test("integerCrossings: none while inside a segment", () => {
  assert.deepEqual(S.integerCrossings(2.1, 2.9), []);
  assert.deepEqual(S.integerCrossings(2.0, 2.5), []);
  assert.deepEqual(S.integerCrossings(3.0, 2.5), []);
});

test("integerCrossings: ascending and descending single crossings", () => {
  assert.deepEqual(S.integerCrossings(2.4, 3.0), [{ index: 3, dir: 1 }]);
  assert.deepEqual(S.integerCrossings(2.0, 3.0), [{ index: 3, dir: 1 }]);
  assert.deepEqual(S.integerCrossings(3.4, 3.0), [{ index: 3, dir: -1 }]);
});

test("integerCrossings: multiple crossings in travel order", () => {
  assert.deepEqual(S.integerCrossings(2.4, 4.1), [{ index: 3, dir: 1 }, { index: 4, dir: 1 }]);
  assert.deepEqual(S.integerCrossings(3.2, 1.8), [{ index: 3, dir: -1 }, { index: 2, dir: -1 }]);
});
