/*   -*- coding: utf-8 -*-  */

/***********************************************************************
*
*        Module   : Tei
*        Fichier  : TeiHandler.c
*        Auteur   : J. DUCLOY
*        Date     : octobre 2012
*
************************************************************************/

/*  TeiHandler

Ce module vie à simplifier les manipulations sur un dcoument TEI

Il sert à gérer un document courant (unique dans une étape de programmation);

Il contient notamment un ensemble de pointeurs qui simplifie la localisation d'un élément de l'arborescence d'un document en cours de construction ou d'analyse. Ces pointeurs sont de la forme Tei_

 */

#include "TeiHandler.h"
#include "Utf8Converter.h"
#include <ctype.h>

SxmlNode *TeiHandlerNew()
{
  Tei_root=SxmlElementCreate("TEI");
  SxmlAppendChild(Tei_root, Tei_header=SxmlElementCreate("teiHeader"));
  SxmlSetAttribute(Tei_root, "xmlns:wicri", "http://ticri.inpl-nancy.fr");
  SxmlAppendChild(Tei_header, Tei_fileDesc=SxmlElementCreate("fileDesc"));
  SxmlAppendChild(Tei_header, Tei_profileDesc=SxmlElementCreate("profileDesc"));
  SxmlAppendChild(Tei_fileDesc, Tei_titleStmt=SxmlElementCreate("titleStmt"));
  SxmlAppendChild(Tei_fileDesc, Tei_publicationStmt=SxmlElementCreate("publicationStmt"));
  SxmlAppendChild(Tei_fileDesc, Tei_sourceDesc=SxmlElementCreate("sourceDesc"));
  SxmlAppendChild(Tei_sourceDesc, Tei_biblStruct=SxmlElementCreate("biblStruct"));
  SxmlAppendChild(Tei_biblStruct, Tei_analytic=SxmlElementCreate("analytic"));

  SxmlAppendChild(Tei_profileDesc, Tei_textClass=SxmlElementCreate("textClass"));
  Tei_front=NULL;
  Tei_back=NULL;
  Tei_back_listBibl=NULL;
  Tei_seriesStmt=NULL;
  Tei_series=NULL;
  Tei_seriesImprint=NULL;
  Tei_monogr=NULL;
  Tei_text=NULL;
  return Tei_root;
}

SxmlNode *TeiHandlerInitFromRoot()
{
  /* Tei_root=SxmlGetFirstChildByTagName(docInput,"TEI"); */
  Tei_header=SxmlGetFirstChildByTagName(Tei_root,"teiHeader");
  Tei_fileDesc=SxmlGetFirstChildByTagName(Tei_header,"fileDesc");
  Tei_publicationStmt=SxmlGetFirstChildByTagName(Tei_fileDesc, "publicationStmt");
  if ((Tei_profileDesc=SxmlGetFirstChildByTagName(Tei_header,"profileDesc")))
    {
      Tei_textClass=SxmlGetFirstChildByTagName(Tei_profileDesc, "textClass");
    }
  else Tei_textClass=NULL;
  if (Tei_fileDesc)
    {
      Tei_titleStmt=SxmlGetFirstChildByTagName(Tei_fileDesc,"titleStmt");
      Tei_sourceDesc=SxmlGetFirstChildByTagName(Tei_fileDesc,"sourceDesc");
    }
  else 
    {
      Tei_titleStmt=NULL;
      Tei_sourceDesc=NULL;
    }
  if (Tei_sourceDesc)
    {
      Tei_biblStruct=SxmlGetFirstChildByTagName(Tei_sourceDesc,"biblStruct");
    }
  else Tei_biblStruct=NULL;
  if  (Tei_biblStruct)
    {
      Tei_analytic=SxmlGetFirstChildByTagName(Tei_biblStruct, "analytic");
      Tei_series=SxmlGetFirstChildByTagName(Tei_biblStruct, "series");
    }
  else
    {
      Tei_analytic=NULL;
    }
  Tei_text=SxmlGetFirstChildByTagName(Tei_root,"text");
  if (Tei_text)
    {
      Tei_body=SxmlGetFirstChildByTagName(Tei_text,"body");
    }
  return Tei_root;
}

