#include <stdlib.h>

//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================

float AVRIDLE;

typedef struct noidle {
	float jump;
	float last;
	float next;
	float idle;
	struct noidle *precedant;
	struct noidle *suivant;
	void (*funcptr) (void);
} NOiD_iDLE;

typedef struct noidlist {
	struct noidle *premier;
	struct noidle *dernier;
} NOiD_iDLE_LiST;

//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================
float lastsecond, sumidle;

float NOiD_iDLE_loop(float time, NOiD_iDLE_LiST * ceuxci)
{
	if (ceuxci == NULL)
	{
		return 0;
	}
	float wait;
	if ((ceuxci->premier != NULL)&&(ceuxci->dernier != NULL))
	{
		NOiD_iDLE * ceci = ceuxci->premier;
		while (ceci != NULL)
		{
			if (ceci->next <= time)
			{
				if (ceci->funcptr != NULL)
				{
					//ceci->last = ceci->next;
					ceci->next = time + ceci->jump;
					ceci->idle = 0;
					wait = 0;
					ceci->funcptr();
				}
			} else {
				ceci->idle = ceci->next - time;
				if (ceci->idle <= wait)
				{	wait = ceci->idle;	}
			}
			ceci = ceci->suivant;
		}
	}
	if (AVRIDLE >= (lastsecond+1))
	{
		AVRIDLE = sumidle;
		sumidle = 0;	
	}
	sumidle += wait;
	return wait;
}

//================================================================================================
//================================================================================================
//================================================================================================

NOiD_iDLE * NOiD_iDLE_create(float interval,void (*function)(void), NOiD_iDLE_LiST * ceuxci)
{
	if (ceuxci == NULL)
	{
		return NULL;
	} else {
		NOiD_iDLE * ceci;
		if ((ceuxci->premier == NULL)&&(ceuxci->dernier == NULL))
		{
			ceci = malloc(sizeof(NOiD_iDLE));
			ceci->precedant = NULL;
			ceci->suivant = NULL;
			ceuxci->premier = ceci;
			ceuxci->dernier = ceci;
			ceci->jump = interval;
			ceci->next = 0;
			ceci->idle = 0;
			ceci->funcptr = function;
		} else {
			if (ceuxci->premier == ceuxci->dernier)
			{
				ceci = malloc(sizeof(NOiD_iDLE));
				ceuxci->dernier = ceci;
				ceuxci->dernier->precedant = ceuxci->premier;
				ceuxci->dernier->suivant = NULL;
				ceuxci->premier->precedant = NULL;
				ceuxci->premier->suivant = ceuxci->dernier;
				ceci->jump = interval;
				ceci->next = 0;
				ceci->idle = 0;
				ceci->funcptr = function;
			} else {
				if (ceuxci->dernier->suivant == NULL)
				{
					ceci = malloc(sizeof(NOiD_iDLE));
					ceci->precedant = ceuxci->dernier;
					ceci->suivant = NULL;
					ceuxci->dernier->suivant = ceci;
					ceuxci->dernier = ceci;
					ceci->jump = interval;
					ceci->next = 0;
					ceci->idle = 0;
					ceci->funcptr = function;
				}
			}
		}
	return ceci;
	}
}

//================================================================================================
//================================================================================================
//================================================================================================

void NOiD_iDLE_destroy(NOiD_iDLE *ceci, NOiD_iDLE_LiST * ceuxci)
{
	if (ceuxci == NULL)
	{
		return;
	}

	if (ceci != NULL)
	{
		if (ceuxci->premier == ceuxci->dernier)
		{
			ceuxci->premier = NULL;
			ceuxci->dernier = NULL;
			free(ceci);
		} else {
			if (ceci->precedant == NULL)
			{
				ceci->suivant->precedant = NULL;
				ceuxci->premier = ceci->suivant;
				free(ceci);
				return;
			}
			if (ceci->suivant == NULL)
			{
				ceci->precedant->suivant = NULL;
				ceuxci->dernier = ceci->precedant;
				free(ceci);
				return;
			}
			ceci->precedant->suivant = ceci->suivant;
			ceci->suivant->precedant = ceci->precedant;
			free(ceci);
			return;

		}
	}
}

//================================================================================================
//================================================================================================
//================================================================================================

NOiD_iDLE_LiST * NOiD_iDLE_createLiST(void)
{
	NOiD_iDLE_LiST *genda;
	genda = malloc(sizeof(genda));
	return genda;
}

//================================================================================================
//================================================================================================
//================================================================================================

void NOiD_iDLE_freeLiST(NOiD_iDLE_LiST *  genda)
{
	if ((genda->premier != NULL)&&(genda->premier != NULL))
	{
		if (genda->premier == genda->dernier)
		{
			NOiD_iDLE_destroy(genda->premier, genda);
		} else {
			NOiD_iDLE * ceci = genda->premier;
			while (ceci != NULL)
			{
				NOiD_iDLE * ca = ceci;
				ceci = ceci->suivant;
				NOiD_iDLE_destroy(ca, genda);
			}
		}
		free(genda);
		genda = NULL;
	}
}

