/*   -*- coding: utf-8 -*-  */
/******************************************************************************
*
*               Module   : Explor
*               Fichier  : ExplorTools.c
*               Auteur   : J. DUCLOY
******************************************************************************/

#include "Except.h"
#include "Explor.h"

StrDict        *ExplorTableParam=NULL;
char * ExplorIncludeCategoryLang=NULL;
int   ExplorAreaIsMulti;

char *ExplorGetFromDict(char *k1)
{
  return StrDictSearch(ExplorTableParam,k1);
}

char *ExplorGetFromDictK2(char *k1, char *k2)
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    return ExplorGetFromDict(BufferString(bKey));
}

char *ExplorGetFromDictWithPrefix(char *prefix, char *code)
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,prefix);
    BufferStrcat(bKey,code);
    return ExplorGetFromDict(BufferString(bKey));
}

char *ExplorSetDictK2(char *k1, char *k2, char *value)
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    StrDictSet(ExplorTableParam, strdup(BufferString(bKey)), value);
    return value;
}


char *ExplorGetFromDictK3(char *k1, char *k2, char *k3 )
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k3);
    return ExplorGetFromDict(BufferString(bKey));
}

char *ExplorCascadeFromDictK3(char *k1, char *k2, char *key )
{
  char *strResult;
  if (!k2) return ExplorGetFromDictK2(k1, key);
  if ((strResult=ExplorGetFromDictK3(k1, k2, key)))
    return strResult;
  return ExplorGetFromDictK2(k1, key);
}

char *ExplorGetFromDictK4(char *k1, char *k2, char *k3, char *k4 )
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k3);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k4);
    return ExplorGetFromDict(BufferString(bKey));
}

char *ExplorCascadeFromDictK4(char *k1, char *k2, char *k3, char *key )
{
  char *strResult;
  if (!k3) return ExplorCascadeFromDictK3(k1, k2, key);
  if ((strResult=ExplorGetFromDictK4(k1, k2, k3, key)))
    return strResult;
  return ExplorCascadeFromDictK3(k1, k2, key);
}

char *ExplorGetFromDictK5(char *k1, char *k2, char *k3, char *k4, char *k5 )
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k3);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k4);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k5);
    return ExplorGetFromDict(BufferString(bKey));
}

char *ExplorCascadeFromDictK5(char *k1, char *k2, char *k3, char *k4, char *key )
{
  char *strResult;
  if (!k4) return ExplorCascadeFromDictK4(k1, k2, k3, key);
  if ((strResult=ExplorGetFromDictK5(k1, k2, k3, k4, key)))
    return strResult;
  return ExplorCascadeFromDictK4(k1, k2, k3, key);
}

char *ExplorSetDict(char *k1, char *value)
{
  return StrDictSet(ExplorTableParam, k1, value);
}

char *ExplorSetDictK3(char *k1, char *k2, char *k3,  char *value)
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k3);
    StrDictSet(ExplorTableParam, strdup(BufferString(bKey)), value);
    return value;
}

char *ExplorSetDictK4(char *k1, char *k2, char *k3, char *k4,  char *value)
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k3);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k4);
    StrDictSet(ExplorTableParam, strdup(BufferString(bKey)), value);
    return value;
}

char *ExplorSetDictK5(char *k1, char *k2, char *k3, char *k4, char *k5,  char *value)
{
    static Buffer *bKey = NULL;
    if(!bKey)bKey=BufferCreate(10,10);
    BufferStrcpy(bKey,k1);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k2);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k3);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k4);
    BufferStrcat(bKey,"/");
    BufferStrcat(bKey,k5);
    StrDictSet(ExplorTableParam, strdup(BufferString(bKey)), value);
    return value;
}

char *ExplorGetShortNameStream(char *streamCode, char *stream, char *step)
{
  static Buffer *bufName=NULL;
  char *name;
  if (!bufName) bufName=NewBuffer();
  BufferStrcpy(bufName, "shortNameStream");
  BufferStrcat(bufName, streamCode);
  name=ExplorCascadeFromDictK4("Area", stream, step, BufferString(bufName));
  if (name)return name;
  return streamCode;
}

char *ExplorGetNameStream(char *streamCode, char *stream, char *step)
{
  static Buffer *bufName=NULL;
  char *name;
  if (!bufName) bufName=NewBuffer();
  BufferStrcpy(bufName, "nameStream");
  BufferStrcat(bufName, streamCode);
  name=ExplorCascadeFromDictK4("Area", stream, step, BufferString(bufName));
  if (name)return name;
  return ExplorGetShortNameStream(streamCode, stream, step);
}

/*
                            TreeNode
 */