SxmlNode *TeiHandlerInit(SxmlNode *docInput)
{
  Tei_root=SxmlGetFirstChildByTagName(docInput,"TEI");
  if (Tei_root)TeiHandlerInitFromRoot();
  return (Tei_root);
}

SxmlNode *TeiHandlerInitFromIstex(SxmlNode *docInput)
{
  SxmlNode *fulltext;
  fulltext=SxmlGetFirstChildByTagName(docInput, "fulltext");
  if(!fulltext)return NULL;
  Tei_root=SxmlGetFirstChildByTagName(fulltext,"istex:fulltextTEI");
  if (Tei_root)TeiHandlerInitFromRoot();
  return (Tei_root);
}


SxmlNode *TeiInputNextRecord()
{
  SxmlNode *docInput;
  SxmlNode *teiRoot;
  docInput=SxmlInputNextDocumentElement();
  if (!docInput) return NULL;
  teiRoot=TeiHandlerInit(docInput);
  return docInput;
}

SxmlNode *TeiInputNextIstexRecord()
{
  SxmlNode *docInput;
  SxmlNode *teiRoot;
  docInput=SxmlInputNextDocumentElement();
  if (!docInput) return NULL;
  teiRoot=TeiHandlerInitFromIstex(docInput);
  return docInput;
}

SxmlNode *TeiHeader_author=NULL;

SxmlNode *TeiAuthorInit()
{
  TeiHeader_author_name_First=NULL;
  TeiHeader_author_name_Last=NULL;  
  TeiHeader_author_name=NULL;
  TeiHeader_author_affiliation=NULL;
  TeiHeader_author_affiliation_country=NULL;
  TeiHeader_author_affiliation_Country=NULL;
  TeiHeader_author_affiliation_placeName=NULL;
  TeiHeader_author_affiliation_placeName_region=NULL;
  TeiHeader_author_affiliation_placeName_Region=NULL;
  if (!TeiHeader_author) return NULL;
  TeiHeader_author_name=SxmlGetFirstChildByTagName(TeiHeader_author, "name");
  if (TeiHeader_author_name)
    {
      TeiHeader_author_name_First=SxmlGetAttribute(TeiHeader_author_name, "first");
      TeiHeader_author_name_Last=SxmlGetAttribute(TeiHeader_author_name, "last");
    }
  TeiHeader_author_affiliation=SxmlGetFirstChildByTagName(TeiHeader_author, "affiliation");
  if (TeiHeader_author_affiliation)
    {
      TeiHeader_author_affiliation_country=SxmlGetFirstChildByTagName(TeiHeader_author_affiliation, "country");
      if (TeiHeader_author_affiliation_country) TeiHeader_author_affiliation_Country=SxmlLeafText(TeiHeader_author_affiliation_country);
      TeiHeader_author_affiliation_placeName=SxmlGetFirstChildByTagName(TeiHeader_author_affiliation, "placeName");
      if (TeiHeader_author_affiliation_placeName)
	{
	  TeiHeader_author_affiliation_placeName_region=SxmlGetFirstChildByTagName(TeiHeader_author_affiliation_placeName, "region");
	  if (TeiHeader_author_affiliation_placeName_region)TeiHeader_author_affiliation_placeName_Region=SxmlLeafText(TeiHeader_author_affiliation_placeName_region);
	}
    }
  return TeiHeader_author;
}

