/* Auteur : nicolas Janey        */
/* nicolas.janey@univ-fcomte.fr  */

#include <stdio.h>
#include <string.h>
#include <direct.h>
#include <io.h>
#include <stdlib.h>

char rc[3] = { 0x0D,0x0A,0x00 };

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

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

void substitution2(char *buf,char *src,char *dst,int p) {
  int l = longueur(buf);
  int lsrc = longueur(src);
  int ldst = longueur(dst);
  printf("%d %d %d %d\n",l,p,lsrc,ldst);
  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 p = 0;
  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 <= ns-nc ) );
  p--;
  return(( p > ns-nc-1 ) ? -1 : p);
}

int nextIndexOf(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 <= ns-nc ) );
  p--;
  return(( p > ns-nc-1 ) ? -1 : p);
}

char *filename(char *s) {
  int p = strlen(s)-1;
  while ( ( p != -1 ) && ( s[p] != '/' ) && ( s[p] != '\\' ) )
    p-- ;
  p++;
  return(&s[p]);
}

void generationFichierJava(char *javaFile,
                           char *javaFileDest,
                           char *javaClass,
                           char *javaClassDest) {
  printf("Fichier java source      : %s\n",javaFile);
  printf("Fichier java destination : %s\n",javaFileDest);
  printf("Classe source            : %s\n",javaClass);
  printf("Classe destination       : %s\n",javaClassDest);
  int size;
  { struct _finddata_t fileinfo ;
    long hld = _findfirst(javaFile,&fileinfo) ;
    size = fileinfo.size;
    _findclose(hld) ; }
  FILE *src = fopen(javaFile,"rb");
  FILE *dst = fopen(javaFileDest,"wb");
  if ( ( src != NULL ) && ( dst != NULL ) ) {
    char *buf =(char *) calloc(1,size+1000);
    fread(buf,1,size,src);
    { char chaine[4] = { 0x20,0x0D,0x0A,0x00 } ;
      int p;
      do {
        p = firstIndexOf(buf,chaine);
        if ( p != -1 )
          substitution(buf,chaine,rc,p); }
      while ( p != -1 ) ; }
    { char chaine[30];
      { strcpy(chaine,"import java.io.*;");
        strcat(chaine,rc);
        strcat(chaine,rc); } 
      int p = firstIndexOf(buf,chaine);
      if ( p != -1 )
        substitution(buf,chaine,"",p); }
    { char chaine[100];
      { strcpy(chaine,"  static BufferedReader flux = new BufferedReader(new InputStreamReader(System.in));");
        strcat(chaine,rc); } 
      int p = firstIndexOf(buf,chaine);
      if ( p != -1 )
        substitution(buf,chaine,"",p); }
    { char chaine[] = " throws IOException" ;
      int p;
      do {
        p = firstIndexOf(buf,chaine);
        if ( p != -1 )
          substitution(buf,chaine,"",p); }
      while ( p != -1 ) ; }
    { char chaine[100] = { ' ','a','r','g','s',')',' ','{',0x0D,0x0A,0x00};
      char repl[500];
      strcpy(repl,chaine);
      strcat(repl,"    Console.setTitle(\"");
      strcat(repl,javaClass);
      strcat(repl,"\");");
      strcat(repl,rc);
      int p = firstIndexOf(buf,chaine);
      if ( p != -1 ) {
        substitution2(buf,chaine,repl,p); } }
    { int p;
      int pold = -2;
      do { 
        if ( pold == -2 )
          p = firstIndexOf(buf,javaClass);
          else
          p = nextIndexOf(buf,javaClass,pold);
        if ( p != -1 ) {
          pold = p+1;
          if ( buf[p-1] != '\"' )
            substitution2(buf,javaClass,javaClassDest,p); } }
      while ( p != -1 ) ; }
    { int p;
      do {
        p = firstIndexOf(buf,"System.out");
        if ( p != -1 )
          substitution2(buf,"System.out","Console.out",p); }
      while ( p != -1 ) ; }
    { int p;
      do {
        p = firstIndexOf(buf,"flux.readLine");
        if ( p != -1 )
          substitution2(buf,"flux.readLine","Console.in.readLine",p); }
      while ( p != -1 ) ; }
    fwrite(buf,1,longueur(buf),dst);
    fclose(src);
    fclose(dst);
    free(buf); }
    else {
    printf("Probleme!!!\n"); }
}

void generationFichierManifest(char *javaClassDest,char *dest) {
  char filename[256];
  strcpy(filename,dest);
  strcat(filename,"\\");
  strcat(filename,"Manifest.mf");
  FILE *f = fopen(filename,"wt");
  if ( f ) {
    fprintf(f,"Manifest-Version: 1.0\nCreated-By: 1.5.0 (Sun Microsystems Inc.)\nMain-Class: %s\n",javaClassDest);
    fclose(f); }
}

void effacementFichierManifest(char *javaClassDest,char *dest) {
  char filename[256];
  strcpy(filename,dest);
  strcat(filename,"\\");
  strcat(filename,"Manifest.mf");
  _unlink(filename);
}

void generationFichierJar(char *javaClassDest,char *dest) {
  char jarFile[1024];
  strcpy(jarFile,javaClassDest);
  strcat(jarFile,".jar");
  jarFile[0] += 32;
  char commande[1024];
  _chdir(dest);
  sprintf(commande,"jar cvfm %s Manifest.mf %s.class",jarFile,javaClassDest);
  system(commande);
  sprintf(commande,"jar uvf %s CanvasConsole.class",jarFile);
  system(commande);
  sprintf(commande,"jar uvf %s Console.class",jarFile);
  system(commande);
  sprintf(commande,"jar uvf %s ConsolePrinter.class",jarFile);
  system(commande);
  sprintf(commande,"jar uvf %s ConsoleReader.class",jarFile);
  system(commande);
  sprintf(commande,"jar uvf %s FrameConsole.class",jarFile);
  system(commande);
  sprintf(commande,"jar uvf %s CurseurCanvasConsole.class",jarFile);
  system(commande);
  _chdir("..");
}

void compilationFichierJava(char *javaClassDest,char *dest,char *version,char *bootclasspath) {
  _chdir(dest);
  char commande[1024];
  sprintf(commande,"javac -Xlint:deprecation -Xlint:unchecked -source %s -target %s -bootclasspath %s -extdirs \"\" %s.java",version,version,bootclasspath,javaClassDest);
  system(commande);
  _chdir("..");
}

int main(int argc,char* argv[]) {
  char javaFile[4096];
  strcpy(javaFile,argv[1]);
  strcat(javaFile,".java");
  char javaClass[4096];
  strcpy(javaClass,filename(argv[1]));
  char javaClassDest[4096];
  strcpy(javaClassDest,javaClass);
  char javaFileDest[4096];
  strcpy(javaFileDest,argv[2]);
  strcat(javaFileDest,"\\");
  strcat(javaFileDest,javaClass);
  strcat(javaFileDest,".java");
  generationFichierJava(javaFile,javaFileDest,javaClass,javaClassDest);
  compilationFichierJava(javaClassDest,argv[2],argv[3],argv[4]);
	return(0);
}

