// 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;
    if (p) {
        delete p;
    }
    CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
    if (pStringMap) {
        pStringMap->RemoveAll();
        FX_Free(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;
}
