// UTS 2000 - Fichier 'aigauto.cpp' Lecture des variables pour commander automatiquement les aiguillage en fonction des trains sur les cantons .
//
// V3.7c Le 30/09/2016
/*****************************************************************************/
/* Début AIGAUTO                                                             */
/*****************************************************************************/
#include  <windows.h>
#include  <string.h>
#include  <stdlib.h>
#include  <stdio.h>
#include "Train_UTS.h"
#include "aigauto.h"
#include "canton.h"
#include "selectif.h"
#include "Train.h"

#define _CRT_SECURE_NO_WARNINGS  // Limite les messages de warning dans Visual C++

// Déclaration des fonctions externes
extern int  get_line(FILE*, char [][CHAR_CONFIG_NB], int*);
extern void EasyTextOut(int , int , char* );
extern void EasyLine(int, int, int, int);
extern int pio_var_ch2int(char []);
extern int pio_var_int2ch(int ,char []);
extern int pio_define_convert(char [],char []);
extern int pio_get_val(int);
extern void bmp_SetTextColor(int no_color);
extern cTrain train;


// Déclaration des variables externes
extern HDC     hMemDC;
extern HFONT   bmp_fonte;
extern HPEN    bmp_stylo_noir, bmp_stylo_gris128, bmp_stylo_gris192, bmp_stylo_blanc, bmp_stylo_jaune;
extern HBRUSH  bmp_pinceau_blanc, bmp_pinceau_jaune, bmp_pinceau_gris192, bmp_pinceau_gris220, bmp_pinceau_vert;
extern cCanton  canton;
extern int screen_mode;
extern int moins_char_normal; 
extern int nb_aigauto_lus;	// Pour connaitre le nombre de lignes lues dans la partie '#aigauto' de 'config.txt' pour ne pas dépasser la limite de 100.
extern int cfg_aigauto;
extern int vio_det[NB_CARTE][NB_CANTON];
extern int vio_aig_res[NB_AIG];
extern int vio_aig_cmd[NB_AIG];
extern int vio_aig_pos0[NB_AIG];
extern int vio_aig_pos1[NB_AIG];
extern int x_mouse,y_mouse, screen_mode_retour;

//
cAigauto aigauto;

//
cAigauto::cAigauto(void)
{}

