/************************************************************/
/* RTFIndex v2.0 by Olivier Couvreur                        */
/* A WIN32 console application for building Index RTF files */
/* supports both WC 11.0 and VC 5.0 compiler                */
/************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

#define NAME    "RTFIndex"
#define VERSION "2.0"
#define AUTHOR  "Olivier Couvreur"
 
/* some macros in order to compile under WC 11.0 or VC 5.0 */
#if defined(__WATCOMC__)
#include <dos.h>
#define M_INITFIND
#define M_FINDFIRST(a,b,c) (!_dos_findfirst(a,b,c))
#define M_FINDNEXT(c)      _dos_findnext(c)
#define M_FINDCLOSE(c)     _dos_findclose(c)
#define M_FINDDATA         find_t
#else
#include <io.h>
#define M_INITFIND			long findhandle=-1L;
#define M_FINDFIRST(a,b,c) ((findhandle=_findfirst(a,c))!=-1L)
#define M_FINDNEXT(c)      _findnext(findhandle,c)
#define M_FINDCLOSE(a)     _findclose(findhandle)
#define M_FINDDATA         _finddata_t
#endif

/* The magic header */
char RTFHeader[]=
"{\\rtf1\\ansi\\ansicpg1252\\uc1 \\deff0\\deflang1033\\deflangfe1036{\\fonttbl{\\f0\\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}{\\f17\\froman\\fcharset238\\fprq2 Times New Roman CE;}{\\f18\\froman\\fcharset204\\fprq2 Times New Roman Cyr;}"
"{\\f20\\froman\\fcharset161\\fprq2 Times New Roman Greek;}{\\f21\\froman\\fcharset162\\fprq2 Times New Roman Tur;}{\\f22\\froman\\fcharset186\\fprq2 Times New Roman Baltic;}}{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;\\red0\\green255\\blue255;"
"\\red0\\green255\\blue0;\\red255\\green0\\blue255;\\red255\\green0\\blue0;\\red255\\green255\\blue0;\\red255\\green255\\blue255;\\red0\\green0\\blue128;\\red0\\green128\\blue128;\\red0\\green128\\blue0;\\red128\\green0\\blue128;\\red128\\green0\\blue0;\\red128\\green128\\blue0;"
"\\red128\\green128\\blue128;\\red192\\green192\\blue192;}{\\stylesheet{\\widctlpar\\adjustright \\fs20\\lang1036 \\snext0 Normal;}{\\s4\\fi-284\\li284\\sb240\\sa60\\widctlpar\\adjustright \\b\\i\\cf2\\lang2057 \\sbasedon0 \\snext0 heading 4;}{\\*\\cs10 \\additive "
"Default Paragraph Font;}{\\s15\\widctlpar\\adjustright \\fs20\\lang1036 \\sbasedon0 \\snext15 footnote text;}{\\*\\cs16 \\additive \\super \\sbasedon10 footnote reference;}{\\s17\\keepn\\widctlpar\\adjustright \\b\\fs28\\cf11\\lang1036 \\sbasedon0 \\snext17 Title;}{"
"\\s18\\widctlpar\\tqc\\tx4536\\tqr\\tx9072\\adjustright \\fs20\\lang1036 \\sbasedon0 \\snext18 header;}{\\s19\\widctlpar\\tqc\\tx4536\\tqr\\tx9072\\adjustright \\fs20\\lang1036 \\sbasedon0 \\snext19 footer;}{\\*\\cs20 \\additive \\uldb\\nosupersub Lien;}{\\*\\cs21 \\additive "
"\\v\\ulnone\\nosupersub R\\'e9f\\'e9rence;}}{\\info{\\title K$ Nom de la M\\'e9taAction}{\\author Xavier Billault}{\\keywords %s}{\\operator Yves BABITCH}{\\creatim\\yr1997\\mo3\\dy19\\hr9\\min34}{\\revtim\\yr1998\\mo7\\dy23\\hr12\\min5}{\\version12}{\\edmins17}"
"{\\nofpages1}{\\nofwords13}{\\nofchars79}{\\*\\company UBI SOFT}{\\nofcharsws0}{\\vern89}}\\margl1417\\margr1417\\margt1417\\margb1417 \\deftab708\\widowctrl\\ftnbj\\aenddoc\\hyphhotz425\\hyphcaps0\\formshade\\viewkind1\\viewscale129\\viewzk2 \\fet0\\sectd "
"\\linex0\\headery709\\footery709\\colsx709\\endnhere\\sectdefaultcl {\\*\\pnseclvl1\\pnucrm\\pnstart1\\pnindent720\\pnhang{\\pntxta .}}{\\*\\pnseclvl2\\pnucltr\\pnstart1\\pnindent720\\pnhang{\\pntxta .}}{\\*\\pnseclvl3\\pndec\\pnstart1\\pnindent720\\pnhang{\\pntxta .}}{\\*\\pnseclvl4"
"\\pnlcltr\\pnstart1\\pnindent720\\pnhang{\\pntxta )}}{\\*\\pnseclvl5\\pndec\\pnstart1\\pnindent720\\pnhang{\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl6\\pnlcltr\\pnstart1\\pnindent720\\pnhang{\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl7\\pnlcrm\\pnstart1\\pnindent720\\pnhang{\\pntxtb (}"
"{\\pntxta )}}{\\*\\pnseclvl8\\pnlcltr\\pnstart1\\pnindent720\\pnhang{\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl9\\pnlcrm\\pnstart1\\pnindent720\\pnhang{\\pntxtb (}{\\pntxta )}}\\pard\\plain \\s17\\keepn\\widctlpar\\adjustright \\b\\fs28\\cf11\\lang1036 {\\cs16\\super #{\\footnote "
"\\pard\\plain \\s15\\widctlpar\\adjustright \\fs20\\lang1036 {\\cs16\\super #}{ IDH_}{\\field\\fldedit{\\*\\fldinst { KEYWORDS \\\\* UPPER \\\\* MERGEFORMAT }}{\\fldrslt {%s}}}}K{\\footnote \\pard\\plain \\s15\\widctlpar\\adjustright \\fs20\\lang1036 {\\cs16\\super K}"
"{\\field{\\*\\fldinst { KEYWORDS  \\\\* MERGEFORMAT }}{\\fldrslt {%s}}}}${\\footnote \\pard\\plain \\s15\\widctlpar\\adjustright \\fs20\\lang1036 {\\cs16\\super $}{ }{\\field{\\*\\fldinst { KEYWORDS  \\\\* MERGEFORMAT }}{\\fldrslt {%s}}}}}"
"{\\field{\\*\\fldinst { KEYWORDS  \\\\* MERGEFORMAT }}{\\fldrslt {%s}}}{\\par }"
"\\pard\\plain \\s4\\fi-284\\li284\\sb240\\sa60\\widctlpar\\outlinelevel3\\adjustright \\b\\i\\cf2\\lang2057 "
"\\pard\\plain \\widctlpar\\adjustright \\fs20\\lang1036 "
"{\\par }";

