/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_XMLLITE_XMLELEMENT_H_
#define TALK_XMLLITE_XMLELEMENT_H_

#include <iosfwd>
#include <string>

#include "talk/base/scoped_ptr.h"
#include "talk/xmllite/qname.h"

namespace buzz {

class XmlChild;
class XmlText;
class XmlElement;
class XmlAttr;

class XmlChild {
 public:
  XmlChild* NextChild() { return next_child_; }
  const XmlChild* NextChild() const { return next_child_; }

  bool IsText() const { return IsTextImpl(); }

  XmlElement* AsElement() { return AsElementImpl(); }
  const XmlElement* AsElement() const { return AsElementImpl(); }

  XmlText* AsText() { return AsTextImpl(); }
  const XmlText* AsText() const { return AsTextImpl(); }


 protected:
  XmlChild() :
    next_child_(NULL) {
  }

  virtual bool IsTextImpl() const = 0;
  virtual XmlElement* AsElementImpl() const = 0;
  virtual XmlText* AsTextImpl() const = 0;


  virtual ~XmlChild();

 private:
  friend class XmlElement;

  XmlChild(const XmlChild& noimpl);

  XmlChild* next_child_;
};

class XmlText : public XmlChild {
 public:
  explicit XmlText(const std::string& text) :
    XmlChild(),
    text_(text) {
  }
  explicit XmlText(const XmlText& t) :
    XmlChild(),
    text_(t.text_) {
  }
  explicit XmlText(const char* cstr, size_t len) :
    XmlChild(),
    text_(cstr, len) {
  }
  virtual ~XmlText();

  const std::string& Text() const { return text_; }
  void SetText(const std::string& text);
  void AddParsedText(const char* buf, int len);
  void AddText(const std::string& text);

 protected:
  virtual bool IsTextImpl() const;
  virtual XmlElement* AsElementImpl() const;
  virtual XmlText* AsTextImpl() const;

 private:
  std::string text_;
};

class XmlAttr {
 public:
  XmlAttr* NextAttr() const { return next_attr_; }
  const QName& Name() const { return name_; }
  const std::string& Value() const { return value_; }

 private:
  friend class XmlElement;

  explicit XmlAttr(const QName& name, const std::string& value) :
    next_attr_(NULL),
    name_(name),
    value_(value) {
  }
  explicit XmlAttr(const XmlAttr& att) :
    next_attr_(NULL),
    name_(att.name_),
    value_(att.value_) {
  }

  XmlAttr* next_attr_;
  QName name_;
  std::string value_;
};

class XmlElement : public XmlChild {
 public:
  explicit XmlElement(const QName& name);
  explicit XmlElement(const QName& name, bool useDefaultNs);
  explicit XmlElement(const XmlElement& elt);

  virtual ~XmlElement();

  const QName& Name() const { return name_; }
  void SetName(const QName& name) { name_ = name; }

  const std::string BodyText() const;
  void SetBodyText(const std::string& text);

  const QName FirstElementName() const;

  XmlAttr* FirstAttr();
  const XmlAttr* FirstAttr() const
    { return const_cast<XmlElement *>(this)->FirstAttr(); }

  // Attr will return an empty string if the attribute isn't there:
  // use HasAttr to test presence of an attribute.
  const std::string Attr(const StaticQName& name) const;
  const std::string Attr(const QName& name) const;
  bool HasAttr(const StaticQName& name) const;
  bool HasAttr(const QName& name) const;
  void SetAttr(const QName& name, const std::string& value);
  void ClearAttr(const QName& name);

  XmlChild* FirstChild();
  const XmlChild* FirstChild() const {
    return const_cast<XmlElement *>(this)->FirstChild();
  }

  XmlElement* FirstElement();
  const XmlElement* FirstElement() const {
    return const_cast<XmlElement *>(this)->FirstElement();
  }

  XmlElement* NextElement();
  const XmlElement* NextElement() const {
    return const_cast<XmlElement *>(this)->NextElement();
  }

  XmlElement* FirstWithNamespace(const std::string& ns);
  const XmlElement* FirstWithNamespace(const std::string& ns) const {
    return const_cast<XmlElement *>(this)->FirstWithNamespace(ns);
  }

  XmlElement* NextWithNamespace(const std::string& ns);
  const XmlElement* NextWithNamespace(const std::string& ns) const {
    return const_cast<XmlElement *>(this)->NextWithNamespace(ns);
  }

  XmlElement* FirstNamed(const StaticQName& name);
  const XmlElement* FirstNamed(const StaticQName& name) const {
    return const_cast<XmlElement *>(this)->FirstNamed(name);
  }

  XmlElement* FirstNamed(const QName& name);
  const XmlElement* FirstNamed(const QName& name) const {
    return const_cast<XmlElement *>(this)->FirstNamed(name);
  }

  XmlElement* NextNamed(const StaticQName& name);
  const XmlElement* NextNamed(const StaticQName& name) const {
    return const_cast<XmlElement *>(this)->NextNamed(name);
  }

  XmlElement* NextNamed(const QName& name);
  const XmlElement* NextNamed(const QName& name) const {
    return const_cast<XmlElement *>(this)->NextNamed(name);
  }

  // Finds the first element named 'name'.  If that element can't be found then
  // adds one and returns it.
  XmlElement* FindOrAddNamedChild(const QName& name);

  const std::string TextNamed(const QName& name) const;

  void InsertChildAfter(XmlChild* predecessor, XmlChild* new_child);
  void RemoveChildAfter(XmlChild* predecessor);

  void AddParsedText(const char* buf, int len);
  // Note: CDATA is not supported by XMPP, therefore using this function will
  // generate non-XMPP compatible XML.
  void AddCDATAText(const char* buf, int len);
  void AddText(const std::string& text);
  void AddText(const std::string& text, int depth);
  void AddElement(XmlElement* child);
  void AddElement(XmlElement* child, int depth);
  void AddAttr(const QName& name, const std::string& value);
  void AddAttr(const QName& name, const std::string& value, int depth);
  void ClearNamedChildren(const QName& name);
  void ClearAttributes();
  void ClearChildren();

  static XmlElement* ForStr(const std::string& str);
  std::string Str() const;

  bool IsCDATA() const { return cdata_; }

 protected:
  virtual bool IsTextImpl() const;
  virtual XmlElement* AsElementImpl() const;
  virtual XmlText* AsTextImpl() const;

 private:
  QName name_;
  XmlAttr* first_attr_;
  XmlAttr* last_attr_;
  XmlChild* first_child_;
  XmlChild* last_child_;
  bool cdata_;
};

}  // namespace buzz

#endif  // TALK_XMLLITE_XMLELEMENT_H_
