/**************************************************************************
<MODULE NAME>
<FILENAME> mod_list.c </FILENAME>
<HISTORY>
  <MODIFICATION>
    <DATE> </DATE>
    <AUTHOR>  </AUTHOR>
    <DESCRIPTION>
    The list (party) administrator
    Initialization, display, selection...
    </DESCRIPTION>
  </MODIFICATION>
</HISTORY>
</MODULE NAME>
**************************************************************************/

/**************************************************************************
INCLUDE FILES
**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <graphics.h>
#include "defs.h"
#include "list.h"
#include "scrutin.h"
#include "..\CrdReade.r\LibCrdRd.h"
#include "..\LibAlrBx\LIBALRBX.H"

/**************************************************************************
EXTERNAL VARIABLES
**************************************************************************/
extern int       gaiNbListScrut[NB_MAX_SCRUT];
extern int       giCodeVoteEnd;
extern int       giCurrentList;
extern int       giCurrentScr;
extern int       giKlavier;
extern s_Scrutin gshScrutin[10];
extern char      gszArrond[4];
extern unsigned char gucMavType;
extern char    **pszMsg;


/**************************************************************************
FUNCTION PROTOTYPES
**************************************************************************/
extern int   Cand_Display(void);
extern void  Cand_Select(int, int, int);
extern int   Msg_Election(void);
extern int   Pen_Capture(int *, int *);
extern int (*ptfunct)(void);
extern int   Scrut_Loop(void);
extern void  Set_Cursor(int);
extern int   Vote_Empty(void);
extern int   Vote_End(void);

/**************************************************************************
GLOBAL VARIABLES
**************************************************************************/
char    aszTabEff[NB_MAX_SCRUT][NB_MAX_LISTS];   /* effective */
char    aszTabSuppl[NB_MAX_SCRUT][NB_MAX_LISTS]; /* substitute */
s_List *gshList;

/**************************************************************************
LOCAL VARIABLES
**************************************************************************/
static int gaiPosList[NB_MAX_LISTS][4]; /* coordinates */
static int nbre_Liste_Int;
static int giNbrLignes; /* rows of lists */
static int iLineNbCar = 35;
static int iListNbCar = 25;
static int iStartEffPos = 29;
static int iStartSupplPos = 32;

#define QUATRE_EGALE_3_PLUS_1 1 /* sinon 4 = 2+2 */
extern void Wait_Loop(int);
/**************************************************************************
<FUNCTION>
  <NAME> List_Fill </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>
  Reads machvotl.tbl and fills list's structure
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
void List_Fill(FILE *_fpl, int _nbi, int _iScr)
{
  int  iS;
  char bufl[50];
  int j;
  char buffer[10];
  int iEffectif, iSuppleant;
  s_List *shAdrL=NULL;
/* << 9.01b */
  /*static long depl = 0.;*/
  static long depl = 0;
/* 9.01b >> */

  shAdrL = gshList = (s_List *) malloc(sizeof(s_List)* _nbi);
  gshScrutin[_iScr].ptlist = gshList;
  for(j=0;j < _nbi;j++)
  {
    /* Reads line */
    fgets(bufl,iLineNbCar+1,_fpl);
    /* Starting position (machvotc.tbl) */
    ltoa(depl,buffer,10);
    strncpy(gshList->adresse_cand,buffer,6);
    gshList->adresse_cand[6] = '\0';
    /* Code */
    gshList->code_l = bufl[0];
    /* electoral college */
    gshList->college = bufl[1];
    /* List Identification (Num) */
    strncpy(gshList->numlist_l,bufl + 2,2);
    if( gshList->numlist_l[0] == '0') gshList->numlist_l[0] = ' ';
    gshList->numlist_l[2] = '\0';
    /* List Label */
    strncpy(gshList->nom_l,bufl + 4,iListNbCar);
    gshList->nom_l[iListNbCar] = '\0';
    for (iS = iListNbCar-1;
        ((gshList->nom_l[iS] == ' ') && (iS >= 0)); iS--) gshList->nom_l[iS] = '\0';
    /* effective */
    strncpy(gshList->nbreff_l,bufl + iStartEffPos,3);
    gshList->nbreff_l[3] = '\0';
    iEffectif = atoi(gshList->nbreff_l);
    aszTabEff[_iScr][j] = iEffectif;
    /* substitute */
    strncpy(gshList->nbrsup_l,bufl + iStartSupplPos,2);
    gshList->nbrsup_l[2] = '\0';
    iSuppleant = atoi(gshList->nbrsup_l);
    aszTabSuppl[_iScr][j] = iSuppleant;

    /* The last one ? */
    if(j < _nbi-1)
    {
      depl += (iEffectif + iSuppleant) * 81;
      gshList++;
    }
  }
  gshList = shAdrL;
}


