/**************************************************************************
<MODULE NAME>
<FILENAME> mod_scru.c (scrutin) </FILENAME>
<HISTORY>
  <MODIFICATION>
    <DATE> </DATE>
    <AUTHOR> </AUTHOR>
    <DESCRIPTION>
    Jeton (token)
    machvots.tbl
    ballots' results
    ballots' sequence
    ballots' loop (access control (National/Stranger))
    </DESCRIPTION>
  </MODIFICATION>
</HISTORY>
<FUNCTIONS>

</FUNCTIONS>
</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 "cfgscrut.h"
#include "defs.h"
#include "scrutin.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 unsigned char guszCard[75];
extern int     giCurrentScr;
extern int     giSWCard;
extern char   *pszMsg1[N_SCR_MESSAGE];
extern char  **pszMsg;

/**************************************************************************
FUNCTION PROTOTYPES
**************************************************************************/
extern void  Calcul_Crc(char *, int);
extern void  Card_Crc_Write(char *);
extern void  Card_Written(char *);
extern int   List_Display(void);
extern void  List_Fill(FILE *, int, int);
extern void  Msg_Error_Exit(char *);
extern int   Para_Read(void);
extern int (*ptfunct)(void);
extern void  Vote_Encode(char *, int, int, int *);
extern int   Vote_End(void);

/**************************************************************************
GLOBAL VARIABLES
**************************************************************************/
int  gaiNbListScrut[NB_MAX_SCRUT]; /* Amount of lists by ballot */
int  giNbrScrutin;
int  giCardNBytes;
int  giVoteMaxBytes;
char gszJeton[16];
char gszJetonMini[6];
char gszArrond[4];
s_CFGSCRUT gshCfgScrut[NMX_SCRUTIN_T+1] = { {0, 0, 0},
        {VM_EUROPE,   NMXV_EUROPE,   NMXB_EUROPE},
        {VM_CHAMBRE,  NMXV_CHAMBRE,  NMXB_CHAMBRE},
        {VM_SENAT,    NMXV_SENAT,    NMXB_SENAT},
        {VM_REGION,   NMXV_REGION,   NMXB_REGION},
        {VM_PROVINCE, NMXV_PROVINCE, NMXB_PROVINCE},
        {VM_COMMUNE,  NMXV_COMMUNE,  NMXB_COMMUNE},
        {VM_CONSEIL_FLAMANT,NMXV_CONSEIL_FLAMANT,NMXB_CONSEIL_FLAMANT}
        };
s_Scrutin gshScrutin[10];

/**************************************************************************
<FUNCTION>
  <NAME> Build_Jeton </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  Creation of the "jeton" (token) from a given string
  </DESCRIPTION>
  <PARAMETERS>
    <PARAMETER>
      <NAME> _pzIn </NAME>
      <TYPE> char * </TYPE>
      <IO> IN </ IO >
    </PARAMETER>
    <PARAMETER>
      <NAME> _pzOut </NAME>
      <TYPE> char * </TYPE>
      <IO> OUT </ IO >
    </PARAMETER>
  </PARAMETERS>
</FUNCTION>
**************************************************************************/
static void Build_Jeton(char *_pzIn, char *_pzOut)
{
  int i;
  int jj, mm,aa;
  int cant,buv1,buv2,tmp;
  char Cjj[3],Cmm[3],Caa[3];
  char Ccant[4], Cbuv1[4],Cbuv2[4];
  char _Code[] = "0EC3ZN678LAB2DFRH1IJK9M5OPQGSTUVWXY4";

  strncpy(Ccant,_pzIn + 3,3);
  strncpy(Cbuv1,_pzIn + 6,2);
  strncpy(Cbuv2,_pzIn + 8,1);
  strncpy(Cjj,_pzIn   + 9,2);
  strncpy(Cmm,_pzIn   + 11,2);
  strncpy(Caa,_pzIn   + 13,2);

  Ccant[3] = '\0';
  Cbuv1[2] = '\0';
  Cbuv2[1] = '\0';
  Cjj[2]   = '\0';
  Cmm[2]   = '\0';
  Caa[2]   = '\0';

  cant = atoi(Ccant);
  buv1 = atoi(Cbuv1);
  buv2 = atoi(Cbuv2);
  jj   = atoi(Cjj);
  mm   = atoi(Cmm);
  aa   = atoi(Caa);

  for(i = 0; i < 5;i++)
  {
    _pzOut[1] = _Code[buv1 % 35];
    _pzOut[3] = _Code[buv2 % 35];
    _pzOut[2] = _Code[(jj + cant) % 35];
    _pzOut[0] = _Code[mm   % 35];
    _pzOut[4] = _Code[aa   % 35];
  }
  _pzOut[5] = '\0';
}

