// Lista.h
// Declaração da classe cLista    ( Lista de Alunos )
// Lista Duplamente Ligada

// Aulas de 11 e 17 de Janeiro de 2002


template<class cELEMLISTA>
class cLista
{
protected :

	int NrElementos;
	cELEMLISTA *SentinelaInicio;	// ponteiro para o elemento de controle no inicio da lista
	cELEMLISTA *SentinelaFim;	    // ponteiro para o elemento de controle no fim da lista
	cELEMLISTA *Tail;
	
public :
	cLista();
	~cLista();   // destrutor
	
	bool Inserir( cAluno Al  );				// Inserção no fim
	bool Remover( cAluno Al  );				// Remove o aluno Nr 'NrAl'	
	cAluno *Obter( int pos );               // Obtem o aluno que está na posição 'pos'
	int GetNrElementos();					// Retorna o nr de elementos da lista

private :
	bool Procurar( cAluno Al, cELEMLISTA* &pEl , cELEMLISTA* &pAnterior );
};


template<class cELEMLISTA>
cLista<cELEMLISTA>::cLista()
{
	NrElementos = 0;
	
	SentinelaInicio  = new cELEMLISTA();    // Cria o elemento de controle no inicio da lista   
	SentinelaFim     = new cELEMLISTA();	// Cria o elemento de controle no fim da lista   

	SentinelaInicio->Ligacao( SentinelaFim );
	Tail = SentinelaInicio;
}

template<class cELEMLISTA>
cLista<cELEMLISTA>::~cLista()
{
	cELEMLISTA *p, *pNext;

	for ( p=SentinelaInicio; p ;  )
	{
		pNext = p->GetProximo();
		delete p;
		p = pNext;
	}
}

template<class cELEMLISTA>
int cLista<cELEMLISTA>::GetNrElementos()
{
	return NrElementos;
}


template<class cELEMLISTA>
bool cLista<cELEMLISTA>::Inserir( cAluno Al )
{
	cELEMLISTA *pNovo;
	
	pNovo = new cELEMLISTA();

	pNovo->Aluno  = Al;
	
	
	Tail->Ligacao( pNovo );				 // Liga o último elem. ao novo
	pNovo->Ligacao(SentinelaFim);		 // Liga o novo á sentinela fim
	Tail = pNovo;

	
	NrElementos ++;
	return true;
}

template<class cELEMLISTA>
bool cLista<cELEMLISTA>::Remover(  cAluno Al  )
{
	cELEMLISTA *p, *pAnt;
	bool Encontrou;

	if ( NrElementos == 0 ) return false;  // Se a lista estiver vazia ...
	
	Encontrou = Procurar( Al, p,  pAnt );

	if ( !Encontrou ) return false;

	pAnt->Ligacao( p->GetProximo() );
	
	delete p;

	NrElementos --;
	return true;
}

template<class cELEMLISTA>
cAluno *cLista<cELEMLISTA>::Obter( int pos )    //  0<= pos <= NrElementos 
{
	if ( pos < 0 || pos > NrElementos ) return 0;

	int i;
	cELEMLISTA *p;


	for ( i=1, p=SentinelaInicio->GetProximo() ; i < pos; i++, p=p->GetProximo() ) ;


	cElemListaSimples *ps = p->GetProximo();
	

	return &(p->Aluno) ;
}

template<class cELEMLISTA>
bool cLista<cELEMLISTA>::Procurar( cAluno Al,  cELEMLISTA* &pEl ,cELEMLISTA* &pAnterior )
{
	cELEMLISTA *p, *pAnt;

	pAnt = SentinelaInicio;
	p = SentinelaInicio->GetProximo() ;

	while ( p!=SentinelaFim &&  ! ( Al == p->Aluno ) )
	{
		pAnt = p;
		p = p->GetProximo() ;
	}

	pAnterior = pAnt;
	pEl = p;
	
	return ( p != SentinelaFim );
}