char *TeiHeader_author_getOrgWithPrio(char *prio, char *abs)
{
  SxmlNode *orgNameNode;
  if (!TeiHeader_author_affiliation) return abs;
  orgNameNode=SxmlGetFirstChildTagAtt(TeiHeader_author_affiliation, "orgName", "type", prio);
  if (!orgNameNode) orgNameNode=SxmlGetFirstChildByTagName(TeiHeader_author_affiliation, "orgName");
  if (!orgNameNode) return abs;
  return SxmlLeafText(orgNameNode);
}

SxmlNode *TeiInputNextAuthor()
{
  if (TeiHeader_author)
    {
      TeiHeader_author=SxmlGetNextSiblingByTagName(TeiHeader_author, "author");
      if  (TeiHeader_author) 
	{
	  TeiAuthorInit();
	  return TeiHeader_author;
	}
    }
  while(TeiInputNextRecord())
    {
      if (Tei_analytic) 
	{
	  TeiHeader_author=SxmlGetFirstChildByTagName(Tei_analytic, "author");
	  if (TeiHeader_author) 
	    {
	      TeiAuthorInit();
	      return TeiHeader_author;
	    }
	}
    }
  return NULL;
}

SxmlNode *TeiHandlerStoreAbstract(SxmlNode *abstract, char *lang)
{
  SxmlNode *absNode;
  SxmlNode *teiAbstract;
  if(!abstract)return NULL;
  if (!SxmlFirstChild(abstract))return NULL;
  if (!Tei_front)SxmlAppendChild(Tei_root, Tei_front=SxmlElementCreate("front"));
  SxmlAppendChild(Tei_front, teiAbstract=SxmlElementCreate("div"));
  SxmlSetAttribute(teiAbstract,"type","abstract");

  SxmlReset (abstract);
  while ((absNode=SxmlNextNode(abstract)))
    {
      SxmlAppendChild(teiAbstract,SxmlClone(absNode));
    }

  if (lang) SxmlSetAttribute(teiAbstract,"xml:lang",lang);
  return teiAbstract;
}

char* TeiHandlerLang(char *lang)
{
  switch (lang[0])
    {
    case 'f':
    case 'F':
      return ("fr");
    case 'e':
    case 'E':
      return ("en"); 
    }
  return ("inc");
}

SxmlNode *TeiHandlerSetIssn(char *issn)
{
  SxmlNode *nodeIdno;
  if (!Tei_seriesStmt) SxmlAppendChild(Tei_fileDesc, Tei_seriesStmt=SxmlElementCreate("seriesStmt"));
  SxmlAppendChild(Tei_seriesStmt, nodeIdno=SxmlLeafCreate("idno", issn));
  SxmlSetAttribute(nodeIdno,"type","ISSN");
  if (!Tei_series) SxmlAppendChild(Tei_biblStruct, Tei_series=SxmlElementCreate("series"));
  SxmlAppendChild(Tei_series, SxmlClone(nodeIdno));
  return nodeIdno;
}

SxmlNode *TeiHandlerSetEIssn(char *issn)
{
  SxmlNode *nodeIdno;
  if (!Tei_seriesStmt) SxmlAppendChild(Tei_fileDesc, Tei_seriesStmt=SxmlElementCreate("seriesStmt"));
  SxmlAppendChild(Tei_seriesStmt, nodeIdno=SxmlLeafCreate("idno", issn));
  SxmlSetAttribute(nodeIdno,"type","eISSN");
  return nodeIdno;
}

char *TeiHandlerGetIssn()
{
  SxmlNode *issnNode;
  if (!Tei_series)return NULL;
  issnNode=SxmlGetFirstChildTagAtt( Tei_series, "idno", "type", "ISSN");
  if (issnNode)return SxmlLeafText(issnNode);
  issnNode=SxmlGetFirstChildTagAtt( Tei_series, "idno", "type", "eISSN");
  if (!issnNode)return NULL;
  return SxmlLeafText(issnNode);
}

