//================================================================================
//================================================================================
//================================================================================
//==============================the object========================================
//================================================================================
//================================================================================
//================================================================================

typedef struct noidea_env
{
	void * self;

	NOIDEA_memory * env;
	void * (*alloc)(struct noidea_env*,int);
	void (*free) (struct noidea_env * , void * );

	NOIDEA_node * list;
	NOIDEA_node * (*append) (struct noidea_env * ,int);
	void (*remove) (struct noidea_env * ,NOIDEA_node*);
	void * (*next) (struct noidea_env * );

	NOIDEA_node * thread;
	NOIDEA_node * (*start) (struct noidea_env * ,void (*)(void),signed long int);
	void (*stop) (struct noidea_env * , NOIDEA_node *);
	signed long int (*loop) (struct noidea_env *, signed long int );

}noidea_env;
void * noidea_alloc(noidea_env* noidea_self,int size){	return NOIDEA_alloc(noidea_self->env,size);}
void noidea_free(noidea_env* noidea_self, void * ptr){	NOIDEA_free(noidea_self->env,ptr);}

typedef NOIDEA_node noidea_nod;
NOIDEA_node * noidea_append(struct noidea_env * noidea_self ,int noidea_size)
{	void * noidea_mem = noidea_alloc(noidea_self,sizeof(NOIDEA_node)+noidea_size);
	return NOIDEA_create(noidea_self->list,noidea_mem + sizeof(NOIDEA_node),noidea_mem);
}
void noidea_remove(struct noidea_env * noidea_self, NOIDEA_node * noidea_nud){	noidea_free(noidea_self,NOIDEA_destroy(noidea_self->list,noidea_nud));}
void * noidea_next(struct noidea_env * noidea_self){	NOIDEA_loop(noidea_self->list);}

void noidea_rien(void){}
NOIDEA_node * noidea_start (struct noidea_env * noidea_self,void (*noidea_func)(void),signed long int noidea_when){	return NOIDEA_schedule(noidea_self->thread,noidea_func,noidea_when,noidea_alloc(noidea_self,sizeof(NOIDEA_node)+sizeof(NOIDEA_agenda)));}
void noidea_stop (struct noidea_env * noidea_self, NOIDEA_node * noidea_thread){	NOIDEA_free(noidea_self->env,NOIDEA_cancel(noidea_self->thread,noidea_thread));}
signed long int noidea_loop (struct noidea_env * noidea_self, signed long int noidea_now){	return NOIDEA_do(noidea_self->thread,noidea_now);}

noidea_env * noidea_init(void * ptr, int size)
{
	noidea_env * self = (noidea_env*) ptr;
	self->self = self;

	self->env = NOIDEA_seg(ptr + sizeof(noidea_env),size - sizeof(noidea_env));
	self->alloc = noidea_alloc;
	self->free =  noidea_free;

	self->list = NOIDEA_create(0,ptr,noidea_alloc(self,sizeof(NOIDEA_node)));
	self->append = noidea_append;
	self->remove = noidea_remove;
	self->next = noidea_next;

	self->thread = NOIDEA_schedule(0,&noidea_rien,1000000,noidea_alloc(self,sizeof(NOIDEA_node)+sizeof(NOIDEA_agenda)));
	self->start = noidea_start;
	self->stop = noidea_stop;
	self->loop = noidea_loop;

	return self;
}
