#ifndef DOMLETTE_EXPAT_INTERFACE_H
#define DOMLETTE_EXPAT_INTERFACE_H

#ifdef __cplusplus
extern "C" {
#endif

/*

  This header provides access to Domlette's Expat interface from C.

  Before calling any of the functions or macros, you must initialize
  the routines with:

    ExpatInterface_IMPORT

  This would typically be done in your init function.

*/

  struct ExpatParserStruct;
  typedef struct ExpatParserStruct *ExpatParser;

  typedef void (*ExpatStartDocumentHandler)(void *userData);

  typedef void (*ExpatEndDocumentHandler)(void *userData);

  /* name is a PyUnicodeObject, atts is a PyDictObject */
  typedef void (*ExpatStartElementHandler)(void *userData, 
                                           PyObject *name,
                                           PyObject **atts);

  /* name is a PyUnicodeObject */
  typedef void (*ExpatEndElementHandler)(void *userData,
                                         PyObject *name);

  /* data is a PyUnicodeObject */
  typedef void (*ExpatCharacterDataHandler)(void *userData,
                                            PyObject *data);

  /* target is a PyUnicodeObject, data is a PyUnicodeObject */
  typedef void (*ExpatProcessingInstructionHandler)(void *userData,
                                                    PyObject *target,
                                                    PyObject *data);

  /* data is a PyUnicodeObject */
  typedef void (*ExpatCommentHandler)(void *userData,
                                      PyObject *data);

  /* prefix is a PyUnicodeObject or Py_None, uri is a PyUnicodeObject */
  typedef void (*ExpatStartNamespaceDeclHandler)(void *userData,
                                                 PyObject *prefix,
                                                 PyObject *uri);

  /* prefix is a PyUnicodeObject or Py_None */
  typedef void (*ExpatEndNamespaceDeclHandler)(void *userData,
                                               PyObject *prefix);

  /* systemId is a PyUnicodeObject or Py_None, 
     publicId is a PyUnicodeObject or Py_None
  */
  typedef void (*ExpatDoctypeDeclHandler)(void *userData,
                                          PyObject *systemId,
                                          PyObject *publicId);

  /* name is a PyUnicodeObject, uri is a PyUnicodeObject */
  typedef void (*ExpatUnparsedEntityDeclHandler)(void *userData,
                                                 PyObject *name,
                                                 PyObject *uri);

  typedef struct {
    ExpatParser (*ParserCreate)(void *userState);
    
    void (*ParserFree)(ExpatParser parser);

    int (*ParseDocument)(ExpatParser parser, PyObject *source,
                         int doExternalEntityParsing);

    int (*ParseEntity)(ExpatParser parser, PyObject *source);

    void (*ParserStop)(ExpatParser parser);

    PyObject *(*GetBase)(ExpatParser parser);

    int (*GetLineNumber)(ExpatParser parser);
    
    int (*GetColumnNumber)(ExpatParser parser);

    int (*SplitName)(ExpatParser parser, PyObject *triplet, 
                     PyObject **namespaceURI,
                     PyObject **localName,
                     PyObject **qualifiedName,
                     PyObject **prefix);
    
    void (*SetStartDocumentHandler)(ExpatParser parser,
                                    ExpatStartDocumentHandler handler);

    void (*SetEndDocumentHandler)(ExpatParser parser,
                                  ExpatEndDocumentHandler handler);

    void (*SetStartElementHandler)(ExpatParser parser,
                                   ExpatStartElementHandler handler);

    void (*SetEndElementHandler)(ExpatParser parser,
                                 ExpatEndElementHandler handler);

    void (*SetCharacterDataHandler)(ExpatParser parser,
                                    ExpatCharacterDataHandler handler);

    void (*SetProcessingInstructionHandler)(
                                    ExpatParser parser,
                                    ExpatProcessingInstructionHandler handler);

    void (*SetCommentHandler)(ExpatParser parser,
                              ExpatCommentHandler handler);

    void (*SetStartNamespaceDeclHandler)(
                                    ExpatParser parser,
                                    ExpatStartNamespaceDeclHandler handler);

    void (*SetEndNamespaceDeclHandler)(
                                    ExpatParser parser,
                                    ExpatEndNamespaceDeclHandler handler);

    void (*SetDoctypeDeclHandler)(ExpatParser parser,
                                  ExpatDoctypeDeclHandler handler);

    void (*SetUnparsedEntityDeclHandler)(
                                    ExpatParser parser,
                                    ExpatUnparsedEntityDeclHandler handler);

    void (*SetXIncludeProcessing)(ExpatParser parser, int doXIncludeProcessing);

    int (*SetWhitespaceRules)(ExpatParser parser, PyObject *rules);

  } Expat_APIObject;


#ifndef Domlette_BUILDING_MODULE

/* --- C API ----------------------------------------------------*/

  static Expat_APIObject *Expat_API;

#define Expat_IMPORT Expat_API =                                \
    (Expat_APIObject *) PyCObject_Import("Ft.Xml.cDomlettec",   \
                                         "Expat_CAPI")

#define Expat_ParserCreate \
  Expat_API->ParserCreate
#define Expat_ParserFree \
  Expat_API->ParserFree
#define Expat_ParseDocument \
  Expat_API->ParseDocument
#define Expat_ParseEntity \
  Expat_API->ParseEntity
#define Expat_ParserStop \
  Expat_API->ParserStop
#define Expat_GetBase \
  Expat_API->GetBase
#define Expat_GetLineNumber \
  Expat_API->GetLineNumber
#define Expat_GetColumnNumber \
  Expat_API->GetColumnNumber
#define Expat_SplitName \
  Expat_API->SplitName
#define Expat_SetStartDocumentHandler \
  Expat_API->SetStartDocumentHandler
#define Expat_SetEndDocumentHandler \
  Expat_API->SetEndDocumentHandler
#define Expat_SetStartElementHandler \
  Expat_API->SetStartElementHandler
#define Expat_SetEndElementHandler \
  Expat_API->SetEndElementHandler
#define Expat_SetCharacterDataHandler \
  Expat_API->SetCharacterDataHandler
#define Expat_SetProcessingInstructionHandler \
  Expat_API->SetProcessingInstructionHandler
#define Expat_SetCommentHandler \
  Expat_API->SetCommentHandler
#define Expat_SetStartNamespaceDeclHandler \
  Expat_API->SetStartNamespaceDeclHandler
#define Expat_SetEndNamespaceDeclHandler \
  Expat_API->SetEndNamespaceDeclHandler
#define Expat_SetDoctypeDeclHandler \
  Expat_API->SetDoctypeDeclHandler
#define Expat_SetUnparsedEntityDeclHandler \
  Expat_API->SetUnparserEntityDeclHandler
#define Expat_SetStartExternalEntityHandler \
  Expat_API->SetStartExternalEntityHandler
#define Expat_SetEndExternalEntityHandler \
  Expat_API->SetEndExternalEntityHandler
#define Expat_SetXIncludeProcessing \
  Expat_API->SetXIncludeProcessing
#define Expat_SetWhitespaceRules \
  Expat_API->SetWhitespaceRules

#endif /* !Domlette_BUILDING_MODULE */

#ifdef __cplusplus
}
#endif

#endif /* DOMLETTE_EXPAT_INTERFACE_H */