SxmlNode *ExplorTreeNode(SxmlNode *rootNode, char *stream, char *step, char *indexAssoc)
{
  SxmlNode *retNode;
  retNode=ExplorAreaSiteLang;
  if (stream)
    {
      SxmlNode *streamNode;
      SxmlReset (rootNode);
      while ((streamNode=SxmlNextNode(rootNode)))
	{
	  if (SxmlHasAttribute(streamNode, "code", stream))
	    {
	      if (step)
		{
		  SxmlNode *stepNode;
		  SxmlReset (streamNode);
		  while ((stepNode=SxmlNextNode(streamNode)))
		    {
		      if (SxmlHasAttribute(stepNode, "code", step))
			{
			  if(indexAssoc)
			    {
			      SxmlNode *indexAssocNode;
			      SxmlReset (stepNode);
			      while ((indexAssocNode=SxmlNextNode(stepNode)))
				{
				  if (SxmlHasAttribute(indexAssocNode, "code", indexAssoc))
				    return indexAssocNode;
				}
			      return NULL;
			    }
			  else return stepNode;        /* to be completed */
			}
		    }
		  return NULL; /* unknown step */
		}
	      else return streamNode;
	    }
	}
      return NULL;
    }
  return retNode;
}

SxmlNode *ExplorSiteTreeNode(char *stream, char *step, char *indexAssoc)
{
  return ExplorTreeNode(ExplorAreaSiteLang, stream, step, indexAssoc);
}

SxmlNode *ExplorAreaTreeNode(char *stream, char *step, char *indexAssoc)
{
  return ExplorTreeNode(ExplorAreaData, stream, step, indexAssoc);
}

SxmlNode *ExplorGetStreamNodeFromTreeNode(SxmlNode *tn1)
{
  if (!tn1)return NULL;
  if (SxmlNodeHasName(tn1,"step"))return SxmlParent (tn1);
  if (SxmlNodeHasName(tn1,"stream"))return tn1;
  if (SxmlNodeHasName(tn1,"main"))return tn1;
  if (SxmlNodeHasName(tn1,"zoom"))return tn1;
  return ExplorGetStreamNodeFromTreeNode(SxmlParent(tn1));
}

char *ExplorTreeNodeShortName(SxmlNode *tn1)
{
  char *v1;
  if (!tn1) return NULL;
  if ((v1=SxmlGetAttribute(tn1,"shortName"))) return v1;
  if ((v1=SxmlGetAttribute(tn1,"name"))) return v1;
  return SxmlGetAttribute(tn1,"code");
}

char *ExplorTreeNodeName(SxmlNode *tn1)
{
  char *v1;
  if (!tn1) return NULL;
  if ((v1=SxmlGetAttribute(tn1,"name"))) return v1;
  if ((v1=SxmlGetAttribute(tn1,"shortName"))) return v1;
  return SxmlGetAttribute(tn1,"code");
}

char *ExplorTreeIndexMainPage(SxmlNode *indexNode)
{
  char *v1;
  static Buffer *bufUrl;
  if (!indexNode)return NULL;
  if ((v1=SxmlGetAttribute(indexNode,"mainPage"))) return v1;
  if (!bufUrl) bufUrl=NewBuffer();
  BufferStrcpy(bufUrl, "indexHead.php?index=");
  BufferStrcat(bufUrl, SxmlGetAttribute(indexNode, "code"));
  return(BufferString(bufUrl));
}

char *ExplorTreeNodeLinkToStream(SxmlNode *treeNode, char *targetStream, char *page)
{
  static Buffer* bufLink=NULL;
  if (!bufLink)bufLink=NewBuffer();
  else BufferReset(bufLink);
  if (treeNode==ExplorAreaSiteLang)
    {
      BufferStrcpy(bufLink, targetStream);
      BufferStrcat(bufLink, "/");
    }
  else if ((SxmlNodeHasName(treeNode, "stream"))
	    ||(SxmlNodeHasName(treeNode, "main")))
    {
      BufferStrcpy(bufLink, "../");
      BufferStrcat(bufLink, targetStream);
      BufferStrcat(bufLink, "/");
    }
  else if ((SxmlNodeHasName(treeNode, "step")))
    {
      BufferStrcpy(bufLink, "../../");
      BufferStrcat(bufLink, targetStream);
      BufferStrcat(bufLink, "/");
    }
  BufferStrcat (bufLink, page);
  return strdup(BufferString(bufLink));
}

SxmlNode *ExplorSiteTreeNodeFromPathRecursive(SxmlNode *treeNode, char *path)
{
  char *posSlash;
  posSlash=strchr(path, '/');
  if (!posSlash)
    {
      SxmlNode *childNode;
      childNode=SxmlFirstChild(treeNode);
      while (childNode)
	{
	  if (SxmlHasAttribute(childNode, "code", path)) return childNode;
	  childNode=SxmlNextSibling(childNode);
	}
    }
  return NULL;
}

SxmlNode *ExplorSiteTreeNodeFromPath(char *path)
{
  char *posSlash;
  if (strncmp(path, "Area", 4)!=0) return NULL;
  posSlash=strchr(path, '/');
  if (!posSlash) return ExplorAreaSiteLang;
  return ExplorSiteTreeNodeFromPathRecursive(ExplorAreaSiteLang, posSlash+1);
}

