/*
 *  Copyright (c) 2004-2013 Gert Wollny <gw.fossdev@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *  As an exception to this license, "NEC C&C Research Labs" may use
 *  this software under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation.
 *
 */

#ifndef __xmlio_h
#define __xmlio_h


#include <mialm/miadefines.h>
#include <libxml/parser.h>
#include <glib.h>

typedef struct _ParserState ParserState;

typedef struct _ParserStateStack ParserStateStack;

/**
   tag_start_callback: 
   @user_data: data passd in by the user when calling the SAX parser
   @attrs: attributes of the XML tag that was just opened. 
   
   This is the prototype of the callback funtion that will be called by the SAX parser at the opening of a new XML tag.
 */
typedef void (*tag_start_callback) (ParserState * user_data,
				    const xmlChar ** attrs);

/**
   tag_ch_callback: 
   @user_data: data passd in by the user when calling the SAX parser
   @ch: character string 
   @len: length of the incomming character string 
   
   This is the prototype of the callback funtion that will be called whenever a chunk of characters is read 
   when handling an XML tag. The contents of a XML tag may come in parts, hence the incoming data should be accumulated. 
*/
typedef void (*tag_ch_callback) (ParserState * user_data, const xmlChar * ch,
				 int len);

/**
   tag_end_callback: 
   @user_data: data passd in by the user when calling the SAX parser
   @property: property identifies this tag corresponds to. 

   This is the prototype of the callback funtion that will be called by the SAX parser at the closing of a XML tag. 
*/
typedef void (*tag_end_callback) (ParserState * user_data, const gchar *property);


typedef struct _ParserTags ParserTags;

/**
 * ParserTags:
 * @tag_name: name of the XML tag to be handled by this table entry 
 * @start_callback: callback to execute when the tag starts 
 * @ch_callback:  callback to execute when string data is read
 * @end_callback: callback to execute when the tag ends, should handle storing of the read data  
 * @parser_tags: sub-table that describes the supported child-tags of this XML tag 
 * 
 * This table entry describes the handling of a certain XML tag. When the tag opens, it will call the 
 * @start_callback function and push its related the property and ch_callback and end_callback values 
 * on the @ParserStateStack that is used to parse the XML file at hand. 
 * If a new tag is read, that the sub-table will be used to identify the proper handler, and  if none is available, 
 * the unknown tag handler will be used to skip over this tag. 
 */
struct _ParserTags
{
	const gchar *tag_name;
	tag_start_callback start_callback;
	tag_ch_callback ch_callback;
	tag_end_callback end_callback;
	const ParserTags *parser_tags;
};

/**
   END_PARSER_TAGS:
   
   Defines the end of a parset tags table.
 */
#define END_PARSER_TAGS {0,0,0,0,0}


/**
 * ParserState:
 * @pss: stack to store the parser states
 * @data: additional user data that is passed to the parser 
 * 
 * This structure holds the current state when parsing an XML file. 
 * 
 */
struct _ParserState
{
	ParserStateStack *pss;
	gpointer data;
};

/**
 * ParserStateStack:
 * @tag_id: unused field??
 * @unknown_depth: xml-tree depth when reading (and discarding an unkown tag) 
 * @property:  the property related to the tag that is currently read 
 * @ch_callback:  currently active callback function to handle read characters 
 * @end_callback: currently active callback funtion to call when the currently read tag ends 
 * @n_parser_tags: size of following tag-callback map
 * @parser_tags: table of tag-callback mappings 
 * @ch:  string to accumulate corrently parsed section 
 * @data: private data passed to the parser 
 *
 * A structure to hold the state of the parser.  
 */

struct _ParserStateStack
{
	/*< private >*/
	ParserStateStack *parent;

	/*< public >*/
	gint tag_id;
	gint unknown_depth;
	GString *property;
	tag_ch_callback ch_callback;
	tag_end_callback end_callback;
	gint n_parser_tags;
	const ParserTags *parser_tags;
	GString *ch;
	gpointer data;
};

G_BEGIN_DECLS

void 
xmlio_end_string(ParserState * state, const gchar *property);

void xmlio_end_float(ParserState * state, const gchar *property);

void xmlio_get_string (ParserState * state, const xmlChar * ch,
		       int len);
gboolean
xml_write_float (xmlNodePtr root, xmlNsPtr ns, const gchar * tag, gfloat f);


int 
xml_sax_parse (const gchar * filename, const ParserTags * tags,
	       gpointer pdata);

G_END_DECLS

#endif


