/*
    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
*/
/*
    str_refs.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "str_fun.h"
#include "str_refs.h"

/*
     Aus funktionsaehnlichen Strings vom Typ "%edit(, )" das Argument
     in Klammern extrahieren. fmodel ist die "Schablone" "%edit()" mit
     der der eingegebene String instring verglichen wird. Das extrahierte
     Argument wird outstring uebergeben.

     Gibt '0' zurueck, wenn fmodel nicht passt oder das 'Argument' nicht
     extrahiert werden kann, bei Erfolg '1'.
*/

int extractargument(const char * fmodel, char * instring, char * outstring)
{
   unsigned int i, j;
   unsigned open_pos;
   open_pos = 0;
   j=0;
   strcpy(outstring,"");

   if (instring[strlen(instring)-1]!=')') return 0;
   if (fmodel[strlen(fmodel)-1]!=')') return 0;
   if (strlen(fmodel) > strlen(instring)) return 0;

   for (i=0;i<strlen(fmodel)-1;i++)
   {
      if (fmodel[i]!=instring[i]) return 0;
      if (fmodel[i]=='(')
      {
         if (instring[i]=='(')
         {
             open_pos = i;   /* Position der oeffnenden Klammer */
             break;
         }
         else return 0;
      }
   }
   j = 0;
   for (i=open_pos+1;i<strlen(instring)-1;i++)
   {
      outstring[j]=instring[i];
      j++;
   }
   outstring[j]='\0';
   return 1;
}

int extractargument_curly(const char * fmodel, char * instring, char * outstring)
{
   unsigned int i, j;
   unsigned open_pos;
   open_pos = 0;
   j=0;
   strcpy(outstring,"");

   if (instring[strlen(instring)-1]!='}') return 0;
   if (fmodel[strlen(fmodel)-1]!='}') return 0;
   if (strlen(fmodel) > strlen(instring)) return 0;

   for (i=0;i<strlen(fmodel)-1;i++)
   {
      if (fmodel[i]!=instring[i]) return 0;
      if (fmodel[i]=='{')
      {
         if (instring[i]=='{')
         {
             open_pos = i;   /* Position der oeffnenden Klammer */
             break;
         }
         else return 0;
      }
   }
   j = 0;
   for (i=open_pos+1;i<strlen(instring)-1;i++)
   {
      outstring[j]=instring[i];
      j++;
   }
   outstring[j]='\0';
   return 1;
}


int extractargument_square(const char * fmodel, char * instring, char * outstring)
{
   unsigned int i, j;
   unsigned open_pos;
   open_pos = 0;
   j=0;
   strcpy(outstring,"");

   if (instring[strlen(instring)-1]!=']') return 0;
   if (fmodel[strlen(fmodel)-1]!=']') return 0;
   if (strlen(fmodel) > strlen(instring)) return 0;

   for (i=0;i<strlen(fmodel)-1;i++)
   {
      if (fmodel[i]!=instring[i]) return 0;
      if (fmodel[i]=='[')
      {
         if (instring[i]=='[')
         {
             open_pos = i;   /* Position der oeffnenden Klammer */
             break;
         }
         else return 0;
      }
   }
   j = 0;
   for (i=open_pos+1;i<strlen(instring)-1;i++)
   {
      outstring[j]=instring[i];
      j++;
   }
   outstring[j]='\0';
   return 1;
}


/*
     extractargument_square_round(
                             fmodel,
                             instring,
                             outstring_sq,
                             outstring_rd
                             )
     extracts from strings of type "%aaa[b](c)" `arguments' b and c and
     copies b to outstring_sq and c to outstring_rd.
     fmodel is the template "%aaa[]()".

     extractargument_square_round() returns '0' if fmodel does not fit or
     arguments cannot be extracted, otherwise it returns '1'.
*/

int extractargument_square_round(const char * fmodel, char * instring, char * outstring_sq, char * outstring_rd)
{
   unsigned int i, j;
   unsigned open_sq_pos;
   unsigned close_sq_pos;
   unsigned open_rd_pos;
   unsigned close_rd_pos;
   open_sq_pos = 0;
   open_rd_pos = 0;
   close_sq_pos = 0;
   close_rd_pos = 0;
   j=0;
   strcpy(outstring_sq,"");
   strcpy(outstring_rd,"");

   if (instring[strlen(instring)-1]!=')') return 0;
   if (fmodel[strlen(fmodel)-1]!=')') return 0;
   if (strlen(fmodel) > strlen(instring)) return 0;
   
   close_rd_pos = strlen(instring)-1;
   
   for (i=0;i<strlen(fmodel)-1;i++)
   {
      if (fmodel[i]!=instring[i]) return 0;
      if (fmodel[i]=='[')
      {
         if (instring[i]=='[')
         {
             open_sq_pos = i;  
             break;
         }
         else 
         {
            return 0;
         }
      }
   }
   for (i=0;i<strlen(instring)-1;i++)
   {
      if (instring[i]==']')
      {
         close_sq_pos=i;
      }
      if (instring[i]=='(')
      {
         open_rd_pos=i;
      }
   }
   if (open_sq_pos >= close_sq_pos) return 0; 
   if (close_sq_pos >= open_rd_pos) return 0; 
   if (open_rd_pos >= close_rd_pos) return 0; 
   
   j = 0;
   for (i=open_sq_pos+1;i<close_sq_pos;i++)
   {
      outstring_sq[j]=instring[i];
      j++;
   }
   outstring_sq[j]='\0';
   j = 0;
   for (i=open_rd_pos+1;i<close_rd_pos;i++)
   {
      outstring_rd[j]=instring[i];
      j++;
   }
   outstring_rd[j]='\0';
   
   return 1;
}



