#include <io.h>
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

struct comment {
  char open[10];
  char close[10]; };

static int comment = 0;
static int tag = 0;
static int numeroLigne = 0;
static int par;
static int nbc = 0;
static struct comment *co = NULL;
static char *coulParagraphe = NULL;
static char *size = NULL;
static int sz = 4;
static char *font = "Courier New";

void complemente(char *s) {
  int l = strlen(s);
  s[3] = 0x00;
  if ( l == 1 ) {
    s[2] = s[0];
    s[0] = s[1] = '0'; }
  if ( l == 2 ) {
    s[2] = s[1];
    s[1] = s[0];
    s[0] = '0'; }
}

void conversion(char c1,FILE *dest) {
  static int numerol = 2;
  switch (c1) {
    case 0x0D  : break;
    case 0x0A  : if ( comment ) {
                   comment = 0;
                   fprintf(dest,"</font>"); }
                 if ( numeroLigne ) {
                   char texte[10];
                   sprintf(texte,"%d",numerol);
                   complemente(texte);
                   fprintf(dest,"<br>\n<font color=\"#008000\">%s</font>&nbsp;&nbsp;",texte);
                   numerol++; }
                   else
                   fprintf(dest,"<br>\n");
                 break;
    case ' '   : if ( tag )
                   fprintf(dest," ");
                   else
                   fprintf(dest,"&nbsp;");
                 break;
    case '<'   : fprintf(dest,"&lt;");
                 break;
    case '>'   : fprintf(dest,"&gt;");
                 break;
    case '"'   : if ( tag )
                   fprintf(dest,"\"");
                   else
                   fprintf(dest,"&quot;");
                 break;
    case '&'   : fprintf(dest,"&amp;");
                 break;
    default    : fwrite(&c1,1,1,dest); }
}

void traitementSpecial1(FILE *src,FILE *dest) {
  char c1;
  fread(&c1,1,1,src);
  switch ( c1 ) {
    case '*'   : fread(&c1,1,1,src);
                 switch ( c1 ) {
                   case '#' : { char s[100];
                                fscanf(src,"%s",s);
                                fprintf(dest,"%s",s);
                                if ( !strcmp(s,"<font") ) {
                                  fscanf(src,"%s",s);
                                  fprintf(dest," %s",s); }
                                fread(&c1,1,1,src);
                                fread(&c1,1,1,src);
                                fread(&c1,1,1,src); }
                                break;
                   default  : fprintf(dest,"<font color=\"#008000\">/*");
                              comment = 1;
                              conversion(c1,dest);
                              break; }
                 break;
    case '/'   : fprintf(dest,"<font color=\"#008000\">//");
                 comment = 1;
                 break;
    default    : char signe = '/';
                 fwrite(&signe,1,1,dest);
                 conversion(c1,dest);
                 break; }
}

void traitementSpecial2(FILE *src,FILE *dest) {
  char c1;
  fread(&c1,1,1,src);
  if ( c1 == '/' ) {
    comment = 0;
    fprintf(dest,"*/</font>"); }
    else {
    char signe = '*';
    fwrite(&signe,1,1,dest);
    conversion(c1,dest); }
}

void traitementSpecial3(FILE *src,FILE *dest) {
  char c1;
  fread(&c1,1,1,src);
  if ( c1 == '@' ) {
    tag = 1;
    fprintf(dest,"<"); }
    else {
    conversion('<',dest);
    conversion(c1,dest); }
}

void traitementSpecial4(FILE *src,FILE *dest) {
  char c1;
  fread(&c1,1,1,src);
  if ( c1 == '@' ) {
    tag = 0;
    fprintf(dest,">"); }
    else {
    conversion('>',dest);
    conversion(c1,dest); }
}

int longueur(char *s) {
  int cpt = 0;
  while ( s[cpt] != 0x00 )
    cpt++;
  return(cpt);
}

void substitution2(char *buf,char *src,char *dst,int p) {
  int l = longueur(buf);
  int lsrc = longueur(src);
  int ldst = longueur(dst);
  printf("*");
  int nbo = l-p-lsrc+1;
  for ( int j = 0 ; j < nbo ; j++ )
    buf[l+ldst-lsrc-j] = buf[l-j];
  for ( int i = 0 ; i < ldst ; i++ ) {
    buf[p+i] = dst[i]; }
}

int firstIndexOf(char *s,char *c) {
  int ns = longueur(s);
  int nc = longueur(c);
  int stop;
  int p = 0;
  do {
    stop = 1;
    for ( int i = 0 ; i < nc ; i++ )
      if ( s[p+i] != c[i] ) {
        stop = 0;
        i = nc ; }
    p++; }
  while ( ( !stop ) && ( p+nc <= ns ) );
  p--;
  return(p);
}

