package ste.pendu.wordeditor;

import java.io.Serializable;
import java.io.IOException;
import java.util.Iterator;
import java.beans.PropertyChangeListener;
import java.util.List;

/**
 * Panier de mots pour jouer au Pendu.
 * 
 * <p>Cette interface défini la manière d'implémenter un WordListBean
 * (le bean (visuel) devra étendre javax.swing.JPanel). La fabrique de
 * contrôleurs attendra comme information cette interface pour pouvoir
 * construire un contrôleur.</p>
 * 
 * <p>Les classes implémentant cette interface contiendront un ensemble
 * de mots que le PenduBean pourrait appeler pour jouer. La classe devra
 * aussi être capable de récupérer les données qui auront été
 * sauvegardées sur un disque soit sous forme d'un fichier texte
 * (extension .txt), soit sous forme d'une instance sérialisée
 * (extension .ser).</p>
 * 
 * <p>Attention, il n'y a pas de doublon!</p>
 *
 * @see java.beans.PropertyChangeSupport
 * @see java.util.List
 * @see java.io.Serializable
 */
public interface WordListModel extends Serializable
{

  /**
   * Ajout d'un mot à une position précise.
   * 
   * @param index la position
   * @param mot le mot à ajouter
   */
  public void addWord(int index, String mot);

  /**
   * Ajout d'un mot à la suite.
   * 
   * @param mot le mot à ajouter
   * @return <code>true</code> comme le demande l'API Collection
   * @see java.util.List#add(Object)
   */
  public boolean addWord(String mot);

  /**
   * Efface tous les mots en mémoire.
   */
  public void clear();

  /**
   * Retourne le nombre de mots.
   * 
   * @return le nombre de mots
   */
  public int getWordListSize();

  /**
   * Retourne un tableau de tous les mots.
   * 
   * @return un tableau contenant tous les mots
   */
  public String[] getWords();

  /**
   * Retourne le mot à la position indiquée.
   * 
   * @param index la position du mot recherché
   * @return le mot à la position 'index'
   */
  public String getWord(int index);

  /**
   * Retourne l'index du mot passé en argument.
   * 
   * @param mot
   * @return l'index du mot recherché
   */
  public int indexOfWord(String mot);

  /**
   * État de sauvegarde des mots.
   * 
   * @return s'il n'y a eu aucune modification depuis la dernière
   * sauvegarde, la valeur retournée est <code>true</code>, mais s'il y
   * a eu une modification, la valeur retournée est <code>false</code>
   */
  public boolean isSaved();

  /**
   * Un iterateur sur tous les mots.
   * 
   * @return l'itérateur avec tous les mots
   * @see java.util.Iterator
   */
  public Iterator iterator();

  /**
   * Retire le mot à l'index.
   * 
   * @param index index du mot à retirer
   * @return le mot qui a été supprimé
   */
  public String removeWord(int index);

  /**
   * Retire le mot.
   * 
   * @param mot le mot à supprimer
   * @return <code>true</code> si le mot a bien été supprimé,
   * <code>false</code> si le mot n'était pas dans la liste
   */
  public boolean removeWord(String mot);

  /**
   * Mise à jour du nom du fichier. Cette méthode force le chargement
   * des mots qui sont dans le fichier. La méthode pour lire le fichier
   * sera déterminée en fonction de l'extension du nom de fichier (idem
   * dans la methode {@link #saveAs(String)}).
   * 
   * @param fichier le nom du fichier
   * @exception IOException Exception des entrées/sorties. Par exemple
   * si le fichier n'est pas trouvé, illisible, ou s'il n'a pas le bon
   * format!
   * 
   * <p><b>Un mot sur le format du fichier contenant les mots du Pendu</b></p>
   * 
   * <ul><li><b>Fichier texte:</b> il contient un mot par ligne;</li>
   * <li><b>Fichier sérialisé:</b> il s'agit d'une instance de
   * WordListModel. Au moment du chargement, il faudra donc lire tous les
   * mots de cette instance et les ajouter à l'instance courante.</li>
   * </ul>
   * 
   * @exception IOException si un problème a eu lieu lors de la lecture
   * du fichier
   */
  public void setFileName(String fichier)
    throws IOException;

  /**
   * Récupère le nom du fichier.
   * 
   * @return le nom du fichier
   */
  public String getFileName();

  /**
   * Sauvegarde dans le même fichier.
   * 
   * @exception IOException Exception des entrées/sorties.
   */
  public void save()
    throws IOException;

  /**
   * Sauvegarde dans un autre fichier. La méthode pour enregistrer le
   * fichier sera déterminée en fonction de l'extention (idem dans la
   * methode {@link #setFileName(String)}).
   * 
   * @param fichier le nouveau nom de fichier
   * @exception IOException Exception des entrées/sorties.
   */
  public void saveAs(String fichier)
    throws IOException;

  /**
   * Ajoute un écouteur des changements de propriété.
   * 
   * @param ecouteur l'écouteur des propriétés
   */
  public void addPropertyChangeListener(PropertyChangeListener ecouteur);

  /**
   * Ajoute un écouteur des changements de propriété.
   * 
   * @param nom le nom de la propriété à écouter
   * @param ecouteur l'écouteur des propriétés
   */
  public void addPropertyChangeListener(String nom,
                                        PropertyChangeListener ecouteur);
  
  /**
   * Retourne les écouteurs de propriété.
   * 
   * @return les écouteurs
   */
  public PropertyChangeListener[] getPropertyChangeListeners();
  
  /**
   * Retourne les écouteurs telle propriété.
   * 
   * @param nom le nom de la propriété dont on veut récupérer l'écouteur
   * @return les écouteurs
   */
  public PropertyChangeListener[] getPropertyChangeListeners(String nom);

  /**
   * Supprimer l'écouteur
   * 
   * @param ecouteur l'écouteur à supprimer
   */
  public void removePropertyChangeListener(PropertyChangeListener ecouteur);

  /**
   * Supprimer l'écouteur
   * 
   * @param nom nom de la propriété
   * @param ecouteur l'écouteur à supprimer
   */
  public void removePropertyChangeListener(String nom, PropertyChangeListener ecouteur);
  

}