/**************************************************************************
<FUNCTION>
  <NAME> Scrut_Read </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>
  fill up scrutin variables (reading machvots.tbl)
  </DESCRIPTION>
</FUNCTION>
**************************************************************************/
void Scrut_Read(void)
{
  char bufs[512],c;
  int i,j;
  FILE *fpl, *fps;

#if (MEMORY_CHECK >= 1)
  if(Debut_Mcbc() != 7) Msg_Error_Exit("Incorrect Config");
#endif

  i = 0;
  giNbrScrutin = 0;

  fps = fopen("machvots.tbl","r");
/* << 9.01c */
  if(fps == NULL) Msg_Error_Exit("Machvots.tbl FILE ERROR");
/* 9.01c >> */
  fpl = fopen("machvotl.tbl","r");
/* << 9.01c */
  if(fpl == NULL) Msg_Error_Exit("Machvotl.tbl FILE ERROR");
/* 9.01c >> */

  /* Read the first 16 caracts */
  fread(bufs,16,1,fps);
  strncpy(gszJeton,bufs,15);
  gszJeton[15] = '\0';

  strncpy(gszArrond,bufs,3);
  gszArrond[3] = '\0';

  /* Jeton */
  Build_Jeton(gszJeton,gszJetonMini);
  fread(bufs,8,1,fps);

  giVoteMaxBytes = 0;
  while(!feof(fps))
  {
    /* Code */
    gshScrutin[i].code_s = bufs[0];
    strncpy(gshScrutin[i].scrutin_max_cand,bufs + 1,2);
    /* Max Eff+Substitute +1 */
    gshScrutin[i].scrutin_max_cand[2] = '\0';
    /* Max Substitute */
    strncpy(gshScrutin[i].scrutin_max_supp,bufs + 3,2);
    gshScrutin[i].scrutin_max_supp[2] = '\0';
    /* Type */
    gshScrutin[i].nom_s = bufs[5];
    gshScrutin[i].TYPE_SCRUTIN = (int)((int)bufs[5] - (int)'0');
    /* Incr giVoteMaxBytes */
    giVoteMaxBytes += (gshCfgScrut[gshScrutin[i].TYPE_SCRUTIN].nmxB +2);
    /* Nbr Lists +1 */
    strncpy(gshScrutin[i].nbrelist_s,bufs + 6,2);
    gshScrutin[i].nbrelist_s[2] = '\0';
    gaiNbListScrut[i] = atoi(gshScrutin[i].nbrelist_s);

    giNbrScrutin++;
    /* Read the machvotl.tbl */
    List_Fill(fpl,atoi(gshScrutin[i].nbrelist_s),i);
    i++;
    fread(bufs,8,1,fps);
  }
  fclose(fps);
  fclose(fpl);

  /* giCardNBytes */
  giCardNBytes = giVoteMaxBytes + _C_JETON_MAX_BYTE;
  giCardNBytes += _C_TEST_MAX_BYTE + _C_CRC_MAX_BYTE + _C_PASSAGE_MAX_BYTE;
}

/**************************************************************************
<FUNCTION>
  <NAME> Scrut_Result </NAME>
  <TYPE> LOCAL </TYPE>
  <DESCRIPTION>
  </DESCRIPTION>
  <RETURNS>
    <TYPE> int </TYPE>
    <DESCRIPTION>
    cfr "int (*ptfunct)(void)"
    </DESCRIPTION>
  </RETURNS>
</FUNCTION>
**************************************************************************/
int Scrut_Result(void)
{
  int iList, i, y, iDebut;

  iDebut = _C_VOTE_PLACE;

  /* Specify that a vote has been done */
  Card_Written(guszCard);

  /* For all ballots */
  for(i=0; i<giNbrScrutin; i++)
  {
    /* List's id attribution */
    if(arcMemoScrutin[i] == 0) iList = 99; /* Empty vote */
    else
    {
      if(arcMemoScrutin[i] == 2) iList = 98; /* Vote not allowed (Stranger) */
      else
      {
        for(y = 0;y < atoi(gshScrutin[i].nbrelist_s);y++)
        {
          if(arcMemoList[i][y] == 1) iList = y + 1;
        }
      }
    }
    Vote_Encode(guszCard, i, iList, &iDebut);
  }

  Calcul_Crc(guszCard,_C_TEST_PLACE);
  Card_Crc_Write(guszCard);
  ptfunct = Vote_End;
  return(0);
}

/**************************************************************************
<FUNCTION>
  <NAME> Scrut_Loop </NAME>
  <TYPE> GLOBAL </TYPE>
  <DESCRIPTION>
  </DESCRIPTION>
  <RETURNS>
    <TYPE> int </TYPE>
    <DESCRIPTION> cfr "int (*ptfunct)(void)" </DESCRIPTION>
  </RETURNS>
</FUNCTION>
**************************************************************************/
int Scrut_Loop(void)
{
  /* One by one */
  while(giCurrentScr < giNbrScrutin)
  {
    if((guszCard[_C_TEST_PLACE] == 'N') /* if National or */
        || ((guszCard[_C_TEST_PLACE] == 'S') && /* if Stranger AND */
           (gshScrutin[giCurrentScr].TYPE_SCRUTIN == 6)))   /* COMM */
    {
      /* Access to the lists */
      ptfunct = List_Display;
      return(0);
    }
    else
    {
      arcMemoScrutin[giCurrentScr] = 2; /* pass over (for example Stranger) */
      ++giCurrentScr;
      return(0);
    }
  }

  ptfunct = Scrut_Result;
  return(0);
}