int firstIndexOf(char *s,char *c,int p) {
  int ns = longueur(s);
  int nc = longueur(c);
  int stop;
  do {
    stop = 1;
    for ( int i = 0 ; i < nc ; i++ )
      if ( s[p+i] != c[i] ) {
        stop = 0;
        i = nc ; }
    p++; }
  while ( ( !stop ) && ( p+nc <= ns ) );
  p--;
  if ( !stop )
    return(-1);
  if ( p == 0 )
    return(p);
  if ( isalnum(s[p-1]) )
    return(-p);
  if ( p+nc < ns )
    if ( isalnum(s[p+nc]) )
      return(-p);
  return(p);
}

int compare(char *buf,char *s) {
  int l = strlen(s);
  for ( int i = 0 ; i < l ; i++ )
    if ( buf[i] != s[i] )
      return(0);
  return(1);
}

int inComment(char *buf,int p) {
  int stop = 0;
  int rc = 0;
  while ( !stop ) {
    if ( p == -1 )
      return(0);
    if ( nbc > 0 ) {
      if ( compare(&buf[p],co[0].open) )
        return(1);
      if ( compare(&buf[p],co[0].close) )
        return(0); }
    if ( ( buf[p] == '/' ) && ( buf[p+1] == '*' ) )
      return(1);
    if ( ( buf[p] == '*' ) && ( buf[p+1] == '/' ) )
      return(0);
    if ( ( buf[p] == 0x0D ) && ( buf[p+1] == 0x0A ) )
      rc = 1;
    if ( ( buf[p] == '/' ) && ( buf[p+1] == '/' ) ) {
      if ( !rc )
        return(1);
        else
        return(0); }
    p--; }
  return(0);
}

void pretraite(char *src,char *dst,char **chaine,int nb) {
  int size;
  { struct _finddata_t fileinfo ;
    long hld = _findfirst(src,&fileinfo) ;
    size = fileinfo.size;
    _findclose(hld) ; }
  FILE *fsrc;
  fsrc = fopen(src,"rb");
  FILE *fdst;
  fdst = fopen(dst,"wb");
  if ( fsrc && fdst ) {
    char *buf =(char *) calloc(1,size+1000000);
    fread(buf,1,size,fsrc);
    buf[size] = 0x00;
    for ( int i = 0 ; i < nb ; i++ ) {
      int pos = 0;
      char subst[1024];
      strcpy(subst,"<@font color=\"#800000\">@");
      strcat(subst,chaine[i]);
      strcat(subst,"<@/font>@");
      int p;
      do {
        p = firstIndexOf(buf,chaine[i],pos);
        if ( p != -1 ) {
          if ( p >= 0 ) {
            if ( !inComment(buf,p) ) {
              substitution2(buf,chaine[i],subst,p);
              pos = p+strlen(subst); }
              else
              pos = p+strlen(chaine[i]); }
            else
            pos = -p+strlen(chaine[i]); } }
      while ( p != -1 ) ; }
    printf("\n");
    fwrite(buf,1,longueur(buf),fdst);
    fclose(fdst);
    fclose(fsrc); }
}

char **listeColoration(char *file,int *nb) {
  char mot[200];
  FILE *fsrc;
  fsrc = fopen(file,"rb");
  int cpt = 0;
  while ( fscanf(fsrc,"%s",mot) != EOF )
    cpt++;
  fseek(fsrc,0L,SEEK_SET);
  fflush(fsrc);
  *nb = cpt;
  char **st =(char **) calloc(cpt,sizeof(char *));  
  cpt = 0;
  while ( fscanf(fsrc,"%s",mot) != EOF ) {
    st[cpt] =(char *) calloc(strlen(mot)+1,sizeof(char));
    strcpy(st[cpt],mot);
    cpt++; }
  fclose(fsrc);
  return(st);
}

struct comment *lectureCommentaires(char *s,int *nbc,struct comment *co) {
  char st[100];
  strcpy(st,s);
  struct comment *co2;
  co2 =(struct comment *) realloc(co,(*nbc)+1*sizeof(struct comment));
  int pos = firstIndexOf(s,"-");
  strcpy(co2[*nbc].close,(char *) &s[pos+1]);
  st[pos] = 0x00;
  strcpy(co2[*nbc].open,st);
  (*nbc)++;
  return(co2);
}

int traitementCommentaires(char c1,struct comment *co,int nbc,FILE *dest) {
  for ( int i = 0 ; i < nbc ; i++ )
    if ( strlen(co[i].open) == 1 ) {
      if ( c1 == co[i].open[0] ) {
        fprintf(dest,"<font color=\"#008000\">");
        comment = 1;
        conversion(c1,dest);
        return(1); }
      if ( c1 == co[i].close[0] ) {
        conversion(c1,dest);
        fprintf(dest,"</font>");
        comment = 0;
        return(1); } }
  return(0);
}

