/*   -*- coding: utf-8 -*-  */
/**********************************************************************
*
*      Module  : SxPath
*      Fichier : SxPath.h
*      Auteur  : J. Ducloy, François PARMENTIER
*
************************************************************************
* 
*     Copyleft
*
************************************************************************/
/**
   @file

   @brief Common declarations for SxPath functions

   @author &copy; INIST-CNRS
   @author Jacques DUCLOY 
   @author François PARMENTIER 
           <DilibMaster@inist.fr>

 */

/**
   \page xpath SxPath Syntax

   <h2>Syntax for SxPath language (XPath for Sxml) - DILIB implementation</h2>

   \anchor locationpath
   \par Location path (SxPath syntax)
   -# LocationPath ::= RelativeLocationPath
   -# RelativeLocationPath ::= Step
                             | RelativeLocationPath '/' Step
   -# Step ::= AxisSpecifier NodeTest Predicate*
                             | AbbreviatedAxisSpecifier
   -# AxisSpecifier ::= AxisName '::' | AbbreviatedAxisSpecifier
   -# AxisName ::= 'descendant'
                             | 'child'
                             | 'following-sibling'
   -# NodeTest ::= NameTest
   -# Predicate ::= '[' PredicateExpr']'

   \par Sxml Syntax
     \<!ENTITY testPredicate ( testName position )\><br>
     \<!ELEMENT union ( locationPath+ )\><br>
     \<!ELEMENT locationPath ( child* descendant* following-sibling* )\><br>
     \<!ELEMENT child ( \&testPredicate; )\>

   \par Description
     Most of the specification of DILIB SxPath is conform  to  W3C
     one.

   \par
     Dilib offers two ways of writing SxPath  :  the  usual  SxPath
     syntax, and an Xml equivalent.

   \par Example
     inist/pA/fA14/s3
   \par
     child::inist/child::pA/child::fA14/child::s3
     
   @see http://www.w3.org/TR/xpath
   @author Jacques DUCLOY François PARMENTIER <DilibMaster@inist.fr>

*/

#ifndef _SXPATH_H_
#define _SXPATH_H_

#include "SxmlNode.h"
#include "SxmlProcessor.h"

SxmlNode *SxPathExpressionParse();
/**
   An SxPathExpression is an SxmlNode which type is
   XML_NODE_SXPATH_EXPRESSION, and which subtype is among:
   - SXPATH_AXIS_CHILD
   - SXPATH_AXIS_ATTRIBUTE
   - SXPATH_AXIS_CHILD_NAME
   - SXPATH_AXIS_DESCENDANT
   - SXPATH_AXIS_FOLLOWING_SIBLING
   - SXPATH_LOCATION_PATH
   - SXPATH_OPERATOR_UNION
   - SXPATH_TEST_NAME
   - SXPATH_PREDICATE_POSITION
   - SXPATH_PREDICATE_ATTRIBUTE
 */
typedef SxmlNode SxPathExpression;

/**
   An SxPathResult is an SxmlNode which type is XML_NODE_SXPATH_RESULT,
   which name is @e #pathResult and which subtype is among: 
   - SXPATH_RESULT_ITER_NODE   deprecated ??? - too complex 
   - SXPATH_RESULT_FIRST_NODE
   - SXPATH_RESULT_NODE_SET
   - SXPATH_RESULT_ANY_TYPE (?)

   Its first child is an SxmlNodePointer to an SxmlProcessor, and its
   other children SxPathResultStep (?), SxPathExpression (?), etc.

   In other words, an @ref SxPathResult is a compiled SxPath string (or
   @ref SxPathExpression). It is used when an SxPath is needed.
 */
typedef SxmlNode     SxPathResult;


/**
   An SxPathResultName is an SxmlNode which type is SxmlNodePointer,
   pointing to an SxPathExpression (value). Its name is @e #step.

   It also has a pointer on a "ContextNode" (internalValue) and on a
   "NextNode" (nextNode). The ContextNode is the node matching the
   ExpressionNode. The NextNode is the next node to evaluate.
 */
typedef SxmlNode SxPathResultStep;

#define SXPATH_LOCATION_PATH           14

#define SXPATH_AXIS_ANCESTOR           1
#define SXPATH_AXIS_ANCESTOR_OR_SELF   2
#define SXPATH_AXIS_ATTRIBUTE          3
#define SXPATH_AXIS_CHILD              4
#define SXPATH_AXIS_DESCENDANT         5
#define SXPATH_AXIS_DESCENDANT_OR_SELF 6
#define SXPATH_AXIS_FOLLOWING          7
#define SXPATH_AXIS_FOLLOWING_SIBLING  8
#define SXPATH_AXIS_NAMESPACE          9
#define SXPATH_AXIS_PARENT             10
#define SXPATH_AXIS_PRECEDING          11
#define SXPATH_AXIS_PRECEDING_SIBLING  12
#define SXPATH_AXIS_SELF               13

#define SXPATH_AXIS_CHILD_POSITION     15

#define SXPATH_PREDICATE_POSITION      20
#define SXPATH_PREDICATE_ATTRIBUTE     21

#define SXPATH_FIRST_CHILD_BY_TAG_NAME 25

#define SXPATH_OPERATOR_UNION          30
#define SXPATH_RELATIONAL_EXPR         31

#define SXPATH_AXIS_CHILD_NAME         99

#define SXPATH_TEST_NAME               16
#define SXPATH_TEST_NODE               17
#define SXPATH_TEST_COMMENT            18

