#ifndef _nsl_h
#define _nsl_h

/* This file contains the public interface to the Normalised Sgml Library */

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#if ! defined(macintosh) && (defined(__CYGWIN__) || ! defined(WIN32))
#include <sys/types.h>
#endif

#include "lt-defs.h"		/* can't use "Char" without this */

/* The different types of NSL_Data */

typedef enum {NSL_undefined,NSL_text_data,NSL_item_data,
	      NSL_pi_data,NSL_comment_data,
	      NSL_cdata_data,NSL_eref_data,NSL_free_data} NSL_Data_Type;

typedef enum {NSL_attr_num, NSL_attr_nums, NSL_attr_id,
	      NSL_attr_refid, NSL_attr_refids, NSL_attr_string,
	      NSL_attr_entity, NSL_attr_entities, NSL_attr_float,
	      NSL_attr_token, NSL_attr_tokens, NSL_attr_notation} NSL_AVType;

/* The different kinds of attribute default values          */
/* These are now in the same order as SP's
                   AttributeDefinitionDesc:DefaultValueType */

/* NB NSL_defval_optional == a default value has been given */
/*    NSL_defval_value    == a #FIXED attribute             */

typedef enum {NSL_defval_required, NSL_defval_current, NSL_defval_implied, 
	      NSL_defval_conref, NSL_defval_optional, NSL_defval_value
} NSL_ADefType;

typedef enum {NSL_bad,
	      /* The first are for bits */
	      NSL_start_bit, NSL_end_bit, NSL_empty_bit,
	      NSL_eof_bit, NSL_text_bit, NSL_pi_bit,
	      NSL_doctype_bit, NSL_comment_bit,
	      /* the rest of these are Item types */
	      NSL_inchoate, NSL_non_empty, NSL_empty, NSL_free} NSL_BI_Type;

typedef enum{ NSL_Ent_sgmlText, NSL_Ent_pi, NSL_Ent_cdata,
	      NSL_Ent_sdata, NSL_Ent_ndata, 
	      NSL_Ent_subdoc } NSL_Entity_DataType ;

typedef const struct AttributeSummary* NSL_AttributeSummary;
typedef const struct EntitySummary*    NSL_EntitySummary;
struct NSL_ElementSummary_I;

struct NSL_Doctype_I;
/* can't use typedef or const doesn't work */
#define NSL_Doctype struct NSL_Doctype_I*
#define NSL_ElementSummary struct NSL_ElementSummary_I*

/* Tree node corresponding to an SGML element */
typedef struct NSL_Item {
    const Char *label; /* The SGML element name */
    const Char *prefix;		/* The prefix, or null if unprefixed */
    const Char *llabel;		/* The local part of a namespaced name */
    const char8 *nsuri;		/* The uri of a namespaced name */
    struct namespace_binding *ns_dict;	/* Linked list of namespace bindings */
    int nsc;			/* Count of local ns records */
    int nsowned;		/* True if ns recs should be freed */
    const NSL_Doctype doctype;
    NSL_BI_Type type;
    struct NSL_Data *data; /* The SGML element content */
    const NSL_ElementSummary defn; /* The NSL summary definition of
				the element type */
    struct NSL_Attr *attr; /* Linked list of actual (as opposed to defaulted)
			      attributes for the element */
    struct NSL_Data *in; /* dominating NSL_Data if any */
} NSL_Item;

/* Linked list for SGML element content:  mixed NSL_Items and text in
   mixed content, all NSL_Items in element-only content */

typedef struct NSL_Data {
    int ref;
    NSL_Data_Type type; /* type pointed to by first */
    struct NSL_Data *next; /* next NSL_Data or NULL */
    void *first; /* could be either text, a processing instruction
		    or an NSL_Item as per type field               */
    NSL_Item *in; /* dominating item */
} NSL_Data;

/* Container for passing structure to user */
typedef struct NSL_Bit {
    NSL_BI_Type type;
    int flags; /* only valid if type NSL_text_bit */
    union {
      NSL_Item *item; /* type NSL_start_bit */
      Char *body; /* text, pi */
      void * data; /* NSL_internal_bit */
    } value;
    const Char *label; /* valid only if type NSL_start_bit or NSL_end_bit */
                       /* or NSL_empty_bit */
    const Char *prefix;		/* The prefix, or null if unprefixed */
    const Char *llabel;		/* The local part of a namespaced name */
    const char8 *nsuri;		/* The uri of a namespaced name */
    struct namespace_binding *ns_dict;	/* Linked list of namespace bindings */
    int nsc;			/* Count of local ns records */
    int nsowned;		/* True if ns recs should be freed */
} NSL_Bit;

/* Flags for text bits */

