/*
    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
*/

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

 extern config_set one_config_set;
 extern char wrtxtbu[WRTXTBU_LEN+1];


/*
 * Selection of menu options at the [...]: - prompt.
 *
 * 'menuoptionen' contains menu options and descritions in the format
 *
 * [a] first menu option     [b] second menu option
 * [c] third menu option     [d] forth menu option
 *
 * 'menu' is an implicit menu option which shows the 'menuoption'
 * string. A default may be given with 'eingabe', which later is set to the
 * selected option.
 *
 * a typical call to menu_wahl():
 * { 
 *  static char ein[INPUT_BU_LEN+1];
 *  int option;
 *  ... 
 *  strcpy(ein,"menu");
 *
 *  wrtxt("\nMenu: demo for selection of options\n");
 *
 *  option = menu_wahl(ein,
 *    "[a] first option\n"
 *    "[b] second option\n"
 *    "[q] quit");
 *  if (option==1)
 *  {
 *    ...
 *  }
 * } 
 * The function returns the number of the menu option.
 */
int menu_wahl(char * eingabe, char * menuoptionen)
{
  char * ex_zeile;
  char * exex_zeile;
  int rueckwert;
  int option_gefunden;
  int anzahl_optionen;
  int i;
  
  rueckwert = 0;
  option_gefunden = 0;
#if defined(REFS_USES_LINUXGCC)
  char eingabe_temp[INPUT_BU_LEN+1];
#endif
  if ((ex_zeile = (char*) malloc((strlen(menuoptionen)+1) * sizeof(char)))==NULL)
  {
     fprintf(stderr,"\nERROR in menu_wahl(): "
       "cannot allocate memory for ex_zeile\n");
     exit(1);
  }
  if ((exex_zeile = (char*) malloc((strlen(menuoptionen)+1) * sizeof(char)))==NULL)
  {
     fprintf(stderr,"\nERROR in menu_wahl(): "
       "cannot allocate memory for exex_zeile\n");
     exit(1);
  }
   
  anzahl_optionen = countitem(menuoptionen,"[");
  
  for(;;)
  {
    char temporaer[INPUT_BU_LEN + 1];
    
    strcpy(temporaer,eingabe);
    
    if (strlen(eingabe)>0)
    {
      /* printf("\n[%s]%s",eingabe,one_config_set.prompt); */
      wrtxt("\n[");
      wrtxt(eingabe);
      wrtxt("]");
      wrtxt(one_config_set.prompt);
    }
    else 
    {
      /* printf("\n[...]%s",one_config_set.prompt); */
      wrtxt("\n[...]");
      wrtxt(one_config_set.prompt);
    }
    fflush(stdout);
      /* Linux: utf8 --> latin1 
         win32: cp850 --> latin1
      */
    fgets(eingabe,INPUT_BU_LEN,stdin);
    fflush(stdin);
    /* begin new 8.10.2006 */
#if defined(REFS_USES_MINGW)
    cp850_to_latin1(eingabe);
#endif
#if defined(REFS_USES_LINUXGCC)
    if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
    {
       strlimcpy(eingabe_temp,eingabe,INPUT_BU_LEN);
       strcpy(eingabe,"");
       utf8_to_latin1(eingabe,eingabe_temp,INPUT_BU_LEN);
    }
#endif
    /* end new 8.10.2006 */
    rtrim(eingabe,'\n');
    /* begin new Jun 2002 */
    trim(eingabe,' ');
    /* end new Jun 2002 */
    if (strlen(eingabe)==0)
    {
      strcpy(eingabe,temporaer);
    }
    if (!strcmp(eingabe,"menu"))
    {
      /* printf("\n%s\n",menuoptionen); */
      wrtxt("\n");
#if defined(REFS_USES_MINGW)
      wrtxt(menuoptionen);
#endif
#if defined(REFS_USES_LINUXGCC)
      wrtxt_hl_sq_brackets(menuoptionen);
#endif
      wrtxt("\n");
    }
    else
    {
      /* here comparisons */
       for (i=1;i<=anzahl_optionen;i++)
       {
         extractitem(i,menuoptionen,"[",ex_zeile);
         extractitem(1,ex_zeile,"]",exex_zeile);
         ltrim(exex_zeile,' ');
         if (strcmp(exex_zeile,eingabe)==0)
         {
           rueckwert = i; 
           break;
         }
       }
       if (rueckwert == 0)
       {
          /* printf("\nInvalid menu option, please read menu options.\n"); */
          wrtxt("\nInvalid menu option, please read menu options.\n");
          strcpy(eingabe,"menu");
       }
    }
    if (rueckwert > 0)
    {
      break;
    }
  }
  free(ex_zeile);
  free(exex_zeile);
  return rueckwert;
}

