/*
  ==============================================================================

    This file was auto-generated!

    It contains the basic startup code for a Juce application.

  ==============================================================================
*/

#ifndef _JAYSYNTH_MIDICC_
#define _JAYSYNTH_MIDICC_

#include <JuceHeader.h>

#include <synth/synth_defs.h>
#include <synth/voice.h>
#include <synth/vco.h>
#include <synth/noise.h>
#include <synth/smooth.h>
#include <synth/vcf.h>
#include <synth/lfo.h>
#include <synth/env.h>
#include <synth/param_scale.h>

//==============================================================================
#define	MIDICONTROLLER_TYPE_VELKEY		0x00000080

typedef struct midiCC_container_t
{
	int controllerID;
	bool isAssigned;
	bool doChangeParameter;
	bool doApplyOnPatchInit;
	param_info_t constraints;
	param_info_t control;
	param_info_t param;
	bool isVelAssigned;
	bool isKeyAssigned;
	param_info_t curve_vel;
	param_info_t curve_key;
	int velKeyCombineOP;
	LinkedListPointer<midiCC_container_t> nextListItem;
} midiCC_container_t;

class JaySynthMidiCC
{
public:

	JaySynthMidiCC();
	~JaySynthMidiCC();

    JaySynthMidiCC& operator= (JaySynthMidiCC& other);
	void copyMidiCC(JaySynthMidiCC const *pSrc);
	bool isMidiCCmodified(void) const;
	String toParameterNameXML (String const &name) const;
	int findParamID_byName(String name);
	void export_midi_cc(XmlElement *pXML_doc) const;
	int import_midi_cc(XmlElement const *pXML_doc);
	void export_midi_velkey(XmlElement *pXML_doc) const;
	int import_midi_velkey(XmlElement const *pXML_doc);
	int import_midi_cc_legacy(XmlElement const *pXML_doc);
	void add(midiCC_container_t *pObj, int controllerID);
	void remove(midiCC_container_t *pObj, int controllerID);
	struct midiCC_container_t* getAtParamID(int paramID);
	int getNumDestinations(int controllerID);
	void removeDestinations(int controllerID);
	midiCC_container_t* getDestination(int controllerID, int index);
	int getParamID(midiCC_container_t *pObj);
	int getControllerID(midiCC_container_t *pObj);
	void setControllerID(midiCC_container_t *pObj, int controllerID);
	bool isAssigned(midiCC_container_t *pObj);
	void setDoChangeParameter(midiCC_container_t *pObj, bool doChangeParameter);
	bool doChangeParameter(midiCC_container_t *pObj);
	void setDoApplyOnPatchInit(midiCC_container_t *pObj, bool doApplyOnPatchInit);
	bool doApplyOnPatchInit(midiCC_container_t *pObj);
	synth_float_t getConstraintsMin(midiCC_container_t *pObj);
	synth_float_t getConstraintsMax(midiCC_container_t *pObj);
	param_info_t* getConstraints(midiCC_container_t *pObj);
	synth_float_t getControlMin(midiCC_container_t *pObj);
	void setControlMin(midiCC_container_t *pObj, synth_float_t value);
	synth_float_t getControlMax(midiCC_container_t *pObj);
	void setControlMax(midiCC_container_t *pObj, synth_float_t value);
	param_info_t* getControl(midiCC_container_t *pObj);
	synth_float_t getParamMin(midiCC_container_t *pObj);
	void setParamMin(midiCC_container_t *pObj, synth_float_t value);
	synth_float_t getParamMax(midiCC_container_t *pObj);
	void setParamMax(midiCC_container_t *pObj, synth_float_t value);
	param_info_t* getParam(midiCC_container_t *pObj);
	param_info_t* getVelCurve(midiCC_container_t *pObj);
	void setVelCurveMin(midiCC_container_t *pObj, synth_float_t value);
	void setVelCurveMax(midiCC_container_t *pObj, synth_float_t value);
	void setVelCurveSkew(midiCC_container_t *pObj, synth_float_t value);
	void setVelCurveShape(midiCC_container_t *pObj, synth_float_t value);
	param_info_t* getKeyCurve(midiCC_container_t *pObj);
	void setKeyCurveMin(midiCC_container_t *pObj, synth_float_t value);
	void setKeyCurveMax(midiCC_container_t *pObj, synth_float_t value);
	void setKeyCurveSkew(midiCC_container_t *pObj, synth_float_t value);
	void setKeyCurveShape(midiCC_container_t *pObj, synth_float_t value);
	bool isAssignedVel(midiCC_container_t *pObj);
	bool isAssignedKey(midiCC_container_t *pObj);
	void setAssignedVel(midiCC_container_t *pObj, bool active);
	void setAssignedKey(midiCC_container_t *pObj, bool active);
	int getVelKeyCombineOP(midiCC_container_t *pObj);
	void setVelKeyCombineOP(midiCC_container_t *pObj, int combineOP);
	bool isAssignedVelKeyControl(int paramID);
	synth_float_t getVelKeyControl(int paramID, synth_float_t vel, synth_float_t key);

	enum
	{
		VELKEY_OP_ADD = 0,
		VELKEY_OP_SUB,
		VELKEY_OP_MUL,
		VELKEY_NUM_OPS
	};

private:
	midiCC_container_t midiCC_containers[SYNTH_NUM_PARAMS];
	LinkedListPointer <midiCC_container_t> midiCC_dest[NUM_MIDI_CONTROLLERS];
	NamedValueSet paramNamedValueSet;
	bool isModified;

};

#endif  // _JAYSYNTH_MIDICC_
