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

    This file was generated by user!

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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#include <synth/synth_defs.h>
#include "JaySynthMonophonicMGR.h"

/** A JaySynth voice that just plays incredible sounds.. */
JaySynthMonophonicMGR::JaySynthMonophonicMGR()
{
	init();
}

JaySynthMonophonicMGR::~JaySynthMonophonicMGR()
{
}

void JaySynthMonophonicMGR::init(void)
{
	int i;

	memset (keys, 0, sizeof(keys));
	for (i=0; i < 128; i++)
		keys[i].note = i;

	pLatest = NULL;
}

void JaySynthMonophonicMGR::add(int note, float vel)
{
	if ((note < 0) || (note > 127))
		return;

	// Delete if velocity == 0
	if (vel == 0)
	{
		del(note);
		return;
	}

	// Delete first if note already exists
	if (keys[note].vel > 0)
		del(note);

	// Add key
	keys[note].vel = vel;

	keys[note].pPrev = NULL;
	keys[note].pNext = pLatest;

	if (pLatest)
		pLatest->pPrev = &keys[note];

	pLatest = &keys[note];

}

void JaySynthMonophonicMGR::del(int note)
{
	if ((note < 0) || (note > 127))
		return;

	if (keys[note].pPrev)
		keys[note].pPrev->pNext = keys[note].pNext;

	if (keys[note].pNext)
		keys[note].pNext->pPrev = keys[note].pPrev;

	// Do I delete the newest note
	if (!keys[note].pPrev)
		pLatest = keys[note].pNext;

	keys[note].vel = 0;
	keys[note].pPrev = NULL;
	keys[note].pNext = NULL;

}

int JaySynthMonophonicMGR::getNumNotes(void)
{
	key_linkedlist_t *pKey = pLatest;
	int num_notes = 0;

	while(pKey)
	{
		num_notes++;
		pKey = pKey->pNext;
	}

	return num_notes;

}

int JaySynthMonophonicMGR::getLatestNote(void)
{
	if (!pLatest)
		return -1;

	return pLatest->note;
}

int JaySynthMonophonicMGR::getHighestNote(void)
{
	key_linkedlist_t *pKey = pLatest;
	int note = -1;

	while(pKey)
	{
		if (note < pKey->note)
			note = pKey->note;

		pKey = pKey->pNext;
	}

	if (note < 0)
		return -1;

	return keys[note].note;
}

float JaySynthMonophonicMGR::getVel(int note)
{
	if ((note < 0) || (note > 127))
		return 0;

	return keys[note].vel;
}