#define SXPATH_RESULT_ANY_TYPE          0
#define SXPATH_RESULT_NODE_SET          4
#define SXPATH_RESULT_FIRST_NODE       10
#define SXPATH_RESULT_ITER_NODE        11

/**
   Tests whether @a x is an axis.
   @param x should be an SxPathExpression.
   @returns 0 if the SxPathExpression passed is not an axis.
   @remarks This macro does not check if @a x is an SxPathExpression!
 */
#define SxPathExpressionIsAxis(x) (SxmlNodeSubType(x)<15)
#define SxPathResultStack(x)                (SxmlFirstChild(x))
#define SxPathResultStepExpressionNode(x)      ((SxmlNode *)SxmlNodeValue(x))
#define SxPathSetResultStepExpressionNode(x,y) (SxmlSetNodeValue(x,(char *)(y)))
/**
   Gets the ContextNode of the @a x SxPathResultStep.
   @param x should be an SxPathResultStep
   @returns the ContextNode @a x
   @remarks This macro does not check if @a x is an SxPathResultStep!
 */
#define SxPathResultStepContextNode(x)      (x->internalValue.n)
/**
   Sets the ContextNode of the @a x SxPathResultStep.
   @param x should be an SxPathResultStep
   @param y the ContextNode to set
   @remarks This macro does not check if @a x is an SxPathResultStep!
 */
#define SxPathSetResultStepContextNode(x,y) (x->internalValue.n=(y))

/*                                SxPathEval.c  */

SxmlNode         *SxPathSetResultListCreate(SxPathResult *xr1, SxmlNode     *x1);
SxPathResult     *SxPathResultCreate(SxmlProcessor *proc1, int resultType);
SxPathResultStep *SxPathResultStepCreate(SxPathResult     *xr1, SxPathExpression *xpe1);
SxPathResult     *SxPathExpressionEvaluate(SxPathExpression *xe1, SxmlNode *xn1, int resultType, SxPathResult *resultNode);
SxPathResult     *SxPathFirstCompile(char *str);
SxPathResult     *SxPathSetCompile(char *str);

/*                                SxPathTool.c  */

SxmlNode *SxPathCreateItem(SxmlNode *p1, SxmlNode *n1);

/*                                ???.c    */

SxmlNode *SxPathResultNextNode();
SxmlNode *SxPathResultNode(SxPathResult *xr1);
SxmlNode *SxPathChildReset();
SxmlNode *SxPathChildNextNode(SxPathResultStep *step1);
SxmlNode *SxPathChildNameNextNode();

SxmlNode *SxPathDescendantFirstByTagName(SxmlNode *n1, char *t1);
SxmlNode *SxPathDescendantNameIterNext();
SxmlNode *SxPathDescendantNameIterInit();

SxmlNode *SxPathChildNameIterInit();
SxmlNode *SxPathChildNameIterNext();

SxmlNode *SxPathIterCreate();
SxmlNode *SxPathIterInit();
SxmlNode *SxPathIterNext();
SxmlNode *SxPathCompile();

SxmlNode *SxPathEvalPredicates();
SxmlNode *SxPathChildFirst();
SxmlNode *SxPathFirstSelectAxis();
SxmlNode  *SxPathFirstEval();
SxmlNode  *SxPathFirstSelectAxis();
SxPathResult *SxPathFirstCompileOnSxml();
SxPathResult *SxPathSetCompileOnSxml();
SxmlNode *SxPathProcSet();
SxmlNode *SxPathSetEval();
SxmlNode *SxPathSetSelectAxis();

SxmlNode *SxPathExpressionTranslate();
SxmlNode *SxPathFirstResultNode();
SxmlMemory *SxPathMemoryInit();
SxmlNode *SxPathSxmlParseForRecord();

/*                                                     file SxPathEval */



/*                                                     file SxPathExpr */

SxPathExpression *SxPathExpressionUnionCreate();
SxPathExpression *SxPathExpressionCreate(char *s1);

/*                                                     file SxPathTools.c */

SxmlNode *SxPathEvalTestNameInAxis(SxmlNode *testNameNode, SxmlNode *x2, SxmlNode *pos);
SxmlNode *SxPathEvalListPredicates( SxmlNode *firstPredicate, SxmlNode *x1, SxmlNode *pos);
SxmlNode *SxPathEvalOnePredicate( SxmlNode *predicateItem, SxmlNode *x1, SxmlNode *pos);

/*                                                     file SxPathFirst.c */

SxmlNode *SxPathEvalFirst(SxPathExpression *locPath1, SxmlNode *x1);
SxmlNode *SxPathEvalFirstSelectAxis(SxPathExpression *xp1, SxmlNode  *x1);
SxmlNode *SxPathEvalFirstChild( SxPathExpression *xp1, SxmlNode *x1, SxmlNode *pos);
SxmlNode *SxPathEvalFirstChildPosition(SxPathExpression *xp1, SxmlNode *x1);
SxmlNode *SxPathEvalFirstAxisAttribute( SxPathExpression *xp1,  SxmlNode  *x1, SxmlNode *pos);
SxmlNode *SxPathEvalFirstFollowingSibling(SxPathExpression *xp1, SxmlNode *x1, SxmlNode *pos);
SxmlNode *SxPathEvalFirstDescendant( SxPathExpression *xp1, SxmlNode *x1, SxmlNode *pos);

/*                                                     file SxPathEasy.c */

char     *SxPathEasyGetFirstText(SxmlNode *n, char *pathStr);
SxmlNode *SxPathEasyGetFirst(SxmlNode *n, char *pathStr);

#endif  /* _SXPATH_H_  */
