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


#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>
#include "SxPath.h"
#include "Buffer.h"
#include "WicriPaysFromEn.h"
#include "WicriRegionFromEn.h"
#include "WicriFrance.h"
#include "RegExp.h"

extern char *optarg;
extern int   optind;
int getopt();

char *DILIB;

SxPathResult *teiPathAffiliation;
SxPathResult *teiPathAffiliationOld;

StrSearchTable *tableVilles;
StrSearchTable *tableFranceVilleToPlace;

Buffer* bufPays;
Buffer* bufTableName;

char *inistResolveNoCountry(SxmlNode *affiliation, SxmlNode *wicriNoCountry)
{
  char *country;
  char *cityText;
  
  if((country=WicriPaysFromEnglish(SxmlLeafText(wicriNoCountry))))
    {
      SxmlAppendChild(affiliation,SxmlLeafCreate("country", country));
      SxmlRemoveChild(wicriNoCountry);
      SxmlFree(wicriNoCountry);
      return country;
    }
  if ((cityText=StrSearch(tableVilles, SxmlLeafText(wicriNoCountry))))
    {
      SxmlNode *cityList;
      SxmlNode *countryNode;
      SxmlNode *placeName;
      SxmlNode *nextNode;
      SxmlNode *regName;
      cityList=SxmlFromString(cityText);
      countryNode=SxmlFirstChild(cityList);
      country=SxmlLeafText(countryNode);
      SxmlAppendChild(affiliation,SxmlLeafCreate("country", country));
      
      SxmlAppendChild(affiliation, placeName=SxmlElementCreate("placeName"));
      nextNode=SxmlNextSibling(countryNode);
      if (SxmlLength(cityList)>3)
	{
	  SxmlAppendChild(placeName, regName=SxmlLeafCreate("region",SxmlLeafText(nextNode)));
	  SxmlSetAttribute(regName,"type","state");
	  nextNode=SxmlNextSibling(nextNode);
	}
      while (nextNode)
	{
	  char *regOrCity;
	  regOrCity=SxmlLeafText(nextNode);
	  if ((nextNode=SxmlNextSibling(nextNode)))
	    {
	      SxmlAppendChild(placeName, regName=SxmlLeafCreate("region",regOrCity));
	      SxmlSetAttribute(regName,"type","region");
	    }
	  else
	    {
	      SxmlAppendChild(placeName, regName=SxmlLeafCreate("settlement",regOrCity));
	      SxmlSetAttribute(regName,"type","town");
	    }
	}
      SxmlRemoveChild(wicriNoCountry);
      SxmlFree(wicriNoCountry);
      return country;
    }
  return NULL;
}

SxmlNode *inistGetRegion(SxmlNode *affiliation, SxmlNode *inistF14, char *strS2, char *country)
{
  SxmlNode *retNode;
  SxmlNode *inistF14S1;
  char *strS1;
  char *level;
  SxmlNode *resUniv;

  level=SxmlGetAttribute (affiliation, "wicri:level");
  if (level &&level[0]>'1') return affiliation;
  if (strS2)
    {
      char *comma;
      if ((comma=strrchr(strS2,',')))
	{
	  char *begLast;
	  begLast=comma+1;
	  while (*begLast==' ')begLast++;
	  retNode=WicriGetRegionFromSubField(affiliation, begLast, strS2, country);
	}
      else retNode=WicriGetRegionFromSubField(affiliation, strS2, strS2, country);
      if (retNode) return retNode;
    }
  inistF14S1=SxmlGetFirstChildByTagName(inistF14,"s1");
  if (inistF14S1 && SxmlIsLeaf(inistF14S1)) strS1=SxmlLeafText(inistF14S1);
  else strS1=NULL;
  if (strS1)
    {
    char *posComma;

    posComma=strrchr(strS1,',');
    if (posComma)
      {
	char *beginSubField;
	SxmlNode *retNode;
	char *countryInsteadCity;
	beginSubField=posComma+1;
	while ( beginSubField[0]==' ')beginSubField++;
	
	if ((countryInsteadCity=WicriPaysFromEnglish(beginSubField))
	    &&(strcmp (country, countryInsteadCity)==0))
	{
	  static Buffer* bufNewField=NULL;
	  char *previousComma;
	  if (!bufNewField) bufNewField=NewBuffer();
	  BufferStrncpy(bufNewField, strS1, posComma-strS1);
	  previousComma=strrchr(BufferString(bufNewField), ',');
	  if (!previousComma)
	    {
	      SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",strS1));
	      return NULL;
	    }
	    beginSubField=previousComma+1;
	    while ( beginSubField[0]==' ')beginSubField++;
	    retNode=WicriGetRegionFromSubField(affiliation, beginSubField, strS1, country);
	    if (retNode) return retNode;
	    else
	      {
		SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",beginSubField));
		return NULL;
	      }
	  }
	retNode=WicriGetRegionFromSubField(affiliation, beginSubField, strS1, country);
	if (retNode) return retNode;
	else
	  {
	    if (strS2)SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",strS2));
	    else SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",strS1));
	    return NULL;
	  }
      }
    retNode=WicriGetRegionFromSubField(affiliation, strS1, strS1, country);
    resUniv=WicriAffiliationSetUnivFromField(affiliation, strS1);
    if (retNode||resUniv)
      {
	SxmlNode *noReg;
	if ((noReg=SxmlGetFirstChildByTagName(affiliation, "wicri:noRegion"))) SxmlFree(noReg);
	if (resUniv)return resUniv;
	return retNode;
      }
    /* if (retNode) return retNode; */
    else
      {
	SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",strS1));
	return NULL;
      }
    }
  if (strS2)
    {
      SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",strS2));
    }
  return NULL;
}

