// Copyright 2014 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

#ifndef CORE_INCLUDE_FXCRT_FX_XML_H_
#define CORE_INCLUDE_FXCRT_FX_XML_H_

#include <vector>

#include "core/include/fxcrt/fx_basic.h"

class CXML_AttrItem {
 public:
  CFX_ByteString m_QSpaceName;
  CFX_ByteString m_AttrName;
  CFX_WideString m_Value;
};

class CXML_AttrMap {
 public:
  CXML_AttrMap() { m_pMap = NULL; }
  ~CXML_AttrMap() { RemoveAll(); }
  const CFX_WideString* Lookup(const CFX_ByteStringC& space,
                               const CFX_ByteStringC& name) const;
  void SetAt(const CFX_ByteStringC& space,
             const CFX_ByteStringC& name,
             const CFX_WideStringC& value);
  void RemoveAt(const CFX_ByteStringC& space, const CFX_ByteStringC& name);
  void RemoveAll();
  int GetSize() const;
  CXML_AttrItem& GetAt(int index) const;
  CFX_ObjectArray<CXML_AttrItem>* m_pMap;
};

class CXML_Content {
 public:
  CXML_Content() : m_bCDATA(FALSE), m_Content() {}
  void Set(FX_BOOL bCDATA, const CFX_WideStringC& content) {
    m_bCDATA = bCDATA;
    m_Content = content;
  }
  FX_BOOL m_bCDATA;
  CFX_WideString m_Content;
};

class CXML_Element {
 public:
  enum ChildType { Invalid, Element, Content };

  static CXML_Element* Parse(const void* pBuffer,
                             size_t size,
                             FX_BOOL bSaveSpaceChars = FALSE,
                             FX_FILESIZE* pParsedSize = NULL);
  static CXML_Element* Parse(IFX_FileRead* pFile,
                             FX_BOOL bSaveSpaceChars = FALSE,
                             FX_FILESIZE* pParsedSize = NULL);
  static CXML_Element* Parse(IFX_BufferRead* pBuffer,
                             FX_BOOL bSaveSpaceChars = FALSE,
                             FX_FILESIZE* pParsedSize = NULL);

  CXML_Element(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagName);
  CXML_Element(const CFX_ByteStringC& qTagName);
  CXML_Element();
  ~CXML_Element();

  void Empty();
  CFX_ByteString GetTagName(FX_BOOL bQualified = FALSE) const;
  CFX_ByteString GetNamespace(FX_BOOL bQualified = FALSE) const;
  CFX_ByteString GetNamespaceURI(const CFX_ByteStringC& qName) const;
  CXML_Element* GetParent() const { return m_pParent; }
  FX_DWORD CountAttrs() const { return m_AttrMap.GetSize(); }
  void GetAttrByIndex(int index,
                      CFX_ByteString& space,
                      CFX_ByteString& name,
                      CFX_WideString& value) const;
  FX_BOOL HasAttr(const CFX_ByteStringC& qName) const;
  FX_BOOL GetAttrValue(const CFX_ByteStringC& name,
                       CFX_WideString& attribute) const;
  CFX_WideString GetAttrValue(const CFX_ByteStringC& name) const {
    CFX_WideString attr;
    GetAttrValue(name, attr);
    return attr;
  }

  FX_BOOL GetAttrValue(const CFX_ByteStringC& space,
                       const CFX_ByteStringC& name,
                       CFX_WideString& attribute) const;
  CFX_WideString GetAttrValue(const CFX_ByteStringC& space,
                              const CFX_ByteStringC& name) const {
    CFX_WideString attr;
    GetAttrValue(space, name, attr);
    return attr;
  }

  FX_BOOL GetAttrInteger(const CFX_ByteStringC& name, int& attribute) const;
  int GetAttrInteger(const CFX_ByteStringC& name) const {
    int attr = 0;
    GetAttrInteger(name, attr);
    return attr;
  }

  FX_BOOL GetAttrInteger(const CFX_ByteStringC& space,
                         const CFX_ByteStringC& name,
                         int& attribute) const;
  int GetAttrInteger(const CFX_ByteStringC& space,
                     const CFX_ByteStringC& name) const {
    int attr = 0;
    GetAttrInteger(space, name, attr);
    return attr;
  }

  FX_BOOL GetAttrFloat(const CFX_ByteStringC& name, FX_FLOAT& attribute) const;
  FX_FLOAT GetAttrFloat(const CFX_ByteStringC& name) const {
    FX_FLOAT attr = 0;
    GetAttrFloat(name, attr);
    return attr;
  }

  FX_BOOL GetAttrFloat(const CFX_ByteStringC& space,
                       const CFX_ByteStringC& name,
                       FX_FLOAT& attribute) const;
  FX_FLOAT GetAttrFloat(const CFX_ByteStringC& space,
                        const CFX_ByteStringC& name) const {
    FX_FLOAT attr = 0;
    GetAttrFloat(space, name, attr);
    return attr;
  }

  FX_DWORD CountChildren() const { return m_Children.size(); }
  ChildType GetChildType(FX_DWORD index) const;
  CFX_WideString GetContent(FX_DWORD index) const;
  CXML_Element* GetElement(FX_DWORD index) const;
  CXML_Element* GetElement(const CFX_ByteStringC& space,
                           const CFX_ByteStringC& tag) const {
    return GetElement(space, tag, 0);
  }

  FX_DWORD CountElements(const CFX_ByteStringC& space,
                         const CFX_ByteStringC& tag) const;
  CXML_Element* GetElement(const CFX_ByteStringC& space,
                           const CFX_ByteStringC& tag,
                           int index) const;

  FX_DWORD FindElement(CXML_Element* pChild) const;
  void SetTag(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagname);
  void SetTag(const CFX_ByteStringC& qTagName);
  void RemoveChildren();
  void RemoveChild(FX_DWORD index);

 protected:
  struct ChildRecord {
    ChildType type;
    void* child;  // CXML_Element and CXML_Content lack a common ancestor.
  };

  CXML_Element* m_pParent;
  CFX_ByteString m_QSpaceName;
  CFX_ByteString m_TagName;
  CXML_AttrMap m_AttrMap;
  std::vector<ChildRecord> m_Children;

  friend class CXML_Parser;
  friend class CXML_Composer;
};

#endif  // CORE_INCLUDE_FXCRT_FX_XML_H_
