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

#include "../../include/fpdfdoc/fpdf_doc.h"
#include "../../include/fxcrt/fx_xml.h"
typedef struct _PDFDOC_METADATA {
    CPDF_Document *m_pDoc;
    CXML_Element *m_pXmlElmnt;
    CXML_Element *m_pElmntRdf;
    CFX_CMapByteStringToPtr *m_pStringMap;
} PDFDOC_METADATA, * PDFDOC_LPMETADATA;
typedef PDFDOC_METADATA const * PDFDOC_LPCMETADATA;
const FX_LPCSTR gs_FPDFDOC_Metadata_Titles[] = {
    "Title", "title",
    "Subject", "description",
    "Author", "creator",
    "Keywords", "Keywords",
    "Producer", "Producer",
    "Creator", "CreatorTool",
    "CreationDate", "CreateDate",
    "ModDate", "ModifyDate",
    "MetadataDate", "MetadataDate"
};
CPDF_Metadata::CPDF_Metadata()
{
    m_pData = FX_Alloc(PDFDOC_METADATA, 1);
    CFX_CMapByteStringToPtr *&pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
    pStringMap = FX_NEW CFX_CMapByteStringToPtr;
    if (pStringMap != NULL) {
        CFX_ByteString bstr;
        for (int i = 0; i < 18; i += 2) {
            bstr = gs_FPDFDOC_Metadata_Titles[i];
            pStringMap->AddValue(bstr, (void*)gs_FPDFDOC_Metadata_Titles[i + 1]);
        }
    }
}
CPDF_Metadata::~CPDF_Metadata()
{
    FXSYS_assert(m_pData != NULL);
    CXML_Element *&p = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
    delete p;
    CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
    if (pStringMap) {
        pStringMap->RemoveAll();
        delete pStringMap;
    }
    FX_Free(m_pData);
}
void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc)
{
    FXSYS_assert(pDoc != NULL);
    ((PDFDOC_LPMETADATA)m_pData)->m_pDoc = pDoc;
    CPDF_Dictionary *pRoot = pDoc->GetRoot();
    CPDF_Stream *pStream = pRoot->GetStream(FX_BSTRC("Metadata"));
    if (!pStream) {
        return;
    }
    CPDF_StreamAcc acc;
    acc.LoadAllData(pStream, FALSE);
    int size = acc.GetSize();
    FX_LPCBYTE pBuf = acc.GetData();
    CXML_Element *&pXmlElmnt = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
    pXmlElmnt = CXML_Element::Parse(pBuf, size);
    if (!pXmlElmnt) {
        return;
    }
    CXML_Element *&pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
    if (pXmlElmnt->GetTagName() == FX_BSTRC("RDF")) {
        pElmntRdf = pXmlElmnt;
    } else {
        pElmntRdf = pXmlElmnt->GetElement(NULL, FX_BSTRC("RDF"));
    }
}
FX_INT32 CPDF_Metadata::GetString(FX_BSTR bsItem, CFX_WideString &wsStr)
{
    if (!((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt) {
        return -1;
    }
    if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap) {
        return -1;
    }
    void *szTag;
    if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap->Lookup(bsItem, szTag)) {
        return -1;
    }
    CFX_ByteString bsTag = (FX_LPCSTR)szTag;
    wsStr = L"";
    CXML_Element *pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
    if (!pElmntRdf) {
        return -1;
    }
    int nChild = pElmntRdf->CountChildren();
    for (int i = 0; i < nChild; i++) {
        CXML_Element *pTag = pElmntRdf->GetElement(NULL, FX_BSTRC("Description"), i);
        if (!pTag) {
            continue;
        }
        if (bsItem == FX_BSTRC("Title") || bsItem == FX_BSTRC("Subject")) {
            CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Alt"));
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
            if (!pElmnt) {
                continue;
            }
            wsStr = pElmnt->GetContent(0);
            return wsStr.GetLength();
        } else if (bsItem == FX_BSTRC("Author")) {
            CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq"));
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
            if (!pElmnt) {
                continue;
            }
            wsStr = pElmnt->GetContent(0);
            return wsStr.GetLength();
        } else {
            CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
            if (!pElmnt) {
                continue;
            }
            wsStr = pElmnt->GetContent(0);
            return wsStr.GetLength();
        }
    }
    return -1;
}
CXML_Element* CPDF_Metadata::GetRoot() const
{
    return ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
}
CXML_Element* CPDF_Metadata::GetRDF() const
{
    return ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
}