// 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/fpdfapi/fpdf_page.h"
#include "../../../include/fpdfapi/fpdf_serial.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fxcodec/fx_codec.h"
#include "../fpdf_page/pageint.h"
CFX_ByteTextBuf& operator << (CFX_ByteTextBuf& ar, CFX_AffineMatrix& matrix)
{
    ar << matrix.a << " " << matrix.b << " " << matrix.c << " " << matrix.d << " " << matrix.e << " " << matrix.f;
    return ar;
}
CPDF_PageContentGenerate::CPDF_PageContentGenerate(CPDF_Page* pPage) : m_pPage(pPage)
{
    m_pDocument = NULL;
    if (m_pPage) {
        m_pDocument = m_pPage->m_pDocument;
    }
}
CPDF_PageContentGenerate::~CPDF_PageContentGenerate()
{
    for (int i = 0; i < m_pageObjects.GetSize(); ++i) {
        CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_pageObjects[i];
        if (pPageObj) {
            pPageObj->Release();
        }
    }
}
FX_BOOL CPDF_PageContentGenerate::InsertPageObject(CPDF_PageObject* pPageObject)
{
    if (!pPageObject) {
        return FALSE;
    }
    return m_pageObjects.Add(pPageObject);
}
void CPDF_PageContentGenerate::GenerateContent()
{
    CFX_ByteTextBuf buf;
    CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict;
    for (int i = 0; i < m_pageObjects.GetSize(); ++i) {
        CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_pageObjects[i];
        if (!pPageObj || pPageObj->m_Type != PDFPAGE_IMAGE) {
            continue;
        }
        ProcessImage(buf, (CPDF_ImageObject*)pPageObj);
    }
    CPDF_Object* pContent = pPageDict->GetElementValue("Contents");
    if (pContent != NULL) {
        pPageDict->RemoveAt("Contents");
    }
    CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
    pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE);
    m_pDocument->AddIndirectObject(pStream);
    pPageDict->SetAtReference("Contents", m_pDocument, pStream->GetObjNum());
}
CFX_ByteString CPDF_PageContentGenerate::RealizeResource(CPDF_Object* pResourceObj, const FX_CHAR* szType)
{
    if (m_pPage->m_pResources == NULL) {
        m_pPage->m_pResources = FX_NEW CPDF_Dictionary;
        int objnum = m_pDocument->AddIndirectObject(m_pPage->m_pResources);
        m_pPage->m_pFormDict->SetAtReference("Resources", m_pDocument, objnum);
    }
    CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDict(szType);
    if (pResList == NULL) {
        pResList = FX_NEW CPDF_Dictionary;
        m_pPage->m_pResources->SetAt(szType, pResList);
    }
    m_pDocument->AddIndirectObject(pResourceObj);
    CFX_ByteString name;
    int idnum = 1;
    while (1) {
        name.Format("FX%c%d", szType[0], idnum);
        if (!pResList->KeyExist(name)) {
            break;
        }
        idnum ++;
    }
    pResList->AddReference(name, m_pDocument, pResourceObj->GetObjNum());
    return name;
}
void CPDF_PageContentGenerate::ProcessImage(CFX_ByteTextBuf& buf, CPDF_ImageObject* pImageObj)
{
    if ((pImageObj->m_Matrix.a == 0 && pImageObj->m_Matrix.b == 0) ||
            (pImageObj->m_Matrix.c == 0 && pImageObj->m_Matrix.d == 0)) {
        return;
    }
    buf << "q " << pImageObj->m_Matrix << " cm ";
    if (!pImageObj->m_pImage->IsInline()) {
        CPDF_Stream* pStream = pImageObj->m_pImage->GetStream();
        FX_DWORD dwSavedObjNum = pStream->GetObjNum();
        CFX_ByteString name = RealizeResource(pStream, "XObject");
        if (dwSavedObjNum == 0) {
            pImageObj->m_pImage->Release();
            pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pStream);
        }
        buf << "/" << PDF_NameEncode(name) << " Do Q\n";
    }
}
void CPDF_PageContentGenerate::ProcessForm(CFX_ByteTextBuf& buf, FX_LPCBYTE data, FX_DWORD size, CFX_Matrix& matrix)
{
    if (!data || !size) {
        return;
    }
    CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
    CPDF_Dictionary* pFormDict = CPDF_Dictionary::Create();
    pFormDict->SetAtName(FX_BSTR("Type"), FX_BSTR("XObject"));
    pFormDict->SetAtName(FX_BSTR("Subtype"), FX_BSTR("Form"));
    CFX_FloatRect bbox = m_pPage->GetPageBBox();
    matrix.TransformRect(bbox);
    pFormDict->SetAtRect(FX_BSTR("BBox"), bbox);
    pStream->InitStream((FX_LPBYTE)data, size, pFormDict);
    buf << "q " << matrix << " cm ";
    CFX_ByteString name = RealizeResource(pStream, "XObject");
    buf << "/" << PDF_NameEncode(name) << " Do Q\n";
}
void CPDF_PageContentGenerate::TransformContent(CFX_Matrix& matrix)
{
    CPDF_Object* pContent = m_pPage->m_pFormDict->GetElementValue("Contents");
    if (!pContent) {
        return;
    }
    CFX_ByteTextBuf buf;
    int type = pContent->GetType();
    if (type == PDFOBJ_ARRAY) {
        CPDF_Array* pArray = (CPDF_Array*)pContent;
        int iCount = pArray->GetCount();
        CPDF_StreamAcc** pContentArray = (CPDF_StreamAcc**)FX_Alloc(CPDF_StreamAcc*, iCount);
        int size = 0;
        int i = 0;
        for (i = 0; i < iCount; ++i) {
            pContent = pArray->GetElement(i);
            if (!pContent || pContent->GetType() != PDFOBJ_STREAM) {
                continue;
            }
            CPDF_StreamAcc* pStream = FX_NEW CPDF_StreamAcc();
            pStream->LoadAllData((CPDF_Stream*)pContent);
            pContentArray[i] = pStream;
            size += pContentArray[i]->GetSize() + 1;
        }
        int pos = 0;
        FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, size);
        for (i = 0; i < iCount; ++i) {
            FXSYS_memcpy32(pBuf + pos, pContentArray[i]->GetData(), pContentArray[i]->GetSize());
            pos += pContentArray[i]->GetSize() + 1;
            pBuf[pos - 1] = ' ';
            delete pContentArray[i];
        }
        ProcessForm(buf, pBuf, size, matrix);
        FX_Free(pBuf);
        FX_Free(pContentArray);
    } else if (type == PDFOBJ_STREAM) {
        CPDF_StreamAcc contentStream;
        contentStream.LoadAllData((CPDF_Stream*)pContent);
        ProcessForm(buf, contentStream.GetData(), contentStream.GetSize(), matrix);
    }
    CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
    pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE);
    m_pDocument->AddIndirectObject(pStream);
    m_pPage->m_pFormDict->SetAtReference("Contents", m_pDocument, pStream->GetObjNum());
}