//
void cAigauto::init(char filename[])
/*
cant: c10:+11   plusur: c12 c13   condi: var_0.0 var_1.1                        actions: a0.0 a1.1
cant:  c7:-10   plusur: c0 c1     condi: det_6.0 pos1_aig_8.1  pos1_aig_9.1     actions: a6.0 a7.0
cant: c11:+10   plusur:           condi: in_51.1 garage_lock_status_1.0         actions: a11.0 a12.1

#define AIGAUTO_TAB_NB				100	// Nombre maximum de lignes déclarées dans la section #aigauto de config.txt.
#define AIGAUTO_TAB_NB_MAX_CANT		  6	// Nombre maximum de cantons déclarées par ligne dans la partie #aigauto
#define AIGAUTO_TAB_NB_MAX_VAR		  6	// Nombre maximum de conditions déclarées dans la partie #aigauto
#define AIGAUTO_TAB_NB_MAX_AIG		  6	// Nombre maximum d'aiguillages déclarés dans la partie #aigauto
//
#define AIGAUTO_TAB_IND_CANT_NO       0	// Numéro du canton.
#define AIGAUTO_TAB_IND_CANT_VIT      1	// Vitesse minimum pour une activation des actions (-64 à -1 et +1 à +64).
#define AIGAUTO_TAB_IND_ACTION_OK     2	// Stock l'état de la dernière action, pour ne la déclencher qu'au passage 0 -> 1.
#define AIGAUTO_TAB_IND_CANT_0_NO     3 // Conditions sur les cantons = n° de cantons.
#define AIGAUTO_TAB_IND_VAR_0         AIGAUTO_TAB_IND_CANT_0_NO+AIGAUTO_TAB_NB_MAX_CANT  // Conditions sur les variables = n° de variables       (Nb de variables max = AIGAUTO_TAB_NB_MAX_VAR).
#define AIGAUTO_TAB_IND_VAL_0         AIGAUTO_TAB_IND_VAR_0+AIGAUTO_TAB_NB_MAX_VAR       //                              = état de la variables
#define AIGAUTO_TAB_IND_AIG_0_NO      AIGAUTO_TAB_IND_VAL_0+AIGAUTO_TAB_NB_MAX_VAR       // Si conditions remplies, active les aiguillages = n° de l'aiguillage  (Nb aig max = AIGAUTO_TAB_NB_MAX_AIG).
#define AIGAUTO_TAB_IND_AIG_0_POS     AIGAUTO_TAB_IND_AIG_0_NO+AIGAUTO_TAB_NB_MAX_AIG    //                                                = position de l'aiguillage
#define AIGAUTO_TAB_IND_TAILLE        AIGAUTO_TAB_IND_AIG_0_POS+AIGAUTO_TAB_NB_MAX_AIG   // Taille du tableau.
*/
{
	FILE* pf;
	char ch[CHAR_CONFIG_NB],ch_tab[BLOC_CONFIG_NB][CHAR_CONFIG_NB],ch_error[200],ch_syst[100];
	int  i,j,i_param,ch_nb,no_aigauto,no_cant,i_verif,cant_verif,aigauto_mode;

	for(j=0;j<AIGAUTO_TAB_NB;j++) {
		for(i=0;i<AIGAUTO_TAB_IND_TAILLE;i++) aigauto_tab[j][i]=-1;
	    aigauto_tab[j][AIGAUTO_TAB_IND_ACTION_OK]=0;		// L'état de la dernière action ne peut être que '0' ou '1'.
	}
	if((pf=fopen(filename,"rt"))==NULL){
		MessageBox(NULL,"Impossible d'ouvrir le fichier de configuration du #aigauto","Erreur",MB_OK|MB_ICONERROR);	exit(1);
	}

	while(fscanf(pf,"%s%*[^\n]\n",ch)!=EOF) {	// " %s" => "%s%*[^\n]\n" = Nouvelle formule au 02/03/2012, lit uniquement le permier mot de chaque ligne.
		if(STR_SAME strcmp(ch,"#aigauto")) {
			fscanf(pf," %s",ch);	// Passe le caractère '['.
			no_aigauto=0;
			moins_char_normal=0; // '-' est un caractères normal, comme '+'.
			while(get_line(pf,ch_tab,&ch_nb)) {
				if(ch_nb>=BLOC_CONFIG_NB) {
					MessageBox(NULL,"Le fichier config.txt comporte une ligne trop complexe dans la section '#aigauto'","Erreur",MB_OK|MB_ICONERROR);
					MessageBox(NULL,"Section '#aigauto' (ligne>75 blocs) commençant par (taper sur Entrée) : ","Erreur",MB_OK|MB_ICONERROR);
					strcpy(ch_error,"Section #aigauto Erreur ligne :");
					for(i=0;i<ch_nb;i++) { strcat(ch_error,"  "); strcat(ch_error,ch_tab[i]); }
					MessageBox(NULL,ch_error,"UTS - Erreur",MB_OK|MB_ICONERROR); exit(1);
				}
				if(ch_tab[0][0]==']') break;			// Fin de la section #aigauto
				if(no_aigauto>=AIGAUTO_TAB_NB) break;	// Fin de la section #aigauto
				for(i=0;i<ch_nb;i++) if(ch_tab[i][0]=='@') ch_nb=i;  // Supprime sur une lignes le texte après un '@' = Commentaires.
				no_cant=-1;
				aigauto_mode=0;	// 0|1=Aucun mode, 2=Mode définition des cantons 3=Mode définition des variables, 4=Mode définition des aiguillages.
				i=0;
				while(i<ch_nb) {
					i_verif=i;
					cant_verif=1;
// cant: c10:+11
					if (aigauto_mode==0 && STR_SAME strcmp(ch_tab[i],"cant") && ch_tab[i+1][0]==':' && ch_nb-i>=6) {
						aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_NO]=atoi(&ch_tab[i+2][1]); // N° du canton encours
						no_cant=1;
						if (ch_tab[i+4][0]=='-') aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_VIT]=-atoi(&ch_tab[i+5][0]); // Vitesse sur canton en cours.
						if (ch_tab[i+4][0]=='+') aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_VIT]=atoi(&ch_tab[i+5][0]);  // Vitesse sur canton en cours.
						// Vérification de l'entête.
						cant_verif=0;
						if (atoi(&ch_tab[i+2][0])>=0 && atoi(&ch_tab[i+2][0])<(300+NB_CANTON) && (atoi(&ch_tab[i+2][0])%100)<NB_CANTON) cant_verif=1; // OK
						if (ch_tab[i+3][0]!=':')                                  cant_verif=0; // Erreur
						if (ch_tab[i+4][0]!='-' && ch_tab[i+4][0]!='+')           cant_verif=0; // Erreur 
						if (atoi(&ch_tab[i+5][0])<1 || atoi(&ch_tab[i+5][0])>VITESSE_CANT_MAXI) cant_verif=0; // Erreur, Vitesse minimum = 1.
						aigauto_mode=1;  // 1=Mode définition autres,
						i_param=0; i=i+6;
					}
					else if (aigauto_mode==1 && STR_SAME strcmp(ch_tab[i],"plusur") && ch_tab[i+1][0]==':' && ch_nb-i>=2) {
						aigauto_mode=2;  // 2=Mode définition des cantons
						i_param=0; i=i+2;
					}
					else if (aigauto_mode==2 && STR_SAME strcmp(ch_tab[i],"condi") && ch_tab[i+1][0]==':' && ch_nb-i>=2) {
						aigauto_mode=3;  // 3=Mode définition des conditions.
						i_param=0; i=i+2;
					}
					else if (aigauto_mode==3 && STR_SAME strcmp(ch_tab[i],"actions") && ch_tab[i+1][0]==':' && ch_nb-i>=2) {
						aigauto_mode=4;  // 4=Mode définition des aiguillages.
						i_param=0; i=i+2;
					}
//	plusur: c12.0 c13.1 
					else if ((aigauto_mode==2)&&(ch_nb-i>=1)) {  // Recherche des cantons avec CE train = cx
						if (i_param<AIGAUTO_TAB_NB_MAX_CANT) {
							if (ch_tab[i][0]!='c') cant_verif=0;			// Erreur on n'accepte que c. comme descriptif.
							if (atoi(&ch_tab[i][1])<0 || atoi(&ch_tab[i][1])>=(300+NB_CANTON) || (atoi(&ch_tab[i][1])%100)>=NB_CANTON) cant_verif=0; // Erreur
							if (cant_verif!=0) {
								aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_0_NO+i_param]= atoi(&ch_tab[i][1]);
								i_param++; i=i+1;
							}
						}
						else cant_verif=0; // On a  dépassé le nb autorisé de cantons, on va sortir du programme en fin de boucle.
					}
//	condi: det_6.0 pos1_aig_8.1  pos1_aig_9.1
//	condi: in_51.1 garage_lock_status_1.0
					else if (aigauto_mode==3 && ch_nb-i>=3) {  // Recherche des variables = var_xxx.y
						if (i_param<BALAUTO_VITMAX_NB_MAX_VAR) {
							if (ch_tab[i+1][0]!='.')                        cant_verif=0; // Erreur.
							if (ch_tab[i+2][0]!='0' && ch_tab[i+2][0]!='1') cant_verif=0; // Erreur on n'accepte que 0 ou 1 comme valeur.
							// On va faire un effort, on va convertir exceptionnellement "ax.y" en "posy_aig_x.1".
							if (cant_verif==1 && ch_tab[i][0]=='a' && ch_tab[i][1]>='0'&& ch_tab[i][1]<='9') {
								if (ch_tab[i+2][0]=='0') strcpy(ch_error,"pos0_aig_");
								else                     strcpy(ch_error,"pos1_aig_");
								strcat(ch_error,&ch_tab[i][1]); // = "posy_aig_x"
								strcpy(ch_tab[i],ch_error);
							}	
							if (pio_define_convert(ch_tab[i],ch_syst)==0)   strcpy(ch_syst,ch_tab[i]);  // Converti '401' en 'in_1'.
							j=pio_var_ch2int(ch_syst);													// Converti 'in_1' en '401'.
							if (j!=-1) aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_VAR_0+i_param]=j; else cant_verif=0; // Erreur sur le n° de variables.
							if (cant_verif!=0) aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_VAL_0+i_param]=atoi(&ch_tab[i+2][0]);
							i_param++; i=i+3;
						}
						else cant_verif=0; // On a  dépassé le nb de variable autorisée, on va sortir du programme en fin de boucle.
					}
