/*                               -*- Mode: C -*-
 *
 * verification.c --- MPI. TP7 verification.
 *
 * cc verification.c -lX11 -o verification
 *
 * Author          : Denis GIROU (CNRS/IDRIS - France) <Denis.Girou@idris.fr>
 * 
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>

main (int argc, char **argv)
{
  char              Titre[] = "MPI - Session 7 verification.";

  Display           *Affichage;
  Window            Fenetre;
  GC                ContexteGraphique;
  XEvent            Evenement;
  XSizeHints        Attributs;

  int               Ecran;
  unsigned long     AvantPlan, ArrierePlan;

  char              NomFichier[17];

  int               NbPoints = 242;
  XPoint            Points[242];


  /* Definition of the display and color front and rear */
  Affichage         = XOpenDisplay  ("");
  Ecran             = DefaultScreen (Affichage);
  ArrierePlan       = WhitePixel    (Affichage, Ecran);
  AvantPlan         = BlackPixel    (Affichage, Ecran);

  /* Window creation with a size 650 x 650 */
  Attributs.x       = 0;
  Attributs.y       = 0;
  Attributs.width   = 650;
  Attributs.height  = 650;
  Attributs.flags   = PPosition | PSize;
  Fenetre           = XCreateSimpleWindow (Affichage, DefaultRootWindow (Affichage),
                                           Attributs.x, Attributs.y,
                                           Attributs.width, Attributs.height,
                                           5, AvantPlan, ArrierePlan);

  XSetStandardProperties (Affichage, Fenetre, Titre, Titre,
                          None, argv, argc, &Attributs);

  ContexteGraphique = XCreateGC (Affichage, Fenetre, 0, 0);

  XSetBackground    (Affichage, ContexteGraphique, ArrierePlan);
  XSetForeground    (Affichage, ContexteGraphique, AvantPlan);

  XSelectInput      (Affichage, Fenetre, ButtonPressMask);

  /* Display of the window on screen */
  XMapRaised        (Affichage, Fenetre);

  /* Trace graphs */

  XNextEvent        (Affichage, &Evenement);

  /* Read via explicit offsets, in individual mode */
  strcpy            (NomFichier, "file_deiN.dat");
  LectureDonnees    (NomFichier, NbPoints, Points);
  TraceGraphique    (Affichage, Fenetre, ContexteGraphique,
                     "MPI_FILE_READ_AT", NbPoints, Points);
  XNextEvent        (Affichage, &Evenement);
  XClearWindow      (Affichage, Fenetre);


  /* Read via shared file pointers, in collective mode */
  strcpy            (NomFichier, "file_ppcN.dat");
  LectureDonnees    (NomFichier, NbPoints, Points);
  TraceGraphique    (Affichage, Fenetre, ContexteGraphique,
                     "MPI_FILE_READ_ORDERED", NbPoints, Points);
  XNextEvent        (Affichage, &Evenement);
  XClearWindow      (Affichage, Fenetre);

  /* Read via individual pointers, in individual mode */
  strcpy            (NomFichier, "file_piiN.dat");
  LectureDonnees    (NomFichier, NbPoints, Points);
  TraceGraphique    (Affichage, Fenetre, ContexteGraphique,
                     "MPI_FILE_READ", NbPoints, Points);
  XNextEvent        (Affichage, &Evenement);
  XClearWindow      (Affichage, Fenetre);

  /* Read via shared file pointers, in individual mode */
  strcpy            (NomFichier, "file_ppiN.dat");
  LectureDonnees    (NomFichier, NbPoints, Points);
  TraceGraphique    (Affichage, Fenetre, ContexteGraphique,
                     "MPI_FILE_READ_SHARED", NbPoints, Points);
  XNextEvent        (Affichage, &Evenement);
  XClearWindow      (Affichage, Fenetre);

  /* Ressources free and kill of the window */
  XFreeGC           (Affichage, ContexteGraphique);
  XDestroyWindow    (Affichage, Fenetre);
  XCloseDisplay     (Affichage);

  exit(0);
}

/* Read data in files */
LectureDonnees (char   *NomFichier,
                int    NbPoints,
                XPoint Points[NbPoints])
{
  FILE *Fichier;
  char *NumeroFichier = strchr (NomFichier, 'N');
  int  IPoint, Point;


  *NumeroFichier = '0';
  if ((Fichier = fopen(NomFichier, "rt")) == NULL) {
     fprintf(stderr, "Error open the file '%s'\n",NomFichier);
     exit(1);
  }

  for (IPoint=0; IPoint<NbPoints/2; IPoint++) {
      fscanf(Fichier, "%d", &Point);
      Points[IPoint].x = Point;
  }
  fclose(Fichier);

  *NumeroFichier = '2';
  if ((Fichier = fopen(NomFichier, "rt")) == NULL) {
     fprintf(stderr, "Error open the file '%s'\n",NomFichier);
     exit(1);
  }
  for (IPoint=0; IPoint<NbPoints/2; IPoint++) {
      fscanf(Fichier, "%d", &Point);
      Points[IPoint].y = 620 - Point;
  }
  fclose(Fichier);

  *NumeroFichier = '1';
  if ((Fichier = fopen(NomFichier, "rt")) == NULL) {
     fprintf(stderr, "Error open the file '%s'\n",NomFichier);
     exit(1);
  }
  for (IPoint=NbPoints/2; IPoint<NbPoints; IPoint++) {
      fscanf(Fichier, "%d\n", &Point);
      Points[IPoint].x = Point;
  }
  fclose(Fichier);

  *NumeroFichier = '3';
  if ((Fichier = fopen(NomFichier, "rt")) == NULL) {
     fprintf(stderr, "Error open the file '%s'\n",NomFichier);
     exit(1);
  }
  for (IPoint=NbPoints/2; IPoint<NbPoints; IPoint++) {
      fscanf(Fichier, "%d", &Point);
      Points[IPoint].y = 620 - Point;
  }
  fclose(Fichier);
}

/* Trace graph */
TraceGraphique (Display  *Affichage,
                Drawable Fenetre,
                GC       ContexteGraphique,
                char     *MessageType,
                int      NbPoints,
                XPoint   Points[NbPoints])
{
  Font          Fonte;
  char          MessageSuite[] = "Clik the window to continue.";

  XDrawLines       (Affichage, Fenetre, ContexteGraphique, Points, NbPoints,
                    CoordModeOrigin);

  /* Load of the melting 12x24 */
  Fonte            = XLoadFont (Affichage, "12x24");
  XSetFont         (Affichage, ContexteGraphique, Fonte);
  XDrawImageString (Affichage, Fenetre, ContexteGraphique, 5, 640,
                    MessageType, strlen(MessageType));

  /* Load of the melting 8x16 */
  Fonte            = XLoadFont (Affichage, "8x16");
  XSetFont         (Affichage, ContexteGraphique, Fonte);
  XDrawImageString (Affichage, Fenetre, ContexteGraphique, 340, 640,
                    MessageSuite, strlen(MessageSuite));
}
