/**
 * Commande.java                                 7 mai 2021
 * IUT Rodez info1 2020-2021, pas de copyright, aucun droit
 */
package interpreteurlir.motscles;

import interpreteurlir.Contexte;
import interpreteurlir.InterpreteurException;
import interpreteurlir.programmes.Programme;

/**
 * Une commande (générale) n'a aucun comportement. 
 * Voir les sous-classes pour les comportements.
 * Une commande contient tous les liens nécessaires à son exécution.
 * Une commande peut être exécutée.
 * @author Nicolas Caminade
 * @author Sylvan Courtiol
 * @author Pierre Debas
 * @author Heïa Dexter
 * @author Lucas Vabre
 */
public abstract class Commande {
    
    /** référence du programme global */
    protected static Programme programmeGlobal;
    
    /** référence du contexte possiblement manié directement par la commande */
    protected Contexte contexte;

    /**
     * Initialise une commande avec les liens dont elle a besoin pour 
     * s'exécuter à partir des arguments. 
     * Cependant la commande ne s'exécute pas à la construction.
     * La commande a accès au contexte passé en argument.
     * @param arguments chaîne de texte représentant les arguments
     * @param contexte référence du contexte global
     * @throws InterpreteurException est propagée si Commande la reçoit
     * @throws NullPointerException si contexte ou arguments est null
     */
    public Commande(String arguments, Contexte contexte) {
        super();
        if (arguments == null || contexte == null) {
            throw new NullPointerException();
        }
        
        // arguments non utilisés dans Commande générale
        this.contexte = contexte;
    }
    
    /**
     * Commande d'exécution de la commande.
     * @return true si la commande affiche un feedback directement sur la sortie
     *         standard, sinon false
     */
    public abstract boolean executer();
    
    /**
     * Référence le programme pour accéder et modifier le programme chargé.
     * Le référencement vaut pour toutes les commandes/instructions
     * et est possible une unique fois.
     * @param aReferencer référence du programme global
     * @return <ul><li>true si le programme a pu être référencé</li>
     *             <li>true si aReferencer == programme déjà référencer</li>
     *             <li>false si aReferencer est null</li>
     *             <li>false si un programme est déjà référencer</li>
     *         </ul>
     */
    public static boolean referencerProgramme(Programme aReferencer) {
        if (aReferencer != null 
                && (   programmeGlobal == null 
                    || aReferencer == programmeGlobal)) {
            programmeGlobal = aReferencer;
            return true;
        }
        return false;
    }
        
    

}