SxmlNode *TeiHandlerSetUrl(char *site, char *key)
{
  SxmlNode *nodeIdno;
  if (!site)return NULL;
  if (key)
    {
      static Buffer* bufUrl=NULL;
      if (!bufUrl) bufUrl=NewBuffer();
      BufferStrcpy(bufUrl, site);
      BufferStrcat(bufUrl, key);
      nodeIdno=TeiAppendIdno("url", BufferString(bufUrl));
    }
  else
    {
      nodeIdno=TeiAppendIdno("url", site);
    }
  return nodeIdno;
}

SxmlNode *TeiHandlerSetSeriesDoi(char *doi)
{
  SxmlNode *nodeDoi;

  if (!Tei_seriesStmt) SxmlAppendChild(Tei_fileDesc, Tei_seriesStmt=SxmlElementCreate("seriesStmt"));
  SxmlAppendChild(Tei_seriesStmt, nodeDoi=SxmlLeafCreate("idno", doi));
  SxmlSetAttribute(nodeDoi, "type", "doi");
  return nodeDoi;
}

SxmlNode *TeiHandlerSetDoi(char *doi)
{
  SxmlNode *nodeDoi;
  SxmlNode *nodeDoiBibl;
  SxmlAppendChild(Tei_publicationStmt, nodeDoi=SxmlLeafCreate("idno", doi));
  SxmlAppendChild(Tei_biblStruct, nodeDoiBibl=SxmlClone(nodeDoi));

  SxmlSetAttribute(nodeDoi, "type", "doi");
  SxmlSetAttribute(nodeDoiBibl, "type", "DOI"); /* conformity ISTEX */

  return nodeDoi;
}

SxmlNode *TeiHandlerSetAnalyticStmtTitleStr(char *title, char *lang)
{
  SxmlNode *titleField;
  if (!title)return NULL;
  titleField=SxmlLeafCreate("title", title);
  if (lang) SxmlSetAttribute(titleField, "xml:lang", lang);
  SxmlAppendChild(Tei_titleStmt,titleField);
  if (!Tei_analytic)SxmlAppendChild(Tei_biblStruct, Tei_analytic=SxmlElementCreate("analytic"));
  SxmlAppendChild(Tei_analytic, SxmlClone(titleField));
  return titleField;
}

SxmlNode *TeiHandlerSetAnalyticStmtTitle(SxmlNode *title, char *lang)
{
  SxmlNode *titleField;
  SxmlNode *titleNode;
  if (!title)return NULL;
  titleField=SxmlElementCreate("title");
  if (lang) SxmlSetAttribute(titleField, "xml:lang", lang);
  SxmlAppendChild(Tei_titleStmt,titleField);
  SxmlReset (title);
  while ((titleNode=SxmlNextNode(title)))
    {
      SxmlAppendChild(titleField,SxmlClone(title));
    }
  if (!Tei_analytic)SxmlAppendChild(Tei_biblStruct, Tei_analytic=SxmlElementCreate("analytic"));
  SxmlAppendChild(Tei_analytic, SxmlClone(titleField));
  return titleField;
}

SxmlNode *TeiHandlerSetSeriesTitle(char *title, char *level, char*type)
{
  SxmlNode *nodeTitle;
  if (!Tei_seriesStmt) SxmlAppendChild(Tei_fileDesc, Tei_seriesStmt=SxmlElementCreate("seriesStmt"));
  SxmlAppendChild(Tei_seriesStmt, nodeTitle=SxmlLeafCreate("title", title));
  if (level) SxmlSetAttribute(nodeTitle,"level",level);
  else SxmlSetAttribute(nodeTitle,"level","s");
  if (type) SxmlSetAttribute(nodeTitle,"type", type);
  else SxmlSetAttribute(nodeTitle,"type","main");
  if (!Tei_series) SxmlAppendChild(Tei_biblStruct, Tei_series=SxmlElementCreate("series"));
  SxmlAppendChild(Tei_series, SxmlClone(nodeTitle));
  return nodeTitle;
}

