/*   -*- coding: utf-8 -*-  */
#include <stdlib.h> 
#include <string.h>
#include "Buffer.h"
#include "RegExp.h"
#include "StrDict.h"
#include "WicriFrance.h"
#include "Utf8Converter.h"
#include "RegExp.h"

StrSearchTable *WicriFranceInseeToRegionTable=NULL;
StrDict        *WicriFranceInseeToRegionTableFr=NULL;
StrDict        *WicriFranceInseeToRegionOldTableFr=NULL;
StrDict        *WicriFranceCityToPlaceTable=NULL;
StrDict        *WicriFranceCityLcToPlaceTable=NULL;
StrSearchTable *WicriTableFranceTutellesFr=NULL;

Buffer         *WicriFranceBufName=NULL;

StrDict        *WicriFranceGetInseeToRegionTableFr()
{
  if (WicriFranceInseeToRegionTableFr) return WicriFranceInseeToRegionTableFr;
  if (!WicriFranceBufName)  WicriFranceBufName=NewBuffer();
  BufferStrcpy(WicriFranceBufName,WicriGetDataRoot());
  BufferStrcat(WicriFranceBufName,"/France/codeInseeToRegion.tab");
  WicriFranceInseeToRegionTableFr=StrDictFromFile(BufferString(WicriFranceBufName));
  return WicriFranceInseeToRegionTableFr;
}

StrDict        *WicriFranceGetInseeToRegionOldTableFr()
{
  if (WicriFranceInseeToRegionOldTableFr) return WicriFranceInseeToRegionOldTableFr;
  if (!WicriFranceBufName)  WicriFranceBufName=NewBuffer();
  BufferStrcpy(WicriFranceBufName,WicriGetDataRoot());
  BufferStrcat(WicriFranceBufName,"/France/codeInseeToRegionOld.tab");
  WicriFranceInseeToRegionOldTableFr=StrDictFromFile(BufferString(WicriFranceBufName));
  return WicriFranceInseeToRegionOldTableFr;
}

StrSearchTable *WicriFranceGetInseeToRegionTable()          /* To be deprecated */
{
  static Buffer *bufName=NULL;
  char *wicriDataRoot;

  if (WicriFranceInseeToRegionTable) return WicriFranceInseeToRegionTable;
  if (!bufName)  bufName=NewBuffer();
  wicriDataRoot=WicriGetDataRoot();
  BufferStrcpy(bufName,wicriDataRoot);
  BufferStrcat(bufName,"/GeoTables/France/CodeInseeToRegion.tab");
  WicriFranceInseeToRegionTable=StrSearchGetTable(BufferString(bufName),100);
  return WicriFranceInseeToRegionTable;
}

StrDict *WicriFranceGetCityToPlaceTable()
{
  static Buffer *bufName=NULL;
  char *wicriDataRoot;

  if (WicriFranceCityToPlaceTable) return WicriFranceCityToPlaceTable;
  if (!bufName)  bufName=NewBuffer();
  wicriDataRoot=WicriGetDataRoot();
  BufferStrcpy(bufName,wicriDataRoot);
  BufferStrcat(bufName,"/France/VillesToTeiPlace.dict");
  WicriFranceCityToPlaceTable=StrDictFromFile(BufferString(bufName));
  return WicriFranceCityToPlaceTable;
}

StrDict *WicriFranceGetCityLcToPlaceTable()
{
  static Buffer *bufName=NULL;
  char *wicriDataRoot;

  if (WicriFranceCityLcToPlaceTable) return WicriFranceCityLcToPlaceTable;
  if (!bufName)  bufName=NewBuffer();
  wicriDataRoot=WicriGetDataRoot();
  BufferStrcpy(bufName,wicriDataRoot);
  /*   BufferStrcat(bufName,"/France/villesLcToTeiPlace.tab"); */
  BufferStrcat(bufName,"/France/VillesLcToTeiPlace.dict"); 
  WicriFranceCityLcToPlaceTable=StrDictFromFile(BufferString(bufName));
  return WicriFranceCityLcToPlaceTable;
}

SxmlNode *WicriFranceGetCityRegionFromTableVilles(SxmlNode *affiliation, char *str)
{
  char *placeStr;
  if ((placeStr=StrDictSearch(WicriFranceGetCityToPlaceTable(), str)))
    {
      SxmlNode *placeNode;
      SxmlNode *placeName;
      SxmlNode *inputPlaceName;
      SxmlNode *inputSettlement;
      SxmlNode *regionNode;


      placeNode= SxmlFromString(placeStr);
      inputPlaceName=SxmlGetFirstChildByTagName(placeNode, "placeName");
      SxmlAppendChild(affiliation, placeName=SxmlElementCreate("placeName"));
      regionNode=SxmlGetFirstChildTagAtt(inputPlaceName, "region", "type", "region");
      if(regionNode)SxmlAppendChild(placeName, SxmlClone(regionNode));
      regionNode=SxmlGetFirstChildTagAtt(inputPlaceName, "region", "type", "old region");
      if(regionNode)SxmlAppendChild(placeName, SxmlClone(regionNode));
      inputSettlement=SxmlGetFirstChildByTagName(inputPlaceName, "settlement");
      while (inputSettlement)
	{
	  SxmlAppendChild(placeName, SxmlClone(inputSettlement));
	  inputSettlement=SxmlGetNextSiblingByTagName(inputSettlement, "settlement");
	}
      SxmlFree(placeNode);
      SxmlSetAttribute(affiliation, "wicri:level", "3");
      return affiliation;
    }
  return NULL;
}