char RTFFooter[]=
"}\n";

#define  MAX_STRING_SIZE 256
#define  NB_MAX_RTF 1000
typedef struct
{
  char FileName[MAX_STRING_SIZE];
  char IndexName[MAX_STRING_SIZE];
} RTFIndexStruct;

RTFIndexStruct RTFIndex[NB_MAX_RTF];

long filesize( FILE *fp )
{
    long save_pos, size_of_file;

    save_pos = ftell( fp );
    fseek( fp, 0L, SEEK_END );
    size_of_file = ftell( fp );
    fseek( fp, save_pos, SEEK_SET );
    return( size_of_file );
}

/* look for ... string in text "keywords ...}" */
void AddRTFFileToIndex(char *directory,RTFIndexStruct *RTFIndex)
{
  FILE *infp;
  char filename[MAX_STRING_SIZE];
  char *ptr1,*ptr2;
  char *mem;
  long size;
  char keyword1[]="keywords ";
  char keyword2[]="}";

  _makepath(filename,NULL,directory,RTFIndex->FileName,NULL);
  strupr(filename);
  
  if ((infp=fopen(filename,"r"))!=NULL)
  {
    size=filesize(infp);
    if ((mem=(char*) malloc(size))!=NULL)
    {
      fread(mem,size,1,infp);
      if ((ptr1=strstr(mem,keyword1))!=NULL)
      {
        ptr1+=strlen(keyword1);
        if ((ptr2=strstr(ptr1,keyword2))!=NULL)
        {
          *ptr2=0;
          strcpy(RTFIndex->IndexName,ptr1);
        }
        else
        {
          strcpy(RTFIndex->IndexName,"Keywords not found");
        }
      }
      free(mem);
    }
    fclose(infp);
  }
}

