/****************************************************************************
*
*      Module  : SxmlNode
*      Fichier : SxmlRecord.c
*      Auteur  : J. Ducloy
*
*      Derniere mise a jour Decembre 2000
*
************************************************************************
* 
*     Copyrigth (C) 2001 CNRS INIST
*
****************************************************************************/

#include "Buffer.h"
#include "SxmlNode.h"
#include "Except.h"
SxmlRecordReader   *SxmlStdinRecordReader=NULL;
SxmlRecord         *SxmlStdinRecord;
SxmlDocument       *SxmlInputDocument;
SxmlNode           *SxmlInputDocumentElement;
char               *SxmlInputRecordKey=NULL;

SxmlRecordReader *SxmlStdinRecordReaderCreate()
{
  SxmlStdinRecordReader=SxmlRecordReaderCreate();
  SxmlRecordReaderSetFile(SxmlStdinRecordReader,stdin);
  SxmlStdinRecord=NULL;
  return SxmlStdinRecordReader;
}

SxmlRecord *SxmlStdinGetRecord()           /*  and SxmlInputGetRecord() ; ex SxmlStdinNextRecord() */
{
  if(!SxmlStdinRecordReader)SxmlStdinRecordReaderCreate();
  if ((SxmlStdinRecord=SxmlRecordReaderGets(SxmlStdinRecordReader)))
    {
      SxmlInputDocument=SxmlLastChild(SxmlStdinRecord);
      SxmlInputDocumentElement=SxmlLastChild(SxmlInputDocument);
      SxmlInputRecordKey=SxmlRecordKeyString(SxmlStdinRecord);
    }
  else
    {
      SxmlInputDocumentElement=NULL;
      SxmlInputDocument=NULL;
      SxmlInputRecordKey=NULL;
    }
  return  SxmlStdinRecord;
}

SxmlNode *SxmlInputGetRecordLastItem()
{
  if(SxmlInputGetRecord())
    {
      return (SxmlFirstChild(SxmlLastChild(SxmlInputRecord)));
    }
  return NULL;
}

SxmlNode *SxmlRecordCreate()
{
  SxmlNode *r1;
  r1=SxmlNodeCreate(XML_NODE_RECORD);
  SxmlSetNodeName(r1,"#record");
  return r1;
}

void SxmlRecordFilePrint(SxmlNode *r1, FILE *f1)
{
  SxmlNode *e1;
  SxmlReset(r1);
  while((e1=SxmlNextNode(r1)))
    {
      SxmlFilePrint(e1,f1);
      if(SxmlNextSibling(e1))fprintf(f1,"\t");
    }
  fprintf(f1,"\n");
}

char *SxmlRecordToString(b1,r1)
     Buffer *b1;
     SxmlRecord *r1;
{
  SxmlNode *e1;
  SxmlReset(r1);
  while((e1=SxmlNextNode(r1)))
    {
      SxmlToStringRecursive(b1,e1);
      if(SxmlNextSibling(e1))BufferStrcat(b1,"\t");
    }
  BufferStrcat(b1,"\n");
  return BufferString(b1);
}

SxmlRecordReader *SxmlRecordReaderCreate()
{
  SxmlRecordReader *r1;
  SxmlNode *rc1;
  r1=SxmlElementCreate("#recordReader");
  SxmlAppendChild(r1,SxmlDocumentReaderCreate());
  rc1=SxmlContainerCreate('S');
  SxmlSetNodeName(rc1,"#recordPointer");
  SxmlAppendChild(r1,rc1);
  return r1;  
}

SxmlNode *SxmlRecordReaderOpen(SxmlNode *x1, char *fn1)  /* fn1 = file name */
{
  return SxmlDocumentReaderOpen(SxmlFirstChild(x1),fn1);
}

void SxmlRecordReaderClose(rr1)
     SxmlNode *rr1;
{
  SxmlDocumentReaderClose(SxmlFirstChild(rr1));
}

