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

#ifndef LIST_H
#define LIST_H

#include "object.h"

/**
  Clase de implementación de vagones de lista doblemente enlazada.
*/

class Index: public Object{

  public:

    Index(Object * obj);
    ~Index();
    Object * getObject();
    Index * getNext();
    Index * getPrev();
    void setNext(Index * index);
    void setPrev(Index * index);

  private:

    Object * obj;
    Index * next;
    Index * prev;
};

/**
  Lista doblemente enlazada.
*/

class List : public Object{

  public:

    enum Result {Inserted, Removed, NullIndex, EmptyList,
                 InvalidIndex, NotFound, OutOfRange};

    /** Constructor default.*/
    List();

    /** Destructor.*/
    ~List();

    /**
      @return true si la lista esta vacía.
    */
    bool isEmpty();

    /**
      @return el primer índice de la lista.
    */
    Index * getFirst();

    /**
      @return el último índice de la lista.
    */
    Index * getLast();

    /**
      @return el final de la lista. Si la lista está vacía getFirts(),
      getLast() y getEnd retornan el mismo valor.
    */
    Index * getEnd();

    /**
      @return el índice asociado al objeto obj. Si el objeto no está en la
      lista retorna NULL.
    */
    Index * indexOf(Object * obj);

    /**
      @return el índice asociado a la posición.
    */
    Index * indexOf(int i);

    /**
      @return la posicion del objeto obj.
    */
    int positionOf(Object * obj);

    /**
      @return true si index es el final de la lista.
    */
    bool isEnd(Index * index);

    /**
      Inserta el objeto obj en la posición index. No se controla que
      el índice parámetro pertenezca a la lista.
    */
    Result insert(Index * index, Object * obj);

    /**
      Inserta el objeto obj en la posición i.
    */
    Result insert(int i, Object * obj);

    /**
      Elimina de la lista el elemento en la posición index.
      Hace un delete si del es true.
    */
    Result remove(Index * index, bool del=false);

    /**
      Vacía la lista. Si del es true hace un delete de todos los objetos.
    */
    void empty(bool del=true);

    /**
      @param index Un índice distinto de NULL y de getEnd().
      @return el próximo index del dado. Si index es el final retorna NULL.
    */
    Index * getNext(Index * index);

    /**
      @param index Un índice distinto de NULL y de getEnd().
      @return el índice anterior al dado. Si index es el primero retorna NULL.
    */
    Index * getPrev(Index * index);

    /**
      @param index Un índice distinto de NULL y de getEnd().
      @return el objeto en la posición index.
    */
    Object * getObject(Index * index);

    /**
      @retorna la cantidad de objetos en la lista.
    */
    int nObjects();

  private:

    Index * thelist;
    int count;
    Index * thelast;
    Index * indexOf(Object * obj, int& i);
};

#endif


