/**************************************************************************
<MODULE NAME>
<FILENAME> mod_cand.c </FILENAME>
<HISTORY>
  <MODIFICATION>
    <DATE> </DATE>
    <AUTHOR>  </AUTHOR>
    <DESCRIPTION>
    Candidates Administrator
    </DESCRIPTION>
  </MODIFICATION>
</HISTORY>
</MODULE NAME>
**************************************************************************/

/**************************************************************************
INCLUDE FILES
**************************************************************************/
#include <bios.h>
#include <io.h>
#include <fcntl.h>
#include <alloc.h>
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <graphics.h>
#include "candid.h"
#include "defs.h"
#include "scrutin.h"
#include "..\CrdReade.r\LibCrdRd.h"
#include "..\LibAlrBx\LIBALRBX.H"

/**************************************************************************
EXTERNAL VARIABLES
**************************************************************************/
extern char      arcMemoCandid[NB_MAX_SCRUT][NB_MAX_LISTS][NB_MAX_CANDID];
extern char      arcMemoList[NB_MAX_SCRUT][NB_MAX_LISTS];
extern char      arcMemoScrutin[NB_MAX_SCRUT];
extern char      aszTabEff[NB_MAX_SCRUT][NB_MAX_LISTS];
extern char      aszTabSuppl[NB_MAX_SCRUT][NB_MAX_LISTS];
extern char      gcCardRW;
extern int       giCodeVoteEnd;
extern int       giCurrentCandid;
extern int       giCurrentList;
extern int       giCurrentScr;
extern int       giKlavier;
extern s_List   *gshList;
extern s_Scrutin gshScrutin[10];
extern int       giSWCard;
extern char      gszArrond[4];
extern unsigned char gucMavType;
extern char    **pszMsg;

/**************************************************************************
FUNCTION PROTOTYPES
**************************************************************************/
extern int   List_Display(void);
extern int   Msg_Election(void);
extern void  Msg_Error_Exit(char *);
extern int   Pen_Capture(int *, int *);
extern int (*ptfunct)(void);
extern void  Screen_Cand_Actions_Allowed(int);
extern void  Screen_Start_Verif(void);
extern void  Screen_Viewing_Next(void);
extern int   Scrut_Loop(void);
extern void  Set_Cursor(int);
extern int   Vote_End(void);
extern void  zero_select(int, int, int);
extern void  Wait_Loop_Int(int);

/**************************************************************************
GLOBAL VARIABLES
**************************************************************************/
int gaiPosc[100][4];

/**************************************************************************
LOCAL VARIABLES
**************************************************************************/
static int     gaiCandidCol[5];
static int     giDebutAffichageY;
static int     giCadreCandidH;
static int     giInterCandidL, giInterCandidC;
static int     giNbCandidCol;
static int     giNbCandidSel; /* Number of selected candidates */
static int     giNombreCol;
static int     giSaisieCandidH, giSaisieCandidL,giCadreCandidL;
static int     giXDep;
static int     giXCapture, giYCapture;
static int     giNomY, giPrenomY;
static s_Cand *gshCand=NULL;
static int     swconf;
static int     swnoir;
static int     swpas;

static int     giViewCandSelectedMode = 0; /* if 1 -> selected candidates
                                 are directly shown like selected (faster) */