//  actions:  a6.0   a7.0
					else if (aigauto_mode==4 && ch_nb-i>=3 ) {  // Recherche des aiguilages = ax.y
						if (i_param<AIGAUTO_TAB_NB_MAX_AIG) {
							if (ch_tab[i][0]!='a'     || ch_tab[i+1][0]!='.') cant_verif=0; // Erreur on n'accepte que a. comme descriptif.
							if (ch_tab[i+2][0]!='0'   && ch_tab[i+2][0]!='1') cant_verif=0; // Erreur on n'accepte que 0 ou 1 comme valeur.
							if (atoi(&ch_tab[i][1])<0 || atoi(&ch_tab[i][1])>=NB_AIG) cant_verif=0; // C'est bien >= NB_AIG, Erreur sur le n° d'aiguillage.
							if (cant_verif!=0) {
								aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_AIG_0_NO+i_param]= atoi(&ch_tab[i][1]);
								aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_AIG_0_POS+i_param]=atoi(&ch_tab[i+2][0]);
								i_param++; i=i+3;
							}
						}
						else cant_verif=0; // On a  dépassé le nb d'aiguillages autorisés, on va sortir du programme en fin de boucle.
					}
					if (cant_verif==0 || i_verif==i) { // Erreur ou on n'a pas trouvé de signification sur la chaine de caractères analysée. On sort pour ne pas boucler ici.
						strcpy(ch_error,"Fichier 'config.txt',\n\nSection #aigauto,\n\nErreur de description sur la ligne :");
						for(i=0;i<ch_nb;i++) { strcat(ch_error,"  "); strcat(ch_error,ch_tab[i]); }
						MessageBox(NULL,ch_error,"UTS - Erreur",MB_OK|MB_ICONERROR); 	exit(1);
					}
				}  // fin d'analyse de tous les éléments de la ligne.
		         if (no_cant!=-1) { // Si l'on a trouvé un canton de défini, on vérifie les paramètres.
					if (aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_VIT]==0||aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_VIT]<-64||aigauto_tab[no_aigauto][AIGAUTO_TAB_IND_CANT_VIT]>64) {
						strcpy(ch_error,"Fichier 'config.txt',\n\nSection #aigauto,\n\nErreur sur la vitesse du canton ligne :");
						for(i=0;i<ch_nb;i++) { strcat(ch_error,"  "); strcat(ch_error,ch_tab[i]); }
						MessageBox(NULL,ch_error,"UTS - Erreur",MB_OK|MB_ICONERROR); 	exit(1);
					} 
					no_aigauto++;
				}
			}	// While (get_line) fin de la ligne de texte.
			break; // Pour sortir de la lecture de la suite du fichier.
		}		// if(==#aigauto)   fin description '#aigauto'.
	}			// While (scanf)    fin du fichier 'config.txt'.
	nb_aigauto_lus=no_aigauto;	// Valeur utilisée sur la page débug.
	moins_char_normal=1;		// '-' est un caractère normal, comme '+'.
	fclose(pf);
}