SxmlNode *SxmlRecordCreateFromReader(x1)
     SxmlNode *x1;
{
  SxmlNode *rec1;
  SxmlNode *doc1;
  rec1=SxmlRecordCreate();
  while((doc1=SxmlDocumentCreateFromReader(SxmlFirstChild(x1))))
    {
      SxmlNode *dFragment;
      switch(SxmlNodeType(doc1))
	{
	case XML_NODE_TEXT:
	  if (SxmlNodeHasValue(doc1,"\n"))
	    {
	      SxmlFree(doc1);
	      return rec1;
	    }
	  dFragment=SxmlDocumentFragmentCreate();
	  SxmlAppendChild(dFragment,doc1);
	  SxmlAppendChild(rec1,dFragment);
	  continue;
	default:
	  SxmlAppendChild(rec1,doc1);
	  continue;
	}
    }
  if (SxmlFirstChild(rec1))return rec1;
  SxmlFree(rec1);
  return NULL;
}

SxmlNode *SxmlRecordUnparsedCreateFromReader(x1)
     SxmlNode *x1;
{
  SxmlNode *rec1;
  SxmlNode *doc1;
  rec1=SxmlRecordCreate();
  while((doc1=SxmlDocumentUnparsedCreateFromReader(SxmlFirstChild(x1))))
    {
      switch(SxmlNodeType(doc1))
	{
	case XML_NODE_TEXT:
	  if (SxmlNodeHasValue(doc1,"\n"))
	    {
	      SxmlFree(doc1);
	      return rec1;
	    }
	  ExceptSetError("SxmlRecordUnParsed","IE","Internal Error","","",2);
	  continue;
	default:
	  SxmlAppendChild(rec1,doc1);
	  continue;
	}
    }
  if (SxmlFirstChild(rec1))return rec1;
  SxmlFree(rec1);
  return NULL;
}

SxmlNode *SxmlRecordReaderGets(SxmlRecordReader *rr1)
{
  SxmlNode *rc1;
  SxmlNode *oldRec;
  SxmlNode *newRec;
  rc1=SxmlNextSibling(SxmlFirstChild(rr1));
  if((oldRec=(SxmlNode *)SxmlNodeValue(rc1)))
    {
      SxmlFree(oldRec);
      SxmlNodeValue(rc1)=NULL; 
    }
  if((newRec=SxmlRecordCreateFromReader(rr1)))
    {
      SxmlSetNodeValue(rc1,(char *)newRec);
      SxmlSetNodeValueToFree(rc1);
    }
  /*else 
    {
        SxmlSetNodeNameToFree(rc1); 
    }*/
  return newRec;
}

SxmlNode *SxmlRecordReaderSetFile(x1,f1)
     SxmlNode *x1;
     FILE *f1;
{
  return SxmlDocumentReaderSetFile(SxmlFirstChild(x1),f1);
}

char *SxmlRecordKeyString(SxmlRecord *r1)
{
  SxmlNode *keyNode;
  if (!(SxmlNodeType(r1)==XML_NODE_RECORD))return NULL;
  if (!(keyNode=SxmlFirstChild(r1))) return NULL;
  if (!(SxmlNextSibling(keyNode)))return NULL;
  return((SxmlNodeValue(SxmlFirstChild(keyNode))));
}

char *SxmlRecordDocumentStr=NULL;

char *SxmlRecordDocumentString(r1)
     SxmlNode *r1;
{
  SxmlNode *doc;
  if (!(SxmlNodeType(r1)==XML_NODE_RECORD))return NULL;
  doc=SxmlLastChild(r1);
  if (SxmlParsed(doc))
    {
      if(SxmlRecordDocumentStr)free (SxmlRecordDocumentStr);
      SxmlRecordDocumentStr=SxmlToString(doc);
      return SxmlRecordDocumentStr;
    }
  else
    {
      return((SxmlNodeValue(SxmlFirstChild(doc))));
    }
}