char *ExplorTreeNodeLinkToStep(SxmlNode *treeNode, char *targetStream, char *targetStep, char *page)
{
  static Buffer* bufLink=NULL;
  if (!bufLink)bufLink=NewBuffer();
  else BufferReset(bufLink);
  if (treeNode==ExplorAreaSiteLang)
    {
      BufferStrcpy(bufLink, targetStream);
      BufferStrcat(bufLink,"/");
      BufferStrcat(bufLink,targetStep);
      BufferStrcat(bufLink,"/");
    }
  else if ((SxmlNodeHasName(treeNode, "stream"))
	    ||(SxmlNodeHasName(treeNode, "main")))
    {
      BufferStrcpy(bufLink, "../");
      BufferStrcat(bufLink, targetStream);
      BufferStrcat(bufLink, "/");
      BufferStrcat(bufLink,targetStep);
      BufferStrcat(bufLink,"/");
    }
  else if ((SxmlNodeHasName(treeNode, "step")))
    {
      BufferStrcpy(bufLink, "../../");
      BufferStrcat(bufLink, targetStream);
      BufferStrcat(bufLink, "/");
      BufferStrcat(bufLink,targetStep);
      BufferStrcat(bufLink,"/");
    }
  BufferStrcat (bufLink, page);
  return strdup(BufferString(bufLink));
}

char *ExplorTreeNodeLinkToCloserStep(SxmlNode *treeNode, char *targetStep, char *page)
{
  static Buffer* bufLink=NULL;
  if (!bufLink)bufLink=NewBuffer();
  else BufferReset(bufLink);
  if (SxmlNodeHasName(treeNode, "step"))
    {
      BufferStrcpy(bufLink,"../");
      BufferStrcat(bufLink,targetStep);
      BufferStrcat(bufLink,"/");
    }
  BufferStrcat (bufLink, page);
  return strdup(BufferString(bufLink));
}

int ExplorTreeLevel (char *name)
{
  switch(name[0])
    {
    case 'l':   /* lang */
      return 1;
    case 'm':   /* main */
      return 2;
    case 's':  /* stream or step */
      if (name[2]=='r') return 2;
      return 3; /* step*/
    case 'i':  /* index */ 
      return 4;
    }
  return 0;
}

SxmlNode *ExplorTreeInheritAttribute(SxmlNode *treeNode, char *name, char *code, char *att, char *val)
{
  int l1;
  int l2;
  char *n2;
  l1=ExplorTreeLevel(n2=SxmlNodeName(treeNode));
  l2=ExplorTreeLevel(name);
  if (l1==l2)
    {
      if ((strcmp(name,n2)==0)
	  &&(SxmlHasAttribute(treeNode,"code",code)))
	SxmlSetAttribute(treeNode, att, val);
      
      return treeNode;
    }
  if (l1<l2)
    {
      SxmlNode *iterNode;
      SxmlNode *retNode;
      retNode=NULL;
      iterNode=SxmlFirstChild(treeNode);
      while(iterNode)
	{
	  SxmlNode *r1;
	  r1=ExplorTreeInheritAttribute(iterNode, name, code, att, val);
	  if (r1) retNode=r1;
	  iterNode=SxmlNextSibling(iterNode);
	}
      return retNode;
    }
  return NULL;
}

char *ExplorGetBiblioSize (char *stream, char *step)
{
  SxmlNode *hcs;
  static Buffer *bufFileName=NULL;
  if (!bufFileName)bufFileName=NewBuffer();
  BufferStrcpy(bufFileName,ExplorAreaDir);
  BufferStrcat(bufFileName,"/Data/");
  BufferStrcat(bufFileName, stream);
  BufferStrcat(bufFileName,"/");
  BufferStrcat(bufFileName, step);
  BufferStrcat(bufFileName,"/biblio.hcs");
  hcs=SxmlFromFile(BufferString(bufFileName));
  return(SxmlLeafText(SxmlGetFirstChildByTagName(hcs,"nrec")));
}

char *ExplorGetIndexSize (char *stream, char *step, char *indexCode)
{
  SxmlNode *hcs;
  static Buffer *bufFileName=NULL;
  if (!bufFileName)bufFileName=NewBuffer();
  BufferStrcpy(bufFileName,ExplorAreaDir);
  BufferStrcat(bufFileName,"/Data/");
  BufferStrcat(bufFileName, stream);
  BufferStrcat(bufFileName,"/");
  BufferStrcat(bufFileName, step);
  BufferStrcat(bufFileName,"/");
  BufferStrcat(bufFileName, indexCode);
  BufferStrcat(bufFileName,".hcs");
  hcs=SxmlFromFile(BufferString(bufFileName));
  if (!hcs) return NULL;
  return(SxmlLeafText(SxmlGetFirstChildByTagName(hcs,"nrec")));

}