#define SECOND_LINE_CENTERED 0

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Fill </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Reads machvotc.tbl and fills candidate's structure
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static void Cand_Fill(void)
{
  long deplacement_file_cand;
  char bufc[100],caisse[35];
  char vide[26];
  int j, k, kp;
  char *p;
  FILE *fpc;
  static s_Cand *shCand=NULL;

  memset(vide,' ',26);
  if(shCand != NULL) free(shCand);
  /* Get the list */
  gshList = gshScrutin[giCurrentScr].ptlist;
  for (giCurrentCandid = 0; giCurrentCandid < giCurrentList;giCurrentCandid++)gshList++;
  /* Get the starting position in machvotc.tbl */
  deplacement_file_cand = atol(gshList->adresse_cand);

  /* Number of candidates */
  kp = aszTabEff[giCurrentScr][giCurrentList] + aszTabSuppl[giCurrentScr][giCurrentList];
  /* Open the machvotc.tbl */
  fpc = fopen("machvotc.tbl","r");
  if(fpc == NULL) Msg_Error_Exit("MACHVOTC FILE ERROR");

  /* Go to the right position */
  fseek(fpc,deplacement_file_cand,0);

  /* structures' allocation */
  shCand = gshCand = (s_Cand *) malloc(sizeof(s_Cand) * kp);
  if(shCand == NULL) Msg_Error_Exit("MALLOC RAM ERROR");
  /* Read candidates */
  for(k=0; k < kp; k++)
  {
    /* Read line */
    fgets(bufc,81,fpc);
    /* code */
    gshCand->code_c = bufc[0];
    /* NumList */
    strncpy(gshCand->numlist_c,bufc + 1,2);
    gshCand->numlist_c[2] = '\0';
    /* Name */
    caisse[25] = '\0';
    strncpy(caisse,vide,25);
    strncpy(caisse,bufc + 3,25);
    j = 24;
    while(caisse[j] == ' ' && j >= 0) caisse[j--] = 0x00;
    strcpy(gshCand->nom_c,caisse);
    /* firstname */
    strncpy(caisse,vide,25);
    strncpy(caisse,bufc + 3 + 25,25);
    j = 24;
    while(caisse[j] == ' ' && j >= 0) caisse[j--] = 0x00;
    strcpy(gshCand->prenom_c,caisse);
    /* "second" firstname */
    strncpy(caisse,vide,25);
    strncpy(caisse,bufc + 3 + 50,25);
    j = 24;
    while(caisse[j] == ' ' && j >= 0) caisse[j--] = 0x00;
    strcpy(gshCand->prenom2_c,caisse);
    /* Effective or Subsitute */
    gshCand->E_S = bufc[78];

    /* Next Candidate */
    if(k < kp-1) gshCand++;
  }
  gshCand = shCand;
  fclose(fpc);
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Init_Display </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Get the graphicals coordinates, lengths... to manage the screen
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static void Cand_Init_Display(void)
{
  int nbr_max;

  nbr_max = atoi(gshScrutin[giCurrentScr].scrutin_max_cand) - 1; /* 1: head */

  if (nbr_max <= 16)
  {
    giNombreCol = 1;
    gaiCandidCol[giCurrentScr] = giNbCandidCol =  16;
    giDebutAffichageY =  34;
    giCadreCandidH   =  23;
    giNomY           =   5;
    giPrenomY        =  16;
    giInterCandidL   =   2;
    giCadreCandidL   = 202;
    giInterCandidC   = 216;
    giSaisieCandidH  =  20;
    giSaisieCandidL  =  30;
    giXDep           =  (640 - giCadreCandidL) /2;
    giXCapture       = giCadreCandidL / 2;
    giYCapture       = (giCadreCandidH -8) / 2; /* 8 = circle's diam */
    return;
  }

  if (nbr_max <= 32)
  {
    giNombreCol = 2;
    gaiCandidCol[giCurrentScr] = giNbCandidCol =  16;
    giDebutAffichageY =  34;
    giCadreCandidH   =  23;
    giNomY           =   5;
    giPrenomY        =  16;
    giInterCandidL   =   2;
    giCadreCandidL   = 202;
    giInterCandidC   = 126;

    giSaisieCandidH  =  20;
    giSaisieCandidL  =  30;
    giXDep           =  (640 - 2* giCadreCandidL - giInterCandidC) /2;
    giXCapture       = giCadreCandidL / 2;
    giYCapture       = (giCadreCandidH -8) / 2; /* 8 = circle's diam */
    return;
  }

  if ((nbr_max > 32) && (nbr_max <= 48))
  {
    giNombreCol = 3;
    gaiCandidCol[giCurrentScr] = giNbCandidCol =  16;
    giDebutAffichageY =  34;
    giCadreCandidH   =  23;
    giNomY           =   5;
    giPrenomY        =  16;
    giInterCandidL   =   2;
    giCadreCandidL   = 202;
    giInterCandidC   = 10;
    giXDep           = (640 - 3*giCadreCandidL - 2*giInterCandidC) /2;
    giSaisieCandidH  =  20;
    giSaisieCandidL  =  30;
    giXCapture       = giCadreCandidL / 2;
    giYCapture       = (giCadreCandidH -8) / 2; /* 8 = circle's diam */
    return;
  }

  if ((nbr_max > 48) && (nbr_max <= 51))
  {
    giNombreCol = 3;
    gaiCandidCol[giCurrentScr] = giNbCandidCol =  17;
    giDebutAffichageY =  34;
    giCadreCandidH   =  22;
    giNomY           =   5;
    giPrenomY        =  14;
    giInterCandidL   =   2;
    giCadreCandidL   = 202;
    giInterCandidC   = 10;
    giXDep           = (640 - 3*giCadreCandidL - 2*giInterCandidC) /2;
    giSaisieCandidH  =  20;
    giSaisieCandidL  =  30;
    giXCapture       = giCadreCandidL / 2;
    giYCapture       = (giCadreCandidH -8) / 2; /* 8 = circle's diam */
    return;
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Update </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>
  The "user" did something (de/selection) ... update the display
  </DESCRIPTION>
  <PARAMETERS>
    <PARAMETER>
      <NAME> _iCandid </NAME>
      <TYPE> int </TYPE>
      <IO> IN </IO>
      <DESCRIPTION>
      Candidate's id
      </DESCRIPTION>
    </PARAMETER>
  </PARAMETERS>
</FUNCTION>
**************************************************************************/
#pragma argsused
void Cand_Update(int _iCandid)
{
  /* Candidate selected ? */
  if(arcMemoCandid[giCurrentScr][giCurrentList][_iCandid] == 1)
  {
    if((swnoir == 0) && (gcCardRW == CARD_WRITE))
    {
      swnoir = 1;
      if(swconf == 0)
      {
        swconf = 1;
        swpas = 1;
        Screen_Cand_Actions_Allowed(swconf);
      }
    }
  }
  else /* Candidate unselected */
  {
    if((swpas == 0) && (gcCardRW == CARD_WRITE))
    {
      Screen_Cand_Actions_Allowed(swconf);
      swpas = 1;
    }
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Coord </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Gives the coordinates of a candidate's (it's frame)
  </DESCRIPTION>
  <PARAMETERS>
    <PARAMETER>
      <NAME> z </NAME>
      <TYPE> int </TYPE>
      <IO> IN </IO>
      <DESCRIPTION>
      Candidate's id
      </DESCRIPTION>
    </PARAMETER>
    <PARAMETER>
      <NAME> x1, x2, y1, y2 </NAME>
      <TYPE> int * </TYPE>
      <IO> OUT </IO>
      <DESCRIPTION>
      Rect's coordinates
      </DESCRIPTION>
    </PARAMETER>
  </PARAMETERS>
</FUNCTION>
**************************************************************************/
static void Cand_Coord(int z, int *x1, int *x2, int *y1, int *y2)
{
  if(z != 0) /* A single candidate */
  {
    (*x1) = (gaiPosc[z][1] - giCadreCandidL) + 1;
    (*x2) = ((*x1) + giCadreCandidL);
    (*x2) -= giSaisieCandidL;
    (*y1) = gaiPosc[z][2];
    (*y2) = (*y1) + giCadreCandidH;
  }
  else /* list's head */
  {
    (*x1) = gaiPosc[z][0];
    (*x2) = gaiPosc[z][1]+1;
    (*y1) = gaiPosc[z][2];
    (*y2) = gaiPosc[z][3]+1;
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Reverse </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Reverse the background color (e.g. the de/selection of a candidate)
  </DESCRIPTION>
  <PARAMETERS>
    <PARAMETER>
      <NAME> _iX1,_iX2,_iY1,_iY2 </NAME>
      <TYPE> int </TYPE>
      <IO> IN </ IO >
      <DESCRIPTION>
      The coordinates of the area
      </DESCRIPTION>
    </PARAMETER>
    <PARAMETER>
      <NAME> _iCol1 </NAME>
      <TYPE> int </TYPE>
      <IO> IN </ IO >
      <DESCRIPTION>
      The color to replace
      </DESCRIPTION>
    </PARAMETER>
    <PARAMETER>
      <NAME> _iCol2 </NAME>
      <TYPE> int </TYPE>
      <IO> IN </ IO >
      <DESCRIPTION>
      The new color
      </DESCRIPTION>
    </PARAMETER>
  </PARAMETERS>
</FUNCTION>
**************************************************************************/
static void Cand_Reverse(int _iX1, int _iX2, int _iY1, int _iY2,
                         int _iCol1, int _iCol2)
{
 int x,y;

  for(x = _iX1;x < _iX2;x++)
    for(y = _iY1;y < _iY2;y++)
      if(getpixel(x,y) == _iCol1)
        putpixel(x,y,_iCol2);
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Switch </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static void Cand_Switch(int _iZ1)
{
 int ax1, ax2, ay1, ay2;

  /* Get coordinates */
  Cand_Coord(_iZ1, &ax1, &ax2, &ay1, &ay2);
  setfillstyle(SOLID_FILL, BLACK);
  if(_iZ1 > 0)/*|| !giSWCandidRadio)*/
  {
    if(arcMemoCandid[giCurrentScr][giCurrentList][_iZ1] == 1)/* was Selected */
      Cand_Reverse(ax1,ax2,ay1,ay2, WHITE, 7); /* White -> LightGrey */
    else
      Cand_Reverse(ax1,ax2,ay1,ay2, 7, WHITE); /* LightGrey -> White */
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Circle </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Draw a circle ("checkbox", like paper vote)
  </DESCRIPTION>
  <PARAMETERS>
    <PARAMETER>
      <NAME> z </NAME>
      <TYPE> int </TYPE>
      <IO> IN </IO>
      <DESCRIPTION>
      Candidate's id
      </DESCRIPTION>
    </PARAMETER>
  </PARAMETERS>
</FUNCTION>
**************************************************************************/
static void Cand_Circle(int z)
{
 int xc,yc,diam;
 int ax1, ax2, ay1, ay2;
 xc = gaiPosc[z][1];

 /* Get Coordinates */
 Cand_Coord(z, &ax1, &ax2, &ay1, &ay2);

 if(z == 0) /* list's head */
 {
    xc -= (gaiPosc[z][1] - gaiPosc[z][0] ) / 2;
    yc = 15;
    diam = 11;
 }
 else /* One specific candidate */
 {
    xc = xc - giSaisieCandidL / 2;
    yc = gaiPosc[z][2];
    yc = yc + (giCadreCandidH / 2);
    diam = 8;
 }

 settextstyle(SMALL_FONT, HORIZ_DIR, 6);
 setcolor(8);
 circle(xc ,yc , diam);
 if(arcMemoCandid[giCurrentScr][giCurrentList][z] == 1) /* Selected */
 {
   setfillstyle(SOLID_FILL, BLACK);
   floodfill(xc ,yc ,8);
   Cand_Switch(z);
 }
 else /* Unselected */
 {
   setfillstyle(SOLID_FILL, WHITE);
   floodfill(xc,yc, 8);
 }
 setcolor(BLACK);
 setfillstyle(SOLID_FILL, WHITE);
 settextstyle(SMALL_FONT, HORIZ_DIR, 4);
}

/**************************************************************************
<FUNCTION>
  <NAME> Display_Candidates_Attributes </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Display the candidate's attributes (name, firstname)
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static void Display_Candidates_Attributes(int _iX, int _iY)
{
 int iType; /* Name(1), Name & Firstname(2) */

  iType = 0;
  if(gshCand->nom_c[0] != 0x00)    iType = 1;
  if(gshCand->prenom_c[0] != 0x00) iType = 2;

  settextjustify(LEFT_TEXT,CENTER_TEXT);
  outtextxy(_iX +22/*1*/, _iY + giNomY, gshCand->nom_c);
  if(iType == 2)
  {
    if(!SECOND_LINE_CENTERED)
      outtextxy(_iX +22/*1*/,_iY + giPrenomY, gshCand->prenom_c);
    else
    {
      settextjustify(CENTER_TEXT,CENTER_TEXT);
      outtextxy(_iX+ (giCadreCandidL-28) /2,_iY + giPrenomY, gshCand->prenom_c);
    }
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cancel_Selection </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Reset vote's memory
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static void Cancel_Selection(int x, int y, int sw)
{
  int m;

  arcMemoScrutin[x] = 0;
  arcMemoList[x][y] = 0;

  for(m = 0; m < NB_MAX_CANDID-1; m++)
  {
    if(arcMemoCandid[x][y][m] != 0)
    {
      arcMemoCandid[x][y][m] = 0;
      if(sw)
      {
        Cand_Update(m);
        Cand_Circle(m);
        Cand_Switch(m);
      }
    }
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Select </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>
  Specify that a selection has been done
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
void Cand_Select(int _x, int _y, int _z)
{
  arcMemoCandid[_x][_y][_z] = 1;
  arcMemoList[_x][_y] = 1;
  arcMemoScrutin[_x] = 1;
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Check_Selection </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Action (go back, validation) (with the Light Pen)
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static int Cand_Check_Selection(int _iX, int _iY)
{
  int i, x1, x2, y1, y2;

  if(_iY > 452) /* At the bottom (Validate/Cancel or
                   go back tho the lists) */
  {
    if(giNbCandidSel != 0) /* Almost one candidate selected */
    {
      if((_iX > 10) && (_iX < 310)) /* Validation */
      {
        ++giCurrentScr;
        ptfunct = Scrut_Loop;
        return(1);
      }
      if((_iX > 330) && (_iX < 630)) /* Cancel */
      {
        giNbCandidSel = 0;
        swpas   = 0;
        swnoir  = 0;
        swconf  = 0;
        Cancel_Selection(giCurrentScr,giCurrentList,1);
        return(0);
      }
      return(0);
    }
    else /* No candidate selected -> go back to the list selection */
    {
      if((_iX > 110) && (_iX < 530))
      {
        ptfunct = List_Display;
        return(1);
      }
      else /* Not managed */
        return(0);
    }
  }
  else /* Candidate's areas */
  {
    for(i=0;i<=giCurrentCandid;i++) /* Who has been selected ? (LightPen) */
    {
      x1 = gaiPosc[i][0];
      x2 = gaiPosc[i][1];
      y1 = gaiPosc[i][2];
      y2 = gaiPosc[i][3];
      if(i) /* A specific candidate (not the "head of the list") */
      {
        x1 += giXCapture;
        x2 -= giYCapture;
        y1 += giYCapture;
        y2 -= giYCapture;
      }
      if((_iX>=x1) && (_iX<x2))
      {
        if((_iY>=y1) && (_iY<=y2)) /* This area */
        {
          if(arcMemoCandid[giCurrentScr][giCurrentList][i] == 0) /* Unselected -> Selected */
          {
            ++giNbCandidSel; /* cfr iSWDeselectC */
            Cand_Select(giCurrentScr,giCurrentList,i);
            Cand_Update(i);
            Cand_Circle(i);
            Cand_Switch(i);
            return(0);
          }
        }
      }
    }
    return(0);
  }
}

/**************************************************************************
<FUNCTION>
  <NAME> Cand_Display </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>
  </DESCRIPTION>
  <RETURNS>
    <TYPE> int </TYPE>
    <DESCRIPTION>
    cfr "int (*ptfunct)(void)"
    </DESCRIPTION>
  </RETURNS>
</FUNCTION>
**************************************************************************/
int Cand_Display(void)
{
 int Rest_Div, Tampon,nombre_col_bis;
 char buf[30], bufitoa[10];
 int k, j, x, y, iMsgId;
 int iPenX, iPenY, iPenCapture, iHwdDisconnected;

  Rest_Div = giNbCandidSel = swconf = swnoir = swpas = 0;

  /* Init positions, coordinates, lengths... */
  Cand_Init_Display();

  /* Reads machvotc.tbl and fills candidate's structure */
  Cand_Fill();

  /**************************   Head  ****************************/
  buf[0]=gshScrutin[giCurrentScr].nom_s;
  buf[1]= 0x00;
  strcat(buf,gshList->numlist_l);
  buf[3]=gshList->college;
  buf[4]=0x00;
  if(buf[1] == ' ')   buf[1] = '0';

  setfillstyle(SOLID_FILL, BLACK);
  bar(0,0,639,479);
  setfillstyle(SOLID_FILL,WHITE);
  settextstyle(SMALL_FONT, HORIZ_DIR, 6);
  setfillstyle(SOLID_FILL,7);

  /* Area */
  gaiPosc[0][0] = 82;
  gaiPosc[0][1] = gaiPosc[0][0] + 50;
  gaiPosc[0][2] = 2;
  gaiPosc[0][3] = 27;
  bar(gaiPosc[0][0] + 10 ,gaiPosc[0][2], gaiPosc[0][1] - 10 , gaiPosc[0][3]);
  Cand_Circle(0);

  /* Top Right -> current election (commune/province...) */
  setfillstyle(SOLID_FILL,WHITE);
  setcolor(WHITE);
  settextjustify(RIGHT_TEXT,CENTER_TEXT);
  settextstyle( SMALL_FONT, HORIZ_DIR, 5);
  /* Looking for the Label_id corresponding to the current election */
  iMsgId = Msg_Election() +1;
  outtextxy( 630, 13, pszMsg[iMsgId]);
  outtextxy( 629, 13, pszMsg[iMsgId]);
  settextstyle( SMALL_FONT, HORIZ_DIR, 6);

  /* List 's label */
  settextjustify(RIGHT_TEXT,CENTER_TEXT);
  outtextxy(  gaiPosc[0][0] -10, 13, gshList->numlist_l);
  outtextxy(  gaiPosc[0][0] -11, 13, gshList->numlist_l);
  outtextxy(  gaiPosc[0][0] -10, 14, gshList->numlist_l);
  outtextxy(  gaiPosc[0][0] -11, 14, gshList->numlist_l);

  settextjustify(LEFT_TEXT,CENTER_TEXT);
  outtextxy( gaiPosc[0][1] +10, 13, gshList->nom_l);
  outtextxy( gaiPosc[0][1] +11, 13, gshList->nom_l);
  outtextxy( gaiPosc[0][1] +10, 14, gshList->nom_l);
  outtextxy( gaiPosc[0][1] +11, 14, gshList->nom_l);

  /* If view: selected ? */
  if(!giViewCandSelectedMode) Cand_Switch(0);

  /* A separation line */
  setcolor( WHITE);
  line(0,30,639,30);  /* ligne de sparation. */

  /* The candidate's area */
  settextjustify(CENTER_TEXT,CENTER_TEXT);
  settextstyle( SMALL_FONT, HORIZ_DIR, 4);
  setcolor( BLACK);

  /* How much candidates to manage ? */
  giCurrentCandid = aszTabEff[giCurrentScr][giCurrentList] + aszTabSuppl[giCurrentScr][giCurrentList];

  if(aszTabSuppl[giCurrentScr][giCurrentList] > 0) giNombreCol--;

  nombre_col_bis  = aszTabEff[giCurrentScr][giCurrentList] / giNbCandidCol;
  if((aszTabEff[giCurrentScr][giCurrentList] % giNbCandidCol) > 0) nombre_col_bis++;
  if(nombre_col_bis < giNombreCol)   giNombreCol = nombre_col_bis;

  giNbCandidCol = (aszTabEff[giCurrentScr][giCurrentList] / (giNombreCol));
  Rest_Div = (aszTabEff[giCurrentScr][giCurrentList] % (giNombreCol));
  if(giNbCandidCol > 23)
  { giNbCandidCol  = 23;
    Rest_Div =  0;
  }

  /* Display the candidates */
  for(k=1,x = giXDep;(k < aszTabEff[giCurrentScr][giCurrentList] + 1);x+= giCadreCandidL + giInterCandidC)
  {
     if((Rest_Div == 0) || (giNbCandidCol == gaiCandidCol[giCurrentScr])) Tampon = giNbCandidCol;
     else
     {
       Tampon = giNbCandidCol + 1;
       Rest_Div--;
     }
     for( j = 0,y = giDebutAffichageY;
          (k < aszTabEff[giCurrentScr][giCurrentList] + 1) && j < Tampon;
          y+= giCadreCandidH + giInterCandidL,k++,j++)
     {
       gaiPosc[k][0]= x;
       gaiPosc[k][1]= (x + giCadreCandidL) - 1;
       gaiPosc[k][2]=  y;
       gaiPosc[k][3]= (y + giCadreCandidH) - 1;

       settextjustify(CENTER_TEXT,CENTER_TEXT);
       settextstyle( SMALL_FONT, HORIZ_DIR, 5);
       setcolor( WHITE);
       settextjustify(CENTER_TEXT,CENTER_TEXT);
       settextstyle( SMALL_FONT, HORIZ_DIR, 4);
       setcolor( BLACK);

       setfillstyle(SOLID_FILL,WHITE);
       bar(x,y,gaiPosc[k][1],gaiPosc[k][3]);

       /* Num */
       settextjustify(CENTER_TEXT,CENTER_TEXT);
       settextstyle( SMALL_FONT, HORIZ_DIR, 5);
       outtextxy(x + 10,(y + giCadreCandidH/2) -2, itoa(k,bufitoa,10));
       outtextxy(x + 11,(y + giCadreCandidH/2) -2, itoa(k,bufitoa,10));
       settextstyle( SMALL_FONT, HORIZ_DIR, 4);
       /* Sep */
       setfillstyle(SOLID_FILL,BLACK);
       bar(x+20,y,x+20,gaiPosc[k][3]);

       setfillstyle(SOLID_FILL,7);
       bar((x+giCadreCandidL)-giSaisieCandidL, y, gaiPosc[k][1], gaiPosc[k][3]);
       Display_Candidates_Attributes(x, y);
       Cand_Update(k);
       Cand_Circle(k);
       /*Cand_Switch(k);*/
       gshCand++;
     }
  }

  settextjustify(CENTER_TEXT,CENTER_TEXT);
  settextstyle(SMALL_FONT, HORIZ_DIR, 6);
  setcolor( WHITE);

  /* Substitute(s) */
  if ((aszTabSuppl[giCurrentScr][giCurrentList] > 0) && ( aszTabEff[giCurrentScr][giCurrentList] < 70))
  {
    x = 639 -( giXDep + giCadreCandidL);
    y = giDebutAffichageY;
    j = 1;
    outtextxy(x + (giCadreCandidL + giSaisieCandidL) / 2 ,y + ((giCadreCandidH/2) - giInterCandidL) - 1,pszMsg[47]);
    outtextxy(x + ((giCadreCandidL + giSaisieCandidL) / 2 ) + 1 ,y + ((giCadreCandidH/2) - giInterCandidL) - 1,pszMsg[47]);
    settextstyle( SMALL_FONT, HORIZ_DIR, 4);
    setcolor( BLACK);
  }
  else
  {
    if((aszTabSuppl[giCurrentScr][giCurrentList] > 0) && ( aszTabEff[giCurrentScr][giCurrentList] > 69))
    {
      j = j++;
      x-= giCadreCandidL + giInterCandidC;
      outtextxy(x + (giCadreCandidL + giSaisieCandidL) / 2,y + ((giCadreCandidH/2) - giInterCandidL) - 1,pszMsg[47]);
      outtextxy(x + ((giCadreCandidL + giSaisieCandidL)/ 2 ) + 1 ,y + ((giCadreCandidH/2) - giInterCandidL) - 1,pszMsg[47]);
      settextstyle( SMALL_FONT, HORIZ_DIR, 4);
      setcolor( BLACK);
    }
  }
  settextjustify(LEFT_TEXT,CENTER_TEXT);

  for(;(k<giCurrentCandid+1);x+=giCadreCandidL+giInterCandidC,y=0,j=0)
  {
    for(y +=((giCadreCandidH+giInterCandidL));
        (k<giCurrentCandid+1);
        y+=giCadreCandidH + giInterCandidL,k++,j++)
    {
      if(j == 0) y += giDebutAffichageY - (giCadreCandidH + giInterCandidL);

      gaiPosc[k][0]= x;
      gaiPosc[k][1]= (x + giCadreCandidL) - 1;
      gaiPosc[k][2]=  y;
      gaiPosc[k][3]= (y + giCadreCandidH) - 1;

      setfillstyle(SOLID_FILL,WHITE);
      bar(x,y,gaiPosc[k][1],gaiPosc[k][3]);

      setfillstyle(SOLID_FILL,7);
      bar((x+giCadreCandidL)-giSaisieCandidL, y, gaiPosc[k][1], gaiPosc[k][3]);

      Display_Candidates_Attributes(x, y);
      Cand_Update(k);
      Cand_Circle(k);
      Cand_Switch(k);
      gshCand++;
    }
  }
  Set_Cursor(CURSOR_XY);

  /* Visualisation mode */
  if(gcCardRW == CARD_READ)
  {
    Screen_Viewing_Next();
    Wait_Loop_Int(10);
    return(0);
  }

  /* Waiting for an intervention (Interruption (button pressed)
     or selection (LightPen)) */
  giKlavier = 1;
  while(giKlavier)
  {
    Set_Cursor(CURSOR_ON);
    iHwdDisconnected = iPenCapture = Pen_Capture(&iPenX, &iPenY);
    if(iPenCapture == 1)
    {
      Set_Cursor(CURSOR_OFF);
      if(Cand_Check_Selection(iPenX, iPenY))
        return(0);
    }
    PEN_OR_ALARMBOX_DISCONNECTED
  }

  /* Interruption */
  Set_Cursor(CURSOR_OFF);
  giCodeVoteEnd = 13;
  ptfunct = Vote_End;
  return(0);
}
