// Do not edit this file manually.
// It has been automatically generated from *.org sources.

/*
 * bibentrydirectout.c  (based on bibtexout.c)
 *
 * Copyright (c) Georgi N. Boshnakov 2020-2024
 *
 * Program and source code released under the GPL version 2
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "str.h"
#include "strsearch.h"
#include "utf8.h"
#include "xml.h"
#include "fields.h"
#include "generic.h"
#include "name.h"
#include "title.h"
#include "type.h"
#include "url.h"
#include "bibformats.h"

#include "common_bt_blt_btd_out.h"
#include "common_beout.h"

static int  bibentrydirectout_assemble( fields *in, fields *out, param *pm, unsigned long refnum );

/*****************************************************
 PUBLIC: int bibentrydirectout_initparams()
*****************************************************/

int
bibentrydirectout_initparams( param *pm, const char *progname )
{
	pm->writeformat      = BIBL_BIBENTRYOUT;
	pm->format_opts      = 0;
	pm->charsetout       = BIBL_CHARSET_DEFAULT;
	pm->charsetout_src   = BIBL_SRC_DEFAULT;
	pm->latexout         = 1;
	pm->utf8out          = BIBL_CHARSET_UTF8_DEFAULT;
	pm->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;
	pm->xmlout           = BIBL_XMLOUT_FALSE;
	pm->nosplittitle     = 0;
	pm->verbose          = 0;
	pm->addcount         = 0;
	pm->singlerefperfile = 0;

	pm->headerf   = bibentrydirectout_writeheader; // generic_writeheader;
	pm->footerf   = bibentrydirectout_writefooter; // NULL;
	pm->assemblef = bibentrydirectout_assemble;
	pm->writef    = bibentrydirectout_write;

	if ( !pm->progname ) {
		if ( !progname ) pm->progname = NULL;
		else {
			pm->progname = strdup( progname );
			if ( !pm->progname ) return BIBL_ERR_MEMERR;
		}
	}

	return BIBL_OK;
}

/*****************************************************
 PUBLIC: int bibentrydirectout_assemble()
*****************************************************/

static void
append_simple_quoted_tag( fields *in, char *intag, char *outtag, fields *out, int *status )
{
    int n, fstatus;
    str qtag;

    str_init( &qtag);
 
    n = fields_find( in, intag, LEVEL_ANY );
    if ( n!=FIELDS_NOTFOUND ) {
	fields_set_used( in, n );

	str_strcatc( &qtag, "\"" );
	str_strcatc( &qtag, outtag );
	str_strcatc( &qtag, "\"" );
		
	fstatus = fields_add( out, qtag.data, fields_value( in, n, FIELDS_CHRP ), LEVEL_MAIN );
	if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
    }

    str_free( &qtag );

}

static int
bibentryout_type( char *fld_val )
{
    int len = strlen(fld_val);

    switch(len) {
    case  4:
	if ( !strcasecmp( fld_val, "Book" ) )  return TYPE_BOOK;
	if ( !strcasecmp( fld_val, "Misc" ) )  return TYPE_MISC;
	break;

    case  6:
	if ( !strcasecmp( fld_val, "Inbook" ) )  return TYPE_INBOOK;
	if ( !strcasecmp( fld_val, "Manual" ) )  return TYPE_MANUAL;
	break;

    case  7:
	if ( !strcasecmp( fld_val, "Article" ) ) return TYPE_ARTICLE;
	if ( !strcasecmp( fld_val, "Booklet" ) ) return TYPE_BOOKLET; // added 2023-11-05
	break;

    case  9:
	if ( !strcasecmp( fld_val, "PhdThesis" ) )  return TYPE_PHDTHESIS;
	break;

    case 10:
	if ( !strcasecmp( fld_val, "TechReport" ) )  return TYPE_TECHREPORT;
	if ( !strcasecmp( fld_val, "Collection" ) )  return TYPE_COLLECTION;
	if ( !strcasecmp( fld_val, "Electronic" ) )  return TYPE_ELECTRONIC;
	break;

    case 11:
	if ( !strcasecmp( fld_val, "Proceedings" ) ) return TYPE_PROCEEDINGS;
	if ( !strcasecmp( fld_val, "Unpublished" ) )  return TYPE_UNPUBLISHED;
	break;

    case 12:
	if ( !strcasecmp( fld_val, "InCollection" ) ) return TYPE_INCOLLECTION;
	break;

    case 13:
	if ( !strcasecmp( fld_val, "InProceedings" ) )  return TYPE_INPROCEEDINGS;
	if ( !strcasecmp( fld_val, "MastersThesis" ) )  return TYPE_MASTERSTHESIS;
	if ( !strcasecmp( fld_val, "DiplomaThesis" ) )  return TYPE_DIPLOMATHESIS;
	break;

    // default:
	//   if ( !strcmp( fld_val, "online" ) )  return TYPE_MISC;
	//   break;
    }
    return TYPE_UNKNOWN; // 0
}