/*
   Fuegt 'trenner' in einen abgekuerzten Zeitschriftennamen 'inzeile' ein, Ausgabe
   in 'auszeile':
   inzeile:     N Engl J Med
   trenner      '. '
   auszaile:    N. Engl. J. Med
*/


void fdjsdelimiter(char * inzeile, char * auszeile, char * trenner, unsigned int MAXL)
{
  unsigned int laenge, i,j;
  laenge = strlen(inzeile);
  strcpy(auszeile,"");
  if (strlen(trenner)==0)
     strcpy(trenner," ");
  j=0;
  for (i=0;i<=laenge-1;i++)
  {
     if (inzeile[i]!=' ')
     {
        auszeile[j]=inzeile[i];
        j++;
        if (j==MAXL)
        {
          auszeile[j] = '\0';
          return;
        }
     }
     else
     {
        unsigned int k;
        for (k=0;k<=strlen(trenner)-1;k++)
        {
           auszeile[j] = trenner[k];
           j++;
           if (j==MAXL)
           {
             auszeile[j] = '\0';
             return;
           }
        }
     }
  }
  auszeile[j] = '\0';
  return;
}

int seitenziffern(char * vons, char * biss)
{
   unsigned int i, laenge;
   if (strlen(vons)==0 || strlen(biss)==0) return 0;
   if (strlen(vons)!=strlen(biss)) return 0;
   if (!strcmp(vons,biss))
   {
      strcpy(biss,"");
      return 0;
   }
   laenge = strlen(vons);
   for (i=0;i<laenge;i++)
   {
      if (vons[i]==biss[i]) biss[i]=' ';
        else break;
   }
   ltrim(biss,' ');
   return 1;
}

/* Seite 1233 - 43  -> biss_neu: 1243 */
int seitenziffern_komplettieren(char * vons, char * biss, char * biss_neu)
{
   int vonlen, bislen, i, j;
   vonlen=strlen(vons);
   bislen=strlen(biss);
   strcpy(biss_neu,"");
   if (bislen==0 || vonlen==0)
   {
     return 1;
   }
   if (bislen >= vonlen)
   {
     strcpy(biss_neu,biss);
     return 1;
   }
   strcpy(biss_neu,vons);
   j = bislen - 1;
   for (i=vonlen-1;i>=0;i--)
   {
       if (j>=0)
       {
          biss_neu[i] = biss[j];
       }
       j--;
   }
   return 1;
}

/*
 extract_idnr() processes `instring' of the type (for References idnr-field)
 "url:http://www.tmed.med.uni-rostock.de/hla.pdf doi:12.365 pmid:123625411" 
 It copies the id-number of idnrtype to outstring. Example
 
  extract_idnr(
   "url:http://www.tmed.med.uni-rostock.de/hla.pdf doi:12.365 pmid:123625411",
   "doi",
   outstring
  )

 `outstring' now has the value "12.365"
  Limitations: `instring' with length of less than 4 is not processed.
  
  In case of success, extract_idnr() returns: `1', if no idnr of type idnrtype
  is found: `0'
 */

int extract_idnr(char * instring, char * idnrtype, char * outstring)
{
   int i, anzahl_nr, laenge, rueckwert;
   char * idtag;
   char * ex_zeile;
   char * exex_zeile;
   
   rueckwert=0;
   strcpy(outstring,"");
   laenge=strlen(instring);
   if (strlen(instring) < 4)
   {
      return rueckwert;
   }
   if ((idtag = (char*) malloc((laenge +1) * sizeof(char)))==NULL)
   {
      fprintf(stderr,"\nERROR in extract_idnr(): "
        "cannot allocate memory for idtag\n");
      exit(1);
   }
   if ((ex_zeile = (char*) malloc((laenge +1) * sizeof(char)))==NULL)
   {
      fprintf(stderr,"\nERROR in extract_idnr(): "
        "cannot allocate memory for ex_zeile\n");
      exit(1);
   }
   if ((exex_zeile = (char*) malloc((laenge +1) * sizeof(char)))==NULL)
   {
      fprintf(stderr,"\nERROR in extract_idnr(): "
        "cannot allocate memory for exex_zeile\n");
      exit(1);
   }

   
   anzahl_nr = countitem(instring," ");
   for (i=1;i<=anzahl_nr;i++)
   {
      extractitem(i,instring," ",ex_zeile);
      if (countitem(ex_zeile,":") > 1)
      {
         extractitem(1,ex_zeile,":",idtag);
         if (strcmp(idtag,idnrtype)==0)
         {
           extract_subs(exex_zeile,ex_zeile,strlen(idtag)+1,strlen(ex_zeile));
           if (strlen(exex_zeile)>0)
           {
              strlimcpy(outstring,exex_zeile,laenge);
              rueckwert=1;
              break;
           }
         }
         
      }
   }
   
   free(idtag);
   free(ex_zeile);
   free(exex_zeile);
   return rueckwert;
}

