/*
 * Instituto Superior de Engenharia do Porto
 *
 * Estruturas de Informação
 *
 * 2000/2001
 *
 * ------------------------------------------
 *
 * Classe de Lista de Inteiros (LIFO)
 *
 * listaint.cpp
 *
 */

#include <iostream.h>
#include "listaint.h"
#include "..\ei-include\erro.h"

ListaInteiros::ListaInteiros()
{
	m_pInicio = NULL;
	m_nCount = 0;
}

ListaInteiros::ListaInteiros(const ListaInteiros& o)
{
	m_pInicio = NULL;
	m_nCount = 0;
	copia(*this, o.m_pInicio);
}

ListaInteiros& ListaInteiros::operator=(const ListaInteiros& o)
{
	removerTodos();
	copia(*this, o.m_pInicio);
	return *this;
}

void ListaInteiros::copia(ListaInteiros& l, const ListaInteiros::NoInteiro* p)
{
	// caso terminal
	if (p == NULL)
		return;

	//caso geral
	copia(l, p->m_pProx);
	l.inserir(p->m_nConteudo);
}


ListaInteiros::~ListaInteiros()
{
	removerTodos();
}

void ListaInteiros::removerTodos()
{
	while (!vazia())
		retirar();
}

bool ListaInteiros::inserir(int iValor)
{
	NoInteiro* pNo = new NoInteiro(iValor, m_pInicio);
	//pNo->m_nConteudo = iValor;
	//pNo->m_pProx = m_pInicio;
	m_pInicio = pNo;

	return true;
}

int ListaInteiros::retirar()
{
	if (vazia())
		throw Erro(ERRO_GENERICO);

	int v = m_pInicio->m_nConteudo;
	NoInteiro* p = m_pInicio;
	m_pInicio = m_pInicio->m_pProx;

	delete p;

	return v;
}

bool operator==(const ListaInteiros& a, const ListaInteiros& b)
{
	if (a.comprimento() != b.comprimento())
		return false;

	ListaInteiros::NoInteiro* p1 = a.m_pInicio;
	ListaInteiros::NoInteiro* p2 = b.m_pInicio;
	while(p1 != NULL)
	{
		if (p1->m_nConteudo != p2->m_nConteudo)
			return false;

		p1 = p1->m_pProx;
		p2 = p2->m_pProx;
	}
	return true;
}

ListaInteiros operator+(const ListaInteiros& a, const ListaInteiros& b)
{
	ListaInteiros laux(a);

	ListaInteiros::copia(laux, b.m_pInicio);

	return laux;
}

ostream& operator<<(ostream& output, const ListaInteiros& obj)
{
	output << "[";
	for (ListaInteiros::NoInteiro* p = obj.m_pInicio; p != NULL; p = p->m_pProx)
	{
		output << p->m_nConteudo;
		if (p->m_pProx != NULL)
			output << ", ";
	}
	output << "]";
	return output;
}
