//**********************************************************************
//**********************************************************************
//	Projet      : Ulysse
//	Laboratoire : GREYC-ISMRA
//	Fichier     : controleur.cc
//      Annee       : 1997          ,
//	Auteur      : Christophe GODEREAUX
//**********************************************************************
//**********************************************************************


//#include "assoc.cc"

#define Je 	(*this)
#define J 	(*this)
#define Mon 	(*this)
#define Ma 	(*this)

#define CP strcpy

#define NB_MAX_AGENT 4 // pour conserver les noms des differents agents

//**********************************************************************
//**********************************************************************
//********************** CONTROLEUR
//**********************************************************************
//**********************************************************************

class Controleur {
	Tablo<Agent_virtuel> tab_ag;
	Utilisateur utilisateur;
	char destinataire[20];
	int num_destinataire;
	char tab_nom_agent[NB_MAX_AGENT][10];	
	char console[20];// console ou est connecte l'utilisateur

	char * repertoire, *user;
	RuleList *rules;
	LexList *dico;
	tablocution sons;

  public:
//	Memoire_ling mem_ling_commune;
	tablocution locutions;
	int locuteur; // numero de l'inter parlant : -1=utilisateur
	int nb_ag(){return tab_ag.nbr();} // nombre d'agents virtuels

	Controleur();
	void init(char*  ,char*  ,char * ,RuleList *,LexList *,int,char*);
	void affiche_locuteurs();
	int cherche_destinataire(Edge* PO);
	void donne_la_main_au_destinataire(Chart*,char*,char*);
	int donne_la_main_au_destinataire(char*,char*);
	void fait_parler_agent(char*);
        void verifie_creation_agent();
	void cree_agent();
	void cree_processus_agent_dive();
	char* ecoute(int);
	char * entend_mot(int,char*);
	int affiche_reponse(char*,int,int);
	int entend(Chart* & ,const Edge* &);
	void initialise_fichier_dialogue();
	void ajoute_reponse_dialogue(char*,int);
	void ajoute_replique_dialogue(char*,int);
	void ajoute_replique_dialogue(char*,int,int);
	Locuteur& le_locuteur(int);
	Locuteur& le_locuteur(){return le_locuteur(locuteur);}
	void efface_replique(){le_locuteur().efface_replique();}
};
  
Controleur::Controleur()
:tab_ag(1)//,mem_ling_commune(3)
{
}

void Controleur::init(char* nom_user ,char* rep ,char * nom_agent,
		      RuleList *rules0,LexList *dico0,int argc,
		      char * divesound)
{
  Mon.repertoire=strdup(rep);
  Mon.user=strdup(nom_user);
  J.initialise_fichier_dialogue(); 
  Ma.rules=rules0;
  Mon.dico=dico0;
  if (divesound) Mon.sons.init(divesound,"fic-son");
  else {
    cerr<<"LA VARIABLE D\'ENVIRONNEMENT DIVESOUND N\'EST PAS DECLAREE !";
    cerr<<"VOUS POUVEZ ESSAYER : setenv DIVESOUND /users3/these/christo/son";
    cerr.flush();
  }
  Ma.locutions.init(".","fic-loc");   
  Utilisateur utilisateur0(nom_user,argc,rep,Mon.user);
  Mon.utilisateur=utilisateur0;
DEB1
  if (nom_agent==NULL) CP(Mon.tab_nom_agent[0],"BOB");
  else CP(Mon.tab_nom_agent[0],nom_agent);
  CP(Mon.tab_nom_agent[1],"CHRISTO");
  CP(Mon.tab_nom_agent[2],"JO");
  CP(Mon.tab_nom_agent[3],"TOM");
DEB1
  Je.cree_agent();
DEB2
  CP(Mon.destinataire,Mon.tab_nom_agent[0]);
  Mon.num_destinataire=0;
  Mon.locuteur=-1;//l'utilisateur
  if (getenv("DISPLAY")) 
    CP(Ma.console,getenv("DISPLAY"));
  else {
   cerr<<"La variable d'environnement DISPLAY n'est pas exporte. On l'initialise a mercure:0\n";
   CP(Ma.console,"mercure:");
  }
copy_jusque(Ma.console,':');
DEB3
}

void Controleur::initialise_fichier_dialogue()
{
  char f[100],commande[110];
  sprintf(f,"%s/%s.dialogue",Mon.repertoire,Mon.user);
  sprintf(commande,"csh initialise_dialogue >%s ;chmod 666 %s",f,f);
  system(commande);
}

void Controleur::affiche_locuteurs()
{
  cout<<"\nVOICI L'ENSEMBLE DES "<<nb_ag()+1<<" LOCUTEURS :\n";
  for (int i=-1; i<nb_ag();i++){
    cout<<le_locuteur(i);
  }
  cout.flush();
}

Locuteur& Controleur::le_locuteur(int num)
{
  if (num==-1) return Mon.utilisateur;
  else return Mon.tab_ag[num];
}



