/***************************************************************************
                          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 implementacin 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 vaca.
    */
    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 vaca 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 posicin.
    */
    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 posicin index. No se controla que
      el ndice parmetro pertenezca a la lista.
    */
    Result insert(Index * index, Object * obj);

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

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

    /**
      Vaca 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 prximo 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 posicin 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


