#pragma once
//array ciclico (al aņadir si no entran mas tira por detras)
template <typename T>
class Cgarray_cicli
{
public:
	//variables-----------------------------------------------------
	int max_elem;//indica el maximo de elementos que puede almacenar
	int n;//indica el numero de elementos almacenados
	int m;//capacidad actual del array
	int ini;//indice al primer elemento;
	int increment;	//incremento para pedir memo
	T* ptr;   //array de elementos
	//c y d----------------------------------------------------------
	//*******************************************************
	Cgarray_cicli(void)
	{
		ptr=NULL;
		increment=100;
		ini=0;
		m=n=0;
		max_elem=0;
	};
	//*******************************************************
	~Cgarray_cicli(void)
	{
		if (ptr)
			free(ptr);
	};
	//*******************************************************
	inline BOOL inicia(int maxi)//inicia la lista poniendo el maximo de elementos que puede almacenar
	{
		if (maxi<=0)
			return FALSE;
		max_elem=maxi;
		n=0;
		ini=0;
		if (ptr)
			free(ptr);
		ptr=(T*)malloc(sizeof(T)*m);
		if (!ptr)
		{
			max_elem=0;
			return FALSE;
		}
		return TRUE;
	};
	//*******************************************************
	inline T* operator[](int i)//da el elemento i-esimo
	{ 
		if (max_elem<=0 || i<=0 || i>=n)
			return NULL;
		return &ptr[(ini+i)%max_elem];
	};
	//*******************************************************
	inline BOOL operator+(T &e )//aņade nuevo elemento
	{ 
		if (max_elem<=0|| !ptr)
			return FALSE;
		if (n==max_elem)//esta lleno, pone al inicio-----
		{
			memcpy(&ptr[ini],&e,sizeof(T));
			ini=(ini+1)%max_elem;
			return TRUE;
		}
		//revisa memoria---------------------------------
		if (m<n+1)
		{
			m+=increment;
			if (ptr)
				ptr=(T*)realloc(ptr,sizeof(T)*m);
			else
				ptr=(T*)malloc(sizeof(T)*m);
			if (!ptr)
			{
				m=n=ini=0;
				return FALSE;
			}
			memset(&ptr[m-increment],0,increment);
		}
		//copia al final---------------------------------
		memcpy(&ptr[(ini+n)%max_elem],&e,sizeof(T));
		n++;
		return TRUE ;
	};
	//*******************************************************
	inline void borra()//borra los elementos (no livera memoria)
	{
		m=n=ini=0;
		if (ptr)
			free(ptr);
		ptr=NULL;
	};
	//*******************************************************
};