int Controleur::cherche_destinataire(Edge* PO)
{
//deb("cherche_destinataire");
  char *dest=valeur(PO,"","destinataire");
  if (!eg(dest,"idem")) {
    int num=-1;
    for (int i=0;i<Mon.nb_ag();i++){
//deb(dest);debn(tab_ag[i].son_nom());
	if (eg(dest,tab_ag[i].son_nom())) num=i;
    } 
    if (num!=-1){
	CP(Mon.destinataire,dest);
	Mon.num_destinataire=num;
    }
    else {cout<<"Mon nom est "<<Mon.destinataire<<".\n";}
  }
  //cout<<" ] - [ Pour: "<<Mon.destinataire;
  return Mon.num_destinataire;
}

	
void Controleur::donne_la_main_au_destinataire(Chart* p,char* replik,char* reponse)
{
  tab_ag[num_destinataire].traite_enonce(p,replik,reponse);
}

int Controleur::donne_la_main_au_destinataire(char* replique,char* reponse)
{
  if(tab_ag[num_destinataire].traite_enonce(replique,reponse)){
    Mon.utilisateur.efface_replique();
	//-> suppression de la replique de l'utilisateur.
    return TRUE;
  }
  else return FALSE;
}

void Controleur::fait_parler_agent(char* replique)
{
  
  tab_ag[num_destinataire].synthetise_ma_replique(replique);
  cout<<replique<<"\n-------------------------------\n";cout.flush();
}


void Controleur::cree_agent()
{
  Agent_virtuel
    x(tab_nom_agent[nb_ag()],Mon.repertoire,Mon.user,tab_nom_agent[0],
      utilisateur.son_prenom(),Ma.rules,Mon.dico,nb_ag(),&(Mon.sons),this);
  Mon.tab_ag.ajouter(x);
}

void Controleur::cree_processus_agent_dive()
{
  char commande[1000];
  sprintf(commande,"rsh %s csh cree_processus_agent_dive %s>/dev/null&" 
	  ,Ma.console,tab_nom_agent[nb_ag()-1]);
  system(commande);
}


void Controleur::verifie_creation_agent()
{
  int creation=0;
  for(int i=0;i<Mon.nb_ag();i++) {
    if (tab_ag[i].cree_nouveau_agent()) {
	creation=1;
	Je.cree_agent();
	tab_ag[i].initialise_champ_nouveau_agent();
	Je.cree_processus_agent_dive();
    }
  }
  if (creation) J.affiche_locuteurs();
}


char * Controleur::ecoute(int numero_replik)
{
  char* replique;
  do {
    for (int i=-1; i<Mon.nb_ag();i++){
      if (!eg(replique=le_locuteur(i).parle(),"")) {
	Mon.locuteur=i; 
        cout<<"\n-------------------------------\n";
        if(i==-1)
	cout<<"- ";//<<le_locuteur(i).son_prenom()<<' '<<numero_replik<<" : ";
        else cout<<"- "<<le_locuteur(i).son_prenom()<<" énonce : ";
	cout.flush();
        traiter_enonce_pour_analyse_syntaxique(replique);
	return replique; 
      }
    }
  } while (TRUE);
}

int Controleur::affiche_reponse(char* reponse,int num_rep_U,int num_rep_A)
{
  if (!eg(reponse,"Z")&&!eg(reponse,"")){
    cout<<"\n-------------------------------\n";
    cout<<"- "<<le_locuteur(num_destinataire).son_prenom()<<' ';
    cout/*<<num_rep_U<<"."<<num_rep_A++*/<<"répond : "<<reponse;
    cout<<"\n-------------------------------\n";
    cout.flush();
    return TRUE;
  }
  else return FALSE;
}

char * Controleur::entend_mot(int num_locuteur,char* entree)
{
  if (num_locuteur==-1) return Mon.utilisateur.ecoute(entree);
  else return tab_ag[num_locuteur].ecoute(entree);
}


void Controleur::ajoute_reponse_dialogue(char* rep_util,int num_rep)
{
  J.ajoute_replique_dialogue(rep_util,num_rep,Mon.num_destinataire);
}

void Controleur::ajoute_replique_dialogue(char* rep_util,int num_rep)
{
  J.ajoute_replique_dialogue(rep_util,num_rep,Mon.locuteur);
}

void Controleur::ajoute_replique_dialogue(char* rep_util,int num_rep,int l)
{
  char f[100];
  char replique[1000];
//sauvegarde des repliques dans un fichier constituant le dialogue
  sprintf(f,"%s/%s.dialogue",Mon.repertoire,Mon.user);
  ecrire_message(
	le_locuteur(l).derniere_replique(replique,rep_util,num_rep)
	,f,"a");
//sauvegarde des repliques dans un fichier constituant tous les dialogues
  /*sprintf(f,"/users3/these/christo/pub/dial/DIALOGUES.%s",Mon.user);
  ecrire_message(
	le_locuteur(l).derniere_replique(replique,rep_util,num_rep)
	,f,"a");
*/
}


 void fork_ton(char *sound_file,  int volume)
{
  
if (fork() == 0) {
	if (execlp("play",
		   "play",
		   sound_file,
		   (char*)0)) {
	   perror("fork_sound");
	   exit(0);
	}
     }

}  



