/**********************************************************************
*
*  projet   : DilibPro
*  module   : Dam  (Dilib Acces Method)
*  fichier  : DamHfdIter.c
*  Auteur   : Jacques DUCLOY
*  Date     : Fevrier 94
*  $Id: DamHfdIter.c,v 1.3 2005/06/22 12:46:16 parmentf Exp $
*
***********************************************************************
* 
*     Copyright (C) 1995 CRIN - CNRS & INRIA Lorraine
*
***********************************************************************/

#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>

#include "StrSearch.h"
#include "DamHfd.h"

DamHfdIterator *DamHfdIteratorCreate()
{
  DamHfdIterator *iter;
  iter=(DamHfdIterator *) malloc(sizeof(DamHfdIterator));
  iter->table=StrSearchTableCreate(100,100);
  iter->filePathLenght=0;
  iter->subDir=NULL;
  iter->isMultiGroup=0;
  iter->hcs=NULL;
  iter->filePath=NULL;
  return iter;
}

void DamHfdIteratorFree(DamHfdIterator *iter)
{
  if(iter->isMultiGroup)BufferFree(iter->multiBegin);
  StrSearchTableFreeKey(iter->table);
  if(iter->hcs)SgmlFree (iter->hcs);
  if(iter->filePath)free(iter->filePath);
  if(iter->subDir)DamHfdIteratorFree(iter->subDir);
  free(iter);
}

DamHfdIterator *DamHfdIteratorInit(DamHfdIterator *hfdIter, char *dirName)
{
  DIR *dir;
  struct dirent *entry;
  char *entryName;
  int l;
  int lmax;

  lmax=0;

  
  StrSearchTableReset (hfdIter->table);
  hfdIter->currentDir=dirName;
  hfdIter->isMultiGroup=0;
  if (strcmp((dirName+strlen(dirName)-4),".hfd")==0)
    {
      char *fName;
      char *type;
      fName=strdup(dirName);
      fName[strlen(dirName)-1]='s';
      fName[strlen(dirName)-2]='c';
      hfdIter->hcs=SgmlFromFile(fName);
      if((type=SgmlGetAttValById(hfdIter->hcs,"type"))
	 &&(strcmp(type,"group")==0)
	 )
	{
	  hfdIter->isMultiGroup=1;
	  hfdIter->multiBegin=BufferCreate(10,10);
	}
    }
  dir = opendir(dirName);

/*
 construction d'une table triee des fichiers constituant un niveau de HFD
 */

  while ((entry=readdir(dir)))
    {
      l=strlen(entry->d_name);
      entryName=malloc(l+1);
      strcpy(entryName,entry->d_name);
      if (l>lmax) lmax=l;
      if (DamNameIsDir(entryName))
	StrSearchAdd(hfdIter->table,entryName,"D");
      else 
	{
	  if (DamNameIsFile(entryName))
	    StrSearchAdd(hfdIter->table,entryName,"F");
	  else free(entryName);
        }
    };

  closedir(dir);
  
  lmax+=strlen(dirName)+1+1;
  if(hfdIter->filePathLenght<lmax)
    {
      if(hfdIter->filePathLenght)free (hfdIter->filePath);
      hfdIter->filePath=malloc(lmax);
      hfdIter->filePathLenght=lmax;
    }
  StrSearchIteratorReset(hfdIter->table);
  hfdIter->subDirExploring=0;

  return hfdIter;
}

char *DamHfdNextFilePath(DamHfdIterator *hfdIter)
{
  char *nameFile;
  char *typeFile;
  if (hfdIter->subDirExploring)
    {
      if((nameFile=DamHfdNextFilePath(hfdIter->subDir)))
	return nameFile;
      else hfdIter->subDirExploring=0;
    }
  nameFile=StrSearchNext(hfdIter->table);
  if (nameFile)
    {
      typeFile=StrSearchValue(hfdIter->table);
      strcpy(hfdIter->filePath,hfdIter->currentDir);
      strcat(hfdIter->filePath,"/");
      strcat(hfdIter->filePath,nameFile);
      if (hfdIter->isMultiGroup)
	{
	  BufferStrcpy(hfdIter->multiBegin,nameFile);
	  BufferTailCut(hfdIter->multiBegin,3);
	}
      if (typeFile[0]=='F') return hfdIter->filePath;
      if (!hfdIter->subDir)hfdIter->subDir=DamHfdIteratorCreate();
      hfdIter->subDirExploring=1;
      DamHfdIteratorInit(hfdIter->subDir, hfdIter->filePath);
      return DamHfdNextFilePath(hfdIter->subDir);
    }
  else return NULL;
}