/**************************************************************************
<FUNCTION>
  <NAME> List_Init_Display </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
    </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static void List_Init_Display(int *_iNCol, int *_iLg, int *_iRecl,
                              int *_iEspl, int *_iEsph, int *_iH)
{
  int k;
  int diff;
  int ncolonne,lon,recl,espl,esph,h;

  nbre_Liste_Int = 0;
  k = 0;

  while(k <(gaiNbListScrut[giCurrentScr] - 1))
  {
    gshList++;
    k++;
  }
  nbre_Liste_Int = k+1;

  giNbrLignes =  nbre_Liste_Int / 3;
  giNbrLignes +=((nbre_Liste_Int % 3) > 0) ? 1 : 0;
  ncolonne = 3;

  lon = 208; /*210 trop long pour copie d'écran */
  espl = 3;
  esph = 3;
  settextstyle( SMALL_FONT, HORIZ_DIR, 6);

  if(giNbrLignes <= 5)
  {
    h = 60;
    recl = 60;
  }

  if(giNbrLignes > 5 && giNbrLignes <= 6)
  {
    h = 60;
    recl = 56;
  }

  if(giNbrLignes > 6 && giNbrLignes <= 7)
  {
    h = 55;
    recl = 50;
  }

  if(giNbrLignes > 7 && giNbrLignes <= 8)
  {
    h = 55;
    recl = 42;
  }

  if(giNbrLignes > 8 && giNbrLignes <= 9)
  {
    h = 55;
    recl = 36;
  }

  if(giNbrLignes > 9 && giNbrLignes <= 10)
  {
    h = 55;
    recl = 32;
  }

  if(giNbrLignes > 10 && giNbrLignes <= 11)
  {
    h = 55;
    recl = 30;
  }

  if(giNbrLignes > 11 && giNbrLignes <= 12)
  {
    h = 55;
    recl = 25;
  }

  if(giNbrLignes > 12 && giNbrLignes <= 13)
  {
    h = 55;
    recl = 25;
  }

  if(giNbrLignes > 13 && giNbrLignes <= 14)
  {
    --esph;
    h = 55;
    recl = 25;
  }

  /* Output */
  (*_iNCol) = ncolonne;
  (*_iLg)   = lon;
  (*_iRecl) = recl;
  (*_iEspl) = espl;
  (*_iEsph) = esph;
  (*_iH)    = h;
}

/**************************************************************************
<FUNCTION>
  <NAME> List_Check_Selection </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
    </DESCRIPTION>
</FUNCTION>
**************************************************************************/
static int List_Check_Selection(int _iX, int _iY)
{
  /* Empty (Blanco Stem) ? */
  if((_iX > gaiPosList[nbre_Liste_Int - 1][0] + 2) && (_iX < gaiPosList[nbre_Liste_Int - 1][1] - 2))
    if((_iY > gaiPosList[nbre_Liste_Int - 1][2] + 2) && (_iY < gaiPosList[nbre_Liste_Int - 1][3] - 2))
    {
      ptfunct = Vote_Empty;
      return(1);
    }

  /* Not a empty vote */
  for(giCurrentList = 0;giCurrentList < nbre_Liste_Int - 1;giCurrentList++)
  {
    if((_iX > gaiPosList[giCurrentList][0] + 2) && (_iX < gaiPosList[giCurrentList][1] - 2))
      if ((_iY > gaiPosList[giCurrentList][2] + 2) && (_iY < gaiPosList[giCurrentList][3] - 2))
      {
        /* Display the candidates' screen */
        ptfunct = Cand_Display;
        return(1);
      }
  }

  return(0);
}