SxmlNode *WicriFrancePutPlaceFromVille(SxmlNode *affiliation, char *ville)
{
  char *placeStr;
  if ((placeStr=StrDictSearch(WicriFranceGetCityToPlaceTable(), ville)))
    {
      WicriAffiliationPutPlace(affiliation, placeStr);
      return affiliation;
    }
  return NULL;
}

char *WicriFranceGetCityFromTableVillesLc(char *str)
{
  /* returns first settlement in volatile buffer or str */
  char *placeStr;
  static Buffer *lcBuf=NULL;
  char*lcStr;
  char *cityStr;

  if (!lcBuf) lcBuf=NewBuffer();
  lcStr=Utf8StringToSort(str);
  BufferStrcpy(lcBuf, lcStr);
  cityStr=str;
  if ((placeStr=StrDictSearch(WicriFranceGetCityLcToPlaceTable(), lcStr)))
    {
      SxmlNode *placeNode;
      SxmlNode *inputPlaceName;
      SxmlNode *inputSettlement;
      static Buffer *bufCity;
      if (!bufCity) bufCity=NewBuffer();

      if ((placeNode= SxmlFromString(placeStr)))
	{
	  if ((inputPlaceName=SxmlGetFirstChildByTagName(placeNode, "placeName")))
	    {
	      if ((inputSettlement=SxmlGetFirstChildByTagName(inputPlaceName, "settlement")))
		{
		  BufferStrcpy(bufCity, SxmlLeafText(inputSettlement));
		  cityStr=BufferString(bufCity);
		}
	    }
	  SxmlFree(placeNode);
	}
    }
  return cityStr;
}

SxmlNode *WicriFranceGetCityRegionFromTableVillesLc(SxmlNode *affiliation, char *str)
{
  char *placeStr;
  static Buffer *lcBuf=NULL;
  char*lcStr;

  if (!lcBuf) lcBuf=NewBuffer();
  lcStr=Utf8StringToSort(str);
  BufferStrcpy(lcBuf, lcStr);
  if ((placeStr=StrDictSearch(WicriFranceGetCityLcToPlaceTable(), lcStr)))
    {
      SxmlNode *placeNode;
      SxmlNode *placeName;
      SxmlNode *inputPlaceName;
      SxmlNode *inputSettlement;
      SxmlNode *regionNode;


      placeNode= SxmlFromString(placeStr);
      inputPlaceName=SxmlGetFirstChildByTagName(placeNode, "placeName");
      SxmlAppendChild(affiliation, placeName=SxmlElementCreate("placeName"));
      regionNode=SxmlGetFirstChildTagAtt(inputPlaceName, "region", "type", "region");
      if (regionNode) SxmlAppendChild(placeName, SxmlClone(regionNode));
      regionNode=SxmlGetFirstChildTagAtt(inputPlaceName, "region", "type", "old region");
      if (regionNode) SxmlAppendChild(placeName, SxmlClone(regionNode));
      inputSettlement=SxmlGetFirstChildByTagName(inputPlaceName, "settlement");
      while (inputSettlement)
	{
	  SxmlAppendChild(placeName, SxmlClone(inputSettlement));
	  inputSettlement=SxmlGetNextSiblingByTagName(inputSettlement, "settlement");
	}
      SxmlFree(placeNode);
      SxmlSetAttribute(affiliation, "wicri:level", "3");
      return affiliation;
    }
  return NULL;
}


RegExp *WicriCedex=NULL;