SxmlNode *TeiAppendIdno(char *type, char *value)
{
  SxmlNode *idno;
  SxmlAppendChild(Tei_publicationStmt, idno=SxmlLeafCreate("idno", value));
  SxmlSetAttribute(idno, "type", type);
  return idno;
}

SxmlNode *TeiSetIdnoRbid(char *base, char *identifier)
{
  static Buffer *bufRbid=NULL;
  if (!bufRbid)bufRbid=NewBuffer();
  BufferStrcpy(bufRbid, base);
  BufferStrcat(bufRbid, ":");
  BufferStrcat(bufRbid, identifier);
  return TeiAppendIdno("RBID", BufferString(bufRbid));
}

SxmlNode *TeiSetDatePublication(char *date)
{
  SxmlNode *teiDate;
  if(!date)return NULL;
  SxmlAppendChild(Tei_publicationStmt, teiDate=SxmlLeafCreate("date", date));
  if (strlen(date)>3)SxmlSetAttribute(teiDate,"when", date);
  else SxmlSetAttribute(teiDate,"when", "????");
  if ((strlen(date)==4) &&isdigit(*date)) SxmlSetAttribute(teiDate,"year", date);
  else
    {
      static Buffer *bufDate=NULL;
      if (!bufDate) bufDate=NewBuffer();
      BufferStrncpy(bufDate, date,4);
      SxmlSetAttribute(teiDate,"year", BufferString(bufDate));
    }
  return teiDate;
}

SxmlNode *TeiSeriesSetDatePublication(char *date)
{
  SxmlNode *teiDate;
  if (!Tei_seriesImprint)
    {
      if(Tei_series)
	{
	  Tei_seriesImprint=SxmlGetFirstChildByTagName(Tei_series, "imprint");
	  if (!Tei_seriesImprint)  SxmlAppendChild(Tei_series, Tei_seriesImprint=SxmlElementCreate("imprint"));
	}
      else
	{
	  SxmlAppendChild(Tei_biblStruct, Tei_series=SxmlElementCreate("series"));
	  SxmlAppendChild(Tei_series, Tei_seriesImprint=SxmlElementCreate("imprint"));
	}
    }
  SxmlAppendChild(Tei_seriesImprint, teiDate=SxmlLeafCreate("date", date));
  SxmlSetAttribute(teiDate,"when", date);
  SxmlSetAttribute(teiDate, "type", "published");
  return teiDate;
}

SxPathResult *TeiPathIdnoRbid=NULL;

char     *TeiGetIdnoRbid()
{
  SxmlNode *idnoNode;
  if (!TeiPathIdnoRbid)
    {
      TeiPathIdnoRbid=SxPathFirstCompile("teiHeader/fileDesc/publicationStmt/idno@type=RBID");
    }
  idnoNode=SxPathFirstResultNode(TeiPathIdnoRbid,Tei_root );
  if (idnoNode)return SxmlLeafText(idnoNode);
  return NULL;
}

SxPathResult *TeiPathIdnoDate=NULL;

char     *TeiGetIdnoDate()
{
  SxmlNode *idnoNode;
  if (!TeiPathIdnoDate)
    {
      TeiPathIdnoDate=SxPathFirstCompile("teiHeader/fileDesc/publicationStmt/date");
    }
  idnoNode=SxPathFirstResultNode(TeiPathIdnoDate,Tei_root );
  if (idnoNode)return SxmlLeafText(idnoNode);
  return NULL;
}

char *TeiGetTitle (char *lang, char *level)
{
  SxmlNode *titleNode;
  /* parameters are for uncoming usages */
  if (!Tei_titleStmt) return NULL;
  if ((titleNode=SxmlGetFirstChildByTagName(Tei_titleStmt, "title")))
    return (SxmlLeafText(titleNode));  /* to be improved */
  else return NULL;
}