#define NSL_text_isCData 0x01
#define NSL_text_isERef  0x02

/*
 * Attribute Specification Structure.
 */

typedef struct NSL_Attr {
    NSL_AVType valuetype;            /* type of value */
    NSL_ADefType deft;                /* type of default value */
    const Char *name;                      /* name of attribute */
    const Char *lname;		/* The local part of a namespaced name */
    const char8 *nsuri;		/* The uri of a namespaced name */
    union {
	const Char *string;                /* NAME, STRING */
    } value;                         /* actual value */
    struct NSL_Attr *next;          /* list link */
} NSL_Attr;

typedef const struct NSL_Query_I* NSL_Query;

#if 0

/* minimal means nothing but what you're given, including no DDB PI at start,
   normal adds RE before start-tags in element-only content,
   pretty adds RE also at beginning and end of text content */
typedef enum {NSL_read, NSL_read_raw,
	      NSL_write_minimal, NSL_write_normal, 
	      NSL_write_pretty, NSL_write_normal_nd
} NSL_FType;

#else

typedef int NSL_FType;

#define NSL_read 0x01
#define NSL_read_all_bits 0x02
#define NSL_read_strict 0x04
#define NSL_read_no_expand 0x08
#define NSL_read_no_consume_prolog 0x10
#define NSL_read_no_normalise_attributes 0x20
#define NSL_read_no_normalize_attributes 0x20
#define NSL_read_declaration_warnings 0x40
#define NSL_read_validate 0x80
#define NSL_read_namespaces 0x10000
#define NSL_read_defaulted_attributes 0x20000
#define NSL_read_relaxed_any 0x40000
#define NSL_read_allow_undeclared_nsattributes 0x80000

#define NSL_read_flags 0xf00ff

#define NSL_write 0x100
#define NSL_write_no_doctype 0x200
#define NSL_write_plain 0x400
#define NSL_write_fancy 0x800
#define NSL_write_canonical 0xc00
#define NSL_write_default 0x000
#define NSL_write_style 0xc00
#define NSL_write_no_expand 0x1000

#define NSL_write_flags 0x1f00

#define NSL_write_minimal   (NSL_write|NSL_write_plain|NSL_write_no_doctype)
#define NSL_write_normal    (NSL_write)
#define NSL_write_pretty    (NSL_write|NSL_write_fancy)
#define NSL_write_normal_nd (NSL_write|NSL_write_no_doctype)

#endif

typedef struct NSL_File_I* NSL_File;

/* For use by GetAttrDeclaredValue */
/* NB must match AttributeType in Richard's parser, and 
   NSL_Attr_Declared_Value in ddb.h */

typedef enum { NSL_Dec_cdata, NSL_Dec_name, NSL_Dec_number, 
	       NSL_Dec_nmtoken, NSL_Dec_nutoken, NSL_Dec_entity, 
	       NSL_Dec_idref, NSL_Dec_names, NSL_Dec_numbers,
	       NSL_Dec_nmtokens, NSL_Dec_nutokens, NSL_Dec_entities, 
	       NSL_Dec_idrefs, NSL_Dec_id, NSL_Dec_notation,
	       NSL_Dec_nameTokenGroup } NSL_Attr_Dec_Value;

/* For use by ElementContent */
/* NB must match ContentType in Richard's parser, and ctVals in ddb.h */

typedef enum {
    NSL_Content_mixed, NSL_Content_any, NSL_Content_cdata,
    NSL_Content_rcdata, NSL_Content_empty, NSL_Content_element
} NSL_Element_Content;

/* Replicated from dtd.h XXX */

enum cp_type {
    CP_pcdata, CP_name, CP_seq, CP_choice, CP_enum_count
};
typedef enum cp_type CPType;

struct content_particle {
    enum cp_type type;
    int repetition;
    const Char *name;
    struct element_definition *element;
    int nchildren;
    struct content_particle **children;
};

/* Structure for common application options */

typedef struct NSL_Common_Options {
    NSL_Doctype doctype;
    NSL_Doctype aux_doctype;
    int read_type, write_type;
    const char8 *base_url;
} NSL_Common_Options;

/* error stuff for applications */

#include "nsl-err.h"


/* Control of how NSL treats attribute names */

typedef enum { NSL_use_names, NSL_use_strings } NSL_Name_Behaviour ;

/* finally all the function declarations */

#include "nslfunc.h"

/* The value of #IMPLIED attributes which have no explicit value */

extern XML_API const Char * EXPRT NSL_Implied_Attribute_Value;

extern XML_API NSL_Name_Behaviour EXPRT NSL_Global_Names;

#ifdef __cplusplus
}
#endif


#endif /* _nsl_h */
