/*
* Copyright (C) 2007, CompHEP Collaboration
* Author: Alexander Sherstnev 
*------------------------------------------------
* $Id $
*
* $Log $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lhaef.h"


static char * gen_desc_str = NULL;
static int gen_desc_used = 0;

void * init_lhaef_document (void)
{
  return 0;
}

int set_general_description(void * doc, lhaef_general_description * smpl)
{
  char frmt[512];
  int len = 512 + 
  strlen(smpl->title) + 
  strlen(smpl->abstruct) + 
  strlen(smpl->comments) + 
  strlen(smpl->experiment->experiment) + 
  strlen(smpl->experiment->group) + 
  strlen(smpl->experiment->responsiblePerson) + 
  strlen(smpl->experiment->description);

  frmt[0] = '\0';
  strcat (frmt, "        <title>\%s</title>\n"                            );
  strcat (frmt, "        <abstract>\%s</abstract>\n"                      );
  strcat (frmt, "        <authorComments>\%s</authorComments>\n"          );
  strcat (frmt, "        <experimentGroup>\n"                             );
  strcat (frmt, "            <experiment>\%s</experiment>\n"              );
  strcat (frmt, "            <group>\%s</group>\n"                        );
  strcat (frmt, "            <responsiblePerson>\%s</responsiblePerson>\n");
  strcat (frmt, "            <description>\%s</description>\n"            );
  strcat (frmt, "        </experimentGroup>\n"                            );

  if (!gen_desc_used) {
    gen_desc_str = malloc (len * sizeof (char));

    sprintf(gen_desc_str, frmt, 
    smpl->title, 
    smpl->abstruct, 
    smpl->comments, 
    smpl->experiment->experiment, 
    smpl->experiment->group, 
    smpl->experiment->responsiblePerson, 
    smpl->experiment->description);
    gen_desc_used = 1;
  }

  return 0;
}

static char * file_str = NULL;
static int file_used = 0;

int set_file_description(void * doc, lhaef_file * file)
{
  char frmt[512];
  int len = 512 + 
  strlen(file->cross_section_unit) + 
  strlen(file->check_sum_type) + 
  strlen(file->location_type) + 
  strlen(file->machine_name) + 
  strlen(file->location_path);

  frmt[0] = '\0';
  strcat (frmt, "            <eventsNumber>\%10li</eventsNumber>\n"              );
  strcat (frmt, "            <crossSection unit=\"\%s\">\%12.4E</crossSection>\n");
  strcat (frmt, "            <fileSize>\%13li</fileSize>\n"                      );
  strcat (frmt, "            <checksum type=\"\%s\">\%i</checksum>\n"            );
  strcat (frmt, "            <comments></comments>\n"                            );
  strcat (frmt, "            <location>\n"                                       );
  strcat (frmt, "                <path>\%s://:\%s:\%s</path>\n"                  );
  strcat (frmt, "            </location>\n"                                      );

  if (!file_used) {
    file_str = malloc(len * sizeof (char));

    sprintf(file_str, frmt, 
    file->nevents, 
    file->cross_section_unit, 
    file->cross_section, 
    file->size, 
    file->check_sum_type, 
    file->check_sum, 
    file->location_type, 
    file->machine_name, 
    file->location_path);
    file_used = 1;
  }

  return 0;
}

static char * generator_str = NULL;
static int generator_used = 0;

int set_generator (void * doc, lhaef_generator * gen)
{
  char frmt[512];
  int len = 512 + 
  strlen(gen->name) +
  strlen(gen->version) +
  strlen(gen->homepage) +
  strlen(gen->description);

  frmt[0] = '\0';
  strcat (frmt, "            <name>\%s</name>\n"              );
  strcat (frmt, "            <version>\%s</version>\n"        );
  strcat (frmt, "            <homepage>\%s</homepage>\n"      );
  strcat (frmt, "            <description>\n"                 );
  strcat (frmt, "\%s\n"                       );
  strcat (frmt, "            </description>\n"                );

  if (!generator_used) {
    generator_str = malloc(len * sizeof (char));

    sprintf(generator_str, frmt, 
    gen->name, 
    gen->version, 
    gen->homepage, 
    gen->description );
    generator_used = 1;
  }

  return 0;
}

static char * model_str = NULL;
static int model_used = 0;

int set_model (void * doc, lhaef_model * model)
{
  char frmt[512];
  int len = 512 + 
  strlen(model->name) +
  strlen(model->description);

  frmt[0] = '\0';
  strcat (frmt, "             <name>%s</name>\n"              );
  strcat (frmt, "             <description>%s</description>\n");

  if (!model_used) {
    model_str = malloc(len * sizeof (char));

    sprintf(model_str, frmt, 
    model->name, 
    model->description);
    model_used = 1;
  }

  return 0;
}

static char * model_param_str = NULL;
static int model_param_used = 0;

int add_model_parameter (void * doc, lhaef_parameter * par)
{
  char frmt[512];
  char * tmp1;
  int len = 512 + 
  strlen(par->name            ) +
  strlen(par->value           ) +
  strlen(par->notation->plain ) +
  strlen(par->notation->html  ) +
  strlen(par->notation->latex ) +
  strlen(par->notation->mathml) +
  strlen(par->description     );

  frmt[0] = '\0';
  strcat (frmt, "                <parameter>\n"                       );
  strcat (frmt, "                    <name>\%s</name>\n"              );
  strcat (frmt, "                    <value>\%s</value>\n"            );
  strcat (frmt, "                    <notation>\n"                    );
  strcat (frmt, "                        <plain>\%s</plain>\n"        );
  strcat (frmt, "                        <HTML>\%s</HTML>\n"          );
  strcat (frmt, "                        <Latex>\%s</Latex>\n"        );
  strcat (frmt, "                        <MathML>\%s</MathML>\n"      );
  strcat (frmt, "                    </notation>\n"                   );
  strcat (frmt, "                    <description>\%s</description>\n");
  strcat (frmt, "                </parameter>\n"                      );

  tmp1 = malloc(len * sizeof (char));

  sprintf(tmp1, frmt,
  par->name, 
  par->value, 
  par->notation->plain, 
  par->notation->html, 
  par->notation->latex, 
  par->notation->mathml, 
  par->description);

  len = strlen(tmp1);
  if (NULL != model_param_str) {
    len += strlen(model_param_str) + 1;
    model_param_str = realloc (model_param_str, len * sizeof(char));
  } else {
    model_param_str = malloc (len * sizeof(char));
    model_param_str[0] = '\0';
    model_param_used = 1;
  }

  strcat (model_param_str, tmp1);
  free(tmp1);

  return 0;
}

static char * cutset_str = NULL;
static int cutset_used = 0;

int set_cutset(void * doc, int cutsetnumber)
{
  int len = 128;

  if (!cutset_used) {
    cutset_str = malloc(len * sizeof (char));

    sprintf (cutset_str, "            <cutSet cutset_id=\"%i\">\n", 
    cutsetnumber);
    cutset_used = 1;
  }

  return 0;
}

static char * cuts_str = NULL;
static int cuts_used = 0;

int add_cut(void * doc, lhaef_cut * cut, int minon, int maxon)
{
  char * tmp;
  int len = 1024 + 
  strlen(cut->name            ) +
  strlen(cut->cut_logic       ) +
  strlen(cut->notation->plain ) +
  strlen(cut->notation->html  ) +
  strlen(cut->notation->latex ) +
  strlen(cut->notation->mathml);

  char frmt[512];
  strcpy(frmt, "");
  strcat (frmt, "                <cut>\n"                           );
  strcat (frmt, "                    <object>\n"                    );
  strcat (frmt, "                        <name>\%s</name>\n"        );
  strcat (frmt, "                        <notation>\n"              );
  strcat (frmt, "                            <plain>\%s</plain>\n"  );
  strcat (frmt, "                            <HTML>\%s</HTML>\n"    );
  strcat (frmt, "                            <Latex>\%s</Latex>\n"  );
  strcat (frmt, "                            <MathML>\%s</MathML>\n");
  strcat (frmt, "                        </notation>\n"             );
  strcat (frmt, "                    </object>\n"                   );
  if (minon) strcat (frmt, "                    <minValue>\%f</minValue>\n"    );
  if (maxon) strcat (frmt, "                    <maxValue>\%f</maxValue>\n"    );
  strcat (frmt, "                    <logic>\%s</logic>\n"          );
  strcat (frmt, "                </cut>\n"                          );

  tmp = malloc(len * sizeof (char));

  if (minon && maxon) {
    sprintf(tmp, frmt, 
    cut->name, 
    cut->notation->plain, 
    cut->notation->html, 
    cut->notation->latex, 
    cut->notation->mathml, 
    cut->min_value, 
    cut->max_value, 
    cut->cut_logic 
    );
  }

  if (minon && !maxon) {
    sprintf(tmp, frmt, 
    cut->name, 
    cut->notation->plain, 
    cut->notation->html, 
    cut->notation->latex, 
    cut->notation->mathml, 
    cut->min_value, 
    cut->cut_logic 
    );
  }

  if (!minon && maxon) {
    sprintf(tmp, frmt, 
    cut->name, 
    cut->notation->plain, 
    cut->notation->html, 
    cut->notation->latex, 
    cut->notation->mathml, 
    cut->min_value, 
    cut->cut_logic 
    );
  }

  len = strlen(tmp);
  if (NULL != cuts_str) {
    len += strlen(cuts_str) + 1;
    cuts_str = realloc (cuts_str, len * sizeof(char));
  } else {
    cuts_str = malloc (len * sizeof(char));
    cuts_str[0] = '\0';
    cuts_used = 1;
  }

  cuts_str = strcat (cuts_str, tmp);
  free(tmp);
  return 0;
}

int set_author_record(void * doc)
{
  return 0;
}

static char * authors_str = NULL;
static int authors_used = 0;

int add_author(void * doc, lhaef_author * author)
{
  char frmt[512];
  char * tmp;
  int len = 512 + 
  strlen(author->firstName   ) +
  strlen(author->lastName    ) +
  strlen(author->email       ) +
  strlen(author->experiment  ) +
  strlen(author->group       ) +
  strlen(author->organization);

  frmt[0] = '\0';
  strcat (frmt, "            <author>\n"                            );
  strcat (frmt, "                <firstName>\%s</firstName>\n"      );
  strcat (frmt, "                <lastName>\%s</lastName>\n"        );
  strcat (frmt, "                <email>\%s</email>\n"              );
  strcat (frmt, "                <experiment>\%s</experiment>\n"    );
  strcat (frmt, "                <group>\%s</group>\n"              );
  strcat (frmt, "                <organization>\%s</organization>\n");
  strcat (frmt, "            </author>\n"                           );

  tmp = malloc(len * sizeof (char));

  sprintf(tmp, frmt, 
  author->firstName, 
  author->lastName, 
  author->email, 
  author->experiment, 
  author->group, 
  author->organization 
  );

  len = strlen(tmp);
  if (NULL != authors_str) {
    len += strlen(authors_str) + 1;
    authors_str = realloc (authors_str, len * sizeof(char));
  } else {
    authors_str = malloc (len * sizeof(char));
    authors_str[0] = '\0';
    authors_used = 1;
  }

  authors_str = strcat (authors_str, tmp);
  free(tmp);

  return 0;
}

static char * process_str = NULL;
static int process_used = 0;

int create_process(void * doc, lhaef_process * proc)
{
  char frmt[512];
  int len = 512 + 
  strlen(proc->final_state                 ) +
  strlen(proc->final_state_notation->plain ) +
  strlen(proc->final_state_notation->html  ) +
  strlen(proc->final_state_notation->latex ) +
  strlen(proc->final_state_notation->mathml) +
  strlen(proc->cross_section_unit          );

  frmt[0] = '\0';
  strcat (frmt, "            <finalState>\n"                                     );
  strcat (frmt, "                <state>\%s</state>\n"                           );
  strcat (frmt, "                <notation>\n"                                   );
  strcat (frmt, "                    <plain>\%s</plain>\n"                       );
  strcat (frmt, "                    <HTML>\%s</HTML>\n"                         );
  strcat (frmt, "                    <Latex>\%s</Latex>\n"                       );
  strcat (frmt, "                    <MathML>\%s</MathML>\n"                     );
  strcat (frmt, "                </notation>\n"                                  );
  strcat (frmt, "            </finalState>\n"                                    );
  strcat (frmt, "            <crossSection unit=\"\%s\">\%12.4E</crossSection>\n");

  if (!process_used) {
    process_str = malloc(len * sizeof (char));

    sprintf(process_str, frmt, 
    proc->final_state, 
    proc->final_state_notation->plain, 
    proc->final_state_notation->html, 
    proc->final_state_notation->latex, 
    proc->final_state_notation->mathml, 
    proc->cross_section_unit, 
    proc->cross_section );
    process_used = 1;
  }

  return 0;
}

static char * beam_str[2] = {NULL, NULL};
static int beam_used[2] = {0, 0};

int add_process_beam (void * doc, int i, lhaef_beam * beam)
{
  char frmt[512];
  int len = 512 + 
  strlen(beam->particle_name);

  frmt[0] = '\0';
  strcat (frmt, "                <particle pdgcode=\"%i\">%s</particle>\n");
  strcat (frmt, "                <energy unit=\"GeV\">%f</energy>\n"      );

  if (!beam_used[i]) {
    beam_str[i] = malloc(len * sizeof (char));

    sprintf(beam_str[i], frmt, 
    beam->particle_pdgcode, 
    beam->particle_name, 
    beam->energy);
    beam_used[i] = 1;
  }

  return 0;
}

static char * pdf_str[2] = {NULL, NULL};
static int pdf_used[2] = {0, 0};

int add_process_beam_pdf(void * doc, int i, lhaef_pdf * pdf)
{
  char frmt[512];
  int len = 512 + 
  strlen(pdf->name) +
  strlen(pdf->version) +
  strlen(pdf->lhapdf_filename);

  frmt[0] = '\0';
  strcat (frmt, "                <pdf name=\"%s\" version=\"%s\" "     );
  strcat (frmt, "PDFLIBset=\"%i\" PDFLIBgroup=\"%i\" LHAPDFset=\"%i\" ");
  strcat (frmt, "LHAPDFmember=\"%i\" LHAPDFfile=\"%s\" />\n"           );

  if (!pdf_used[i]) {
    pdf_str[i] = malloc(len * sizeof (char));

    sprintf(pdf_str[i], frmt, 
    pdf->name, 
    pdf->version, 
    pdf->pdflib_set, 
    pdf->pdflib_group, 
    pdf->lhapdf_set, 
    pdf->lhapdf_member, 
    pdf->lhapdf_filename );
    pdf_used[i] = 1;
  }

  return 0;
}

static char * pdf_qcd_str = NULL;
static int pdf_qcd_used = 0;

int add_process_beam_pdf_alphas(void * doc, lhaef_alphas * alphas)
{
  char frmt[512];
  int len = 512 + 
  strlen(alphas->description);

  frmt[0] = '\0';
  strcat (frmt, "                <QCDCoupling>\n"                        );
  strcat (frmt, "                    <Lambda unit=\"GeV\">\%f</Lambda>\n");
  strcat (frmt, "                    <NFlavours>\%i</NFlavours>\n"       );
  strcat (frmt, "                    <NLoopsAlphaS>\%i</NLoopsAlphaS>\n" );
  strcat (frmt, "                </QCDCoupling>\n"                       );

  if (!pdf_qcd_used) {
    pdf_qcd_str = malloc(len * sizeof (char));

    sprintf (pdf_qcd_str, frmt, 
    alphas->lambda, 
    alphas->nflavours, 
    alphas->nloops);
    pdf_qcd_used = 1;
  }

  return 0;
}

static char * proc_qcd_str = NULL;
static int proc_qcd_used = 0;

int add_process_alphas(void * doc, lhaef_alphas * alphas)
{
  char frmt[512];
  int len = 512 + 
  strlen(alphas->description);

  frmt[0] = '\0';
  strcat (frmt, "            <QCDCoupling>\n"                        );
  strcat (frmt, "                <Lambda unit=\"GeV\">\%f</Lambda>\n");
  strcat (frmt, "                <NFlavours>\%i</NFlavours>\n"       );
  strcat (frmt, "                <NLoopsAlphaS>\%i</NLoopsAlphaS>\n" );
  strcat (frmt, "            </QCDCoupling>\n"                       );

  if (!proc_qcd_used) {
    proc_qcd_str = malloc(len * sizeof (char));

    sprintf (proc_qcd_str, frmt, 
    alphas->lambda, 
    alphas->nflavours, 
    alphas->nloops);
    proc_qcd_used = 1;
  }

return 0;
}

static char * subproc_str = NULL;
static int subproc_used = 0;

int add_subprocess(void * doc, lhaef_subprocess * sub, int cutsetnumber)
{
  char frmt[1024];
  char * tmp;
  int len = 1024 + 
  strlen(sub->name                        ) +
  strlen(sub->cross_section_unit          ) +
  strlen(sub->FactorisationScale->plain   ) +
  strlen(sub->FactorisationScale->html    ) +
  strlen(sub->FactorisationScale->latex   ) +
  strlen(sub->FactorisationScale->mathml  ) +
  strlen(sub->RenormalisationScale->plain ) +
  strlen(sub->RenormalisationScale->html  ) +
  strlen(sub->RenormalisationScale->latex ) +
  strlen(sub->RenormalisationScale->mathml);

  frmt[0] = '\0';
  strcat (frmt, "                <subprocess cutset_id=\"\%i\">\n"                       );
  strcat (frmt, "                    <notation>\%s</notation>\n"                         );
  strcat (frmt, "                    <crossSection unit=\"\%s\">\%12.4E</crossSection>\n");
  strcat (frmt, "                    <FactorisationScale>\n"                             );
  strcat (frmt, "                        <plain>\%s</plain>\n"                           );
  strcat (frmt, "                        <HTML>\%s</HTML>\n"                             );
  strcat (frmt, "                        <Latex>\%s</Latex>\n"                           );
  strcat (frmt, "                        <MathML>\%s</MathML>\n"                         );
  strcat (frmt, "                    </FactorisationScale>\n"                            );
  strcat (frmt, "                    <RenormalisationScale>\n"                           );
  strcat (frmt, "                        <plain>\%s</plain>\n"                           );
  strcat (frmt, "                        <HTML>\%s</HTML>\n"                             );
  strcat (frmt, "                        <Latex>\%s</Latex>\n"                           );
  strcat (frmt, "                        <MathML>\%s</MathML>\n"                         );
  strcat (frmt, "                    </RenormalisationScale>\n"                          );
  strcat (frmt, "                </subprocess>\n"                                        );

  tmp = malloc(len * sizeof (char));

  sprintf (tmp, frmt, 
  cutsetnumber,
  sub->name, 
  sub->cross_section_unit, 
  sub->cross_section, 
  sub->FactorisationScale->plain, 
  sub->FactorisationScale->html, 
  sub->FactorisationScale->latex, 
  sub->FactorisationScale->mathml, 
  sub->RenormalisationScale->plain, 
  sub->RenormalisationScale->html, 
  sub->RenormalisationScale->latex, 
  sub->RenormalisationScale->mathml 
  );

  len = strlen(tmp);
  if (NULL != subproc_str) {
    len += strlen(subproc_str) + 1;
    subproc_str = realloc (subproc_str, len * sizeof(char));
  } else {
    subproc_str = malloc (len * sizeof(char));
    subproc_str[0] = '\0';
    subproc_used = 1;
  }

  subproc_str = strcat (subproc_str, tmp);
  free(tmp);

  return 0;
}

/*int form_hepml_document(char * the_hepml_doc)*/
char * form_hepml_document(void * doc)
{
  int i;
  char * the_hepml_doc = NULL;
  int len[17] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  int llen = 1024;

  if (NULL != file_str)        len[ 0] = strlen (file_str);
  if (NULL != gen_desc_str)    len[ 1] = strlen (gen_desc_str);
  if (NULL != generator_str)   len[ 2] = strlen (generator_str);
  if (NULL != model_str)       len[ 3] = strlen (model_str);
  if (NULL != model_param_str) len[ 4] = strlen (model_param_str);
  if (NULL != beam_str[0])     len[ 5] = strlen (beam_str[0]);
  if (NULL != pdf_str[0])      len[ 6] = strlen (pdf_str[0]);
  if (NULL != pdf_qcd_str)     len[ 7] = strlen (pdf_qcd_str);
  if (NULL != beam_str[1])     len[ 8] = strlen (beam_str[1]);
  if (NULL != pdf_str[1])      len[ 9] = strlen (pdf_str[1]);
  if (NULL != pdf_qcd_str)     len[10] = strlen (pdf_qcd_str);
  if (NULL != proc_qcd_str)    len[11] = strlen (proc_qcd_str);
  if (NULL != process_str)     len[12] = strlen (process_str);
  if (NULL != subproc_str)     len[13] = strlen (subproc_str);
  if (NULL != cutset_str)      len[14] = strlen (cutset_str);
  if (NULL != cuts_str)        len[15] = strlen (cuts_str);
  if (NULL != authors_str)     len[16] = strlen (authors_str);
  for (i = 0; i < 17; ++i) llen += len[i];

  the_hepml_doc = malloc(llen * sizeof (char));
  the_hepml_doc[0] = '\0';

  strcat (the_hepml_doc, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
  strcat (the_hepml_doc, "<samples xmlns=\"http://mcdb.cern.ch/hepml/0.2/\"\n");
  strcat (the_hepml_doc, "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
  strcat (the_hepml_doc, "    xsi:schemaLocation=\"http://mcdb.cern.ch/hepml/0.2/ file:/home/dudko/MCDB/hepml/schemas/0.2/hepml.xsd\">\n");
  strcat (the_hepml_doc, "    <files>\n");
  strcat (the_hepml_doc, "        <file>\n");
  if (1 == file_used) strcat (the_hepml_doc, file_str);
  strcat (the_hepml_doc, "        </file>\n");
  strcat (the_hepml_doc, "    </files>\n");
  strcat (the_hepml_doc, "    <description>\n");
  if (1 == gen_desc_used) strcat (the_hepml_doc, gen_desc_str);
  strcat (the_hepml_doc, "        <generator>\n");
  if (1 == generator_used) strcat (the_hepml_doc, generator_str);
  strcat (the_hepml_doc, "        </generator>\n");
  strcat (the_hepml_doc, "        <process>\n");
  strcat (the_hepml_doc, "            <beam1>\n");
  if (1 == beam_used[0]) strcat (the_hepml_doc, beam_str[0]);
  if (1 == pdf_used[0])  strcat (the_hepml_doc, pdf_str[0]);
  if (1 == pdf_qcd_used) strcat (the_hepml_doc, pdf_qcd_str);
  strcat (the_hepml_doc, "            </beam1>\n");
  strcat (the_hepml_doc, "            <beam2>\n");
  if (1 == beam_used[1]) strcat (the_hepml_doc, beam_str[1]);
  if (1 == pdf_used[1])  strcat (the_hepml_doc, pdf_str[1]);
  if (1 == pdf_qcd_used) strcat (the_hepml_doc, pdf_qcd_str);
  strcat (the_hepml_doc, "            </beam2>\n");
  if (1 == proc_qcd_used) strcat (the_hepml_doc, proc_qcd_str);
  if (1 == process_used) strcat (the_hepml_doc, process_str);
  strcat (the_hepml_doc, "            <subprocesses>\n");
  if (1 == subproc_used) strcat (the_hepml_doc, subproc_str);
  strcat (the_hepml_doc, "            </subprocesses>\n");
  strcat (the_hepml_doc, "        </process>\n");
  strcat (the_hepml_doc, "        <model>\n");
  if (1 == model_used) strcat (the_hepml_doc, model_str);
  strcat (the_hepml_doc, "            <parameters>\n");
  if (1 == model_param_used) strcat (the_hepml_doc, model_param_str);
  strcat (the_hepml_doc, "            </parameters>\n");
  strcat (the_hepml_doc, "        </model>\n");
  strcat (the_hepml_doc, "        <cuts>\n");
  if (1 == cutset_used) strcat (the_hepml_doc, cutset_str);
  if (1 == cuts_used) strcat (the_hepml_doc, cuts_str);
  strcat (the_hepml_doc, "            </cutSet>\n");
  strcat (the_hepml_doc, "        </cuts>\n");
  strcat (the_hepml_doc, "        <authors>\n");
  if (1 == authors_used) strcat (the_hepml_doc, authors_str);
  strcat (the_hepml_doc, "        </authors>\n");
  strcat (the_hepml_doc, "        <relatedPapers></relatedPapers>\n");
  strcat (the_hepml_doc, "    </description>\n");
  strcat (the_hepml_doc, "</samples>\n");

  if (NULL != file_str       ) free (file_str       );
  if (NULL != gen_desc_str   ) free (gen_desc_str   );
  if (NULL != generator_str  ) free (generator_str  );
  if (NULL != model_str      ) free (model_str      );
  if (NULL != model_param_str) free (model_param_str);
  if (NULL != beam_str[0]    ) free (beam_str[0]    );
  if (NULL != pdf_str[0]     ) free (pdf_str[0]     );
  if (NULL != beam_str[1]    ) free (beam_str[1]    );
  if (NULL != pdf_str[1]     ) free (pdf_str[1]     );
  if (NULL != pdf_qcd_str    ) free (pdf_qcd_str    );
  if (NULL != proc_qcd_str   ) free (proc_qcd_str   );
  if (NULL != process_str    ) free (process_str    );
  if (NULL != subproc_str    ) free (subproc_str    );
  if (NULL != cutset_str     ) free (cutset_str     );
  if (NULL != cuts_str       ) free (cuts_str       );
  if (NULL != authors_str    ) free (authors_str    );

  file_str        = NULL;
  gen_desc_str    = NULL;
  generator_str   = NULL;
  model_str       = NULL;
  model_param_str = NULL;
  beam_str[0]     = NULL;
  pdf_str[0]      = NULL;
  beam_str[1]     = NULL;
  pdf_str[1]      = NULL;
  pdf_qcd_str     = NULL;
  proc_qcd_str    = NULL;
  process_str     = NULL;
  subproc_str     = NULL;
  cutset_str      = NULL;
  cuts_str        = NULL;
  authors_str     = NULL;

  file_used        = 0;
  gen_desc_used    = 0;
  generator_used   = 0;
  model_used       = 0;
  model_param_used = 0;
  beam_used[0]     = 0;
  pdf_used[0]      = 0;
  beam_used[1]     = 0;
  pdf_used[1]      = 0;
  pdf_qcd_used     = 0;
  proc_qcd_used    = 0;
  process_used     = 0;
  subproc_used     = 0;
  cutset_used      = 0;
  cuts_used        = 0;
  authors_used     = 0;

  return the_hepml_doc;
}