char *TeiGetFirstAuthor()
{
  SxmlNode *authorNode;
  SxmlNode *nameNode;
  if (!Tei_titleStmt) return NULL;
  if ((authorNode=SxmlGetFirstChildByTagName(Tei_titleStmt, "author")))
    {
      if ((nameNode=SxmlGetFirstChildByTagName(authorNode, "name")))
      return (SxmlLeafText(nameNode));  
    }
  return NULL;
}

SxmlNode *TeiSetBack()
{
  if (Tei_back) return Tei_back;
  SxmlAppendChild(Tei_root, Tei_back=SxmlElementCreate("back"));
  Tei_back_listBibl=NULL;
  return Tei_back;
}

SxmlNode *TeiSetBackListBibl()
{
  SxmlNode *div1;
  if(Tei_back_listBibl)return Tei_back_listBibl;
  TeiSetBack();
  SxmlAppendChild(Tei_back, div1=SxmlElementCreate("div1"));
  SxmlSetAttribute(div1, "type", "bibliography");
  SxmlAppendChild(div1, Tei_back_listBibl=SxmlElementCreate("listBibl"));
  return Tei_back_listBibl;
}

SxmlNode* TeiAuthorNameFromFirstLast(char *first, char *last) /* deprecated */
{
  static Buffer *bufName=NULL;
  SxmlNode *teiName;
  if (!last)return NULL;
  if (!bufName)bufName=NewBuffer();
  if (first)
    {
      BufferStrcpy(bufName, first);
      BufferStrcat(bufName, " ");
      BufferStrcat(bufName, last);
      teiName=SxmlLeafCreate("name", BufferString(bufName));
    }
  else teiName=SxmlLeafCreate("name", last);
  BufferStrcpy(bufName,  Utf8NameToWikiSort(last));
  if (!first)
    {
      SxmlSetAttribute(teiName, "sortKey", BufferString(bufName));
      SxmlSetAttribute(teiName, "uniqKey", BufferString(bufName));
    }
  else
    {
      BufferStrcat(bufName, ", ");
      BufferStrcat(bufName, Utf8NameToWikiSort(first));
      SxmlSetAttribute(teiName, "sortKey", BufferString(bufName));
      BufferStrcpy(bufName,  Utf8NameToWikiSort(last));
      BufferStrcat(bufName, " ");
      BufferCatChar(bufName, (Utf8NameToWikiSort(first))[0]);
      BufferCatChar(bufName, '\0');
      SxmlSetAttribute(teiName, "uniqKey", BufferString(bufName));
    }
  return teiName;
}



SxmlNode *TeiFindPublicationStmt(SxmlNode *teiRoot)
{
  static SxPathResult *pathTeiPublicationStmt=NULL;
  SxmlNode *publicationStmt;

  if (!pathTeiPublicationStmt) pathTeiPublicationStmt=SxPathFirstCompile("teiHeader/fileDesc/publicationStmt");
  publicationStmt=SxPathFirstResultNode(pathTeiPublicationStmt,teiRoot);
  return publicationStmt;
}

char *TeiLangC3ToC2(char *c3)
{
  if (!c3) return "??";
  switch(*c3)
    {
    case 'e':
      if (strcmp(c3,"eng")==0) return "en";
      break;
    case 'f':
      if (strcmp(c3,"fra")==0) return "fr";
      break;
    }
  return "??";
}

SxmlNode *TeiHandlerHasExplorSource(char *codeSource)
{
  SxmlNode *nodeSource;
  if(!Tei_publicationStmt) return NULL;
  nodeSource=SxmlGetFirstChildTagAtt(Tei_publicationStmt, "idno", "type", "wicri:source");
  while(nodeSource)
    {
      if (strcmp(SxmlLeafText(nodeSource), codeSource)==0)return nodeSource;
      nodeSource=SxmlGetNextSiblingTagAtt(nodeSource,"idno",  "type", "wicri:source");
    }
  return NULL;
}
