/*$cb
 *    This file is a part of libopenmhp.
 *
 *    Copyright (C) 2005 Mikko Novaro <miknov@gmail.com>
 *
 *    See main header file (libopenmhp/openmhp.h) for licensing and
 *    contact information.
 $ce*/

#ifndef _ELEMENT_HPP_
#define _ELEMENT_HPP_

// #include <libxml/parser.h>
#include <list>
#include <string>

/*

   All xml element classes should have a constructor, that takes the
   name of the corresponding xml element. This name is used to
   identify the objects, when retrieving a specific data from the
   parse tree. This habit also makes it possible to use the same one
   class for any xml element that has no specific functionality, or
   those that share common functionality (such as cIntElem).

   XML element object tree should be deleted by deleting the root
   node. No nodes taken from the tree (i.e. by GetChildNode) should be
   de-allocated separately.

*/

namespace xml {

  class cXMLElement {
  private:
    cXMLElement *parentNode;
    std::list <cXMLElement *>*childNodes;
    std::string *pcData; // why string instead of char*?
    char *name;
    void SetParentNode(cXMLElement *elem);
  public:
    cXMLElement(const char *name);
    virtual ~cXMLElement(void);
    void SetName(const char *name);
    /* Returns a pointer to element's name. Don't deallocate. */
    const char *GetName(void);
    void AddChildNode(cXMLElement *elem);
    cXMLElement *GetParentNode(void);
    /* Gets a child node that is of the given element name. */
    cXMLElement *GetChildNode(const char *elemName, int index = 0);
    /* Gets the pc-data of the node. Returned data is a copy of the
       elements data, and should be de-allocated with delete. */
    char *GetData(void);
    
    virtual void Start(const char *name); // TODO: add attributes
    virtual void End(const char *name);
    virtual void Characters(const char *ch, int len);
  };


  // -------------- ACTUAL ELEMENT CLASSES -----------------------------
  
  class cRootElement : public cXMLElement {
  private:
  public:
    cRootElement(const char*);
  };
  
  class cMhpToClient : public cXMLElement {
  public:
    cMhpToClient(const char*);
    void End(const char *name);
  };

  class cIntElem : public cXMLElement {
  public:
    cIntElem(const char*);
    int GetDataInt(void);
  };

  class cImageUpdate : public cIntElem {
  public:
    cImageUpdate(const char*);
    void End(const char *name);
  };
  
  class cVideoScale : public cXMLElement {
  public:
    cVideoScale(const char*);
    void End(const char *name); // executes the request
  };
  
}

#endif
