/***********************************************************************
*
*      Projet  : DilibPro
*      Module  : Sgml
*      Fichier : SgmlNodeTree.c
*      Auteur  : J. Ducloy
*      Origine : J. Ducloy + V. Warth
*
*      Derniere mise a jour Décembre 96
************************************************************************
*
* Copyright (c) 1996 CNRS/CRIN & INRIA Lorraine
* 
************************************************************************/

#include "SgmlNodePrivate.h"

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


/****************************************************************************
*
*   Les fonctions d'ajout dans l'arbre
*
******************************************************************************/
/*-------------------------------------------------------------------------
 *                              SgmlAddLast
 *
 * - Les paramètres :
 *		- pere : pointeur sur le noeud "père"
 *		- fils : pointeur sur le nouveau "fils"
 *
 * - Valeur retournée : pointeur sur le fils 
 -----------------------------------------------------------------------*/

SgmlNode	*SgmlAddLast(SgmlNode *Pere , SgmlNode *Fils)   /* -> fils */
{
  SgmlNode	*frere;
  if (Pere)
    {
      if (Pere->subType=='E')
	{
	  Pere->subType='S';
	  SgmlNodeFormat(Pere)= SgmlNodeFormatMark;
	}
      if (Fils)
	{
	  SgmlFather(Fils) = Pere;
	  if ( SgmlFirst(Pere) == NULL )
	    {
	      SgmlFirst(Pere) = Fils;
	      SgmlLast(Pere) = Fils;
	    }
	  else 
	    {
	      frere = SgmlLast(Pere);
	      SgmlLast(Pere) = Fils;
	      SgmlNext(frere) = Fils;
	      SgmlPrevious(Fils) = frere;
	    };
	}
    }
  else return(NULL);

  return (Fils);
} /* end SgmlAddLast */

/****************************************************************************** 
 *                     SgmlInsertAfter

 ******************************************************************************/
SgmlNode  *SgmlInsertAfter(
          SgmlNode *n1,   /* point d'insertion */
          SgmlNode *n2)   /* noeud a inserer   */
{
      SgmlNode *pere;
      SgmlNode *FrereSuivant;

      if(!n1)return (NULL);
      if(!n2)return (NULL);

      pere = SgmlFather(n1);
      FrereSuivant = SgmlNext(n1);
     

      SgmlFather(n2)=pere;
      if(!FrereSuivant)
              {
              if (pere) SgmlAddLast(pere,n2);
              else {SgmlPrevious(n2)=n1;SgmlNext(n1)=n2;SgmlNext(n2)=NULL;}
              }
      else {          
              SgmlNext(n2)=FrereSuivant; SgmlPrevious(FrereSuivant)=n2;
              SgmlPrevious(n2)=n1;SgmlNext(n1)=n2;
           }

      return(n2);
}

/****************************************************************************** 
 *                     SgmlInsertBefore
 *
 *
 ******************************************************************************/
SgmlNode  *SgmlInsertBefore(
          SgmlNode *n1,   /* point d'insertion */
          SgmlNode *n2)   /* noeud a inserer   */
{
      SgmlNode *pere;
      SgmlNode *FrerePrecedant;

      if(!n1)return (NULL);
      if(!n2)return (NULL);

      pere = SgmlFather(n1);
      FrerePrecedant = SgmlPrevious(n1);
     

      SgmlFather(n2)=pere;
      if(!FrerePrecedant)
              {
              if (pere)SgmlFirst(pere)=n2;
              SgmlPrevious(n1)=n2;
              SgmlNext(n2)=n1;
              SgmlPrevious(n2)=NULL;
              }
      else {          
              SgmlPrevious(n2)=FrerePrecedant; SgmlNext(FrerePrecedant)=n2;
              SgmlNext(n2)=n1;SgmlPrevious(n1)=n2;
           }

      return(n2);
}

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

     SgmlAddFirst

****************************************************************************/
SgmlNode *SgmlAddFirst(SgmlNode *np, SgmlNode *ns)
{
  SgmlNode *fils;

  if ((fils=SgmlFirst(np))) SgmlInsertBefore(fils, ns);
  else SgmlAddLast(np, ns);
  return (ns);
}

/***********************************************************************
*
*      fonction SgmlCard(n1)
*
***********************************************************************/
int SgmlCard(SgmlNode *n1)
{
  SgmlNode *n2;
  int i1;
  if (n1)
    {
      if ((n2=SgmlFirst(n1)))
	{
	  i1=1;
	  while((n2=SgmlNext(n2))) i1++;
	  return i1;
	}
      else return 0;
    }
  else return 0;
}

char *SgmlCardStr(SgmlNode *n1)
{
  int card1;
  static char *bufConv=NULL;
  if(!bufConv)bufConv=malloc(10);
  card1=SgmlCard(n1);
  sprintf(bufConv, "%d", card1);
  return bufConv;
}

/***********************************************************************
*
*      fonction SgmlGetSonNumber(p, n)
*
***********************************************************************/
SgmlNode *SgmlGetSonNumber(SgmlNode *pere, int n)
{
  int i;

  SgmlNode *fils;
  if(!pere)return(NULL);
  if(!(fils=SgmlFirst(pere)))return (NULL);
  i=0;
  while(i++<n)
    {
      if (i==n) return (fils);
      if ((fils=SgmlNext(fils)))
	continue;
      else return (NULL);
    }
  return (NULL);
}

