#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <ctype.h>

  struct fils_occ
   {int pid;
    int fn;
    };
   typedef struct fils_occ FILS_occ;
  struct fils_sum
   {int pid;
    int fd[2];
    };
   typedef struct fils_sum FILS_sum;
//-----------------------est_lettre---------------------------------//
int est_lettre(char c)
{return((c>='a'&&c<='z')||(c>='A'&&c<='Z'));}

//-------------------------est_chiffre-------------------------------//
int est_chiffre(char c)
{return(c>='0'&&c<='9');}
 //--------------------------somme--------------------------------------//
int somme(char s[])
{int i,n,N=0;
for (i=0;i<strlen(s);i++)
  {  if (est_chiffre(s[i]))
    n=(int)(s[i]);
    N=N+n;}
   return(N);}

//---------------------occurence-----------------------------//
void occurence(FILE *fp,int deb,int si,int t[])
{int i;
int j,k;
char line[100];
for(i=0;i<(deb*si);i++)
 {fgets(line,100,fp);}
for (i=(deb*si);i<((deb*si)+si);i++)
   { fgets(line,100,fp);
      while(line[j]!='\n')
         {for(k=0;k<26;k++)
           { if (est_lettre(line[j])&&((line[j])==(65+k)))//----how to know the letter by the code ASCI?????---//
                t[k]++;
                      }}
                  }
                }
  
//---------------------nombre lignes------------------------//
int nb_lignes (FILE *fp)
{
  int n=0;
 char c;
 while ((c = fgetc(fp)) != EOF)
  { if (c == '\n')
    {
      n++;
    }
  }
  return n;
}

//--------------------chaine_codé----------------------------------//
void coder(int t[],char s_cod[])
{  int i;
  char s[51];
 for(i=0;i<51;i+2)
    { s[i]=(char)t[i/2];
     s[i+1]='*';
      }
   }
//----------------------decoder-----------------------------//
void decoder(char s[],int t[])
{ int i;
  for(i=0;i<51;i+2)
    t[i]=(int)(s[7+(2+i)]);
    }
//--------------------fusion---------------------------//
void fusion(int t1[],int t2[])
{int i,n;
for(i=0;i<n;i++)
 t1[i]=t1[i]+t2[i];
   }
//---------------------print of the final table of occurence----------------------------------//
void affiche_tab(int t[])
{ int i;
   printf("A B C D E F G H I J K L M N O P K R S T U V W X Y Z\n");
   printf("---------------------------------------------------\n");
   for(i=0;i<26;i++)
     {printf("%d ",t[i]);}
   }
//---------------------------------------------------------------------------//
main()
 
{ 

    char T_occ[26];
    FILE *fp;
    char s[5];
    char s_cod[6];
    
    FILS_occ f1[30];
    FILS_sum f2[30];
    char s_res[51];
    char sum_inter[5];
    int fd[2],fn,si,p,sum=0,i,nbl,add,nb_par,pid,tab_inter[26],tab_final[26],deb=0,t_pid[8];
    char fichier[30];

    printf("give the file path\n");

    gets(fichier);
    fp=fopen(fichier,"r");
     nbl=nb_lignes(fp);
     printf("the file contain %d lines \n",nbl);

    do{ printf("give the number of lines in paragraph max 6\n");
      scanf("%d", &si);}
      while(si>6);
//----------------------------------number of paragraph----------------------//

       nb_par=(nbl%si);
         if(nb_par=0)
           nb_par=nbl/si;
           else nb_par=nbl/si+1;
   printf("we have %d paragraph\n\n",nb_par);

do{printf("give the number of the process couple\n");
     scanf("%d",&p);}
     while(p>3);
//---------------------------//creation of pipes//----------------------//
    for(i=0;i<(2*p);i++)
    {
       pid=fork();
       if(pid>0)
        { t_pid[i]=pid;
         if(i<p)
        { f1[i].pid=t_pid[i];
              mknod("mypipe",S_IFIFO|0644,0);
            printf("father say: i create the child num %d with nommed pipe\n",f1[i].pid);}
        else{
          f2[(i-p)].pid=t_pid[i];
              pipe(f2[i-p].fd);
              printf("father say: i create the child num %d with ordinary pipe \n",f2[i-p].pid);}
          }
          else 
            break;}

  
//-----------------------------------------------------------------------//
 if(pid>0)
  {
   for(i=0;i<p;i++)
 //-----------------------------------------------------------------------//
   {
     sprintf(s,"%4d",i);  //-----preparing the adress by converting the number of paragraph into string//
             
 //-------------------closing the reading mode of the 2 pipes---------------//
     f1[i].fn=open("mypipe",O_WRONLY);
     close(f2[i].fd[0]);

 //----------------------------writing the adress in the pipes-------------------------//
     write(f1[i].fn,s,6);
     write(f2[i].fd[1],s,6);

 //----------------------------------------------------------//
      f1[i].fn=open("mypipe",O_RDONLY);
      close(f2[i].fd[1]);
   deb=p;

 
        read(f1[i].fn,s_res,58);
        decoder(s_res,tab_inter);
        fusion(tab_final,tab_inter);

//-----------------------------------------------//
         sprintf(s,"%4d",deb);
         f1[i].fn=open("mypipe",O_WRONLY);
         write(f1[i].fn,s,6);
        
//-----------------------------------------------------------------//
         
            read(f2[i].fd[0],sum_inter,6);
            add=(int)sum_inter;
            sum=sum+add;
             sprintf(s,"%4d",deb);
            close(f2[i].fd[0]);
            write(f2[i].fd[1],s,6);
            deb++;       
         
             }    
         } 

}   
//------------------------------------------------------------------------//
 else
  { 
    for(i=0;i<p;i++)
     {   
  //--------------------closing of of the writing mode------------//  
      f1[i].fn=open("mypipe",O_RDONLY);
       close(f2[i].fd[1]); 
                    
  //-------------read of data-----------------//    
    read(f1[i].fn,s,6);
    read(f2[i].fd[0],s,6);}

  //-------------------work to do---------------//
    occurence(fp,deb,si,tab_inter);
    coder(tab_inter,s_res);
    sprintf(sum_inter,"%d",somme(s));
    
   //----------------closing of the reading mode---------//
     f1[i].fn=open("mypipe",O_WRONLY);
     close(f2[i].fd[0]);
  //---------------writing in the 2 pipes---------------//
     write(f1[i].fn,s_res,50);
     write(f2[i].fd[1],sum_inter,6);

   f1[i].fn=open("mypipe",O_RDONLY);
   close(f2[i].fd[1]); 
   read(f1[i].fn,s,6);
      {    occurence(fp,deb,si,tab_inter);
           affiche_tab(tab_inter);
           coder(tab_inter,s_res);
           f1[i].fn=open("mypipe",O_WRONLY);
           write(f1[i].fn,s_res,50);
              }
     read(f2[i].fd[0],s,6);
       {
      sprintf(sum_inter,"%d",somme(s));
      close(f2[i].fd[0]);
      write(f2[i].fd[1],sum_inter,6);
        }
  }
}