/*
    REFERENCES -- bibliographic software
    Copyright (C) 1995-2007  Volker Kiefel

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
    USA
*/

/*
   xtrrm.c: extract reference numbers from manuscript
            (in form of a text file)
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "str_fun.h"
#include "fl_ut.h"
#include "refs.h"
#include "interf.h"
#include "str_refs.h"
#include "xtrrm.h"

#define SPATTERN "refscite()"

#define LZEILE_LEN 262144

#define MUSTER_STR_LEN 40
#define MASKEN_LEN 10


 static char * lzeile;
 static char * ex_zeile;
 static char * exex_zeile;
 static char musterstr[MUSTER_STR_LEN + 1];

 extern char textpfad[PFAD_LEN+1];
 extern char rdbpfad[PFAD_LEN+1];
 extern char wrtxtbu[WRTXTBU_LEN+1];

 extern config_set one_config_set;
 static long anz_refs;
 static bbatchtable_rec one_bbt_rec;


 static char text_name[PFAD_LEN];
 static FILE * fptext;
 static char bbt_name[PFAD_LEN];
 static FILE * fpbbt;

 static int mustertyp;
  /* 1 normal, 2 curly braces */

 static int zeile_parsen(char * muster, char * zle);
 static int hauptmenu_xtrrm(void);
 static int text_lesen(void);
 static int issearchpattern(char * muster);




int xtrrm_main(void)
{
   mustertyp = 1;

   if ((lzeile =  (char *) malloc((LZEILE_LEN + 1) * sizeof(char)))==NULL)
   {
       fprintf(stderr,"\nERROR: Cannot allocate memory for input line\n");
       exit(1);
   }
   if ((ex_zeile =  (char *) malloc((LZEILE_LEN +1) * sizeof(char)))==NULL)
   {
       fprintf(stderr,"\nERROR: Cannot allocate memory for text buffer_1\n");
       exit(1);
   }
   if ((exex_zeile =  (char *) malloc((LZEILE_LEN + 1) * sizeof(char)))==NULL)
   {
       fprintf(stderr,"\nERROR: Cannot allocate memory for text buffer_1\n");
       exit(1);
   }

   hauptmenu_xtrrm();
   free(lzeile);
   free(ex_zeile);
   free(exex_zeile);
   return 0;
}


static int hauptmenu_xtrrm(void)
{
     char eingabe[PFAD_LEN+1];
     int taste;
     char maske[MASKEN_LEN + 1];
     static char ein[INPUT_BU_LEN+1];

     strcpy(maske,"*.txt");
     anz_refs = 0;
     strcpy(musterstr,SPATTERN);

     strcpy(ein,"menu");
     wrtxt("\nMenu: select filename extension (of file to be processed) [txt/tbt/ ... /q]\n");
     taste = menu_wahl(ein,
       "[txt], [tbt], [asc], [doc], [tex] filename extension, [q] quit"
       );
     if (taste==6)
     {
         wrtxt("\n(aborted)\n");
         return 0;
     }
     if (taste==1)
     {
         strcpy(maske,"*.txt");
     }
     if (taste==2)
     {
         strcpy(maske,"*.tbt");
     }
     if (taste==3)
     {
         strcpy(maske,"*.asc");
     }
     if (taste==4)
     {
         strcpy(maske,"*.doc");
     }
     if (taste==5)
     {
         strcpy(maske,"*.tex");
     }


     wrtxt("\n(Next file selection screen: file to processed)\n");
     if (!datei_suchen_mit_pfad(maske,textpfad,text_name))
     {
         wrtxt("\n(Aborted)\n");
         return 0;
     }
     
     strcpy(eingabe,"refsc01");

     if (!dateivornamen_holen(eingabe,"Please enter filename for bbt-file, "
        "`.bbt' will be appended"))
     {
        wrtxt("\n(No valid filename, creating bbt-file aborted)\n");
        return 0;
     }
     
     
     if (!strcmp(eingabe,""))
     {
         wrtxt("\n(Function aborted with empty string)\n");
         return 0;
     }
     strlimcpy(bbt_name,rdbpfad,PFAD_LEN);
     strlimcat(bbt_name,eingabe,PFAD_LEN);
     strlimcat(bbt_name,".bbt",PFAD_LEN);
    
     if (isfile(bbt_name))
     {
       if (!do_overwrite_yn())
       {
           wrtxt("\n(Aborted)\n");
           return 0;
       }
     }
     
     do 
     {
       ein_zeile(musterstr,
         "Accept 'refscite()' or enter new search pattern",
         MUSTER_STR_LEN);
       if (strlen(musterstr)==0)
       {
          strcpy(musterstr,SPATTERN);
       }
       mustertyp=issearchpattern(musterstr);
       if (mustertyp > 0)
       {
           break;
       }
     } while (1);
     
     text_lesen();
     sprintf(wrtxtbu,
       "\n"
       "(Completed: %li reference numbers extracted into file `%s')"
       "\n",anz_refs,bbt_name);
     wrtxt(wrtxtbu);

     return 1;
}