void ExplorGenerShellAssoc(char *stream, char *step, char *assocCode)
{
  /*char * assocCode;*/
  SxmlNode *assocTypeNode;
  char *assocTypeStr;
  char *fromIndex;
  char *fromIndexCode;
  char *thresholdIndexMax;
  char *thresholdIndexMin;
  
  printf("<?dilib file=\"%s/bin/%s%sAssoc%s.sh\" ?>\n", ExplorAreaDir, stream, step, assocCode );
  printf ("#!/bin/sh\n");
  printf ("# This file is generated by Dilib / Explor / ExplorTools \n");

  thresholdIndexMax=ExplorCascadeFromDictK5("Area",stream, step, assocCode, "assocThresholdIndexMax");
  thresholdIndexMin=ExplorCascadeFromDictK5("Area",stream, step, assocCode, "assocThresholdIndexMin");

  assocTypeStr=ExplorGetFromDictK5("Area", stream, step, assocCode, "assocType");
  if (!assocTypeStr) 
    {
      ExceptSetError("ExplorTools", "NF","Type assocType for ", assocCode, " not foubdedin paramFile", 1);
      exit(1);
    }
  assocTypeNode=SxmlFromString(assocTypeStr);
  fromIndex=SxmlLeafText(SxmlNextSibling(SxmlGetFirstChildByTagName(assocTypeNode,"i"))); /* to be improved */
  /* fromIndexCode=ExplorGetFromDictK2(fromIndex, "indexCode");*/
  fromIndexCode=ExplorGetFromDictK5("Area", stream, step, assocCode, "fromCode");
  printf ("#   using %s -> %s \n", assocCode, SxmlToString(assocTypeNode));
  printf ("#         %s -> %s \n", fromIndex, fromIndexCode);
  printf ("\n\nHfdCat %s/Data/%s/%s/%s.hfd \\\n",  ExplorAreaDir, stream, step, fromIndexCode);

  printf ("  | SgmlSelect ");
  if (thresholdIndexMin) printf (" -g \"idx/f#:n>%s\" ", thresholdIndexMin);
  else printf (" -g \"idx/f#:n>1\" ");
  if (thresholdIndexMax) printf (" -g \"idx/f#:n<%s\" ", thresholdIndexMax);
  printf (" \\\n");

  printf ("  | AssocFastFromIndex   \\\n");
  printf ("  | SxmlSelect -g assoc/fij/1 -p @g1 -p @1  \\\n");
  printf ("  | sort -rn      \\\n");                           
  printf ("  | SgmlFast -c 1  \\\n");
  printf ("  | head -1000 >  %s/Data/%s/%s/%s.sort \n\n", ExplorAreaDir, stream, step, assocCode);
  
  printf (" echo \"==== \" %s, step %s, assoc %s done\n", stream, step, assocCode);
  printf (" cat %s/Data/%s/%s/%s.sort | wc \n", ExplorAreaDir, stream, step, assocCode);

  printf("<?dilib appendFile=\"%s/bin/area.mk\" ?>\n", ExplorAreaDir );
  printf("# This part is generated by ExplorTools / ExplorGenerShellAssoc() \n");
  /*
  printf("%s/Make/%s/%s/%s.assoc:  \\\n ", ExplorAreaDir, ExplorStreamCode, step, assocCode);
  printf("                %s/Make/%s/%s/%s.index \n", ExplorAreaDir, ExplorStreamCode, step, fromIndexCode);
  printf("\tsh %s/bin/%s%sAssoc%s.sh \n", ExplorAreaDir, ExplorStreamCode, step, assocCode);
  printf("\ttouch %s/Make/%s/%s/%s.assoc \n\n", ExplorAreaDir, ExplorStreamCode, step, assocCode);
  */
  printf("$(EXPLOR_AREA)/Make/%s/%s/%s.assoc:  \\\n ", ExplorStreamCode, step, assocCode);
  printf("                $(EXPLOR_AREA)/Make/%s/%s/%s.index \n", ExplorStreamCode, step, fromIndexCode);
  printf("\tsh $(EXPLOR_AREA)/bin/%s%sAssoc%s.sh \n", ExplorStreamCode, step, assocCode);
  printf("\ttouch $(EXPLOR_AREA)/Make/%s/%s/%s.assoc \n\n", ExplorStreamCode, step, assocCode);
}

char *ExplorIndexCodeGetXpath(char* stream, char *step, char *indexCode)
{
  char *indexTypeStr;
  SxmlNode *indexType;
  char *indexXpath;

  indexTypeStr=ExplorGetFromDictK5("Area", stream, step, indexCode, "indexType");
  if (!indexTypeStr) return NULL;
  indexType=SxmlFromString(indexTypeStr);
  if (strcmp(SxmlLeafText(SxmlFirstChild(indexType)), "xpath")==1) indexXpath=SxmlLeafText(SxmlNextSibling(SxmlFirstChild(indexType)));
  else indexXpath="undef";
  return indexXpath;
}