int main(int argc,char * argv[]) {
  char htm[300] ;
  char cpp[300] ;
  char des[300] ;
  char occ[300] ;
  char file[300] ;
  strcpy(htm,argv[1]) ;
  strcpy(des,argv[1]) ;
  strcat(des,"l") ;
  strcpy(cpp,argv[2]) ;
  if ( argc >= 4 )
    strcpy(occ,argv[3]) ;
  long pos;
  FILE *f1 = fopen(htm,"r");
  if ( f1 != NULL ) {
    char chaine[65000];
    if ( argc >= 4 ) {
      do {
        do {
          pos = ftell(f1);
          fscanf(f1,"%s",chaine); }
        while ( ( strcmp(chaine,"<!--") ) && ( strcmp(chaine,"<p><!--") ) );
        fscanf(f1,"%s",chaine);
        if ( !strcmp(chaine,"substitution") ) {
          fscanf(f1,"%s",chaine); } }
      while ( strcmp(chaine,occ) ); }
      else {
      do {
        pos = ftell(f1);
        fscanf(f1,"%s",chaine); }
      while ( strcmp(chaine,"<!--") );
      fscanf(f1,"%s",chaine);
      if ( !strcmp(chaine,"substitution") ) {
        fscanf(f1,"%s",chaine); } }
    strcat(cpp,"\\") ;
    strcat(cpp,chaine) ;
    strcpy(file,chaine) ;
    fscanf(f1,"%s",chaine);
    long pos2 = ftell(f1);
    fclose(f1);
    char cpp2[2048];
    strcpy(cpp2,cpp);
    strcat(cpp2,"2");
    int nb = 0;
    char **chain = NULL;
    for ( int arg = 4 ; arg < argc ; arg++ ) {
      if ( ( argv[arg][0] == '-' ) && ( argv[arg][1] == 'm' ) ) {
        chain = listeColoration(&argv[arg][2],&nb) ; }
      if ( !strcmp(argv[arg],"-l" ) )
        numeroLigne = 1;
      if ( ( argv[arg][0] == '-' ) && ( argv[arg][1] == 'c' ) ) {
        co = lectureCommentaires(&argv[arg][2],&nbc,co); }
      if ( ( argv[arg][0] == '-' ) && ( argv[arg][1] == 'p' ) ) {
        coulParagraphe = &argv[arg][2]; }
      if ( ( argv[arg][0] == '-' ) && ( argv[arg][1] == 's' ) ) {
        size = &argv[arg][2];
        sz = atoi(size); }
      if ( ( argv[arg][0] == '-' ) && ( argv[arg][1] == 'f' ) ) {
        font = &argv[arg][2]; } }
    pretraite(cpp,cpp2,chain,nb);
    FILE *f2;
    f2 = fopen(cpp2,"r");
    FILE *dest;
    dest = fopen(des,"w");
    if ( f2 != NULL ) {
      f1 = fopen(htm,"r");
      char c1;
      do {
        fread(&c1,1,1,f1);
        fwrite(&c1,1,1,dest); }
      while ( ftell(f1) != pos2 ) ;
      if ( coulParagraphe )
        fprintf(dest,"\n<p style=\"background-color: rgb(%s)\"><strong><font face=\"%s\" size=\"%d\">",coulParagraphe,font,sz);
        else
        fprintf(dest,"\n<p><strong><font face=\"%s\" size=\"%d\">",font,sz);
      if ( numeroLigne )
        fprintf(dest,"<font color=\"#008000\">001</font>&nbsp;&nbsp;");
      while ( fread(&c1,1,1,f2) ) {
        switch (c1) {
          case '>'   : traitementSpecial4(f2,dest);
                       break;
          case '<'   : traitementSpecial3(f2,dest);
                       break;
          case '/'   : traitementSpecial1(f2,dest);
                       break;
          case '*'   : traitementSpecial2(f2,dest);
                       break;
          default    : if ( !traitementCommentaires(c1,co,nbc,dest) )
                         conversion(c1,dest); } }
      fprintf(dest,"</font></strong></p>\n");
      do {
        fscanf(f1,"%s",chaine); }
      while ( strcmp(chaine,"<!--") );
      fscanf(f1,"%s",chaine);
      fscanf(f1,"%s",chaine);
      fscanf(f1,"%s",chaine);
      fscanf(f1,"%s",chaine);
      fprintf(dest,"<!-- fin substitution %s -->",file);
      while ( fread(&c1,1,1,f1) ) {
        fwrite(&c1,1,1,dest); }
      fclose(f1);
      fclose(f2);
      fflush(dest);
      fclose(dest);
      _unlink(cpp2); } }
	return 0;
}
