// Module 5: OSC Communication Setup - MODIFIED FOR IDRAW OSC
// Save as "5_osc_communication.scd"

(
// Clear any existing OSC definitions
OSCdef.freeAll;

// Variables to track current pen type and color
~currentPenType = \pen;
~currentColor = (r: 0, g: 0, b: 1); // Default blue

// Define OSC responder for iDraw touch data
OSCdef(\touchOSC, { |msg, time, addr, port|
    var x = msg[1].asFloat;
    var y = msg[2].asFloat;
    var pressure = msg[3].asFloat;

    // Log the received data
    ["Touch data:", x, y, pressure, ~currentPenType, ~currentColor].postln;

    // Handle touch based on current pen type
    switch(~currentPenType,
        // Pen - Controls amplitude envelope
        \pen, {
            var attack = x.linlin(-0.5, 0.5, 0, 5);
            var release = y.linlin(-0.5, 0.5, 0, 10);
            var freq = x.linexp(-0.5, 0.5, 100, 2000);

            // Generate sound with RGB-controlled waveform mix
            var synth = Synth(\rgbSynth, [
                \out, ~sourceBus ? 0,
                \freq, freq,
                \amp, pressure.linlin(1, 8, 0.1, 0.8),
                \attack, attack,
                \release, release,
                \redAmt, ~currentColor.r,
                \greenAmt, ~currentColor.g,
                \blueAmt, ~currentColor.b
            ]);

            ["Amplitude envelope:", attack, release].postln;
        },

        // Monoline - Controls filter envelope
        \monoline, {
            var attack = x.linlin(-0.5, 0.5, 0, 5);
            var release = y.linlin(-0.5, 0.5, 0, 10);
            var freq = x.linexp(-0.5, 0.5, 100, 2000);

            // Generate sound with filter envelope
            var synth = Synth(\rgbFilterSynth, [
                \out, ~sourceBus ? 0,
                \freq, freq,
                \amp, pressure.linlin(1, 8, 0.1, 0.8),
                \attack, attack,
                \release, release,
                \filterAttack, attack,
                \filterRelease, release,
                \redAmt, ~currentColor.r,
                \greenAmt, ~currentColor.g,
                \blueAmt, ~currentColor.b
            ]);

            ["Filter envelope:", attack, release].postln;
        },

        // Marker - Controls pitch envelope
        \marker, {
            var attack = x.linlin(-0.5, 0.5, 0, 5);
            var release = y.linlin(-0.5, 0.5, 0, 10);
            var freq = x.linexp(-0.5, 0.5, 100, 2000);

            // Generate sound with pitch envelope
            var synth = Synth(\rgbPitchSynth, [
                \out, ~sourceBus ? 0,
                \freq, freq,
                \amp, pressure.linlin(1, 8, 0.1, 0.8),
                \attack, attack,
                \release, release,
                \pitchAttack, attack,
                \pitchRelease, release,
                \redAmt, ~currentColor.r,
                \greenAmt, ~currentColor.g,
                \blueAmt, ~currentColor.b
            ]);

            ["Pitch envelope:", attack, release].postln;
        },

        // Pencil - Effect preset 1
        \pencil, {
            // Apply Preset 1 effects
            ~filterSynth.set(
                \cutoff, x.linexp(-0.5, 0.5, 20, 18000),
                \res, y.linlin(-0.5, 0.5, 0, 1)
            );

            ~lfoSynth.set(
                \freq, x.linlin(-0.5, 0.5, 0, 15),
                \intensity, pressure.linlin(1, 8, 0, 1)
            );

            ~reverbSynth.set(
                \roomsize, y.linlin(-0.5, 0.5, 0.1, 0.9)
            );

            ["Pencil preset:", "Cutoff", x.linexp(-0.5, 0.5, 20, 18000), "LFO", x.linlin(-0.5, 0.5, 0, 15)].postln;
        },

        // Crayon - Effect preset 2
        \crayon, {
            // Apply Preset 2 effects
            ~lfoSynth.set(
                \freq, x.linlin(-0.5, 0.5, 15, 1),
                \intensity, x.linlin(-0.5, 0.5, 0, 1)
            );

            ~delaySynth.set(
                \delaytime, x.linlin(-0.5, 0.5, 0.01, 1.0)
            );

            ~filterSynth.set(
                \cutoff, y.linexp(-0.5, 0.5, 20, 18000),
                \res, pressure.linlin(1, 5, 0, 1)
            );

            ~reverbSynth.set(
                \mix, y.linlin(-0.5, 0.5, 0, 1)
            );

            ["Crayon preset:", "LFO", x.linlin(-0.5, 0.5, 15, 1), "Filter", y.linexp(-0.5, 0.5, 20, 18000)].postln;
        },

        // Fountain pen - Effect preset 3 (placeholder)
        \fountainPen, {
            // Apply Preset 3 effects (TBD in documentation)
            ["Fountain pen preset (TBD)"].postln;
        },

        // Water color - Effect preset 4 (placeholder)
        \waterColor, {
            // Apply Preset 4 effects (TBD in documentation)
            ["Water color preset (TBD)"].postln;
        }
    );
}, '/touch');

// OSC responder for pen type selection
OSCdef(\penTypeOSC, { |msg, time, addr, port|
    var penType = msg[1].asSymbol;

    // Update current pen type
    ~currentPenType = penType;

    ["Pen type changed:", penType].postln;

    // Initialize relevant effects based on pen type
    switch(penType,
        \pencil, { ~initializePreset1.value; },
        \crayon, { ~initializePreset2.value; },
        \fountainPen, { ~initializePreset3.value; },
        \waterColor, { ~initializePreset4.value; }
    );
}, '/pen');

// OSC responder for color changes
OSCdef(\colorOSC, { |msg, time, addr, port|
    var r = msg[1].asFloat;
    var g = msg[2].asFloat;
    var b = msg[3].asFloat;

    // Update current color
    ~currentColor = (r: r, g: g, b: b);

    ["Color changed:", r, g, b].postln;
}, '/color');

// Start the OSC server on port 57120 (default SuperCollider port)
thisProcess.openUDPPort(57120);
"OSC server ready on port 57120".postln;
"Registered OSC commands: /touch, /pen, /color".postln;
"Ready to receive data from iDraw OSC app".postln;
)