void ExplorGenerShellCross(char *stream, char *step, char *crossCode)
{
  SxmlNode *crossTypeNode;
  char *crossTypeIdent;
  char *crossTypeKey;
  char *crossTypeStr;
  char *fromIndexCode;
  char *toIndexCode;
  char *fromIndexXpath;
  char *toIndexXpath;

  printf("<?dilib file=\"%s/bin/%s%sCross%s.sh\" ?>\n", ExplorAreaDir, stream, step, crossCode );
  printf ("#!/bin/sh\n");
  printf ("# This file is generated by Dilib / Explor / ExplorTools \n");

  crossTypeStr=ExplorGetFromDictK5("Area", stream, step, crossCode, "crossType");
  crossTypeIdent=ExplorGetFromDictK5("Area", stream, step, crossCode, "crossTypeIdent");
  printf ("#   using %s -> %s, %s \n", crossCode, crossTypeStr, crossTypeIdent);
  crossTypeNode=SxmlFromString(crossTypeStr);
  fromIndexCode=ExplorGetFromDictK5("Area", stream, step, crossCode, "fromCode");
  toIndexCode=ExplorGetFromDictK5("Area", stream, step, crossCode, "toCode");
  fromIndexXpath=ExplorIndexCodeGetXpath(stream, step, fromIndexCode);
  toIndexXpath=ExplorIndexCodeGetXpath(stream, step, toIndexCode);
  printf ("#  from       %s -> %s \n", fromIndexCode, fromIndexXpath);
  printf ("#  to       %s -> %s \n", toIndexCode, toIndexXpath);

  ExplorGenerDeleteHfd(stream, step, crossCode);

  if(strcmp(crossTypeIdent, "builtin")==0)
    {
      printf ("\n\nHfdCat %s/Data/%s/%s/biblio.hfd \\\n",  ExplorAreaDir, stream, step);
      crossTypeKey=ExplorGetFromDictK5("Area", stream, step, crossCode, "crossTypeKey");
      if(strcmp(crossTypeKey, "Tei:Pays2author")==0)                                 /*  deprecated */
	{
	  printf ("   | SgmlSelect -s record/TEI/teiHeader/sourceDesc/biblStruct/analytic/author -p @s1  \\\n");
	  printf ("   | SgmlSelect -g author/name# -p @1 -p @g1   \\\n");
	  printf ("   | SgmlSelect -s author/affiliation/country#  -p @s1 -p @2  \\\n");
	}
      printf ("  | sort -u  \\\n");
      printf ("  | SgmlFast -c3  \\\n");
    }
  else
    {
      printf("(\n");
      printf ("   HfdCat %s/Data/%s/%s/%s.hfd \\\n",  ExplorAreaDir, stream, step, fromIndexCode);
      printf ("        | IndexHistoBuilder -a \n");
      printf ("   HfdCat %s/Data/%s/%s/%s.hfd \\\n",  ExplorAreaDir, stream, step, toIndexCode);
      printf ("        | IndexHistoBuilder -b \n");
      printf (")  | sort -u  \\\n");
      printf ("  | IndexHistoBuilder -c \\\n");
      printf ("  | sort  \\\n");
    }
  printf ("  | HistoBuildRec -1 \\\n");
  printf ("  | HfdBuild -h  %s/Data/%s/%s/%s \n\n", ExplorAreaDir, stream, step, crossCode);

  printf ("IndexBuildHid -h  %s/Data/%s/%s/%s -p %s -e k  \n\n", ExplorAreaDir, stream, step, crossCode, fromIndexXpath);
  
  printf (" echo \"==== \" %s, step %s, cross %s done\n", stream, step, crossCode);
  printf (" HfdCat %s/Data/%s/%s/%s.hfd | wc \n", ExplorAreaDir, stream, step, crossCode);
  
  printf("<?dilib appendFile=\"%s/bin/area.mk\" ?>\n", ExplorAreaDir );
  printf("# This part is generated by ExplorTools /ExplorGenerShellCross \n");
  /*
  printf("%s/Make/%s/%s/%s.cross:  \\\n", ExplorAreaDir, stream, step, crossCode);
  printf("                %s/Make/%s/%s/biblio \n", ExplorAreaDir, stream, step);
  printf("\tsh %s/bin/%s%sCross%s.sh\n", ExplorAreaDir, stream, step, crossCode );
  printf("\ttouch %s/Make/%s/%s/%s.cross  \n\n", ExplorAreaDir, stream, step, crossCode);
  */
  printf("$(EXPLOR_AREA)/Make/%s/%s/%s.cross:  \\\n",  stream, step, crossCode);
  printf("                $(EXPLOR_AREA)/Make/%s/%s/biblio \n", stream, step);
  printf("\tsh $(EXPLOR_AREA)/bin/%s%sCross%s.sh\n", stream, step, crossCode );
  printf("\ttouch $(EXPLOR_AREA)/Make/%s/%s/%s.cross  \n\n", stream, step, crossCode);
}