/**************************************************************************
<FUNCTION>
  <NAME> List_Display </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>

  </DESCRIPTION>
  <RETURNS>
    <TYPE> int </TYPE>
    <DESCRIPTION> cfr "int (*ptfunct)(void)" </DESCRIPTION>
  </RETURNS>
</FUNCTION>
**************************************************************************/
int List_Display(void)
{
 char caisse[30],buf[30];
 int i,j,k,x,y, iCl, iMsgId;
 int ncolonne,lon,recl,espl,esph,h;
 int iPenX, iPenY, iPenCapture, iHwdDisconnected;
 int iNumX;

 setfillstyle(SOLID_FILL, BLACK);
 bar(0,0,639,479);
 setcolor(WHITE);
 settextstyle( SMALL_FONT, HORIZ_DIR, 6);
 settextjustify( CENTER_TEXT, CENTER_TEXT );
 /* Looking for the message id corresponding to the current ballot */
 iMsgId = Msg_Election();
 outtextxy(320, 10, pszMsg[iMsgId]);
 outtextxy(319, 10, pszMsg[iMsgId]);
 outtextxy(320, 35, pszMsg[54]);
 settextjustify( LEFT_TEXT, CENTER_TEXT );
 setfillstyle(SOLID_FILL,WHITE);
 setcolor(BLACK);

 gshList = gshScrutin[giCurrentScr].ptlist;
 List_Init_Display(&ncolonne,&lon,&recl,&espl,&esph,&h);
 gshList = gshScrutin[giCurrentScr].ptlist;

 settextstyle(SMALL_FONT, HORIZ_DIR, 4);
 for(iCl=0,k=0,x=4;
     (k < gaiNbListScrut[giCurrentScr]) && (iCl < ncolonne);
     x+= espl + lon,iCl++)
   for(j = 0,y = h;
       (j < giNbrLignes) && (k < gaiNbListScrut[giCurrentScr]);
       k++)
   {
     if(QUATRE_EGALE_3_PLUS_1)
     {
       if(iCl == 1) /* If the second column */
       {
         if(j == giNbrLignes-1) /* If "last but one" row */
         {
           if(gaiNbListScrut[giCurrentScr] != (giNbrLignes*3) &&
              gaiNbListScrut[giCurrentScr] != (giNbrLignes*3)-1)
           {
             break; /* if 9 lists + empty -> 10 items
                       col1 = 4 items, col2 = 3 items, col3 = 3 items
                       X                X                 X
                       X                X                 X
                       X                X                 X
                       X*/
           }
         }
       }
     } /* QUATRE_EGALE_3_PLUS_1 */
     /* Get coordinates */
     gaiPosList[k][0] = x;
     gaiPosList[k][1] = x + lon;
     gaiPosList[k][2] = y;
     gaiPosList[k][3] = y + recl;
     /* Draw bar */
     bar(x,y,x + lon,y + recl);

     /* Displays num and label */
     if(k < (gaiNbListScrut[giCurrentScr] - 1))
     {
       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';
       settextjustify( CENTER_TEXT, CENTER_TEXT );
       iNumX = x+11;
       outtextxy( iNumX, y + recl/2, gshList->numlist_l);
       outtextxy( iNumX+1, y + recl/2, gshList->numlist_l);
       settextjustify( LEFT_TEXT, CENTER_TEXT );
       outtextxy( x + 28, y + recl/2, gshList->nom_l);
       outtextxy( x + 29, y + recl/2, gshList->nom_l);
     }
     else
     {
/* << 9.01c */
       settextstyle(SMALL_FONT, HORIZ_DIR, 5);
/* 9.01c >> */
       outtextxy(x + 28, y + recl/2, pszMsg[46]);
       outtextxy(x + 29, y + recl/2, pszMsg[46]);
     }
     j++;
     y+=esph + recl;
     gshList++;
   }

  Set_Cursor(CURSOR_XY);

  while(giKlavier) /* while ! interrupted */
  {
    Set_Cursor(CURSOR_ON);
    iHwdDisconnected = iPenCapture = Pen_Capture(&iPenX, &iPenY);
    if(iPenCapture == 1)
    {
      Set_Cursor(CURSOR_OFF);
      if(List_Check_Selection(iPenX, iPenY)) return(0);
    }
    PEN_OR_ALARMBOX_DISCONNECTED
  }
  Set_Cursor(CURSOR_OFF);

  giCodeVoteEnd = 13;
  ptfunct = Vote_End;
  return(0);
}
