
#include "Noise.hpp"

void Noise::processAll(const ProcessArgs& args) {
	for (int i = 0; i < _polyChannels; ++i) {
		if (outputs[BLUE_OUTPUT].isConnected()) {
			outputs[BLUE_OUTPUT].setChannels(_polyChannels);
			outputs[BLUE_OUTPUT].setVoltage(clamp(_blue.next() * 20.0f, -10.0f, 10.f), i);
		}
		if (outputs[WHITE_OUTPUT].isConnected()) {
			outputs[WHITE_OUTPUT].setChannels(_polyChannels);
			outputs[WHITE_OUTPUT].setVoltage(clamp(_white.next() * 10.0f, -10.0f, 10.f), i);
		}
		if (outputs[PINK_OUTPUT].isConnected()) {
			outputs[PINK_OUTPUT].setChannels(_polyChannels);
			outputs[PINK_OUTPUT].setVoltage(clamp(_pink.next() * 15.0f, -10.0f, 10.f), i);
		}
		if (outputs[RED_OUTPUT].isConnected()) {
			outputs[RED_OUTPUT].setChannels(_polyChannels);
			outputs[RED_OUTPUT].setVoltage(clamp(_red.next() * 20.0f, -10.0f, 10.f), i);
		}
		if (outputs[GAUSS_OUTPUT].isConnected()) {
			outputs[GAUSS_OUTPUT].setChannels(_polyChannels);
			outputs[GAUSS_OUTPUT].setVoltage(clamp(_gauss.next(), -10.0f, 10.f), i);
		}
	}

	int n = inputs[ABS_INPUT].getChannels();
	outputs[ABS_OUTPUT].setChannels(n);
	for (int i = 0; i < n; ++i) {
		float in = inputs[ABS_INPUT].getPolyVoltage(i);
		if (in < 0.0) {
			in = -in;
		}
		outputs[ABS_OUTPUT].setVoltage(in, i);
	}
}

struct NoiseWidget : BGModuleWidget {
	static constexpr int hp = 3;

	NoiseWidget(Noise* module) {
		setModule(module);
		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
		setPanel(box.size, "Noise");
		createScrews();

		// generated by svg_widgets.rb
		auto absInputPosition = Vec(10.5, 253.0);

		auto blueOutputPosition = Vec(10.5, 24.0);
		auto whiteOutputPosition = Vec(10.5, 65.0);
		auto pinkOutputPosition = Vec(10.5, 106.0);
		auto redOutputPosition = Vec(10.5, 147.0);
		auto gaussOutputPosition = Vec(10.5, 188.0);
		auto absOutputPosition = Vec(10.5, 291.0);
		// end generated by svg_widgets.rb

		addInput(createInput<Port24>(absInputPosition, module, Noise::ABS_INPUT));

		addOutput(createOutput<Port24>(blueOutputPosition, module, Noise::BLUE_OUTPUT));
		addOutput(createOutput<Port24>(whiteOutputPosition, module, Noise::WHITE_OUTPUT));
		addOutput(createOutput<Port24>(pinkOutputPosition, module, Noise::PINK_OUTPUT));
		addOutput(createOutput<Port24>(redOutputPosition, module, Noise::RED_OUTPUT));
		addOutput(createOutput<Port24>(gaussOutputPosition, module, Noise::GAUSS_OUTPUT));
		addOutput(createOutput<Port24>(absOutputPosition, module, Noise::ABS_OUTPUT));
	}

	void contextMenu(Menu* menu) override {
		auto m = dynamic_cast<Noise*>(module);
		assert(m);
		menu->addChild(new PolyChannelsMenuItem(m));
	}
};

Model* modelNoise = bogaudio::createModel<Noise, NoiseWidget>("Bogaudio-Noise", "NOISE", "Noise source", "Noise", "Random", "Polyphonic");