void ExplorGenerShellCluster(char *stream, char *step, char *clusterCode)
{
  /* char * clusterCode; */
  SxmlNode *clusterTypeNode;
  char *clusterTypeStr;
  char *fromAssocCode;
  char *fromIndexCode;
  char *clusterTypeFC;       /* frequency or cosinus */

  printf("<?dilib file=\"%s/bin/%s%sCluster%s.sh\" ?>\n", ExplorAreaDir, stream, step, clusterCode );
  printf ("#!/bin/sh\n");
  printf ("# This file is generated by Dilib / Explor / ExplorTools \n");

  clusterTypeStr=ExplorGetFromDictK5("Area", stream, step, clusterCode, "clusterType");

  clusterTypeNode=SxmlFromString(clusterTypeStr);
  clusterTypeFC=SxmlLeafText(SxmlFirstChild(clusterTypeNode));
  
  fromAssocCode=ExplorGetFromDictK5("Area", stream, step, clusterCode, "fromAssoc");
  fromIndexCode=ExplorGetFromDictK5("Area", stream, step, fromAssocCode, "fromCode");


  printf ("#   using %s -> %s \n", clusterCode, SxmlToString(clusterTypeNode));
  printf ("#         from >%s< and >%s< \n", fromAssocCode, fromIndexCode);
  printf ("\n\ncat %s/Data/%s/%s/%s.sort \\\n",  ExplorAreaDir, stream, step, fromAssocCode);
  if (clusterTypeFC[0]=='f')
    {
      printf("     | SgmlSelect -g assoc/fij# -p @g1 -p @1  \\\n");
      printf("     | IndexClusterFromAssoc   \\\n");
      printf("     | IndexClusterName  \\\n");
    }
  else
    {
      printf("     | IndexAssocCosinus   \\\n");
      printf("     | SgmlSelect -v assoc/fij#=1   \\\n");
      printf("     | sort -rn   \\\n");
      printf("     | IndexClusterFromAssoc   \\\n");
      printf("     | IndexClusterName  \\\n");
    }
  printf("     >  %s/Data/%s/%s/%s.t \n",  ExplorAreaDir, stream, step, clusterCode);

  printf("\n\ncat  %s/Data/%s/%s/%s.t \\\n",  ExplorAreaDir, stream, step, clusterCode);
  printf("     |SgmlFast -c l         \\\n");
  printf("     | SgmlFast -c lassoc   \\\n");
  printf("     | SgmlFast -c lclu     \\\n");
  printf("     | SgmlFast -nk code    \\\n");
  printf("     | SgmlFast -ns mot     \\\n");
  printf("     | sort                 \\\n");
  printf("     | IndexSelect -iSh  %s/Data/%s/%s/%s \\\n",  ExplorAreaDir, stream, step, fromIndexCode);
  printf("     | SxmlSelect -p @2 -p @1    \\\n");
  printf("     |  sort -n   \\\n");
  printf("     | HistoBuildRec  -1 -m 5000 -n car   \\\n");
  printf("     | IndexClusterSetFromHisto -f   %s/Data/%s/%s/%s.t \\\n",  ExplorAreaDir, stream, step, clusterCode);
  printf("     >  %s/Data/%s/%s/%s \n",  ExplorAreaDir, stream, step, clusterCode);

  printf (" echo \"==== \" %s, step %s, Cluster %s done\n", stream, step, clusterCode);
  printf (" cat %s/Data/%s/%s/%s | wc \n", ExplorAreaDir, stream, step, clusterCode);

  printf("<?dilib appendFile=\"%s/bin/area.mk\" ?>\n", ExplorAreaDir );
  printf("# This part is generated by ExplorTools /ExplorGenerShellCluster \n");
  /*
  printf("%s/Make/%s/%s/%s.cluster:  \\\n", ExplorAreaDir, stream, step, clusterCode);
  printf("                %s/Make/%s/%s/%s.assoc \n", ExplorAreaDir, stream, step, fromAssocCode);
  printf("\tsh %s/bin/%s%sCluster%s.sh \n", ExplorAreaDir, ExplorStreamCode, step, clusterCode);
  printf("\ttouch %s/Make/%s/%s/%s.cluster \n\n", ExplorAreaDir, ExplorStreamCode, step, clusterCode);
  */
  printf("$(EXPLOR_AREA)/Make/%s/%s/%s.cluster:  \\\n", stream, step, clusterCode);
  printf("                $(EXPLOR_AREA)/Make/%s/%s/%s.assoc \n", stream, step, fromAssocCode);
  printf("\tsh $(EXPLOR_AREA)/bin/%s%sCluster%s.sh \n", ExplorStreamCode, step, clusterCode);
  printf("\ttouch $(EXPLOR_AREA)/Make/%s/%s/%s.cluster \n\n", ExplorStreamCode, step, clusterCode);
}


