/*   -*- coding: utf-8 -*-  */
/**********************************************************************
*
*  module   : Hfd 
*  fichier  : HfdHcb.h
*  Auteur   : Jacques DUCLOY
*  Date     : Octobre 93
*
***********************************************************************/
#ifndef _HFD_HCB_H_
#define _HFD_HCB_H_

#include "StrDict.h"
#include "HfdRecord.h"

#define HfdEOF   1


struct HfdFile_Struct
{
  unsigned int errCode        :4;
  unsigned int isUnixOpen     :1;
  unsigned int isContOpen     :1;
  unsigned int isContSign     :1;

  FILE        *stream;
  char        *path;
  int          pathSize;
  HfdRecord   *record;
};

typedef struct HfdFile_Struct HfdFile;


/*

 Ces fonctions sont simplement translatées de DanHfd.h Dilib 0.2 pour permettre une manipulation des Hfd en Sxml


 Les principaux objets :

        HCB (HfdHcb) -> Hfd Control Bloc 
	
	Digit        (HfdHcb_Digit)       
                      controleur d'itération sur un digit
	ListDigit    (HfdHcb_ListDigit)
                     controleur d'iterarion pour une liste de digits
	PathUnit     (HfdHcb_PathUnit)
                     controleur associé à un niveau de pathname
	ListPathUnit (HfdHcb_ListPathUnit)
                     controleur associé à un pathname
        Dir          (HfdHcb_Dir)
                     controleur associé à un directory
        ListDir      (HfdHcb_ListDir)
                     controleur associé à une liste de directories

***************************************************************************/


/************************************** Digit **********************/

struct HfdHcbDigit_Struct
{
  char *initString;
  char *curPos;
  struct HfdHcbDigit_Struct *prev;
  struct HfdHcbDigit_Struct *next;
};

typedef struct HfdHcbDigit_Struct HfdHcbDigit;

/************************************* ListDigit ********************/

struct HfdHcbListDigit_Struct
{
  HfdHcbDigit *first;
  HfdHcbDigit *last;
  char         *profile;
  int          card;
};

typedef struct HfdHcbListDigit_Struct HfdHcbListDigit;

/******************************* PathUnit ************************/

struct HfdHcbPathUnit_Struct
{
  HfdHcbListDigit *listDigit;
  char             state ; /* O:open, C: close, \0 null */
  char             *path;
  char             *pathSuffix;
  char             *key;
  struct HfdHcbPathUnit_Struct *prev;
  struct HfdHcbPathUnit_Struct *next;
};

typedef struct HfdHcbPathUnit_Struct HfdHcbPathUnit;

/******************************* HCB_ListPathUnit ************************/

struct HfdHcbListPathUnit_Struct
{
  int                     pathLength;
  int                     keyLength;
  HfdHcbPathUnit         *first;
  HfdHcbPathUnit         *last;  
};

typedef struct HfdHcbListPathUnit_Struct HfdHcbListPathUnit;

/************************************ HCB_Dir ****************************/

struct HfdHcbDir_Struct
{
  struct HfdHcbDir_Struct *prev;
  struct HfdHcbDir_Struct *next;
  HfdHcbPathUnit          *pathDigit;
};

typedef struct HfdHcbDir_Struct HfdHcbDir ;

/******************************* HCB_ListDir *****************************/

struct HfdHcbListDir_Struct
{
  HfdHcbDir         *first;
  HfdHcbDir         *last;  
};

typedef struct HfdHcbListDir_Struct HfdHcbListDir;

/************************** HCB : HfdControlBloc ****************************/

struct HfdHcb_Struct
{
  char                *name;            /* nom du hfd (sans suffixe)        */
  SxmlNode            *desc;            /* descripteur SGML du HCB          */
  char                *descFile;        /* fichier contenant le HCB SGML    */
  char                *rootPath;        /* directory racine du hfd          */
  HfdHcbListPathUnit  *listPathUnit;    /* liste des pathUnit               */
  HfdHcbListDir       *listDir;         /* liste des directory */
  char                *dirKey;          /* partie de la cle associee aux dir */
  HfdHcbPathUnit      *filePathUnit;    /* */
  HfdHcbPathUnit      *recordPathUnit;  /* */
  char                *pathNameBuffer;
  char                *currentPath;
  int                  umask;
  FILE                *file; 
  char                *fileKey;
  char                *key;             /* cle courante */
  char                *regKey;          /* buffer pour operations sur cle */
  HfdFile             *hfdFile;
  Buffer              *wBuf;            /* Buffer de travail */
  unsigned int         isRunning :1;
};

typedef struct HfdHcb_Struct HfdHcb;

/***************************************************************************/

#define HfdHcbLastKey(hcb) hcb->recordPathUnit->key
#define HfdHcbDesc(x)       x->desc
#define HfdHcbRootPath(x)  x->rootPath
#define HfdHcbPathNameSize(x) x->listPathUnit->pathLength

/****************************************************************************/

char   *HfdHcbGetPath(HfdHcb*, char*);
HfdHcb *HfdHcbCreate();
#define HfdHcbFile(hcb) hcb->file
char   *HfdHcbRecordPathNextKey();
void    HfdHcbPrint(HfdHcb *h);
void    HfdHcbFree(HfdHcb *h);
char   *HfdHcbListDirFirstDir(HfdHcb* hcb);
void    HfdHcbFilePathFirstFile(HfdHcb* hcb);
char   *HfdHcbRecordPathFirstKey();
/*
           Fonctions  importées / translatées de DamTool.h 
 */

/****************** quelques macros sur string *****************/

#define HfdToolStrCopy(s1,s2)           \
{                                \
   s1=malloc(strlen(s2)+1);      \
   strcpy (s1,s2);               \
 }

#define HfdToolStrCat2(r,s1,s2)                   \
{                                          \
   r=malloc(strlen(s1)+strlen(s2)+1);      \
   strcpy(r,s1); strcat(r,s2);             \
}

/*************** fonctions/macros sur les listes **************************/
/*
   ces fonctions supposent que la tete contient 2 pointeurs first et last,
   et chaque element 2 pointeurs next et prev
*/

#define HfdToolListPrevNextInsert(list,elem)                   \
{                                                       \
       if (list->first)                                 \
	 {                                              \
	   elem->prev=list->last;                       \
	   list->last->next=elem;                       \
	 }                                              \
       else                                             \
	 {                                              \
	   elem->prev=NULL;                             \
	   list->first=elem;                            \
	 }                                              \
       list->last=elem;                                 \
       elem->next=NULL;                                 \
}




#endif /* _HFD_HCB_H_ */

