/*
 * 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.
 */

#include "talk/xmllite/xmlelement.h"

#include <ostream>
#include <sstream>
#include <string>
#include <vector>

#include "talk/base/common.h"
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlparser.h"
#include "talk/xmllite/xmlbuilder.h"
#include "talk/xmllite/xmlprinter.h"
#include "talk/xmllite/xmlconstants.h"

namespace buzz {

XmlChild::~XmlChild() {
}

bool
XmlText::IsTextImpl() const {
  return true;
}

XmlElement *
XmlText::AsElementImpl() const {
  return NULL;
}

XmlText *
XmlText::AsTextImpl() const {
  return const_cast<XmlText *>(this);
}

void
XmlText::SetText(const std::string & text) {
  text_ = text;
}

void
XmlText::AddParsedText(const char * buf, int len) {
  text_.append(buf, len);
}

void
XmlText::AddText(const std::string & text) {
  text_ += text;
}

XmlText::~XmlText() {
}

XmlElement::XmlElement(const QName & name) :
    name_(name),
    pFirstAttr_(NULL),
    pLastAttr_(NULL),
    pFirstChild_(NULL),
    pLastChild_(NULL),
    cdata_(false) {
}

XmlElement::XmlElement(const XmlElement & elt) :
    XmlChild(),
    name_(elt.name_),
    pFirstAttr_(NULL),
    pLastAttr_(NULL),
    pFirstChild_(NULL),
    pLastChild_(NULL),
    cdata_(false) {

  // copy attributes
  XmlAttr * pAttr;
  XmlAttr ** ppLastAttr = &pFirstAttr_;
  XmlAttr * newAttr = NULL;
  for (pAttr = elt.pFirstAttr_; pAttr; pAttr = pAttr->NextAttr()) {
    newAttr = new XmlAttr(*pAttr);
    *ppLastAttr = newAttr;
    ppLastAttr = &(newAttr->pNextAttr_);
  }
  pLastAttr_ = newAttr;

  // copy children
  XmlChild * pChild;
  XmlChild ** ppLast = &pFirstChild_;
  XmlChild * newChild = NULL;

  for (pChild = elt.pFirstChild_; pChild; pChild = pChild->NextChild()) {
    if (pChild->IsText()) {
      newChild = new XmlText(*(pChild->AsText()));
    } else {
      newChild = new XmlElement(*(pChild->AsElement()));
    }
    *ppLast = newChild;
    ppLast = &(newChild->pNextChild_);
  }
  pLastChild_ = newChild;

  cdata_ = elt.cdata_;
}

XmlElement::XmlElement(const QName & name, bool useDefaultNs) :
  name_(name),
  pFirstAttr_(useDefaultNs ? new XmlAttr(QN_XMLNS, name.Namespace()) : NULL),
  pLastAttr_(pFirstAttr_),
  pFirstChild_(NULL),
  pLastChild_(NULL),
  cdata_(false) {
}

bool
XmlElement::IsTextImpl() const {
  return false;
}

XmlElement *
XmlElement::AsElementImpl() const {
  return const_cast<XmlElement *>(this);
}

XmlText *
XmlElement::AsTextImpl() const {
  return NULL;
}

const std::string &
XmlElement::BodyText() const {
  if (pFirstChild_ && pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
    return pFirstChild_->AsText()->Text();
  }

  return EmptyStringRef();
}

void
XmlElement::SetBodyText(const std::string & text) {
  if (text == STR_EMPTY) {
    ClearChildren();
  } else if (pFirstChild_ == NULL) {
    AddText(text);
  } else if (pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
    pFirstChild_->AsText()->SetText(text);
  } else {
    ClearChildren();
    AddText(text);
  }
}

const QName &
XmlElement::FirstElementName() const {
  const XmlElement * element = FirstElement();
  if (element == NULL)
    return EmptyQNameRef();
  return element->Name();
}

XmlAttr *
XmlElement::FirstAttr() {
  return pFirstAttr_;
}

const std::string &
XmlElement::Attr(const StaticQName & name) const {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
    if (pattr->name_ == name)
      return pattr->value_;
  }
  return EmptyStringRef();
}

const std::string &
XmlElement::Attr(const QName & name) const {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
    if (pattr->name_ == name)
      return pattr->value_;
  }
  return EmptyStringRef();
}

bool
XmlElement::HasAttr(const StaticQName & name) const {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
    if (pattr->name_ == name)
      return true;
  }
  return false;
}

bool
XmlElement::HasAttr(const QName & name) const {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
    if (pattr->name_ == name)
      return true;
  }
  return false;
}

void
XmlElement::SetAttr(const QName & name, const std::string & value) {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
    if (pattr->name_ == name)
      break;
  }
  if (!pattr) {
    pattr = new XmlAttr(name, value);
    if (pLastAttr_)
      pLastAttr_->pNextAttr_ = pattr;
    else
      pFirstAttr_ = pattr;
    pLastAttr_ = pattr;
    return;
  }
  pattr->value_ = value;
}

void
XmlElement::ClearAttr(const QName & name) {
  XmlAttr * pattr;
  XmlAttr *pLastAttr = NULL;
  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
    if (pattr->name_ == name)
      break;
    pLastAttr = pattr;
  }
  if (!pattr)
    return;
  if (!pLastAttr)
    pFirstAttr_ = pattr->pNextAttr_;
  else
    pLastAttr->pNextAttr_ = pattr->pNextAttr_;
  if (pLastAttr_ == pattr)
    pLastAttr_ = pLastAttr;
  delete pattr;
}

XmlChild *
XmlElement::FirstChild() {
  return pFirstChild_;
}