void proceedAffiliation(SxmlNode * affiliation)
{
  SxmlNode *countryNode;
  SxmlNode *wicriNoCountry;
  char *strS2;
  char *strS1;
  char *attAuto;
  SxmlNode *inistF14;
  SxmlNode *inistF14S2;
  SxmlNode *inistF14S1;
  char *country;

  strS2=NULL;
  strS1=NULL;
  if((wicriNoCountry=SxmlGetFirstChildByTagName(affiliation,"wicri:noCountry")))
    {
      country=inistResolveNoCountry(affiliation, wicriNoCountry);
    }
  countryNode=SxmlGetFirstChildByTagName(affiliation,"country");
  if(!countryNode)return;
  country=SxmlLeafText(countryNode);
  inistF14=SxmlGetFirstChildByTagName(affiliation,"inist:fA14");
  if (!inistF14)return;
  inistF14S2=SxmlGetFirstChildByTagName(inistF14,"s2");
  if (inistF14S2 && SxmlIsLeaf(inistF14S2)) strS2=SxmlLeafText(inistF14S2);
  else strS2=NULL;
  
  attAuto=SxmlGetAttribute(countryNode, "wicri:auto");
  if (attAuto && strS2) WicriOldIsoCodeToPays(affiliation, countryNode, strS2, NULL);
    
  inistGetRegion(affiliation, inistF14, strS2, country);

  inistF14S1=SxmlGetFirstChildByTagName(inistF14,"s1");
  if (inistF14S1 && SxmlIsLeaf(inistF14S1)) strS1=SxmlLeafText(inistF14S1);
  if (strS1)WicriAffiliationSetUnivFromField(affiliation, strS1);
}

int main (int argc, char **argv) {

   char *tablesDir;
   SxmlNode *docInput;
   SxmlNode *listAffiliations;
   SxmlNode *affiliation;

   bufPays=BufferCreate(10,10);
   bufTableName=BufferCreate(10,10);

   DILIB=getenv("DILIB");
   BufferStrcpy(bufTableName, DILIB);
   BufferStrcat(bufTableName, "/data/Wicri/GeoTables/");
   tablesDir=strdup (BufferString(bufTableName));

   BufferStrcpy(bufTableName, tablesDir);
   BufferStrcat(bufTableName, "/Pays/LargeCitiesFr.tab");
   tableVilles=StrSearchGetTable(BufferString(bufTableName),100);

   BufferStrcpy(bufTableName, tablesDir);
   BufferStrcat(bufTableName, "France/VillesToTeiPlace.tab");
   tableFranceVilleToPlace=StrSearchGetTable(BufferString(bufTableName),100);

   teiPathAffiliationOld=SxPathSetCompile("TEI/teiHeader/fileDesc/titleStmt/author/affiliation");
   teiPathAffiliation=SxPathSetCompile("TEI/teiHeader/fileDesc/sourceDesc/biblStruct/analytic/author/affiliation");

   while ((docInput=SxmlInputNextDocumentElement()))
     {      
       if (!(SxmlNodeHasName(docInput,"record")))continue;
       if ((listAffiliations=SxPathSetResultListCreate(teiPathAffiliation, docInput)))
	 {
	   while((affiliation=SxmlNodeListNextNode(listAffiliations)))
	     {
	       proceedAffiliation(affiliation);       
	     } 
	 }
     if ((listAffiliations=SxPathSetResultListCreate(teiPathAffiliationOld, docInput)))
	 {
	   while((affiliation=SxmlNodeListNextNode(listAffiliations)))
	     {
	       proceedAffiliation(affiliation);       
	     } 
	 }
       SxmlPrint (SxmlInputRecord);
     }
   exit(EXIT_SUCCESS);
}