SxmlNode *WicriFranceGetCityRegionFromCodeInsee(SxmlNode *affiliation, char *str)
{
  char *codeInsee;
  char *region;
  char *region2015;
  SxmlNode *regName;
  SxmlNode *placeName;
  char *posSpace;
  
  if (!WicriCedex)WicriCedex=RegExpCreate("[ \\-]*[Cc][Ee][Dd][eE][xX]");
  codeInsee=malloc(5);
  strncpy (codeInsee,str,2);
  if (strcmp(codeInsee, "97")==0)
    strncpy (codeInsee, str,3);
  /*  region=StrSearch(WicriFranceGetInseeToRegionTable(), codeInsee);
  if (!region)return NULL;
  */
  region=StrDictSearch(WicriFranceGetInseeToRegionOldTableFr(), codeInsee);
  if (!region)return NULL;
  region2015=StrDictSearch(WicriFranceGetInseeToRegionTableFr(), codeInsee);
  if (!region2015)return NULL;
  SxmlAppendChild(affiliation, placeName=SxmlElementCreate("placeName"));
  SxmlAppendChild(placeName, regName=SxmlLeafCreate("region",region2015));
  SxmlSetAttribute(regName,"type","region");
  SxmlSetAttribute(regName,"nuts","2");
  if(strcmp (region, region2015)!=0)
    {
      SxmlAppendChild(placeName, regName=SxmlLeafCreate("region",region));
      SxmlSetAttribute(regName,"type","old region");
      SxmlSetAttribute(regName,"nuts","2");
    }
  if ((posSpace=strchr(str,' ')))
    {
      char *cedex;
      if ((cedex=RegExpFind(WicriCedex,posSpace))
	  &&(cedex > posSpace+2)
	  )
	{
	  static Buffer *bufCity;
	  if (!bufCity) bufCity=NewBuffer();
	  BufferStrncpy(bufCity, posSpace+1, cedex-posSpace-1);
	  SxmlAppendChild(placeName, regName=SxmlLeafCreate("settlement", WicriFranceGetCityFromTableVillesLc(BufferString(bufCity))));
	}
      else SxmlAppendChild(placeName, regName=SxmlLeafCreate("settlement", WicriFranceGetCityFromTableVillesLc(posSpace+1)));
      SxmlSetAttribute(regName,"type","city");
    }
  free(codeInsee);
  SxmlSetAttribute(affiliation, "wicri:level", "3");
  return affiliation;
}

SxmlNode *WicriFranceGetRegionFromField(SxmlNode *affiliation, char *beginRegion, char *strRegionArea)
{
  char *beginZip;
  SxmlNode *retNode;
  if (!WicriRegExpZip5)
    {
      WicriRegExpZip5=RegExpCreate("[0-9][0-9][0-9][0-9][0-9]");
    }
  beginZip=RegExpFind(WicriRegExpZip5, beginRegion);
  if ((!beginZip)
      && ((beginRegion-strRegionArea) > 10))
    {
      beginZip=RegExpFind(WicriRegExpZip5, beginRegion-10);
    }
   if (beginZip)
     {
       retNode=WicriFranceGetCityRegionFromCodeInsee(affiliation, beginZip);
       if (retNode) return retNode;
       SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion",beginZip));
       return NULL;
     }
   retNode=WicriFranceGetCityRegionFromTableVilles(affiliation, beginRegion);
   if (retNode) return retNode;
   retNode=WicriFranceGetCityRegionFromTableVillesLc(affiliation, beginRegion);
   if (retNode) return retNode;
   SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noRegion", beginRegion));
   return NULL;
}

StrSearchTable *WicriTableFranceLaboFr=NULL;

SxmlNode *WicriFranceLaboFrFromKey(char *enStr)
{
  char *orgStr;
  if(!WicriTableFranceLaboFr)
    {
      char *DILIB;
      static Buffer* bufTableName=NULL;
      if (!bufTableName)bufTableName=NewBuffer();
      DILIB=getenv("DILIB");
      bufTableName=NewBuffer();
      BufferStrcpy(bufTableName, DILIB);
      BufferStrcat(bufTableName, "/data/Wicri/France/LaboKey.fr.tab");
      WicriTableFranceLaboFr=StrSearchGetTable(BufferString(bufTableName),100);
    }
  if (!enStr)return NULL;
  orgStr= StrSearch( WicriTableFranceLaboFr, enStr);
  if (!orgStr)return NULL;
  return SxmlFromString(orgStr);
}

SxmlNode *WicriFranceTutellesFrFromKey(char *enStr)
{
  char *orgStr;
  if(!WicriTableFranceTutellesFr)
    {
      char *DILIB;
      static Buffer* bufTableName=NULL;
      if (!bufTableName)bufTableName=NewBuffer();
      DILIB=getenv("DILIB");
      bufTableName=NewBuffer();
      BufferStrcpy(bufTableName, DILIB);
      BufferStrcat(bufTableName, "/data/Wicri/France/Tutelles.fr.tab");
      WicriTableFranceTutellesFr=StrSearchGetTable(BufferString(bufTableName),100);
    }
  if (!enStr)return NULL;
  orgStr= StrSearch( WicriTableFranceTutellesFr, enStr);
  if (!orgStr)return NULL;
  return SxmlFromString(orgStr);
}

SxmlNode *WicriFranceSetRegOrgFromLabo(SxmlNode *affiliation, char *regStr)
{
  SxmlNode *orgNode;

  if ((orgNode=WicriFranceLaboFrFromKey(regStr)))
    {
      SxmlNode *placeName;
      placeName=SxmlGetFirstChildByTagName(orgNode,"placeName");
     if (placeName)SxmlAppendChild (affiliation, SxmlClone(placeName));
     return affiliation;
    }
  return NULL;
}