XmlElement *
XmlElement::FirstElement() {
  XmlChild * pChild;
  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText())
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::NextElement() {
  XmlChild * pChild;
  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText())
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::FirstWithNamespace(const std::string & ns) {
  XmlChild * pChild;
  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::NextWithNamespace(const std::string & ns) {
  XmlChild * pChild;
  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::FirstNamed(const QName & name) {
  XmlChild * pChild;
  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::FirstNamed(const StaticQName & name) {
  XmlChild * pChild;
  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::NextNamed(const QName & name) {
  XmlChild * pChild;
  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement *
XmlElement::NextNamed(const StaticQName & name) {
  XmlChild * pChild;
  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
      return pChild->AsElement();
  }
  return NULL;
}

XmlElement* XmlElement::FindOrAddNamedChild(const QName& name) {
  XmlElement* child = FirstNamed(name);
  if (!child) {
    child = new XmlElement(name);
    AddElement(child);
  }

  return child;
}

const std::string &
XmlElement::TextNamed(const QName & name) const {
  XmlChild * pChild;
  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
      return pChild->AsElement()->BodyText();
  }
  return EmptyStringRef();
}

void
XmlElement::InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNext) {
  if (pPredecessor == NULL) {
    pNext->pNextChild_ = pFirstChild_;
    pFirstChild_ = pNext;
  }
  else {
    pNext->pNextChild_ = pPredecessor->pNextChild_;
    pPredecessor->pNextChild_ = pNext;
  }
}

void
XmlElement::RemoveChildAfter(XmlChild * pPredecessor) {
  XmlChild * pNext;

  if (pPredecessor == NULL) {
    pNext = pFirstChild_;
    pFirstChild_ = pNext->pNextChild_;
  }
  else {
    pNext = pPredecessor->pNextChild_;
    pPredecessor->pNextChild_ = pNext->pNextChild_;
  }

  if (pLastChild_ == pNext)
    pLastChild_ = pPredecessor;

  delete pNext;
}

void
XmlElement::AddAttr(const QName & name, const std::string & value) {
  ASSERT(!HasAttr(name));

  XmlAttr ** pprev = pLastAttr_ ? &(pLastAttr_->pNextAttr_) : &pFirstAttr_;
  pLastAttr_ = (*pprev = new XmlAttr(name, value));
}

void
XmlElement::AddAttr(const QName & name, const std::string & value,
                         int depth) {
  XmlElement * element = this;
  while (depth--) {
    element = element->pLastChild_->AsElement();
  }
  element->AddAttr(name, value);
}

void
XmlElement::AddParsedText(const char * cstr, int len) {
  if (len == 0)
    return;

  if (pLastChild_ && pLastChild_->IsText()) {
    pLastChild_->AsText()->AddParsedText(cstr, len);
    return;
  }
  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
  pLastChild_ = *pprev = new XmlText(cstr, len);
}

void
XmlElement::AddCDATAText(const char * buf, int len) {
  cdata_ = true;
  AddParsedText(buf, len);
}

void
XmlElement::AddText(const std::string & text) {
  if (text == STR_EMPTY)
    return;

  if (pLastChild_ && pLastChild_->IsText()) {
    pLastChild_->AsText()->AddText(text);
    return;
  }
  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
  pLastChild_ = *pprev = new XmlText(text);
}

void
XmlElement::AddText(const std::string & text, int depth) {
  // note: the first syntax is ambigious for msvc 6
  // XmlElement * pel(this);
  XmlElement * element = this;
  while (depth--) {
    element = element->pLastChild_->AsElement();
  }
  element->AddText(text);
}

void
XmlElement::AddElement(XmlElement *pelChild) {
  if (pelChild == NULL)
    return;

  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
  pLastChild_ = *pprev = pelChild;
  pelChild->pNextChild_ = NULL;
}

void
XmlElement::AddElement(XmlElement *pelChild, int depth) {
  XmlElement * element = this;
  while (depth--) {
    element = element->pLastChild_->AsElement();
  }
  element->AddElement(pelChild);
}

void
XmlElement::ClearNamedChildren(const QName & name) {
  XmlChild * prev_child = NULL;
  XmlChild * next_child;
  XmlChild * child;
  for (child = FirstChild(); child; child = next_child) {
    next_child = child->NextChild();
    if (!child->IsText() && child->AsElement()->Name() == name)
    {
      RemoveChildAfter(prev_child);
      continue;
    }
    prev_child = child;
  }
}

void
XmlElement::ClearAttributes() {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; ) {
    XmlAttr * pToDelete = pattr;
    pattr = pattr->pNextAttr_;
    delete pToDelete;
  }
  pFirstAttr_ = pLastAttr_ = NULL;
}

void
XmlElement::ClearChildren() {
  XmlChild * pchild;
  for (pchild = pFirstChild_; pchild; ) {
    XmlChild * pToDelete = pchild;
    pchild = pchild->pNextChild_;
    delete pToDelete;
  }
  pFirstChild_ = pLastChild_ = NULL;
}

std::string
XmlElement::Str() const {
  std::stringstream ss;
  XmlPrinter::PrintXml(&ss, this);
  return ss.str();
}

XmlElement *
XmlElement::ForStr(const std::string & str) {
  XmlBuilder builder;
  XmlParser::ParseXml(&builder, str);
  return builder.CreateElement();
}

XmlElement::~XmlElement() {
  XmlAttr * pattr;
  for (pattr = pFirstAttr_; pattr; ) {
    XmlAttr * pToDelete = pattr;
    pattr = pattr->pNextAttr_;
    delete pToDelete;
  }

  XmlChild * pchild;
  for (pchild = pFirstChild_; pchild; ) {
    XmlChild * pToDelete = pchild;
    pchild = pchild->pNextChild_;
    delete pToDelete;
  }
}

}
