#ifndef OBSERVABLE_H
#define OBSERVABLE_H
#include <list>
#include <map>
#include <set>

class Observable;

/** @name Observer-Observable
* 
*/


//=========================================================
/**Toutes les instances de cette classe peuvent observer une 
 *instance de la classe Observable.
 *@see Observable
 *@type interface
 */
class Observer
{
 public:
  virtual ~Observer() {}
  /**
   * @memo Méthode indiquant l'ensemble des Observable modifiés.
   * @doc Méthode indiquant l'ensemble des Observable modifiés. 
   * @param begin Iterateur positionné sur le premier élément de l'ensemble.
   * @param end Iterateur positionné sur le dernier élément de l'ensemble.
   */
  virtual void update(std::set<Observable *>::iterator begin ,std::set<Observable *>::iterator end)=0;
};

typedef std::map<Observer *,std::set<Observable *> > ObserverMap;

//=========================================================
/**Toutes les instance de cette classe peuvent être observer 
 *par une instance de la classe Observer. 
 *@see Observer
 */
class Observable
{
 protected:
  static int holdCounter;
  static ObserverMap holdMap;
  std::list<Observer*> observersList;
 public:
  virtual ~Observable() {}
  ///Enregistre l'observeur.
  void addObserver(Observer *);
  ///Renvoie le nombre d'observeur.
  unsigned int countObservers();
  ///Retire l'observeur.
  void deleteObserver(Observer *);
  ///Retire tous les Observeurs.
  void deleteObservers();
  ///Notifie tous les observeurs.
  void notifyObservers();
  ///Commute l'observable dans le mode différé
  static void holdObservers();
  ///Commute l'observeur dans le mode non différé
  static void unholdObservers();
};


inline void Observable::addObserver(Observer *obs)
{  observersList.push_back(obs); }

inline unsigned int Observable::countObservers()
{ return observersList.size(); }

inline void Observable::deleteObserver(Observer *item)
{  observersList.remove(item);}

inline void Observable::deleteObservers()
{ observersList.clear(); }

#endif












