/*
 * WARNING: This file is auto-generated by Renardo.
 * DO NOT MODIFY MANUALLY - any changes will be overwritten automatically!
 * To customize SuperCollider settings, modify your Renardo settings instead.
 */

Renardo {
    classvar server;
    classvar midiout;

    *configure {
        arg remote = false;
        {% if use_default_server %}
        // Use the default SuperCollider server (port 57110)
        server = Server.default;
        {% else %}
        // Create a custom server with the specified port using NetAddr
        server = Server(\renardo, NetAddr("127.0.0.1", {{ osc_port }}));
        {% endif %}
        server.options.memSize = 8192 * 16;
        server.options.maxNodes = 1024 * 32;
        server.options.numOutputBusChannels = {{ num_output_channels }};
        server.options.numInputBusChannels = {{ num_input_channels }};
        if (remote, {
            server.options.bindAddress = "0.0.0.0"; // allow connections from any address
        });
    }

    *oscAddSynthDefFromFile {
        OSCFunc(
            func: {
                arg msg, time, addr, port;
                var fn;
                // Get local filename
                fn = msg[1].asString;
                // Print a message to the user
                ("Loading SynthDef from" + fn).postln;
                // Add SynthDef to file
                fn = File(fn, "r");
                fn.readAllString.interpret;
                fn.close;
            },
            path: 'foxdot'
        );

        OSCFunc(
            func: {
                arg msg, time, addr, port;
                var fn;
                // Get local filename
                fn = msg[1].asString;
                // Print a message to the user
                ("Loading SynthDef from" + fn).postln;
                // Add SynthDef to file
                fn = File(fn, "r");
                fn.readAllString.interpret;
                fn.close;
            },
            path: 'add-synthdef-file'
        );
    }

    *oscAddSynthDefFromCode {
        OSCFunc(
            func: {
                arg msg, time, addr, port;
                var fn;
                // Get local filename
                fn = msg[1].asString;
                // Print a message to the user
                ("Loading SynthDef :" + fn).postln;
                // Add SynthDef to file
                fn = File(fn, "r");
                fn.readAllString.interpret;
                fn.close;
            },
            path: 'add-synthdef-code'
        );
    }

    *start {
        arg remote = false, audio_output_index = -1;
        this.configure(remote);

        // Set audio output device if specified
        if (audio_output_index >= 0, {
            server.options.device = ServerOptions.outDevices[audio_output_index];
            ("Using audio output device: " ++ ServerOptions.outDevices[audio_output_index]).postln;
        });

        server.boot();

        this.oscAddSynthDefFromFile;
        this.oscAddSynthDefFromCode;

        StageLimiterBis.activate(2);

        {% if use_default_server %}
        ("Renardo using default SuperCollider server on port " ++ server.addr.port).postln;
        {% else %}
        ("Listening for messages from Renardo on port " ++ {{ osc_port }}).postln;
        {% endif %}
    }

    *startRemote {
        arg audio_output_index = -1;
        this.start(true, audio_output_index);
    }

    *midi {
        arg port=0;
        MIDIClient.init;
        midiout = MIDIOut(port);
        OSCFunc(
            func: {
                arg msg, time, addr, port;
                var note, vel, sus, channel, nudge;
                // listen for specific MIDI trigger messages from FoxDot
                note    = msg[2];
                vel     = msg[3];
                sus     = msg[4];
                channel = msg[5];
                nudge   = msg[6];
                SystemClock.schedAbs(time + nudge, {midiout.noteOn(channel, note, vel)});
                SystemClock.schedAbs(time + nudge + sus, {midiout.noteOff(channel, note, vel)});
            },
            path: 'foxdot_midi'
        );
        ("Sending Renardo MIDI messages to" + MIDIClient.destinations[port].name).postln;
    }

    *listAudioDevices {
        "=== AUDIO DEVICES ===".postln;
        "".postln;

        "OUTPUT DEVICES:".postln;
        ("Number of Devices: " ++ ServerOptions.outDevices.size).postln;
        ServerOptions.outDevices.do({ |device, index|
            ("   " ++ index ++ " :  " ++ device).postln;
        });

        "".postln;
        "INPUT DEVICES:".postln;
        ("Number of Devices: " ++ ServerOptions.inDevices.size).postln;
        ServerOptions.inDevices.do({ |device, index|
            ("   " ++ index ++ " :  " ++ device).postln;
        });
    }

    *listAudioDevicesJson {
        var outDevices, inDevices;
        outDevices = Dictionary.new;
        inDevices = Dictionary.new;

        ServerOptions.outDevices.do({ |device, index|
            outDevices.put(index, device);
        });

        ServerOptions.inDevices.do({ |device, index|
            inDevices.put(index, device);
        });

        "RENARDO_AUDIO_DEVICES_START".postln;
        ("OUT:" ++ outDevices.asCompileString).postln;
        ("IN:" ++ inDevices.asCompileString).postln;
        "RENARDO_AUDIO_DEVICES_END".postln;
    }
}