//
// cant:  c7:-10   plusur: c0 c1     condi: det_6.0 pos1_aig_8.1  pos1_aig_9.1     actions: a6.0 a7.0
// On recherche les aiguillages à deplacer automatiquement.
//
void cAigauto::tick(void)
{
	int i, j;
	int cant_n, vit_n, train_n, action_n, var_n , val_n, canton_inverse;

	for(i=0;i<AIGAUTO_TAB_NB;i++) {
		if (aigauto_tab[i][AIGAUTO_TAB_IND_CANT_NO]==-1) break; // On arrive à la fin du tableau avec des valeurs.
		cant_n=aigauto_tab[i][AIGAUTO_TAB_IND_CANT_NO];			// cant_n = n° du canton 'aigauto' en cours de traitement.
		train_n = canton.num_train[cant_n/100][cant_n%100];	// On récupere le n° du train.
		canton_inverse = 1;
		if (canton.inv_selectif[cant_n / 100][cant_n % 100] != 0) canton_inverse = -1; // Prend en compte les cantons inversé (après une boucle de retournement) en V3.7c
		if ((canton.master_selectif[cant_n/100][cant_n%100]==1) && (vio_det[cant_n/100][cant_n%100]==1) && (aigauto_tab[i][AIGAUTO_TAB_IND_ACTION_OK]==0)) {
			// Si une action est notée faite, on ne repasse pas dans le code pour gagner du temps.	
			// Pour le canton en cours de traitement, on a trouvé qu'il est un canton principal en conduite manuelle (<>-1) et qui est occupé (==1).
			vit_n=aigauto_tab[i][AIGAUTO_TAB_IND_CANT_VIT];		// vit_n = vitesse du canton en cours de traitement.
			if ((vit_n>0 && canton.vit_selectif[cant_n/100][cant_n%100]>=vit_n)           || (vit_n<0 && canton.vit_selectif[cant_n/100][cant_n%100]<=vit_n) || 
			    (vit_n>0 && canton_inverse*train.cons_sans_correction[train_n]>=vit_n)    || (vit_n<0 && canton_inverse*train.cons_sans_correction[train_n]<=vit_n)) {
				// Pour le canton en cours de traitement, on a trouvé qu'il est un canton principal en conduite manuelle (<>-1) et qui est occupé (==1).
				// et que sa vitesse en manuel est > à celle demandée.
				// On a testé aussi 'cons_sans_correction[train_n]' car un train peut être arrété sur un canton car '#balauto' +'cant:' lui interdit d'avancer
				// si un aiguillage est fermé. On teste la valeur du potentiomètre ou du clavier, comme cela la situation se débloque.
				action_n = 1;													// Par défaut action = 1 si rien n'est déclaré dans 'plusur:'
				// Traitement de 'plusur:' c2 c3
				for(j=0;j<AIGAUTO_TAB_NB_MAX_CANT;j++) {
					if (aigauto_tab[i][AIGAUTO_TAB_IND_CANT_0_NO+j]==-1) break; // On arrive à la fin du tableau avec des valeurs.
					var_n=aigauto_tab[i][AIGAUTO_TAB_IND_CANT_0_NO+j];			// var_n = n° du canton à tester si CE n° de train est dessus.
					if (canton.master_selectif[var_n/100][var_n%100]==1 && 
						vio_det[var_n/100][var_n%100]!=0 && 
						train_n==canton.num_train[var_n/100][var_n%100]) {
						// Pour le canton en cours de traitement, on a trouvé les autres cantons vides ou avec ce même train dessus.
						// CE train est encore sur UN des cantons précédents => On ne fait donc pas les actions.
						action_n=0; break;
					}
				}
				if (action_n==1) { 
					// La directive 'plusur:' est valide, On passe aux tests 'condi:' det_6.0 pos1_aig_8.1  pos1_aig_9.1 
					for(j=0;j<AIGAUTO_TAB_NB_MAX_VAR;j++) {
						if (aigauto_tab[i][AIGAUTO_TAB_IND_VAR_0+j]==-1) break; // On arrive à la fin du tableau avec des valeurs.
						var_n=aigauto_tab[i][AIGAUTO_TAB_IND_VAR_0+j];			// var_n = n° de la variable à tester.
						val_n=aigauto_tab[i][AIGAUTO_TAB_IND_VAL_0+j];			// val_n = valeur à vérifier.
						if (pio_get_val(var_n)!=val_n) { action_n=0; break; }	// [var_n] = val_n ?
						// Il va falloir ajouter un test pour savoir si le canton où va le train (det_xx) est Res_Auto , Master_Selectif ou Update_Selectif.
						// Il faut vérifier si le test est sur une variable de type 'det_xx'. 
						// Si le canton suivant est occupé, on est déjà sorti de la boucle. On passe ici seulement si le canton suivant est vide.
						// On vérifie que le canton suivnat n'est pas reservé par un déplacement automatique pour par un train en conduite manuelle.
						if (var_n>=0 && var_n<(300+NB_CANTON) && (var_n%100)<NB_CANTON) {
							// La variable = type 'det_xx'.
							if (train_n!=canton.num_train[var_n/100][var_n%100]) {
								// Si le prochain canton n'est pas prevu pour CE même train, on vérifie si il est déjà occupé.
								if (canton.res_auto[var_n/100][var_n%100]==1 || 
									canton.master_selectif[var_n/100][var_n%100]==1 || canton.update_selectif[var_n/100][var_n%100]==1) {action_n=0; break;} // V3.4
							}
						}
					}	
				}
				if (action_n==1) { 
					// Les directives 'plusur:' et 'condi:' sont valides.
					// On va effectuer les actions = Commande d'aiguillages.
					// C'est la premiere fois que l'on fait cette action.
					aigauto_tab[i][AIGAUTO_TAB_IND_ACTION_OK]=1;
					for(j=0;j<AIGAUTO_TAB_NB_MAX_AIG;j++) {
						if (aigauto_tab[i][AIGAUTO_TAB_IND_AIG_0_NO+j]==-1) break; // On arrive à la fin du tableau avec des valeurs.
						var_n=aigauto_tab[i][AIGAUTO_TAB_IND_AIG_0_NO+j];		// var_n = n° d'aiguillage à actionner.
						val_n=aigauto_tab[i][AIGAUTO_TAB_IND_AIG_0_POS+j];		// val_n = valeur de l'aiguillage.
						// si l'aiguillage n'est pas reservé et si il n'est pas dans la bonne position, on l'active.
						if (vio_aig_res[var_n]==0 && ((vio_aig_pos0[var_n]==1&&val_n==1) || (vio_aig_pos1[var_n]==1&&val_n==0))) vio_aig_cmd[var_n]=val_n;
						if (vio_aig_res[var_n]!=0) aigauto_tab[i][AIGAUTO_TAB_IND_ACTION_OK]=0; // Finalement les aiguillages étaient reservés, on n'a pas fait l'action.
					}
				}
			}
		}
		else if ((canton.master_selectif[cant_n/100][cant_n%100]==0) && (vio_det[cant_n/100][cant_n%100]==0) ||
			(canton.vit_selectif[cant_n/100][cant_n%100]==0 && train.cons_sans_correction[train_n]==0)) {
			// Il n'y a plus de train sur le canton en cours, ou sa vitesse est nulle. On fait un raz de l'indicateur pour la prochaine fois.
			aigauto_tab[i][AIGAUTO_TAB_IND_ACTION_OK]=0;
		}
	}
}