static int text_lesen(void)
{

     if ((fptext = fopen(text_name,"rt"))==NULL)
     {
          fprintf(stderr,"\nERROR: Cannot read %s\n",text_name);
          exit(1);
     }
     if ((fpbbt = fopen(bbt_name,"wb"))==NULL)
     {
          fprintf(stderr,"\nERROR: Cannot create %s\n",bbt_name);
          exit(1);
     }
     wrtxt("\n(Reading text file)\n");

     while (fgets(lzeile,LZEILE_LEN,fptext)!=NULL)
     {
        if (strlen(lzeile) >= LZEILE_LEN - 1)
        {
            sprintf(wrtxtbu,"\nProblem: Input line > %i characters "
               "(too long)\n",LZEILE_LEN);
            wrtxt(wrtxtbu);
            break;
        }
        rtrim(lzeile,'\n');
        zeile_parsen(musterstr,lzeile);
     }
     fclose(fptext);
     fclose(fpbbt);

     return 0;
}



static int issearchpattern(char * muster)
{
   int laenge;
   int typ; /* xxx1 (), xxx2{} */
   laenge = strlen(muster);

   typ = 0;

   if (laenge < 3 || laenge > MUSTER_STR_LEN)
   {
      return 0;
   }
   if (countitem(muster," \n\t")!=1)
   {
      return 0;
   }
   if (muster[laenge-1]==')') typ = 1;
   if (muster[laenge-1]=='}') typ = 2;

   if (typ==0) return typ;

   if (typ==1)
   {
      if (locate_substring("(",muster)!=laenge-2)
      {
         return 0;
      }
   }

   if (typ==2)
   {
      if (locate_substring("{",muster)!=laenge-2)
      {
         return 0;
      }
   }
   return typ;
}

static int zeile_parsen(char * muster, char * zle)
{
    int i;
    int fund;
    int f_ende;

    char ex_musterstr[MUSTER_STR_LEN + 1];
    strcpy(ex_musterstr,muster);
    ex_musterstr[strlen(muster) - 1] = '\0';

    fund = -1; i = 0;
    do
    {
       fund = locate_substring(ex_musterstr,zle+i);
       if (fund > -1 )
       {
           f_ende = -1;
           if (mustertyp==1)
           {
              f_ende = locate_substring(")",zle+i+fund);
           }
           else // ==2
           {
              f_ende = locate_substring("}",zle+i+fund);
           }
           if (f_ende > -1)
           {
               int ausgeben_ok;
               ausgeben_ok = 1;
               extract_subs(
                    ex_zeile,
                    (zle + i + fund),
                    0,
                    f_ende + 1
                           );

                    if (mustertyp==1)
                    {
                       extractargument(
                           muster,
                           ex_zeile,
                           exex_zeile
                       );
                    }
                    else
                    {
                       extractargument_curly(
                           muster,
                           ex_zeile,
                           exex_zeile
                       );
                    }

                    if (locate_substring(ex_musterstr,exex_zeile) >= 0)
                    {
                        ausgeben_ok = 0;
                        break;
                    }
                    if (strlen(exex_zeile) > KENNZIFFER_LEN)
                    {
                         ausgeben_ok = 0;
                    }
                    if (strlen(exex_zeile) == 0)
                    {
                         ausgeben_ok = 0;
                    }
                    if (ausgeben_ok)
                    {
                       memset(&one_bbt_rec,0,sizeof(one_bbt_rec));
                       strcpy(one_bbt_rec.kennziffer,exex_zeile);
                       if (fwrite(&one_bbt_rec,sizeof(one_bbt_rec),1,fpbbt) < 1) schreibfehler();
                       anz_refs++;
                    }
           }
       }
       else
       {
           break;
       }
       i = i + fund + 1;
    }
    while (1);
    return 0;
}