StrDict *ExplorParamInit(char *pathParamFile)  /* See also ExplorInit */
{
  char     *tabList;
  char     *areaRootStr;
  
  ExplorTableParam=StrDictFromFile(pathParamFile);
  if (!ExplorTableParam) 
    {
      ExceptSetError("ExplorTools", "NF","File",pathParamFile , " not founded or not fit.",1);
      exit(1);
    }
  ExplorAreaDir=StrDictSearch(ExplorTableParam,"Area/dirPath");
  tabList=StrDictSearch(ExplorTableParam,"Area/listStreams");
  if (!tabList)
    {
      ExceptSetError("ExplorTools", "UN","Parameter", "listStreams" , " not founded or not fit.",1);
      exit(1);
    }
  ExplorListStream=SxmlFromString(tabList);

  if ((tabList=StrDictSearch(ExplorTableParam,"Area/langs")))ExplorListLang=SxmlFromString(tabList);
  else ExplorListLang=NULL;
  ExplorAreaCode=StrDictSearch(ExplorTableParam,"Area/areaCode");
  if ((ExplorSiteLang=StrDictSearch(ExplorTableParam,"lang/Area")));
  else ExplorSiteLang="fr";

  areaRootStr=ExplorGetFromDictK2("Area", "areaTree");
  ExplorAreaTree=SxmlFromString(areaRootStr);
  ExplorAreaData=SxmlGetFirstChildByTagName(ExplorAreaTree,"data");
  ExplorAreaSite=SxmlGetFirstChildByTagName(ExplorAreaTree,"site");
  if (ExplorAreaSite)
    {
      /* ExplorAreaSiteLang=SxmlGetFirstChildByTagName(ExplorAreaSite,"lang"); */
      ExplorAreaSiteLang=SxmlLastChild(ExplorAreaSite);
    }
  ExplorWikiCode=ExplorGetFromDictK2("Area", "wikiCode");
  return ExplorTableParam;
}

void  ExplorParamInitForStream(char *pathParamFile, char *stream)
{
  char *strListSteps;
  ExplorParamInit(pathParamFile);
  ExplorSetDict("#stream", stream);
  strListSteps=ExplorGetFromDictK3("Area", stream, "listSteps");
  ExplorListSteps=SxmlFromString(strListSteps);
  ExplorStreamTreeNode=ExplorSiteTreeNode(stream, NULL, NULL);
}

StrDict *ExplorInit(int mode, char *paramStr)  
/*      mode :
           v: env. var.
           a: area code
           d: dir path
 */
{
  static Buffer *bufPath=NULL;
  char *pathParamFile;
  if (!bufPath)bufPath=NewBuffer();
  ExplorAreaDir=NULL;
  switch (mode)
    {
    case 'v':
      if(paramStr) ExplorAreaDir=getenv(paramStr);
      else ExplorAreaDir=getenv("EXPLOR_AREA");
      break;
    case 'a':
      ExplorAreaDir=paramStr;
      break;
    default:break;
    }
  if(!ExplorAreaDir)
    {
      perror("*** ExplorInit unable to compute ExplorAreaDir ***");
      exit (EXIT_FAILURE);
    }
  if (mode=='a') ExplorAreaCode=paramStr;
  else
    {
      char *lastSlash;
      lastSlash=strrchr(ExplorAreaDir,'/');
      if(!lastSlash) ExplorAreaCode=ExplorAreaDir;
      else ExplorAreaCode=lastSlash+1;
    }
  BufferStrcpy(bufPath, ExplorAreaDir);
  BufferStrcat(bufPath, "/Input/AreaParam.data.tab");
  pathParamFile=BufferString(bufPath);
  ExplorTableParam=StrDictFromFile(pathParamFile);
  if (!ExplorTableParam) 
    {
      ExceptSetError("ExplorTools", "NF","File",pathParamFile , " not founded or not fit.",1);
      exit(EXIT_FAILURE);
    }
  BufferStrcpy(bufPath, ExplorAreaDir);
  BufferStrcat(bufPath, "/Input/AreaDataTree.xml");
  ExplorAreaTree=SxmlFromFile(BufferString(bufPath));
  ExplorAreaData=SxmlGetFirstChildByTagName(ExplorAreaTree,"data");
  ExplorWikiCode=ExplorGetFromDictK2("Area", "wikiCode");
  return ExplorTableParam;
}

void ExplorSaveParamTable(char *base, char *suffix)
{
  char *k;
  char *v;
  printf("<?dilib file=\"%s/Input/%s", ExplorAreaDir, base );
  if (suffix) printf(".%s", suffix);
  printf (".tab\" ?>\n");
  StrDictIteratorReset(ExplorTableParam);
  while ((k=StrDictNext(ExplorTableParam)))
    {
      printf("%s\t%s\n",k, StrDictValue(ExplorTableParam));
    }
}

