// file: $isip/tools/class/mmedia/XMLParser/XMLParser.h
// version: $Id: XMLParser.h 10636 2007-01-26 22:18:09Z tm334 $

#if defined(HAVE_EXPAT)

// make sure definitions are only made once
//
#ifndef ISIP_XMLPARSER
#define ISIP_XMLPARSER

//---------------------------------------------------------------------------
//
// include files for external packages:
//
//---------------------------------------------------------------------------

#include <expat.h>

//---------------------------------------------------------------------------
//
// ISIP include files
//
//---------------------------------------------------------------------------  

#ifndef ISIP_CONSOLE
#include <Console.h>
#endif

#ifndef ISIP_XMLTOKEN
#include <XMLToken.h>
#endif

// forward class definitions
//
class XMLToken;

// XMLParser: a class to parse an XML grammar document,
//
class XMLParser {
  
  //---------------------------------------------------------------------------
  //
  // public constants
  //
  //---------------------------------------------------------------------------
public:
  
  // constant: class name
  //
  static const String CLASS_NAME;
  
  //---------------------------------------
  //
  // other important constants
  //
  //---------------------------------------
  
  //----------------------------------------
  //
  // i/o related constants
  //
  //----------------------------------------
  
  //----------------------------------------
  //
  // default values and arguments
  //
  //----------------------------------------
  
  //----------------------------------------
  //
  // error codes
  //
  //----------------------------------------  
  
  static const long ERR = 50950;
  static const long ERR_EXPAT_PARSE = 50951;
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:
  
  // a vector for the xml tokens
  //
  Vector<XMLToken> token_vector_d;
  
  // a vector of values considered valid for
  // the xml tokens stored in the token_vector_d
  //
  Vector<String> valid_values_d;
  
  // debug level
  //
  Integral::DEBUG debug_level_d;

  // expat xml parser
  XML_Parser parser_d;
  
  //---------------------------------------------------------------------------
  //
  // required public methods
  //
  //---------------------------------------------------------------------------
public:
  
  // method: name
  //
  static const String& name() {
    return CLASS_NAME;
  }
  
  // other static methods
  //
  static boolean diagnose(Integral::DEBUG level);
  
  // method: setDebug
  //
  boolean setDebug(Integral::DEBUG level) {
    debug_level_d = level;
    return true;
  }
  
  // method: getDebug
  //
  Integral::DEBUG getDebug() {
    return debug_level_d;
  }
  
  // other debug methods
  // method: debug
  //
  boolean debug(const unichar* msg) const;
  
  // method: default constructor
  //
  XMLParser() {
    debug_level_d = Integral::NONE;
    parser_d=NULL;
  }

  // method: default destructor
  //
  ~XMLParser() {
    Destroy();
  }
  
  // method: read
  //
  boolean read(Sof& sof, long tag, const String& cname = CLASS_NAME) {
    return Error::handle(name(), L"read", Error::NOT_IMPLEM, __FILE__,
			 __LINE__);
  }
  
  // method: write
  //
  boolean write(Sof& sof, long tag, const String& cname = CLASS_NAME) const {
    return Error::handle(name(), L"write", Error::NOT_IMPLEM, __FILE__,
			 __LINE__);
  }
  
  // method: assign
  //
  boolean assign(const XMLParser& xp);
  
  // method: operator=
  //
  boolean operator=(const XMLParser& xp);
  
  // method: operator==
  //
  boolean operator==(const XMLParser& xp) const;
  
  // method: eq
  //
  boolean eq(const XMLParser& xp) const;
  
  // method: clear
  //
  boolean clear(Integral::CMODE ctype);
  
  //---------------------------------------------------------------------------
  //
  // class-specific public methods
  //
  //---------------------------------------------------------------------------
public: 
  
  // method: toXML
  //
  static const String toXML(Vector<XMLToken>& token_vector);
  
  // method: setTokenDepths
  //
  static const boolean setTokenDepths(Vector<XMLToken>& token_vector);
  
  // method: debugTokenDepths
  //
  static const boolean debugTokenDepths(Vector<XMLToken>& token_vector);
  
  // method: getIndent
  //
  static const String getIndent(long depth);
  
  // method: setTokenVector
  //
  boolean setTokenVector(Vector<XMLToken>& token_vector) {
    return token_vector_d.assign(token_vector);
  }
  
  // method: getTokenVector
  //
  Vector<XMLToken>& getTokenVector() {
    return token_vector_d;
  }
  
  // method: setValidTokenValues
  //
  boolean setValidTokenValues(Vector<String> valid_values) {
    return valid_values_d.assign(valid_values);
  }
  
  // method: getValidTokenValues
  //
  Vector<String>& getValidTokenValues() {
    return valid_values_d;
  }
  
  // method: addToken
  //
  boolean addToken(XMLToken token);
  
  // method: markUnhandledTokens
  //
  boolean markUnhandledTokens();
  
  // method: removeUnhandledTokens
  //
  boolean removeUnhandledTokens();
  
  // method: setTokenDepths
  //
  boolean setTokenDepths();
  
  // method: paresXML
  //
  boolean parseXML(String document);
  
  // method: toXML
  //
  String toXML();
  
  //---------------------------------------
  //
  // class-specific public methods
  //
  //---------------------------------------
public: 

  // method: Create
  //
  bool Create(const XML_Char* encoding_a = NULL,
	      const XML_Char* seperator_a= NULL);

  // method: Destroy
  //
  void Destroy();

  // method: Parse
  //
  bool Parse (const char* buffer_a, int length_a = -1, bool is_final_a = true);

  // method: ParserBuffer
  //
  bool ParseBuffer (int length_a, bool is_final_a=true);

  // method: GetBuffer
  //
  void* GetBuffer (int length_a);

  // method: EnableStartElementHandler
  //
  void EnableStartElementHandler (bool enable_a=true);

  // method: EnableEndElementHandler
  //
  void EnableEndElementHandler (bool enable_a=true);

  // method: EnableElementHandler
  //
  void EnableElementHandler (bool enable_a=true);

  // method: EnableCharacterDataHandler
  //
  void EnableCharacterDataHandler (bool enable_a=true);

  // method: StartElementHandler
  //
  static void StartElementHandler (void *user_data_a,
				   const XML_Char* name_a,
				   const XML_Char** attributes_a);

  // method: EndElementHandler
  //
  static void EndElementHandler (void *user_data_a,
				 const XML_Char* name_a);

  // method: CharacterDataHandler
  //
  static void CharacterDataHandler (void *user_data_a,
				    const XML_Char* data_a,
				    int length_a);
  
  // method: OnPostCreate
  //   activates the event handlers
  //
  void OnPostCreate ();
  
  // method: OnStartElement
  //   event handler for xml start elements
  //
  void OnStartElement (const XML_Char *psz_name, const XML_Char **papsz_attrs);
  
  // method: OnEndElement
  //  event handler for xml end elements
  //
  void OnEndElement (const XML_Char *psz_name);
  
  // method: OnCharacterData
  //   event handler for xml cdata elements
  //
  void OnCharacterData (const XML_Char *parsed_data, int n_length);
  
};
#endif

#endif
