// 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 _FX_XML_H_
#define _FX_XML_H_
#ifndef _FX_BASIC_H_
#include "fx_basic.h"
#endif
class CXML_AttrItem : public CFX_Object
{
public:
    CFX_ByteString	m_QSpaceName;
    CFX_ByteString	m_AttrName;
    CFX_WideString	m_Value;
};
class CXML_AttrMap : public CFX_Object
{
public:
    CXML_AttrMap()
    {
        m_pMap = NULL;
    }
    ~CXML_AttrMap()
    {
        RemoveAll();
    }
    const CFX_WideString*	Lookup(FX_BSTR space, FX_BSTR name) const;
    void					SetAt(FX_BSTR space, FX_BSTR name, FX_WSTR value);
    void					RemoveAt(FX_BSTR space, FX_BSTR name);
    void					RemoveAll();
    int						GetSize() const;
    CXML_AttrItem&			GetAt(int index) const;
    CFX_ObjectArray<CXML_AttrItem>*	m_pMap;
};
class CXML_Content : public CFX_Object
{
public:
    CXML_Content() : m_bCDATA(FALSE), m_Content() {}
    void	Set(FX_BOOL bCDATA, FX_WSTR content)
    {
        m_bCDATA = bCDATA;
        m_Content = content;
    }
    FX_BOOL			m_bCDATA;
    CFX_WideString	m_Content;
};
class CXML_Element : public CFX_Object
{
public:
    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(FX_BSTR qSpace, FX_BSTR tagName);
    CXML_Element(FX_BSTR 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(FX_BSTR 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(FX_BSTR qName) const;

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

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

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

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

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

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

    FX_DWORD				CountChildren() const;

    enum ChildType { Invalid, Element, Content};

    ChildType				GetChildType(FX_DWORD index) const;

    CFX_WideString			GetContent(FX_DWORD index) const;

    CXML_Element*			GetElement(FX_DWORD index) const;

    CXML_Element*			GetElement(FX_BSTR space, FX_BSTR tag) const
    {
        return GetElement(space, tag, 0);
    }

    FX_DWORD				CountElements(FX_BSTR space, FX_BSTR tag) const;

    CXML_Element*			GetElement(FX_BSTR space, FX_BSTR tag, int index) const;

    FX_DWORD				FindElement(CXML_Element *pChild) const;




    void					SetTag(FX_BSTR qSpace, FX_BSTR tagname);

    void					SetTag(FX_BSTR qTagName);

    void					RemoveChildren();

    void					RemoveChild(FX_DWORD index);


protected:

    CXML_Element*			m_pParent;
    CFX_ByteString			m_QSpaceName;
    CFX_ByteString			m_TagName;

    CXML_AttrMap			m_AttrMap;

    CFX_PtrArray			m_Children;
    friend class CXML_Parser;
    friend class CXML_Composer;
};
#endif
