/*   -*- coding: utf-8 -*-  */
/******************************************************************************
*
* Module    : Hfd
* Fichier   : HfdFile.c
* Auteur    : Ducloy
*
****************************************************************************
*/

#include "Hfd.h"
#include "RegExp.h"
#include "Except.h"

#include "SxmlNode.h"



HfdFile* HfdFileCreate()
{
  HfdFile* file;
  file = (HfdFile *)malloc(sizeof(HfdFile));
  file->record=HfdRecordCreate(100,100);
  file->pathSize=0;
  file->isUnixOpen=0;

  return file;
}

void HfdFileClose(HfdFile *file)
{
  if(file->isUnixOpen)
    {
      fclose(file->stream);
      file->isUnixOpen=0;
    }
}

void HfdFileFree(HfdFile *file)
{
  if(file)
    {
      HfdFileClose(file);
      if (file->path)free (file->path);
      if (file->record) HfdRecordFree(file->record);
      free(file);
    }
}

HfdFile *HfdFileOpen(HfdFile *file, char *path)
{
  int len;

  file->isContOpen=0;
  file->isContSign=0;
  if(file->isUnixOpen)HfdFileClose(file);
  
  if ((file->stream=fopen(path,"r")))
    {
      file->isUnixOpen=1;
      len=strlen(path);
      if (file->pathSize<len)
	{
          if (file->pathSize) free(file->path);
	  file->path = (char *)malloc((len+1)*sizeof(char));
	  file->pathSize=len;
	}
      strcpy(file->path, path);
      HfdRecordInit(file->record);
      return file;
    }
  else return NULL;
}

/**************** lecture de  HfdRecord(s) *************************/

HfdRecord *HfdFileNextHfdRecord(file)
     HfdFile *file;
{  
  HfdRecord *record;

  if(file->isContOpen)file->isContSign=0;
  if((record=HfdRecordFgets(file->record,file->stream)))
    {
      return record;
    }
  else    /* pb lecture => EOF probable */
    {
      file->errCode=HfdEOF;
      return (NULL);
    }
}

HfdRecord *HfdFileGetRecordKeyForward(file,key)
     HfdFile *file;
     char *key;
{
  HfdRecord *record;
  int cond;

  while ((record=HfdFileNextHfdRecord(file)))
    {
      cond=strcmp(key,HfdRecordKey(record));
      if (cond==0) return record;
      if (cond<0) return NULL;
    };
  return NULL;
}

HfdRecord *HfdFileGetRecordKey(HfdFile *file, char *key)
{
  int cond;
  char *k;
  if((k=HfdFileKey(file)))
    {
      cond = strcmp(key,k);
      if (cond==0) return file->record;
      if (cond>0) return HfdFileGetRecordKeyForward(file,key);
      rewind (file->stream);
      return HfdFileGetRecordKeyForward(file,key);
    }
  else return HfdFileGetRecordKeyForward(file,key);
}

/************************************ HfdFileNextSxml **********************/

SxmlNode* HfdFileNextSxml(file)
     HfdFile *file;
{
  SxmlNode *recSxml;
  HfdRecord *record;

  if ((record = HfdFileNextHfdRecord(file)))
    {
      if((recSxml=HfdRecordToSxml(record))) return SxmlLastChild(recSxml);
    }
  return NULL;
}

SxmlNode* HfdFileNextSxmlRecord(file)
     HfdFile *file;
{
  HfdRecord *record;
  if ((record = HfdFileNextHfdRecord(file)))
    {
      return HfdRecordToSxml(record);
    }
  return NULL;
}

SxmlNode* HfdFileGetSxmlKey(file, k)
     HfdFile *file;
     char *k;
{
  HfdRecord *record;
  SxmlNode *recSxml;
  if ((record = HfdFileGetRecordKey(file,k)))
    {
      if((recSxml=HfdRecordToSxml(record))) return SxmlLastChild(recSxml);
    }
  return NULL;
}

void HfdFileSetRecordTag( HfdFile *file, char *t1)
{
  file->record->tag=t1;
}

HfdFile *HfdFileOpenReadCont(HfdFile *file, char *path)
{
  if (HfdFileOpen(file, path))
    {
      file->isContOpen=1;
      return file;
    }
  return NULL;
}

char *SgmlStrGetLeaf(char *s1, char *tag);
char *HfdRecordSeekContent(record)
     HfdRecord *record;
{
  char *str;
  if(record)
    {
      /* To be improved with rerwritng SgmlStrGetLeaf  */
      if ((str=SgmlStrGetLeaf(BufferString(record->bufferInput), record->tag)))
	{
	  BufferStrcpy(record->content,str);
	  return BufferString(record->content);
	}
      else return NULL;
    }
  else return NULL;
}



HfdRecord *HfdFileGetRecordContForward(file,cont)
     HfdFile *file;
     char    *cont;
{
  HfdRecord *record;
  char       *tag;
  char       *curCont;
  int         cmpCode;

  file->isContSign=0;
  tag=file->record->tag;
  while ((record=HfdFileNextHfdRecord(file)))
    {
      if ((curCont=HfdRecordSeekContent(file->record)))
	{
	  cmpCode=strcmp(curCont,cont);
	  if(cmpCode==0)
	    {
	      file->isContSign=1;
	      return record;
	    }
	  if(cmpCode>0)return NULL;
	}
    };
  return NULL;
}

HfdRecord *HfdFileGetRecordCont(HfdFile *file, char    *cont)
{
  int cond;

  if(file->isContSign)
    {
      cond=strcmp(cont, BufferString(file->record->content));
      if (cond==0) return file->record;
      if (cond>0) return HfdFileGetRecordContForward(file, cont);
      rewind (file->stream);
      return HfdFileGetRecordContForward(file, cont);
    }
  else
    {
      rewind (file->stream);
      return HfdFileGetRecordContForward(file, cont);
    }
}

SxmlNode *HfdFileGetSxmlRecordCont(HfdFile *file, char    *cont)
{
  HfdRecord *r1;
  if((r1=HfdFileGetRecordCont(file,cont)))
    {
      return HfdRecordToSxml(r1);
    }
  else return NULL;
}


SxmlNode *HfdFileGetSxmlCont(HfdFile *file, char    *cont)
{
  SxmlNode *n1;
  if((n1=HfdFileGetSxmlRecordCont(file,cont)))
    {
      return SxmlLastChild(n1);
    }
  else return NULL;
}