static int
bibentrydirectout_assemble( fields *in, fields *out, param *pm, unsigned long refnum )
{
  int type, status = BIBL_OK;
  int n, fstatus;
  char *fld_val;

  n = fields_find( in, "INTERNAL_TYPE", LEVEL_ANY );

  // append_type( type, out, &status );
  if ( n!=FIELDS_NOTFOUND ) { // the item has one of the internal types
    fields_set_used( in, n );
    fld_val = fields_value( in, n, FIELDS_CHRP );

    type = bibentryout_type(fld_val);

    if ( type != TYPE_UNKNOWN )
      fstatus = fields_add( out, "bibtype", fld_val, LEVEL_MAIN );
    else {
      // change the bibtype to "Misc" and store the actual type in "truebibtype"
      fstatus = fields_add( out, "bibtype", "Misc", LEVEL_MAIN );
      // lowercase unknown bibtypes
      for ( long int i=0; i < strlen(fld_val); i++ )
	fld_val[i] = (char)tolower(fld_val[i]);
      fstatus = fields_add( in, "truebibtype", fld_val, LEVEL_MAIN );
    }

  } else { // no internal type for this item
    type = TYPE_MISC; // non-internal types default to Misc
    fstatus = fields_add( out, "bibtype", "Misc", LEVEL_MAIN );
  }

  if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;

  // append_citekey     ( in, out, pm->format_opts, &status );
  append_simple      ( in, "REFNUM", "refnum", out, &status );

  append_simple      ( in, "truebibtype", "truebibtype", out, &status );
     
  append_people_be   ( in, "AUTHOR",     "AUTHOR:CORP",     "AUTHOR:ASIS",     "author", LEVEL_MAIN, out, pm->format_opts, pm->latexout, &status );
  append_people_be   ( in, "EDITOR",     "EDITOR:CORP",     "EDITOR:ASIS",     "editor", LEVEL_ANY, out, pm->format_opts, pm->latexout, &status );
  append_people_be   ( in, "TRANSLATOR", "TRANSLATOR:CORP", "TRANSLATOR:ASIS", "translator", LEVEL_ANY, out, pm->format_opts, pm->latexout, &status );
  append_titles      ( in, type, out, pm->format_opts, &status );
  append_date        ( in, out, &status );
  append_simple      ( in, "EDITION",            "edition",   out, &status );

  append_simple      ( in, "INSTITUTION",        "institution", out, &status );
  append_simple      ( in, "PUBLISHER",          "publisher", out, &status );


  append_simple      ( in, "ADDRESS",            "address",   out, &status );
  append_simple      ( in, "VOLUME",             "volume",    out, &status );
  append_issue_number( in, out, &status );
  append_pages       ( in, out, pm->format_opts, &status );
  append_keywords    ( in, out, &status );
  append_simple      ( in, "CONTENTS",           "contents",  out, &status );
  append_simple      ( in, "ABSTRACT",           "abstract",  out, &status );
  append_simple      ( in, "LOCATION",           "location",  out, &status );
  append_simple      ( in, "DEGREEGRANTOR",      "school",    out, &status );
  append_simple      ( in, "DEGREEGRANTOR:ASIS", "school",    out, &status );
  append_simple      ( in, "DEGREEGRANTOR:CORP", "school",    out, &status );
  append_simpleall   ( in, "NOTES",              "note",      out, &status );
  append_simpleall   ( in, "ANNOTE",             "annote",    out, &status );
  append_simple      ( in, "ISBN",               "isbn",      out, &status );
  append_simple      ( in, "ISSN",               "issn",      out, &status );
  append_simple      ( in, "MRNUMBER",           "mrnumber",  out, &status );
  append_simple      ( in, "CODEN",              "coden",     out, &status );
  append_simple      ( in, "DOI",                "doi",       out, &status );
  append_urls        ( in, out, &status );
  append_fileattach  ( in, out, &status );
  append_arxiv       ( in, out, &status );
  append_simple      ( in, "EPRINTCLASS",        "primaryClass", out, &status );
  append_isi         ( in, out, &status );
  append_simple      ( in, "LANGUAGE",           "language",  out, &status );
  append_howpublished( in, out, &status );

  append_simple      ( in, "CHAPTER",           "chapter",  out, &status ); // Georgi

  // Georgi - some entries may have field 'key' (it is used by some bibtex styles)
  //       other = c(key = "mykey")
  append_key      ( in, "KEY",   "other"        ,  out, &status );

  int i, f_len;
  char * fld_tag;

  f_len = fields_num( in );
  for ( i=0; i<f_len; ++i ) {
  	  if( !fields_used(in, i) ){
  	       fld_tag = fields_tag( in, i, FIELDS_CHRP );
  	       fld_val = fields_value( in, i, FIELDS_CHRP );

  	       append_simple_quoted_tag( in, fld_tag, fld_tag, out, &status );
  	  }
  }
  	
  return status;
}
