/***************************************************************************
                          list.cpp  -  description
                             -------------------
    begin                : Fri Apr 14 2000
    copyright            : (C) 2000 by W. Baraldi & D. Scarpa
    email                : baraldi@lacasilla.com.ar
 ***************************************************************************/

#include <stdio.h>
#include "list.h"

Index::Index(Object * obj){
  next=prev=NULL;
  this->obj=obj;
}

Index::~Index(){}

Object * Index::getObject(){
  return obj;
}

Index * Index::getNext(){
  return next;
}

Index * Index::getPrev(){
  return prev;
}

void Index::setNext(Index * index){
  next=index;
}

void Index::setPrev(Index * index){
  prev=index;
}

List::List(){
  thelist=thelast=NULL;
  count=0;
}

List::~List(){}

bool List::isEmpty(){
  return (!thelist);
}

Index * List::getFirst(){
  return thelist;
}

Index * List::getLast(){
  return thelast;
}

Index * List::getEnd(){
  return NULL;
}

Index * List::indexOf(Object * obj, int& i){
  Index * index=getFirst();
  i=0;
  while (index != getEnd()){
    if (getObject(index)==obj) return index;
    index=getNext(index);
    i++;
  }
  return NULL;
}

Index * List::indexOf(Object * obj){
  int none;

  return indexOf(obj, none);
}

Index * List::indexOf(int i){
  Index * index=getFirst();
  int h;

  while ((h<i) && (index!=getEnd()))
    index=getNext(index);
  return index;
}

int List::positionOf(Object * obj){
  int none;

  indexOf(obj, none);
  return none;
}

bool List::isEnd(Index * index){
  return (!index);
}

List::Result List::insert(Index * index, Object * obj){

  Index * w=new Index(obj);

  if (isEmpty())	//inserción en la lista vacia
     thelist=thelast=w;
  else{
    if (!index) { //inserción en el último lugar
      w->setPrev(thelast);
      thelast->setNext(w);
      thelast=w;
    }
    else{
      w->setNext(index);
      w->setPrev(index->getPrev());
      index->setPrev(w);
      if (w->getPrev()) (w->getPrev())->setNext(w);
      else thelist=w;
    }
  }
  count++;
  return Inserted;
}

List::Result List::insert(int i, Object * obj){

  return (insert(indexOf(i), obj));
}

List::Result List::remove(Index * index, bool del=false){
  if (isEmpty()) return EmptyList;
  if (!index) return NullIndex;

  if (!index->getNext()){
    if (!index->getPrev()){
       if (thelist==index){thelist=thelast=NULL;}
       else return InvalidIndex;
    }
    else{
      (index->getPrev())->setNext(NULL);
       thelast=index->getPrev();
    }
  }
  else{
    if (!index->getPrev()){
      (index->getNext())->setPrev(NULL);
       thelist=index->getNext();
    }
    else{
      (index->getNext())->setPrev(index->getPrev());
      (index->getPrev())->setNext(index->getNext());
    }
  }
  if (del) delete index->getObject();
  delete index;
  count--;
  return Removed;
}

void List::empty(bool del=true){
  while (!isEmpty())
    remove(getFirst(), del);
}

Index * List::getNext(Index  * index){
  return (index->getNext());
}

Index * List::getPrev(Index * index){
  return (index->getPrev());
}

Object * List::getObject(Index * index){
  return (index->getObject());
}

int List::nObjects(){
  return count;
}



