/******************************************************************************
*				     SgmlSearch.c 
*
*  - contient des fonctions de recherche
*    dans l'arbre.
*
****************************************************************************
*
* Copyright (c) 1995 CNRS/CRIN & INRIA Lorraine
* 
*******************************************************************************/
#include "SgmlNode.h"
#include <string.h>
#include <stdio.h>

/************************************************************************
*                     SgmlGetNextGid
*  retourne le premier frere contenant le Gid passe en parametre
*
*
*
**********************************************************************/
SgmlNode *SgmlGetNextGid(Mark,Gid)
      SgmlNode *Mark;
      char *Gid;
{
      SgmlNode *next;

      if ( !Mark ) return(NULL);

      next = SgmlNext(Mark);
      if ( !next ) return (NULL);

      if ( strcmp (SgmlTag(next),Gid)==0) return (next);

      return (SgmlGetNextGid(next,Gid));
}

/************************************************************************
*                     SgmlGetPreviousTag
*  retourne le frere precedent contenant le tag
*
*
*
**********************************************************************/

SgmlNode *SgmlGetPreviousTag(Mark,Gid)
      SgmlNode *Mark;
      char *Gid;
{
      SgmlNode *prev;

      if ( !Mark ) return(NULL);

      prev = SgmlPrevious(Mark);
      if ( !prev ) return (NULL);

      if ( strcmp (SgmlTag(prev),Gid)==0) return (prev);

      return (SgmlGetPreviousTag(prev,Gid));
}



/************************************************************************
*                     SgmlGetSonTag
*  retourne le premier fils contenant le Gid passe en parametre
*
*
*
**********************************************************************/
SgmlNode *SgmlGetSonTag(Mark,Gid)
      SgmlNode *Mark;
      char *Gid;
{
      SgmlNode *fils;

      if ( !Mark ) return(NULL);

      fils = SgmlFirst(Mark);
      if ( !fils ) return (NULL);

      if ( strcmp (SgmlTag(fils),Gid)==0) return (fils);

      return (SgmlGetNextGid(fils,Gid));
}

/************************************************************************
*                     SgmlLastChildTag
*  retourne le premier fils contenant le Gid passe en parametre
*
*
*
**********************************************************************/
SgmlNode *SgmlLastChildTag(Mark,Gid)
      SgmlNode *Mark;
      char *Gid;
{
      SgmlNode *fils;

      if ( !Mark ) return(NULL);

      fils = SgmlLast(Mark);
      if ( !fils ) return (NULL);

      if ( strcmp (SgmlTag(fils),Gid)==0) return (fils);

      return (SgmlGetPreviousTag(fils,Gid));
}

/**********************************************************************
                 SgmlGetSonTagCreater
		 retourne le premier fils dont le tag est superieur au 
		 parametre

**********************************************************************/
SgmlNode *SgmlGetSonTagGreater(mark,tag)
      SgmlNode *mark;
      char *tag;
{
      SgmlNode *fils;

      if ( !mark ) return(NULL);
      fils = SgmlFirst(mark);
      if ( !fils ) return (NULL);
      do { if ( strcmp (SgmlTag(fils),tag)>0) return (fils); }
      while ((fils=SgmlNext(fils)));
      return (NULL);
}


/*************************************************************************
*   SgmlGetFirstData
*  retourne la premiere chaine rencontree dans la structure SGML
*
*
*****************************************************************************/
char *SgmlGetFirstData(Mark)
    SgmlNode *Mark;
  
{
    if ( !Mark )             return (NULL);
    if ( SgmlTypeData(Mark) ) return (SgmlDataString(Mark));
    if ( SgmlFirst(Mark) )    return (SgmlGetFirstData(SgmlFirst(Mark)));
    if ( SgmlNext(Mark) )     return (SgmlGetFirstData(SgmlNext(Mark)));
    return (NULL);
}
/*************************************************************************
*   SgmlRepOrNextFirstData
*   remplace la premiere chaine rencontree dans la structure SGML
*
*
*****************************************************************************/
SgmlNode *SgmlRepFirstOrNextData(Mark,str)
    SgmlNode *Mark;
     char *str;
  
{
    if ( !Mark )              return (NULL);
    if ( SgmlIsData(Mark) ) 
      {
	SgmlDataPutString(Mark,str);
	return Mark;
      }
    if ( SgmlFirst(Mark) )
      {
	if (SgmlRepFirstOrNextData(SgmlFirst(Mark),str)) return Mark;
      }
    if ( SgmlNext(Mark) ) 
      {
	if (SgmlRepFirstOrNextData(SgmlNext(Mark),str)) return Mark;
      }
    return (NULL);
}
/*************************************************************************
*   SgmlRepFirstData
*   remplace la premiere chaine rencontree dans la structure SGML
*
*****************************************************************************/
SgmlNode *SgmlRepFirstData(Mark,str)
    SgmlNode *Mark;
     char *str;
  
{
    if ( !Mark )              return (NULL);
    if ( SgmlIsData(Mark) ) 
      {
	SgmlDataPutString(Mark,str);
	return Mark;
      }
    if ( SgmlFirst(Mark) )
      {
	if (SgmlRepFirstOrNextData(SgmlFirst(Mark),str)) return Mark;
      }
    return (NULL);
}


/*************************************************************************
*   SgmlGetFirstDataByGid
*  retourne la premiere chaine 
*          directement taggee par Gid
*          rencontree dans la structure SGML
*
*
*****************************************************************************/
char *SgmlGetFirstDataByGid(Mark, Gid)
    SgmlNode *Mark;
    char *Gid;
  
{
    SgmlNode *Ndata;

    if ( !Mark )             return (NULL);
    if ( SgmlTypeData(Mark) ) return (NULL);
    if ( strcmp (Gid, SgmlTag(Mark))==0)
       { Ndata = SgmlFirst (Mark);
         if(!Ndata)return(NULL);
         if (SgmlTypeData(Ndata)) return (SgmlDataString(Ndata));
         return (NULL);
       }

    if ( SgmlFirst(Mark) )    return (SgmlGetFirstDataByGid(SgmlFirst(Mark), Gid));
    if ( SgmlNext(Mark) )     return (SgmlGetFirstDataByGid(SgmlNext(Mark), Gid));
    return (NULL);
}

SgmlNode *SgmlGetChildTagAtt(n1,t1,a1,v1)
SgmlNode *n1;
char *t1;
char *a1;
char *v1;
{
  SgmlNode *result;
  SgmlNode *n2;
  result=NULL;
  if ((n1)
      &&(n2=SgmlGetChildTag(n1,t1)))
    {
      do
	{
	  char *att;
	  if((att=SgmlGetAttValById(n2,a1))
	     &&(strcmp(att,v1)==00))
	    {
	      return n2;
	    }
	}while ((n2=SgmlGetNextTag(n2,t1)));
    }
  return result;
}
SgmlNode *SgmlGetNextTagAtt(n1,t1,a1,v1)
SgmlNode *n1;
char *t1;
char *a1;
char *v1;
{
  SgmlNode *result;
  SgmlNode *n2;

  result=NULL;
 
  if ((n2=n1))
    {
      while((n2=SgmlGetNextTag(n2,t1)))
	{
	  char *att;
	  if((att=SgmlGetAttValById(n2,a1))
	     &&(strcmp(att,v1)==00))
	    {
	      return n2;
	    }
	}
    }
  return result;
}
