// 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_render.h"
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#include "../../../include/fxge/fx_ge.h"
#include "../fpdf_page/pageint.h"
#include "render_int.h"
struct CACHEINFO {
    FX_DWORD time;
    CPDF_Stream* pStream;
};
extern "C" {
    static int compare(const void* data1, const void* data2)
    {
        return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time;
    }
};
void CPDF_Page::ClearRenderCache()
{
    if (m_pPageRender) {
        m_pPageRender->ClearAll();
    }
}
void CPDF_PageRenderCache::ClearAll()
{
    FX_POSITION pos = m_ImageCaches.GetStartPosition();
    while (pos) {
        void* key;
        void* value;
        m_ImageCaches.GetNextAssoc(pos, key, value);
        delete (CPDF_ImageCache*)value;
    }
    m_ImageCaches.RemoveAll();
    m_nCacheSize = 0;
    m_nTimeCount = 0;
}
void CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize)
{
    if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize) {
        return;
    }
    int nCount = m_ImageCaches.GetCount();
    CACHEINFO* pCACHEINFO = (CACHEINFO*)FX_Alloc2D(uint8_t, sizeof(CACHEINFO), nCount);
    FX_POSITION pos = m_ImageCaches.GetStartPosition();
    int i = 0;
    while (pos) {
        void* key;
        void* value;
        m_ImageCaches.GetNextAssoc(pos, key, value);
        pCACHEINFO[i].time = ((CPDF_ImageCache*)value)->GetTimeCount();
        pCACHEINFO[i++].pStream = ((CPDF_ImageCache*)value)->GetStream();
    }
    FXSYS_qsort(pCACHEINFO, nCount, sizeof (CACHEINFO), compare);
    FX_DWORD nTimeCount = m_nTimeCount;
    if (nTimeCount + 1 < nTimeCount) {
        for (i = 0; i < nCount; i ++) {
            ((CPDF_ImageCache*)(m_ImageCaches[pCACHEINFO[i].pStream]))->m_dwTimeCount = i;
        }
        m_nTimeCount = nCount;
    }
    i = 0;
    while(nCount > 15) {
        ClearImageCache(pCACHEINFO[i++].pStream);
        nCount--;
    }
    while (m_nCacheSize > (FX_DWORD)dwLimitCacheSize) {
        ClearImageCache(pCACHEINFO[i++].pStream);
    }
    FX_Free(pCACHEINFO);
}
void CPDF_PageRenderCache::ClearImageCache(CPDF_Stream* pStream)
{
    void* value = m_ImageCaches.GetValueAt(pStream);
    if (value == NULL)	{
        m_ImageCaches.RemoveKey(pStream);
        return;
    }
    m_nCacheSize -= ((CPDF_ImageCache*)value)->EstimateSize();
    delete (CPDF_ImageCache*)value;
    m_ImageCaches.RemoveKey(pStream);
}
FX_DWORD CPDF_PageRenderCache::EstimateSize()
{
    FX_DWORD dwSize = 0;
    FX_POSITION pos = m_ImageCaches.GetStartPosition();
    while (pos) {
        void* key;
        void* value;
        m_ImageCaches.GetNextAssoc(pos, key, value);
        dwSize += ((CPDF_ImageCache*)value)->EstimateSize();
    }
    m_nCacheSize = dwSize;
    return dwSize;
}
FX_DWORD CPDF_PageRenderCache::GetCachedSize(CPDF_Stream* pStream) const
{
    if (pStream == NULL) {
        return m_nCacheSize;
    }
    CPDF_ImageCache* pImageCache;
    if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) {
        return 0;
    }
    return pImageCache->EstimateSize();
}
void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream, CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor,
        FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus,
        int32_t downsampleWidth, int32_t downsampleHeight)
{
    CPDF_ImageCache* pImageCache;
    FX_BOOL bFind = m_ImageCaches.Lookup(pStream, (void*&)pImageCache);
    if (!bFind) {
        pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
    }
    m_nTimeCount ++;
    FX_BOOL bCached = pImageCache->GetCachedBitmap(pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS, GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
    if (!bFind) {
        m_ImageCaches.SetAt(pStream, pImageCache);
    }
    if (!bCached) {
        m_nCacheSize += pImageCache->EstimateSize();
    }
}
FX_BOOL	CPDF_PageRenderCache::StartGetCachedBitmap(CPDF_Stream* pStream, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, int32_t downsampleWidth, int32_t downsampleHeight)
{
    m_bCurFindCache = m_ImageCaches.Lookup(pStream, (void*&)m_pCurImageCache);
    if (!m_bCurFindCache) {
        m_pCurImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
    }
    int ret = m_pCurImageCache->StartGetCachedBitmap(pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS, GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
    if (ret == 2) {
        return TRUE;
    }
    m_nTimeCount ++;
    if (!m_bCurFindCache) {
        m_ImageCaches.SetAt(pStream, m_pCurImageCache);
    }
    if (!ret) {
        m_nCacheSize += m_pCurImageCache->EstimateSize();
    }
    return FALSE;
}
FX_BOOL	CPDF_PageRenderCache::Continue(IFX_Pause* pPause)
{
    int ret = m_pCurImageCache->Continue(pPause);
    if (ret == 2) {
        return TRUE;
    }
    m_nTimeCount ++;
    if (!m_bCurFindCache) {
        m_ImageCaches.SetAt(m_pCurImageCache->GetStream(), m_pCurImageCache);
    }
    if (!ret) {
        m_nCacheSize += m_pCurImageCache->EstimateSize();
    }
    return FALSE;
}
void CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap)
{
    CPDF_ImageCache* pImageCache;
    if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) {
        if (pBitmap == NULL) {
            return;
        }
        pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
        m_ImageCaches.SetAt(pStream, pImageCache);
    }
    int oldsize = pImageCache->EstimateSize();
    pImageCache->Reset(pBitmap);
    m_nCacheSize = pImageCache->EstimateSize() - oldsize;
}
CPDF_ImageCache::CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream)
    : m_dwTimeCount(0)
    , m_pCurBitmap(NULL)
    , m_pCurMask(NULL)
    , m_MatteColor(0)
    , m_pRenderStatus(NULL)
    , m_pDocument(pDoc)
    , m_pStream(pStream)
    , m_pCachedBitmap(NULL)
    , m_pCachedMask(NULL)
    , m_dwCacheSize(0)
{
}
CPDF_ImageCache::~CPDF_ImageCache()
{
    delete m_pCachedBitmap;
    m_pCachedBitmap = NULL;
    delete m_pCachedMask;
    m_pCachedMask = NULL;
}
void CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap)
{
    delete m_pCachedBitmap;
    m_pCachedBitmap = NULL;
    if (pBitmap) {
        m_pCachedBitmap = pBitmap->Clone();
    }
    CalcSize();
}
void CPDF_PageRenderCache::ClearImageData()
{
    FX_POSITION pos = m_ImageCaches.GetStartPosition();
    while (pos) {
        void* key;
        void* value;
        m_ImageCaches.GetNextAssoc(pos, key, value);
        ((CPDF_ImageCache*)value)->ClearImageData();
    }
}
void CPDF_ImageCache::ClearImageData()
{
    if (m_pCachedBitmap && m_pCachedBitmap->GetBuffer() == NULL) {
        ((CPDF_DIBSource*)m_pCachedBitmap)->ClearImageData();
    }
}
static FX_DWORD FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB)
{
    return pDIB && pDIB->GetBuffer() ? (FX_DWORD)pDIB->GetHeight() * pDIB->GetPitch() + (FX_DWORD)pDIB->GetPaletteSize() * 4 : 0;
}
FX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor, CPDF_Dictionary* pPageResources,
        FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus,
        int32_t downsampleWidth, int32_t downsampleHeight)
{
    if (m_pCachedBitmap) {
        pBitmap = m_pCachedBitmap;
        pMask = m_pCachedMask;
        MatteColor = m_MatteColor;
        return TRUE;
    }
    if (!pRenderStatus) {
        return FALSE;
    }
    CPDF_RenderContext*pContext = pRenderStatus->GetContext();
    CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache;
    m_dwTimeCount = pPageRenderCache->GetTimeCount();
    CPDF_DIBSource* pSrc = new CPDF_DIBSource;
    CPDF_DIBSource* pMaskSrc = NULL;
    if (!pSrc->Load(m_pDocument, m_pStream, &pMaskSrc, &MatteColor, pRenderStatus->m_pFormResource, pPageResources, bStdCS, GroupFamily, bLoadMask)) {
        delete pSrc;
        pBitmap = NULL;
        return FALSE;
    }
    m_MatteColor = MatteColor;
    if (pSrc->GetPitch() * pSrc->GetHeight() < FPDF_HUGE_IMAGE_SIZE) {
        m_pCachedBitmap = pSrc->Clone();
        delete pSrc;
    } else {
        m_pCachedBitmap = pSrc;
    }
    if (pMaskSrc) {
        m_pCachedMask = pMaskSrc->Clone();
        delete pMaskSrc;
    }

    pBitmap = m_pCachedBitmap;
    pMask = m_pCachedMask;
    CalcSize();
    return FALSE;
}
CFX_DIBSource* CPDF_ImageCache::DetachBitmap()
{
    CFX_DIBSource* pDIBSource = m_pCurBitmap;
    m_pCurBitmap = NULL;
    return pDIBSource;
}
CFX_DIBSource* CPDF_ImageCache::DetachMask()
{
    CFX_DIBSource* pDIBSource = m_pCurMask;
    m_pCurMask = NULL;
    return pDIBSource;
}
int	CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, FX_BOOL bStdCS,
        FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus,
        int32_t downsampleWidth, int32_t downsampleHeight)
{
    if (m_pCachedBitmap) {
        m_pCurBitmap = m_pCachedBitmap;
        m_pCurMask = m_pCachedMask;
        return 1;
    }
    if (!pRenderStatus) {
        return 0;
    }
    m_pRenderStatus = pRenderStatus;
    m_pCurBitmap = new CPDF_DIBSource;
    int ret = ((CPDF_DIBSource*)m_pCurBitmap)->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResources, pPageResources, bStdCS, GroupFamily, bLoadMask);
    if (ret == 2) {
        return ret;
    }
    if (!ret) {
        delete m_pCurBitmap;
        m_pCurBitmap = NULL;
        return 0;
    }
    ContinueGetCachedBitmap();
    return 0;
}
int CPDF_ImageCache::ContinueGetCachedBitmap()
{
    m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->m_MatteColor;
    m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask();
    CPDF_RenderContext*pContext = m_pRenderStatus->GetContext();
    CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache;
    m_dwTimeCount = pPageRenderCache->GetTimeCount();
    if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() < FPDF_HUGE_IMAGE_SIZE) {
        m_pCachedBitmap = m_pCurBitmap->Clone();
        delete m_pCurBitmap;
        m_pCurBitmap = NULL;
    } else {
        m_pCachedBitmap = m_pCurBitmap;
    }
    if (m_pCurMask) {
        m_pCachedMask = m_pCurMask->Clone();
        delete m_pCurMask;
        m_pCurMask = NULL;
    }
    m_pCurBitmap = m_pCachedBitmap;
    m_pCurMask = m_pCachedMask;
    CalcSize();
    return 0;
}
int	CPDF_ImageCache::Continue(IFX_Pause* pPause)
{
    int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause);
    if (ret == 2) {
        return ret;
    }
    if (!ret) {
        delete m_pCurBitmap;
        m_pCurBitmap = NULL;
        return 0;
    }
    ContinueGetCachedBitmap();
    return 0;
}
void CPDF_ImageCache::CalcSize()
{
    m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) + FPDF_ImageCache_EstimateImageSize(m_pCachedMask);
}
void CPDF_Document::ClearRenderFont()
{
    if (m_pDocRender) {
        CFX_FontCache* pCache = m_pDocRender->GetFontCache();
        if (pCache) {
            pCache->FreeCache(FALSE);
        }
    }
}