//
// Affiche les tableaux '#aigauto'
//
void cAigauto::debug(int action)
{
	int i, j;
	char ch[200], ch2[25], ch3[25];	// ch[25] pour contenir 'garage_lock_status_0'+ '/0'
	static int aigauto_deb=0;
	static int dimnx=44;    // Dimension horizontal d'une cellule 'Numéro'
	static int dimcx=68;    // Dimension horizontal d'une cellule 'Cantons'
	static int dimli=350;   // Dimension horizontal d'une cellule 'Libé' min=229
	static int dimy=16;     // Dimension vertical d'une cellule
	static int nblignes=32; // Nombre de ligne du tableau (sans le titre)	
	static int decaly=16;   // Decalage de la premiére ligne vers les bas.

	SelectObject(hMemDC,bmp_fonte); SetBkMode(hMemDC,TRANSPARENT);
	SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);

	if(action==DEBUG_TOTAL_PAINT) {     // ACTION = REDESSINE TOUTE LA FENETRE.
		Rectangle(hMemDC,0,0,1100,700);
		SelectObject(hMemDC,bmp_pinceau_gris192); SelectObject(hMemDC,bmp_stylo_gris192); Rectangle(hMemDC,1100-15,15,1100-2,2); // Rectangle gris pour fermer la fenêtre.
		SelectObject(hMemDC,bmp_stylo_noir); EasyLine(1100-14,3,1100-3,14 ); EasyLine(1100-14,13,1100-3,2); // Croix noire.
		SelectObject(hMemDC,bmp_stylo_noir);  EasyLine(1100-2,1,1100-2,16); EasyLine(1100-16,15,1100-1,15); // Trait noir.
		SelectObject(hMemDC,bmp_stylo_gris128); EasyLine(1100-3,2,1100-3,15); EasyLine(1100-15,14,1100-2,14); // Trait gris foncé.
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
		Rectangle(hMemDC, 0, decaly, 1100, decaly+dimy+1);
		EasyLine(dimnx,                 decaly, dimnx,                decaly+dimy);
		EasyLine(dimnx+dimcx,           decaly, dimnx+dimcx,          decaly+dimy);
		EasyLine(dimnx+dimcx+dimli-99,  decaly, dimnx+dimcx+dimli-99, decaly+dimy);
		EasyLine(dimnx+dimcx+2*dimli,   decaly, dimnx+dimcx+2*dimli,  decaly+dimy);
		bmp_SetTextColor(BMP_CST_COLOR_BLANC);			// Texte en noir.
		EasyTextOut(2,2,"AFFICHE LES VALEURS DU TABLEAU INTERNE 'AIGAUTO'      (100 lignes maximum)"); EasyTextOut(1100-140,2,"(QUITTER = ESC)");
		EasyTextOut(2,decaly+(nblignes+2)*dimy,"Section '#aigauto'");
		SelectObject(hMemDC,bmp_stylo_noir); SelectObject(hMemDC,bmp_pinceau_gris220); // Rectangle gris foncé.
		Rectangle(hMemDC,0,decaly+(nblignes+3)*dimy-2, 97, decaly+(nblignes+4)*dimy);
		SelectObject(hMemDC,bmp_stylo_gris128);
		EasyLine(1,  decaly+(nblignes+4)*dimy-2, 96, decaly+(nblignes+4)*dimy-2);  	// Relief rectangle.
		EasyLine(95, decaly+(nblignes+3)*dimy-2+1, 95, decaly+(nblignes+4)*dimy-2);	// Relief rectangle.
		SelectObject(hMemDC,bmp_stylo_noir);
		EasyLine(97-10, decaly+(nblignes+4)*dimy-2, 97, decaly+(nblignes+4)*dimy-12);  // Dessine un trait dans l'angle = valeurs modifiables.
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
		EasyTextOut(2,decaly+(nblignes+3)*dimy," CLIC-DROIT :AFFICHE LES PAGES 1->2->3, [00-31]->[32-63]->[64-95]");
		
		bmp_SetTextColor(BMP_CST_COLOR_NOIR);			// Texte en noir.
		sprintf_s(ch,"AIGAUTO est :"); 
		EasyTextOut(850,decaly+(nblignes+3)*dimy,ch);

		if (cfg_aigauto==1) {	sprintf_s(ch,"ACTIF"); } else { sprintf_s(ch,"PAS ACTIF"); }
		bmp_SetTextColor(BMP_CST_COLOR_BLEUF);			// Texte en bleu.
		EasyTextOut(850+115,decaly+(nblignes+3)*dimy,ch);

		bmp_SetTextColor(BMP_CST_COLOR_NOIR);			// Texte en noir.
		EasyTextOut(2,decaly+(nblignes+4)*dimy,"Permet de commander automatiquement des aiguillages, quand on conduit un train en manuel.");
		EasyTextOut(2,decaly+(nblignes+5)*dimy,"Colonne 'Cant+-Vi', sur ce canton si vitesse du train > Vi => action possible.");
		EasyTextOut(2,decaly+(nblignes+6)*dimy,"Colonne 'CE train...' en mouvement doit avoir libéré ces cantons, pour déclencher les actions.");
		EasyTextOut(2,decaly+(nblignes+7)*dimy,"Colonne des variables qui doivent être à l'état indiqué, pour déclencher les actions.");
		EasyTextOut(2,decaly+(nblignes+8)*dimy,"Colonne des aiguillages à positionner si déclenchement de l'action.");

		SelectObject(hMemDC,bmp_pinceau_vert); // Rectangle vert.
		Rectangle(hMemDC, 0, -2+decaly+(nblignes+9)*dimy,96,-1+decaly+(nblignes+10)*dimy);
		SelectObject(hMemDC,bmp_pinceau_blanc);
		EasyTextOut(2,decaly+(nblignes+9)*dimy,"LIGNE VERTE = Action déjà faite. Redeviendra normale quand le train quittera ce canton ou sera à vitesse nulle.");

		bmp_SetTextColor(BMP_CST_COLOR_ROUGE);			// Texte en rouge.
		EasyTextOut(2,                     2+decaly,"  n°");		// Indice 'i' du tableau : descr[i][].
		EasyTextOut(2+dimnx,               2+decaly,"Cant+-Vi");	//
		EasyTextOut(2+dimnx+dimcx,         2+decaly,"CE train plus sur ces cantons");	// 
		EasyTextOut(2+dimnx+dimcx+dimli-99,2+decaly,"Conditions à vérifier");			// 
		EasyTextOut(2+dimnx+dimcx+2*dimli, 2+decaly,"Actions sur les aiguillages");		// 
	}

	if(action==DEBUG_MOUSE) { // ACTION = CLIC GAUCHE DE LA SOURIS
		if ((x_mouse > 0 && x_mouse < 97) && (y_mouse > decaly+(nblignes+3)*dimy-2 && y_mouse < decaly+(nblignes+4)*dimy)) { //	Clique dans [CLIC DROIT]
			action=DEBUG_MOUSE_RIGHT; //	Simule le clique-droit traité plus loin.
		}
		else {
			if ((x_mouse > 1100-15 && x_mouse < 1100-2) && (y_mouse > 2 && y_mouse < 15)) {
				screen_mode= screen_mode_retour; 
				return;	// On ferme la fenêtre.
			}
		}
	}

	if(action==DEBUG_MOUSE_RIGHT) {    // ACTION = CLIC DROIT DE LA SOURIS, on passe à la page suivante.
		switch(aigauto_deb/nblignes) {
			case 0 : { screen_mode= MD_ECRAN_AIGAUTO2; break;}
			case 1 : { screen_mode= MD_ECRAN_AIGAUTO3; break;}
			case 2 : { screen_mode= MD_ECRAN_AIGAUTO1; break;}
			default: break;
		}
	}

	if (screen_mode==MD_ECRAN_AIGAUTO1) aigauto_deb= 0;	// Valeur de la premiere ligne à afficher.
	if (screen_mode==MD_ECRAN_AIGAUTO2) aigauto_deb=   nblignes;
	if (screen_mode==MD_ECRAN_AIGAUTO3) aigauto_deb= 2*nblignes;

	if(action==DEBUG_KEY) { }          // ACTION = TOUCHE ENFONCEE

	bmp_SetTextColor(BMP_CST_COLOR_BLEUF);			// Texte en bleu foncé.
	for(i=0;i<nblignes;i++) {
		if(aigauto_deb+i<AIGAUTO_TAB_NB) {
			sprintf_s(ch,"%3d",aigauto_deb+i);
			if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_ACTION_OK]==1) SelectObject(hMemDC,bmp_pinceau_vert); // Ligne verte si action activée.
			else SelectObject(hMemDC,bmp_pinceau_blanc);
			Rectangle(hMemDC, 0, dimy*(i+2), 1100, dimy*(i+3)+1);
			EasyLine(dimnx,                 dimy*(i+2), dimnx,                 dimy*(i+3)+1);
			EasyLine(dimnx+dimcx,           dimy*(i+2), dimnx+dimcx,           dimy*(i+3)+1);
			EasyLine(dimnx+dimcx+dimli-99, dimy*(i+2), dimnx+dimcx+dimli-99, dimy*(i+3)+1);
			EasyLine(dimnx+dimcx+2*dimli,         dimy*(i+2), dimnx+dimcx+2*dimli,         dimy*(i+3)+1);
			if(aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_CANT_NO]==-1)  bmp_SetTextColor(BMP_CST_COLOR_GRIS192); // Texte en gris 192.
			EasyTextOut(10,2+dimy*(i+2),ch);			// N° d'indice du tableau
			bmp_SetTextColor(BMP_CST_COLOR_BLEUF);			// Texte en bleu foncé.
			if(aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_CANT_NO]!=-1) {  // Elément valide ?
				// Affiche c10 +30 = n° Canton +-Vitesse
				sprintf_s(ch,"c%-2d %3d",aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_CANT_NO],aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_CANT_VIT]);
				EasyTextOut(2+dimnx+3,2+dimy*(i+2),ch);
				// Affiche c15.0 c12.1 c15.1 = Cantons devant être libérés par CE train + Le canton doit être .1 = occupé, .0 = libre.
				sprintf_s(ch,"");
				for (j=0;j<AIGAUTO_TAB_NB_MAX_CANT;j++) {   
					if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_CANT_0_NO+j]!=-1) {
						strcat(ch,"c");
						sprintf_s(ch2,"%d  ",aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_CANT_0_NO+j]);
						strcat(ch,ch2);
					}
				}
				EasyTextOut(2+dimnx+dimcx+3,2+dimy*(i+2),ch);				// affiche le texte sur les conditions.
				// Affiche var_1=1 det_13=0 = Liste des conditions devant être réalisées.
				sprintf_s(ch,"");
				for (j=0;j<AIGAUTO_TAB_NB_MAX_VAR;j++) {
					if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_VAR_0+j]!=-1) {
						pio_var_int2ch(aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_VAR_0+j],ch2);
						if (STR_SAME strncmp(ch2,"pos0_aig_",8)) {
							sprintf_s(ch3,"a%s",&ch2[9]);
							strcpy(ch2,ch3);
						}
						else if (STR_SAME strncmp(ch2,"pos1_aig_",8)) {
							sprintf_s(ch3,"a%s",&ch2[9]);
							strcpy(ch2,ch3);
						}
						strcat(ch,ch2);
						if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_VAL_0+j]==0) strcat(ch,"=0 ");
						if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_VAL_0+j]==1) strcat(ch,"=1 ");
					}
				}
				EasyTextOut(2+dimnx+dimcx+dimli-99+3,2+dimy*(i+2),ch);				// affiche le texte sur les conditions.
				// Affiche a0.0 a15.1 a12.0 = Aiguillages devant être activés + Positions = .0 ou .1
				sprintf_s(ch,"");
				for (j=0;j<AIGAUTO_TAB_NB_MAX_AIG;j++) {
					if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_AIG_0_NO+j]!=-1) {
						strcat(ch,"a");
						sprintf_s(ch2,"%d",aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_AIG_0_NO+j]);
						strcat(ch,ch2);
						if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_AIG_0_POS+j]==0) strcat(ch,"=0 ");
						if (aigauto_tab[aigauto_deb+i][AIGAUTO_TAB_IND_AIG_0_POS+j]==1) strcat(ch,"=1 ");
					}
				}
				EasyTextOut(2+dimnx+dimcx+2*dimli+3,2+dimy*(i+2),ch);				// affiche le texte sur les actions sur les aiguillages.
			}
		}
	}
}
/*****************************************************************************/
/* Fin AIGAUTO                                                               */
/*****************************************************************************/