int CompareIndex(const void *op1, const void *op2 )
{
  RTFIndexStruct *p1 = (RTFIndexStruct *) op1;
  RTFIndexStruct *p2 = (RTFIndexStruct*) op2;
  return( strcmp(p1->IndexName, p2->IndexName) );
}

void GenerateRTFIndex(char *file,char *title,char *directory)
{
  FILE *outfp;
  char completefilename[MAX_STRING_SIZE];
  char *filename;
  char pattern[MAX_STRING_SIZE];
  char supertitle[MAX_STRING_SIZE];
  char str[MAX_STRING_SIZE];
  struct M_FINDDATA FINDT;
  unsigned done=0;
  char *ptr;
  long i,n=0;
  M_INITFIND

  if ((ptr=strrchr(file,'.'))!=NULL) *ptr=0;
  _makepath(completefilename,NULL,NULL,file,"rtf");
  strupr(completefilename);

  if ((filename=strrchr(completefilename,'\\'))==NULL)
  filename=&completefilename[0];
  else
  filename++;

  _makepath(pattern,NULL,directory,"*","rtf");
  strupr(pattern);
 
  /* find .rtf files in directory */
  n=0;
  if (M_FINDFIRST(pattern,_A_NORMAL,&FINDT))
  {
    done=0;
    while ( (!done) && (n<NB_MAX_RTF) )
    {
      if (stricmp(filename,FINDT.name))
      {
        strcpy(RTFIndex[n].FileName,FINDT.name);
        printf("Adding file %s to index...\n",RTFIndex[n].FileName);
        AddRTFFileToIndex(directory,&RTFIndex[n]);
        n++;
      }
      done = M_FINDNEXT(&FINDT);
    }
    M_FINDCLOSE(&FINDT);   
  }
  printf("\n");

  if (n>0)
  {
    printf("Sorting index...\n");
    qsort(&RTFIndex[0],n,sizeof(RTFIndexStruct),CompareIndex);

    printf("Generating index %s ...\n",completefilename);
    if ((outfp=fopen(completefilename,"w"))!=NULL)
    {
      strcpy(supertitle,title);strupr(supertitle);
      while ((ptr=strchr(supertitle,' '))!=NULL) *ptr='_';

      fprintf(outfp,RTFHeader,title,supertitle,title,title,title);

      for (i=0;i<n;i++)
      {
        strcpy(str,RTFIndex[i].IndexName);
        fprintf(outfp,"{\\uldb %s}",str);
        strupr(str);
        fprintf(outfp,"{\\v IDH_%s}{\\par }" "\n",str);
      }    

      fprintf(outfp,"%s",RTFFooter);
      fclose(outfp);
      printf("Now, there are %d indexes in %s.\n",n,completefilename);   

      /// save list with rtffiles
	  if ((ptr=strrchr(file,'.'))!=NULL) *ptr=0;
      _makepath(completefilename,NULL,NULL,file,"txt");
      strupr(completefilename);

	  printf("Generating rtf listing %s ...\n",completefilename);
      if ((outfp=fopen(completefilename,"w"))!=NULL)
      {
        for (i=0;i<n;i++)
		{ 
		  fprintf(outfp,"%s\n",RTFIndex[i].IndexName);
		}
		fclose(outfp);
	  }

    }
    else
    {
      printf("Can't open %s for writing\n.",completefilename);
    }
  }
  else
  {
    printf("No RTF files in these directory.\n");
  }
}

void main(int argc,char *argv[])
{
  printf("%s v%s by %s (%s %s)\n\n",NAME,VERSION,AUTHOR,__DATE__,__TIME__);
  if (argc==3)
  {
    GenerateRTFIndex(argv[1],argv[2],NULL);
  }
  else if (argc==4)
  {
    GenerateRTFIndex(argv[1],argv[2],argv[3]);
  }
  else
  {
    printf("Usage : %s RTFFileToGenerate[.RTF] \"RTFIndexTitle\" [DirectoryToScan]\n",NAME);
    printf("        %s MyRTFIndex \"My RTF Title\" MyRTFDir\n",NAME);
  }
  getch();
}
