#ifndef SCREEM_DTD_H
#define SCREEM_DTD_H

#include <glib-object.h>

#include <libxml/tree.h>

#define SCREEM_TYPE_DTD           (screem_dtd_get_type ())
#define SCREEM_DTD(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCREEM_TYPE_DTD, ScreemDTD))
#define SCREEM_IS_DTD(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCREEM_TYPE_DTD))
				   
typedef enum {
	SCREEM_DTD_SHOULD = 1,
	SCREEM_DTD_MUST = 2,
	SCREEM_DTD_MUST_NOT = 3
} ScreemDTDTagExistance;

typedef struct ScreemDTD ScreemDTD;
typedef struct ScreemDTDPrivate ScreemDTDPrivate;

typedef struct ScreemDTDElement ScreemDTDElement;
typedef struct ScreemDTDAttribute ScreemDTDAttribute;
typedef struct ScreemDTDEntity ScreemDTDEntity;
typedef struct ScreemDTDAllowed ScreemDTDAllowed;

typedef struct {
	ScreemDTD *dtd;
	gchar* (*resolve_entity)( void *userdata,
				  const gchar *publicid,
				  const gchar *systemid );
	void *userdata;
} ScreemDTDParse;

struct ScreemDTD {
	GObject parent_object;

	ScreemDTDPrivate *priv;
};

typedef struct {
	GObjectClass parent_class;

} ScreemDTDClass;

GType screem_dtd_get_type( void );		

ScreemDTD *screem_dtd_new( const gchar *publicid, 
			   const gchar *systemid );

const gchar *screem_dtd_get_public_id( const ScreemDTD *dtd );
const gchar *screem_dtd_get_system_id( const ScreemDTD *dtd );
const gchar *screem_dtd_get_root_name( const ScreemDTD *dtd );

gboolean screem_dtd_parse( ScreemDTD *dtd, ScreemDTDParse *parse,
		const gchar *data );

gchar *screem_dtd_dump( const ScreemDTD *dtd );

gchar *screem_dtd_lookup_entity( const ScreemDTD *dtd, 
				const gchar *name,
				gboolean expand );

const ScreemDTDElement *screem_dtd_valid_element( const ScreemDTD *dtd,
					    const gchar *element );
gboolean screem_dtd_valid_child( const ScreemDTD *dtd,
				 const gchar *element,
				 const gchar *child );
gboolean screem_dtd_valid_child_element( const ScreemDTD *dtd,
					const ScreemDTDElement *parent,
					const gchar *child );
ScreemDTDTagExistance screem_dtd_element_close_state( const ScreemDTD *dtd,
						const gchar *element );
ScreemDTDTagExistance screem_dtd_element_close_element_state( const ScreemDTD *dtd,
						const ScreemDTDElement *element );

gboolean screem_dtd_is_root_element( const ScreemDTD *dtd,
				     const gchar *element );

const ScreemDTDAttribute *screem_dtd_valid_attr( const ScreemDTD *dtd,
						 const gchar *element,
						 const gchar *attr );
const ScreemDTDAttribute *screem_dtd_valid_element_attr( const ScreemDTD *dtd,
					const ScreemDTDElement *element,
					 const gchar *attr );

gboolean screem_dtd_attr_is_uri( const ScreemDTD *dtd,
				 const gchar *element,
				 const gchar *attr );


const GSList *screem_dtd_get_elements( const ScreemDTD *dtd );
const GSList *screem_dtd_element_get_attrs( const ScreemDTDElement *element );
const GSList *screem_dtd_element_get_allowed( const ScreemDTDElement *element );

const gchar *screem_dtd_element_get_name( const ScreemDTDElement *element );
const gchar *screem_dtd_element_get_description( const ScreemDTDElement *element );


const gchar *screem_dtd_attribute_get_name( const ScreemDTDAttribute *attr );
const gchar *screem_dtd_attribute_get_description( const ScreemDTDAttribute *attr );
gboolean screem_dtd_attribute_get_required( const ScreemDTDAttribute *attr );
gboolean screem_dtd_attribute_is_uri( const ScreemDTDAttribute *attr );
const GSList *screem_dtd_attribute_get_values( const ScreemDTDAttribute *attr );
const gchar *screem_dtd_attribute_get_default( const ScreemDTDAttribute *attr );

#endif