int wrtxt(char * zeile)
{
#if defined(REFS_USES_MINGW)
   char ausgabe_zeile[AUSGABEZEILE_LEN + 1];
   strcpy(ausgabe_zeile,"");
   strlimcpy(ausgabe_zeile,zeile,AUSGABEZEILE_LEN);
   latin1_to_cp850(ausgabe_zeile);
   printf("%s",ausgabe_zeile);
   fflush(stdout);
#endif
#if defined(REFS_USES_LINUXGCC)
   char ausgabe_zeile[AUSGABEZEILE_LEN + 1];
   strcpy(ausgabe_zeile,"");
   if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
   {
      latin1_to_utf8(ausgabe_zeile,zeile,AUSGABEZEILE_LEN-1);
   }
   if (strcmp(one_config_set.textfile_encoding,ENC_ISO8859)==0)
   {
      strlimcpy(ausgabe_zeile,zeile,AUSGABEZEILE_LEN-1);
   }
   printf("%s",ausgabe_zeile);
   fflush(stdout);
#endif
   return 1;
}

#if defined(REFS_USES_LINUXGCC)
int wrtxt_hl_sq_brackets(char * zeile)
{
   char ausgabe_zeile[AUSGABEZEILE_LEN + 1];
   char ausgabe_zeile_temp[AUSGABEZEILE_LEN + 1];
   int neusuch, code;

   strcpy(ausgabe_zeile,"");
   if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
   {
      latin1_to_utf8(ausgabe_zeile,zeile,AUSGABEZEILE_LEN-1);
   }
   if (strcmp(one_config_set.textfile_encoding,ENC_ISO8859)==0)
   {
      strlimcpy(ausgabe_zeile,zeile,AUSGABEZEILE_LEN-1);
   }
   /* insert escape sequences */ 
   if (strcmp(one_config_set.enable_hl,"0") != 0)
   {
     if (strcmp(one_config_set.enable_hl,"1") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[1m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }
     if (strcmp(one_config_set.enable_hl,"2") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[35m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }
     if (strcmp(one_config_set.enable_hl,"3") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[34;1m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }
     if (strcmp(one_config_set.enable_hl,"4") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[36m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }
     if (strcmp(one_config_set.enable_hl,"5") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[33m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }
     if (strcmp(one_config_set.enable_hl,"6") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[31;1m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }
     if (strcmp(one_config_set.enable_hl,"7") == 0)
     {
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "[",
                         "\033[7;1m[",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
       neusuch = 0;
       for(;;)
       {
          code = serepl(ausgabe_zeile,
                         "]",
                         "]\033[0m",
                         AUSGABEZEILE_LEN,
                         &neusuch,
                         ausgabe_zeile_temp
                         );
         if (code!=1) break; 
       }
     }

   }
   printf("%s",ausgabe_zeile);
   fflush(stdout);

   
   return 1;
}
#endif


// int ein_zeile(char * inzeile, char * text, int stlaenge)
// {
//     /* ein_zeile stores stlaenge characters */
// #if defined(REFS_USES_LINUXGCC)
//     char inzeile_temp[INPUT_BU_LEN+1];
// #endif    
//     wrtxt("\n");
//     wrtxt(text);
//     wrtxt(one_config_set.prompt);
//     fgets(inzeile,stlaenge+1,stdin);
//     fflush(stdin);
//     rtrim(inzeile,'\n');
// #if defined(REFS_USES_MINGW)
//     cp850_to_latin1(inzeile);
// #endif    
// #if defined(REFS_USES_LINUXGCC)
//     if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
//     {
//        strlimcpy(inzeile_temp,inzeile,INPUT_BU_LEN);
//        strcpy(inzeile,"");
//        utf8_to_latin1(inzeile,inzeile_temp,INPUT_BU_LEN);
//     }
// #endif    
//     return 1;
// }

/* changed 24.6.2007 */
int ein_zeile(char * inzeile, char * text, int stlaenge)
{
    /* ein_zeile stores stlaenge characters */
#if defined(REFS_USES_LINUXGCC)
    char inzeile_temp[INPUT_BU_LEN+1];
    char inzeile_roh[INPUT_BU_LEN+1];
    wrtxt("\n");
    wrtxt(text);
    wrtxt(one_config_set.prompt);
    fgets(inzeile_roh,INPUT_BU_LEN+1,stdin); /* ...LEN + 1 richtig?*/
    fflush(stdin);
    rtrim(inzeile_roh,'\n');
    if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
    {
       utf8_to_latin1(inzeile_temp,inzeile_roh,INPUT_BU_LEN);
       strlimcpy(inzeile,inzeile_temp,stlaenge);
    }
#endif    
#if defined(REFS_USES_MINGW)
    wrtxt("\n");
    wrtxt(text);
    wrtxt(one_config_set.prompt);
    fgets(inzeile,stlaenge+1,stdin);
    fflush(stdin);
    rtrim(inzeile,'\n');
    cp850_to_latin1(inzeile);
#endif    
    return 1;
}



/* 
   - vtxt() reads text file `dateiname' in latin-1 encoding, 
   - if `message_text' is not empty, vtxt() shows a prompt with `message_text'
     before showing the first page
*/
int vtxt(char * dateiname, char * message_text)
{
   int openmode;
   if (strlen(message_text)==0)
   {
      openmode = 0;
   }
   else
   {
      openmode = 1;
   }
#if defined(REFS_USES_MINGW)
   return vtxt_var(dateiname, message_text, openmode);
#endif
#if defined(REFS_USES_LINUXGCC)
   if (one_config_set.uses_less==1)
   {
     return vtxt_external_pager(dateiname, message_text, openmode);
   }
   else /* i.e. 0 */
   {
     return vtxt_var(dateiname, message_text, openmode);
   }
#endif
}

int vtxt_external_pager(char * dateiname, char * message_text, int openmode)
{
   char kommando[PFAD_LEN+1];

   if (openmode==1)
   {
     anhalten_mit_text(message_text);
   }
   if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
   {
      strlimcpy(kommando,"recode l1..u8 < ",PFAD_LEN);
      strlimcat(kommando, dateiname,PFAD_LEN);
      // strlimcat(kommando, " | less -Q ",PFAD_LEN);
      strlimcat(kommando, " | less ",PFAD_LEN);
      strlimcat(kommando,one_config_set.less_options,PFAD_LEN);
      strlimcat(kommando," ",PFAD_LEN);
      system(kommando);
   }
   if (strcmp(one_config_set.textfile_encoding,ENC_ISO8859)==0)
   {
      // strlimcpy(kommando,"less -Q ",PFAD_LEN);
      strlimcpy(kommando,"less ",PFAD_LEN);
      strlimcat(kommando,one_config_set.less_options,PFAD_LEN);
      strlimcpy(kommando," ",PFAD_LEN);
      strlimcat(kommando,dateiname,PFAD_LEN);
      system(kommando);
   }
   
   return 1;
}



/* prompts 'message_text', shows text in 'dateiname' 
   openmode 0: shows first page, no prompt
   openmode 1: shows prompt for menu
 */
int vtxt_var(char * dateiname, char * message_text, int openmode)
{

   static char ein[INPUT_BU_LEN+1];
   long stapellaenge;
   long anzahl_zeilen;
   char **textstapel;
   long i, zeiger;
   char zeile[VTXTFILELINE_LEN + 1];
   FILE * fp;
   long spalte;
   int erstansicht; /* 
                       1: shows first page after starting 
                       0: shows normal prompt with 'message_text'
                     */

   stapellaenge=40000L;   
   spalte=0;
   textstapel=NULL;
   erstansicht = 1;
   static char suchstring[INPUT_BU_LEN+1];
   static char suchstring_alt[INPUT_BU_LEN+1];

   if (openmode==1)
   {
     erstansicht = 0;
   }
   
   if ((fp=fopen(dateiname,"r"))==NULL)
   {
      return 0;
   }
   i = 0;
   while (fgets(zeile, VTXTFILELINE_LEN, fp)!=NULL)
   {
      
      if ((textstapel=(char **) realloc(textstapel,(i+1)*sizeof(char *)))==NULL)
      {
        fprintf(stderr,"\nERROR: cannot allocate memory\n");
        exit(1);
      }
      rtrim(zeile,'\n');
      if ((textstapel[i]=(char*) malloc((strlen(zeile)+1)*sizeof(char)))==NULL)
      {
        fprintf(stderr,"\nERROR: cannot allocate memory\n");
        exit(1);
      }
      strcpy(textstapel[i],zeile);
      i++;
      if ((i-1)>=(stapellaenge-1))
      {
         wrtxt("\n(Warning: file not read completely)\n");
         break;
      }
   }
   anzahl_zeilen = i-1;
   fclose(fp);
   zeiger=0;
   
   strcpy(ein,"menu");
   sprintf(wrtxtbu,"\n%s [f/l/n/p/+/-/r/ ... /q]\n", message_text);
   wrtxt(wrtxtbu);
   for (;;)
   {
     int option;
     
     if (erstansicht==0)
     {
       option = menu_wahl(ein,
        "[f] first page     [l] last page      [n] next page      [p] previous page\n" /* 1-4 */
        "[+] line forward   [-] line back      [r] refresh page   [.] first column\n"  /* 5-8 */
        "[>] one page right [<] one page left  [}] one col. right [{] one col. left\n" /* 9-12 */
        "[s] show line no   [g] go to line     [/] find           [q] quit"            /* 13-16 */
        
        );
     } else
     {
        option = 1;
     }
     

     erstansicht = 0;
     if (option==16)
     {
        break;
     }
     if (option==13)
     {
        sprintf(wrtxtbu,"\nLine: %li\n",zeiger+1);
        wrtxt(wrtxtbu);
        anhalten();
        option = 7;
        strcpy(ein,"menu");
     }
     if (option==15)
     {
        long ii;

        if (strlen(suchstring_alt)>0)
        {
           wrtxt("\nLast search text: ``");
           wrtxt(suchstring_alt);
           wrtxt("''\n");
        }
        ein_zeile(suchstring,"Text to be searched for [empty line for last search]",
          INPUT_BU_LEN);
        if (strlen(suchstring)==0)
        
        {
           strlimcpy(suchstring,suchstring_alt,INPUT_BU_LEN);
           option = 7;
           strcpy(ein,"menu");
        } else 
        {
           strlimcpy(suchstring_alt,suchstring,INPUT_BU_LEN);
        }
        wrtxt("\nText ``");
        wrtxt(suchstring);
        wrtxt("'' found in line: ");
        for (ii=0;ii <= anzahl_zeilen; ii++)
        {
           if (locate_substring(suchstring,textstapel[ii])>-1)
           {
              sprintf(wrtxtbu,"%li ",ii+1);
              wrtxt(wrtxtbu);
           }
        }
        wrtxt("\n");
        option = 14;
        strcpy(ein,"menu");
     }

     if (option==14)
     {
        char eingabe[INPUT_BU_LEN+1];
        int ok;
        long zahl;

        ok = 0;

        do
        {
           sprintf(wrtxtbu,"Go to line number [1..%li]",
             anzahl_zeilen+1);
           ein_zeile(eingabe,wrtxtbu,INPUT_BU_LEN);
           if (strlen(eingabe)==0)
           {
             zahl = 1;
             ok = 1;
           } else
           {
             string_in_long(eingabe,&zahl,&ok);
           }
           
        } while (ok!=1);

        zeiger = zahl-1;
        if (zeiger < 0)
        {
          zeiger = 0;
        }
        if (zeiger > (anzahl_zeilen-1))
        {
          zeiger = anzahl_zeilen;
        }
        
        option = 7;
        strcpy(ein,"menu");
     }
     if (option==1)
     {
        zeiger = 0;
     }
     if (option==2) /* last */
     {
        zeiger = anzahl_zeilen - (one_config_set.sl - 3);
     }
     if (option==3)
     {
        zeiger = zeiger + one_config_set.sl - 3 - 1;
     }
     if (option==4)
     {
        zeiger = zeiger - (one_config_set.sl - 3 - 1);
     }
     if (option==5)
     {
        zeiger = zeiger + 1;
     }
     if (option==6)
     {
        zeiger = zeiger - 1;
     }
     if (option==8)
     {
        spalte = 0;
     }
     if (option==9)
     {
        spalte = spalte + (EDITING_LINE_LEN-1);
     }
     if (option==10)
     {
        spalte = spalte - (EDITING_LINE_LEN-1);
     }
     if (option==11)
     {
        spalte = spalte + 1;
     }
     if (option==12)
     {
        spalte = spalte - 1;
     }
     if (spalte < 0)
     {
       spalte = 0;
     }
     if (zeiger>=anzahl_zeilen)
     {
       zeiger = anzahl_zeilen ;
     }
     if (zeiger <  -(one_config_set.sl - 3)) /* ?4 */
     {
        zeiger =  -(one_config_set.sl - 3);
     }
     
     for (i=zeiger;i<=(zeiger+one_config_set.sl-3);i++)
     {
       if (i<=anzahl_zeilen)
       {
         if (i < 0)
         {
            wrtxt("~\n");
         } else
         {
           if (strlen(textstapel[i]) > spalte)
           {
             extract_subs(wrtxtbu,textstapel[i],spalte,EDITING_LINE_LEN);  
             wrtxt(wrtxtbu);
             if (strlen(textstapel[i])> spalte+EDITING_LINE_LEN)
             {
               wrtxt("$");
             }
           }
           wrtxt("\n");
         }
       }
       else 
       {
         wrtxt("~\n");
       }
     }
   }
   
   for (i=0;i<=anzahl_zeilen;i++)
   {
      free(textstapel[i]);
   }
   free(textstapel);
   
   return 0;
}


/* name is output */
int dateivornamen_holen(char * name, char * eingabeaufforderung)
{
#ifdef REFS_USES_MINGW  
 #define DATEIEINGABE_LEN  EINGABE_DATEINAME_VOR_PUNKT
#endif
#ifdef REFS_USES_LINUXGCC  
 #define DATEIEINGABE_LEN  EINGABE_DATEINAME_VOR_PUNKT
#endif
    char eingabe[DATEIEINGABE_LEN +1];
    int ok;
    
    ok = 0;
    while(!ok)
    {
       ein_zeile(eingabe,eingabeaufforderung,DATEIEINGABE_LEN);
       if (strlen(eingabe)==0)
       {
          strcpy(name,eingabe);
          return 0;
       }
       if (isvalidfilename(eingabe))
       {
           strlimcpy(name,eingabe,DATEIEINGABE_LEN);
           ok=1;
       }
    }
    return 1;
}

int do_delete_yn(void)
{
   char ein[INPUT_BU_LEN + 1];
   int taste;
   strcpy(ein,"menu");
   wrtxt("\nMenu: confirmation to delete [y/n]\n");
   taste = menu_wahl(ein,
      "[y] yes, delete\n"
      "[n] no, do not delete"
     );
   if (taste==1)
   {
      return 1;
   }
   else
   {
     return 0;
   }
}


int do_overwrite_yn(void)
{
   char ein[INPUT_BU_LEN + 1];
   int taste;
   strcpy(ein,"menu");
   wrtxt("\nMenu: confirmation to overwrite [y/n]\n");
   taste = menu_wahl(ein,
      "[y] yes, overwrite\n"
      "[n] no, do not overwrite"
     );
   if (taste==1)
   {
      return 1;
   }
   else
   {
     return 0;
   }
}

int do_overwrite_append_oa(void)
{
   char ein[INPUT_BU_LEN + 1];
   int taste;
   strcpy(ein,"menu");
   wrtxt("\nMenu: overwrite file or append to existing file [o/a]\n");
   taste = menu_wahl(ein,
      "[o] overwrite existing file (previous data will be lost)\n"
      "[a] append new data to existing file"
     );
   if (taste==1)
   {
      return 1;
   }
   else
   {
     return 0;
   }
}


void anhalten(void)
{
   char ein[INPUT_BU_LEN+1];
   ein_zeile(ein,"Please press [ENTER] to continue",INPUT_BU_LEN);
   return;
}

void anhalten_mit_text(char * prompttext)
{
   char ein[INPUT_BU_LEN+1];
   ein_zeile(ein,prompttext,INPUT_BU_LEN);
   return;
}
void schreibfehler(void)
{
   char ein[INPUT_BU_LEN+1];
   wrtxt("\nFailure to write to binary file, for information see documentation\n");
   ein_zeile(ein,"Please press [ENTER] to stop References",INPUT_BU_LEN);
   exit(1);
}

/* executes a single command or allows to call a shell */
void shell_ausfuehren(void)
{
   static char kommando[PFAD_LEN+1];
   static char alt_kommando[PFAD_LEN+1];
   /* char kommando[PFAD_LEN+1]; */
#if defined(REFS_USES_MINGW)
   putenv("PROMPT=References, return with `exit' -- $p$g");
#endif
   if (strlen(alt_kommando) < 1)
   {
      ein_zeile(kommando,
        "System command",
        PFAD_LEN);
   } else 
   {
      strcpy(wrtxtbu, "\nPrevious command: ");
      strlimcat(wrtxtbu,alt_kommando,WRTXTBU_LEN);
      strlimcat(wrtxtbu,"\n",WRTXTBU_LEN);
      wrtxt(wrtxtbu);
      ein_zeile(kommando,
        "System command [blank for previous command]",
        PFAD_LEN);
      if (strlen(kommando) < 1)
      {
         strlimcpy(kommando,alt_kommando,PFAD_LEN);
      }
   }
   if (strlen(kommando) < 1)
   {
      wrtxt("\nProblem: no command entered\n");
   }
   else
   {
#if defined(REFS_USES_LINUXGCC)
     wrtxt("\nIf this is an interactive shell launched from References, "
        "finish with `exit'\n\n");
#endif
     system(kommando);
     strlimcpy(alt_kommando,kommando,PFAD_LEN);
   }
   anhalten();
   return;
}


int load_file_yn(char * dname)
{
  static char ein[INPUT_BU_LEN+1];
  int option;
  char meldung[WRTXTBU_LEN +1];
  // char kommando[PFAD_LEN+1];
  if (one_config_set.open_editor_yn!=1)
  {
     return 0;
  }

  if (!isfile(dname) || filesize(dname) < 1)
  {
     return 0;
  }
  // sprintf(meldung,"\nMenu: load file ``%s'' (text editor)? [y/n]\n",dname);
  sprintf(meldung,"\nMenu: open editor with file ``%s''? [y/n]\n",dname);
  wrtxt(meldung);
  strcpy(ein,"menu");
  option = menu_wahl(ein,
    "[y] yes, open file\n"
    "[n] no, do not open file"
    );
  if (option==1)
  {
      textdatei_editieren(dname);
      return 1;
  } else
  {
      return 0;
  }
 
}


int copy_textfile_utf8_to_latin1(char * outfile, char * infile)
{
   FILE * fpin;
   FILE * fpout;
   char * zeile;
   char * ex_zeile;
   long i;
   
   i = 0;
   if ((fpin=fopen(infile,"r"))==NULL)
   {
       printf("\nError: cannot read %s\n",infile);
       exit(1);
   }
   if ((fpout=fopen(outfile,"w"))==NULL)
   {
       printf("\nError: cannot read %s\n",outfile);
       exit(1);
   }

   if ((zeile = (char *) malloc((TEXTZEILE_LEN+1) * sizeof(char)))==NULL)
   {
      printf("\nError: memory allocation failed\n");
      exit(1);
   }
   if ((ex_zeile = (char *) malloc((TEXTZEILE_LEN+1) * sizeof(char)))==NULL)
   {
      printf("\nError: memory allocation failed\n");
      exit(1);
   }
   while (fgets(zeile,TEXTZEILE_LEN,fpin)!=NULL)
   {
       i++;
       if (strlen(zeile) >= TEXTZEILE_LEN - 1)
       {
          printf("\nProblem: line %li too long\n",i);
       }
       strcpy(ex_zeile,"");
       utf8_to_latin1(ex_zeile,zeile,TEXTZEILE_LEN);
       fprintf(fpout,"%s",ex_zeile);
   }
    
   free(zeile);
   fclose(fpout);
   fclose(fpin);
   return 1;
}

int copy_textfile_latin1_to_utf8(char * outfile, char * infile)
{
   FILE * fpin;
   FILE * fpout;
   char * zeile;
   char * ex_zeile;
   long i;
   
   i = 0;
   if ((fpin=fopen(infile,"r"))==NULL)
   {
       printf("\nError: cannot read %s\n",infile);
       exit(1);
   }
   if ((fpout=fopen(outfile,"w"))==NULL)
   {
       printf("\nError: cannot read %s\n",outfile);
       exit(1);
   }

   if ((zeile = (char *) malloc((TEXTZEILE_LEN+1) * sizeof(char)))==NULL)
   {
      printf("\nError: memory allocation failed\n");
      exit(1);
   }
   if ((ex_zeile = (char *) malloc((TEXTZEILE_LEN+1) * sizeof(char)))==NULL)
   {
      printf("\nError: memory allocation failed\n");
      exit(1);
   }
   while (fgets(zeile,TEXTZEILE_LEN,fpin)!=NULL)
   {
       i++;
       if (strlen(zeile) >= TEXTZEILE_LEN - 1)
       {
          printf("\nProblem: line %li too long\n",i);
       }
       strcpy(ex_zeile,"");
       latin1_to_utf8(ex_zeile,zeile,TEXTZEILE_LEN);
       fprintf(fpout,"%s",ex_zeile);
   }
    
   free(zeile);
   fclose(fpout);
   fclose(fpin);
   return 1;
}

/*
  `Text file may be selected for editing' if
    - file name does not end with `$'
    - file name does not end with `_u8'
*/
int textdatei_darf_editiert_werden(char * textd)
{
   if ((locate_substring("$",textd)==
        (strlen(textd)-strlen("$"))))
   {
      return 0;
   }
   if (strlen(textd) >= strlen("_u8"))
   {
      if ((locate_substring("_u8",textd)==
        (strlen(textd)-strlen("_u8"))))
      {
        return 0;
      }
   }
   return 1;
}


int textdatei_editieren(char * textdatei_l1)
{
   if (textdatei_darf_editiert_werden(textdatei_l1)==0)
   {
      wrtxt("\nWarning: Not allowed to edit this file\n");
      anhalten();
      return 0;
   }
   if (!isfile(textdatei_l1))
   {
     textdatei_anlegen(textdatei_l1);
   }
#if defined(REFS_USES_LINUXGCC)
   char textdatei_u8[PFAD_LEN+1];
   char kommando[PFAD_LEN+1];
   
   if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
   {
     strlimcpy(textdatei_u8,textdatei_l1,PFAD_LEN);
     strlimcat(textdatei_u8,"_u8",PFAD_LEN);
     if (isfile(textdatei_u8))
     {
        sprintf(wrtxtbu,"\nWarning: `%s' is already opened for editing\n",
           textdatei_l1);
        wrtxt(wrtxtbu);
        anhalten();
        return 0;
     }
     copy_textfile_latin1_to_utf8(textdatei_u8,textdatei_l1);
     remove(textdatei_l1);
     strlimcpy(kommando,one_config_set.editor_name,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei_u8,PFAD_LEN);
     system(kommando);
     anhalten_mit_text(ANHALTEN_PROMPTTEXT);
     copy_textfile_utf8_to_latin1(textdatei_l1,textdatei_u8);
     remove(textdatei_u8);
   }
   if (strcmp(one_config_set.textfile_encoding,ENC_ISO8859)==0)
   {
     strlimcpy(kommando,one_config_set.editor_name,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei_l1,PFAD_LEN);
     system(kommando);
     anhalten_mit_text(ANHALTEN_PROMPTTEXT);
   }
#endif
#if defined(REFS_USES_MINGW)
   char kommando[PFAD_LEN+1];

   strlimcpy(kommando,one_config_set.editor_name,PFAD_LEN);
   strlimcat(kommando," ",PFAD_LEN);
   strlimcat(kommando,textdatei_l1,PFAD_LEN);
   system(kommando);
   anhalten_mit_text(ANHALTEN_PROMPTTEXT);
#endif
   return 1;
}

int drei_textdateien_editieren(char * textdatei1_l1,
                               char * textdatei2_l1,
                               char * textdatei3_l1)
{
   if (textdatei_darf_editiert_werden(textdatei1_l1)==0)
   {
      wrtxt("\nWarning: Not allowed to edit this file\n");
      anhalten();
      return 0;
   }
   if (textdatei_darf_editiert_werden(textdatei2_l1)==0)
   {
      wrtxt("\nWarning: Not allowed to edit this file\n");
      anhalten();
      return 0;
   }
   if (textdatei_darf_editiert_werden(textdatei3_l1)==0)
   {
      wrtxt("\nWarning: Not allowed to edit this file\n");
      anhalten();
      return 0;
   }

   if (!isfile(textdatei1_l1))
   {
     textdatei_anlegen(textdatei1_l1);
   }
   if (!isfile(textdatei2_l1))
   {
     textdatei_anlegen(textdatei2_l1);
   }
   if (!isfile(textdatei3_l1))
   {
     textdatei_anlegen(textdatei3_l1);
   }
#if defined(REFS_USES_LINUXGCC)
   char textdatei1_u8[PFAD_LEN+1];
   char textdatei2_u8[PFAD_LEN+1];
   char textdatei3_u8[PFAD_LEN+1];
   char kommando[PFAD_LEN+1];
   if (strcmp(one_config_set.textfile_encoding,ENC_UTF8)==0)
   {
     strlimcpy(textdatei1_u8,textdatei1_l1,PFAD_LEN);
     strlimcat(textdatei1_u8,"_u8",PFAD_LEN);
     if (isfile(textdatei1_u8))
     {
        sprintf(wrtxtbu,"\nWarning: `%s' is already opened for editing\n",
           textdatei1_l1);
        wrtxt(wrtxtbu);
        anhalten();
        return 0;
     }
     strlimcpy(textdatei2_u8,textdatei2_l1,PFAD_LEN);
     strlimcat(textdatei2_u8,"_u8",PFAD_LEN);
     if (isfile(textdatei2_u8))
     {
        sprintf(wrtxtbu,"\nWarning: `%s' is already opened for editing\n",
           textdatei2_l1);
        wrtxt(wrtxtbu);
        anhalten();
        return 0;
     }
     strlimcpy(textdatei3_u8,textdatei3_l1,PFAD_LEN);
     strlimcat(textdatei3_u8,"_u8",PFAD_LEN);
     if (isfile(textdatei3_u8))
     {
        sprintf(wrtxtbu,"\nWarning: `%s' is already opened for editing\n",
           textdatei3_l1);
        wrtxt(wrtxtbu);
        anhalten();
        return 0;
     }

     copy_textfile_latin1_to_utf8(textdatei1_u8,textdatei1_l1);
     remove(textdatei1_l1);

     copy_textfile_latin1_to_utf8(textdatei2_u8,textdatei2_l1);
     remove(textdatei2_l1);

     copy_textfile_latin1_to_utf8(textdatei3_u8,textdatei3_l1);
     remove(textdatei3_l1);

     strlimcpy(kommando,one_config_set.editor_name,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei1_u8,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei2_u8,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei3_u8,PFAD_LEN);
     system(kommando);
     
     anhalten_mit_text(ANHALTEN_PROMPTTEXT);
     
     copy_textfile_utf8_to_latin1(textdatei1_l1,textdatei1_u8);
     remove(textdatei1_u8);
     copy_textfile_utf8_to_latin1(textdatei2_l1,textdatei2_u8);
     remove(textdatei2_u8);
     copy_textfile_utf8_to_latin1(textdatei3_l1,textdatei3_u8);
     remove(textdatei3_u8);
   }
   if (strcmp(one_config_set.textfile_encoding,ENC_ISO8859)==0)
   {
     strlimcpy(kommando,one_config_set.editor_name,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei1_l1,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei2_l1,PFAD_LEN);
     strlimcat(kommando," ",PFAD_LEN);
     strlimcat(kommando,textdatei3_l1,PFAD_LEN);
     system(kommando);
     anhalten_mit_text(ANHALTEN_PROMPTTEXT);
   }
#endif
#if defined(REFS_USES_MINGW)
   char kommando[PFAD_LEN+1];

   strlimcpy(kommando,one_config_set.editor_name,PFAD_LEN);
   strlimcat(kommando," ",PFAD_LEN);
   strlimcat(kommando,textdatei1_l1,PFAD_LEN);
   strlimcat(kommando," ",PFAD_LEN);
   strlimcat(kommando,textdatei2_l1,PFAD_LEN);
   strlimcat(kommando," ",PFAD_LEN);
   strlimcat(kommando,textdatei3_l1,PFAD_LEN);
   system(kommando);
   anhalten_mit_text(ANHALTEN_PROMPTTEXT);
#endif
   return 1;
}


int textdatei_anlegen(char * dname)
{
   FILE * fpout;
   if ((fpout=fopen(dname,"w"))==NULL)
   {
       printf("\nError: cannot write to %s\n",dname);
       exit(1);
   }
   
   fprintf(fpout,"New text file `%s'\n",dname);
   
   fclose(fpout);
   return 1;
}