void ExplorGenerShellCreateData( char *streamCode, SxmlNode *streamListSteps)
{
    SxmlNode *stepNode;
    printf("<?dilib file=\"%s/bin/%sCreateData.sh\" ?>\n", ExplorAreaDir, streamCode );
    printf ("#!/bin/sh\n");
    printf ("\n");
    SxmlReset(streamListSteps);
    while ((stepNode=SxmlNextNode(streamListSteps)))
      {
	char *stepCode;
	stepCode=SxmlLeafText(stepNode);
	printf("sh %s/bin/%sCreate%s.sh \n", ExplorAreaDir, streamCode, stepCode );
      }
}

void ExplorGenerAllShellsIndex(char *streamCode)
{
  char *step;
  SxmlNode *stepNode;
  char *index;
  SxmlNode *stepListIndex;
  SxmlNode *streamListSteps;

  streamListSteps=SxmlFromString(ExplorGetFromDictK3("Area", streamCode, "listSteps"));
  SxmlReset (streamListSteps);
  while ((stepNode=SxmlNextNode(streamListSteps)))
    {
      SxmlNode *stepListIndexes;
      SxmlNode *stepListCross;
      SxmlNode *stepListAssoc;
      SxmlNode *stepListCluster;
      SxmlNode *stepTreeNode;
      SxmlNode *indexNode;

      step=SxmlLeafText(stepNode);
      stepTreeNode=ExplorTreeNode(ExplorAreaData, streamCode, step, NULL);
      SxmlReset(stepTreeNode);
      while ((indexNode=SxmlNextNode(stepTreeNode))&&SxmlNodeHasName(indexNode,"index"))
	{
      /*
      if((stepListIndexes=SxmlFromString(ExplorGetFromDictK4("Area",streamCode, step, "listIndexes"))))
	{
	  SxmlReset (stepListIndexes);
	  while ((indexNode=SxmlNextNode(stepListIndexes)))
	    {
      */
	      char *indexTypeStr;
	      char *indexCode;
	      SxmlNode *indexTypeNode;
	      SxmlNode *nodeType;
	      char *xpath;

	      /* indexCode=SxmlLeafText(indexNode); */
	      indexCode=SxmlGetAttribute(indexNode, "code");
	      indexTypeStr=ExplorGetFromDictK5 ("Area", streamCode, step, indexCode, "indexType");
	      if (!indexTypeStr)
		{
		  indexTypeStr=ExplorGetFromDictK2("indexParamName", indexCode); /* Warnning: patch for Zoom to be improved */
		}
	      indexTypeNode=SxmlFromString(indexTypeStr);
	      if (strcmp(SxmlLeafText(nodeType=SxmlFirstChild(indexTypeNode)), "xpath")==0)
		{
		  xpath=SxmlLeafText(SxmlNextSibling(nodeType));
		  ExplorGenerShellIndexPath(ExplorStreamCode, step, indexCode, xpath);
		}
	      if (strcmp(SxmlLeafText(nodeType=SxmlFirstChild(indexTypeNode)), "sxPath")==0)
		{
		  xpath=SxmlLeafText(SxmlNextSibling(nodeType));
		  ExplorGenerShellIndexSxPath(ExplorStreamCode, step, indexCode, xpath);
		}
	      else if (strcmp(SxmlLeafText(nodeType=SxmlFirstChild(indexTypeNode)), "shell")==0)
		{
		  ExplorGenerShellIndexShell(ExplorStreamCode, step, indexCode, indexTypeNode);
		}
	      else if (strcmp(SxmlLeafText(nodeType=SxmlFirstChild(indexTypeNode)), "make")==0)
		{
		  ExplorGenerShellIndexMake(ExplorStreamCode, step, indexCode, indexTypeNode);
		}
	      /*   } */
	}
      if((stepListCross=SxmlFromString(ExplorGetFromDictK4("Area",streamCode, step, "listCross"))))
	{
	  SxmlNode *crossNode;
	  SxmlReset (stepListCross);
	  while ((crossNode=SxmlNextNode(stepListCross)))
	    {
	      char *crossCode;
	      crossCode=SxmlLeafText(crossNode);
	      ExplorGenerShellCross(streamCode, step, crossCode);
	    }
	}
      if((stepListAssoc=SxmlFromString(ExplorGetFromDictK4("Area",streamCode, step, "listAssoc"))))
	{
	  SxmlNode *assocNode;
	  SxmlReset (stepListAssoc);
	  while ((assocNode=SxmlNextNode(stepListAssoc)))
	    {
	      char *assocCode;
	      assocCode=SxmlLeafText(assocNode);
	      ExplorGenerShellAssoc(streamCode, step, assocCode);
	    }
	}
      if((stepListCluster=SxmlFromString(ExplorGetFromDictK4("Area",streamCode, step, "listCluster"))))
	{
	  SxmlNode *clusterNode;
	  SxmlReset (stepListCluster);
	  while ((clusterNode=SxmlNextNode(stepListCluster)))
	    {
	      char *clusterCode;
	      clusterCode=SxmlLeafText(clusterNode);
	      ExplorGenerShellCluster(streamCode, step, clusterCode);
	    }
	}
 
    }
}

SxmlDocumentReader *ExplorSortReader=NULL;
