// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcrt/xml/cfx_xmlelement.h"

#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/xml/cfx_xmlchardata.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

CFX_XMLElement::CFX_XMLElement(const CFX_WideString& wsTag)
    : CFX_XMLAttributeNode(wsTag) {}

CFX_XMLElement::~CFX_XMLElement() {}

FX_XMLNODETYPE CFX_XMLElement::GetType() const {
  return FX_XMLNODE_Element;
}

std::unique_ptr<CFX_XMLNode> CFX_XMLElement::Clone() {
  auto pClone = pdfium::MakeUnique<CFX_XMLElement>(GetName());
  pClone->SetAttributes(GetAttributes());

  CFX_WideString wsText;
  CFX_XMLNode* pChild = m_pChild;
  while (pChild) {
    switch (pChild->GetType()) {
      case FX_XMLNODE_Text:
        wsText += static_cast<CFX_XMLText*>(pChild)->GetText();
        break;
      default:
        break;
    }
    pChild = pChild->m_pNext;
  }
  pClone->SetTextData(wsText);
  return pClone;
}

CFX_WideString CFX_XMLElement::GetLocalTagName() const {
  auto pos = GetName().Find(L':');
  return pos.has_value()
             ? GetName().Right(GetName().GetLength() - pos.value() - 1)
             : GetName();
}

CFX_WideString CFX_XMLElement::GetNamespacePrefix() const {
  auto pos = GetName().Find(L':');
  return pos.has_value() ? GetName().Left(pos.value()) : CFX_WideString();
}

CFX_WideString CFX_XMLElement::GetNamespaceURI() const {
  CFX_WideString wsAttri(L"xmlns");
  CFX_WideString wsPrefix = GetNamespacePrefix();
  if (wsPrefix.GetLength() > 0) {
    wsAttri += L":";
    wsAttri += wsPrefix;
  }

  auto* pNode = static_cast<const CFX_XMLNode*>(this);
  while (pNode) {
    if (pNode->GetType() != FX_XMLNODE_Element)
      break;

    auto* pElement = static_cast<const CFX_XMLElement*>(pNode);
    if (!pElement->HasAttribute(wsAttri)) {
      pNode = pNode->GetNodeItem(CFX_XMLNode::Parent);
      continue;
    }
    return pElement->GetString(wsAttri);
  }
  return CFX_WideString();
}

CFX_WideString CFX_XMLElement::GetTextData() const {
  CFX_WideTextBuf buffer;
  CFX_XMLNode* pChild = m_pChild;
  while (pChild) {
    switch (pChild->GetType()) {
      case FX_XMLNODE_Text:
      case FX_XMLNODE_CharData:
        buffer << static_cast<CFX_XMLText*>(pChild)->GetText();
        break;
      default:
        break;
    }
    pChild = pChild->m_pNext;
  }
  return buffer.MakeString();
}

void CFX_XMLElement::SetTextData(const CFX_WideString& wsText) {
  if (wsText.GetLength() < 1)
    return;
  InsertChildNode(new CFX_XMLText(wsText));
}
