// 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_resource.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../fpdf_font/font_int.h"
#include "cmap_int.h"
void FPDFAPI_FindEmbeddedCMap(const char* name, int charset, int coding, const FXCMAP_CMap*& pMap)
{
    pMap = NULL;
    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
    const FXCMAP_CMap* pCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_pMapList;
    int nCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_Count;
    for (int i = 0; i < nCMaps; i ++) {
        if (FXSYS_strcmp(name, pCMaps[i].m_Name)) {
            continue;
        }
        pMap = &pCMaps[i];
        break;
    }
}
extern "C" {
    static int compareWord(const void* p1, const void* p2)
    {
        return (*(FX_WORD*)p1) - (*(FX_WORD*)p2);
    }
};
extern "C" {
    static int compareWordRange(const void* key, const void* element)
    {
        if (*(FX_WORD*)key < * (FX_WORD*)element) {
            return -1;
        }
        if (*(FX_WORD*)key > ((FX_WORD*)element)[1]) {
            return 1;
        }
        return 0;
    }
};
extern "C" {
    static int compareDWordRange(const void* p1, const void* p2)
    {
        FX_DWORD key = *(FX_DWORD*)p1;
        FX_WORD hiword = (FX_WORD)(key >> 16);
        FX_WORD* element = (FX_WORD*)p2;
        if (hiword < element[0]) {
            return -1;
        }
        if (hiword > element[0]) {
            return 1;
        }
        FX_WORD loword = (FX_WORD)key;
        if (loword < element[1]) {
            return -1;
        }
        if (loword > element[2]) {
            return 1;
        }
        return 0;
    }
};
extern "C" {
    static int compareDWordSingle(const void* p1, const void* p2)
    {
        FX_DWORD key = *(FX_DWORD*)p1;
        FX_DWORD value = ((*(FX_WORD*)p2) << 16) | ((FX_WORD*)p2)[1];
        if (key < value) {
            return -1;
        }
        if (key > value) {
            return 1;
        }
        return 0;
    }
};
FX_WORD FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, FX_DWORD charcode)
{
    if (charcode >> 16) {
        while (1) {
            if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
                FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 8, compareDWordRange);
                if (found) {
                    return found[3] + (FX_WORD)charcode - found[1];
                }
            } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
                FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 6, compareDWordSingle);
                if (found) {
                    return found[2];
                }
            }
            if (pMap->m_UseOffset == 0) {
                return 0;
            }
            pMap = pMap + pMap->m_UseOffset;
        }
        return 0;
    }
    FX_WORD code = (FX_WORD)charcode;
    while (1) {
        if (pMap->m_pWordMap == NULL) {
            return 0;
        }
        if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
            FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&code, pMap->m_pWordMap, pMap->m_WordCount, 4, compareWord);
            if (found) {
                return found[1];
            }
        } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
            FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&code, pMap->m_pWordMap, pMap->m_WordCount, 6, compareWordRange);
            if (found) {
                return found[2] + code - found[0];
            }
        }
        if (pMap->m_UseOffset == 0) {
            return 0;
        }
        pMap = pMap + pMap->m_UseOffset;
    }
    return 0;
}
FX_DWORD FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, FX_WORD cid)
{
    while (1) {
        if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
            const FX_WORD *pCur = pMap->m_pWordMap;
            const FX_WORD *pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2;
            while (pCur < pEnd) {
                if (pCur[1] == cid) {
                    return pCur[0];
                }
                pCur += 2;
            }
        } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
            const FX_WORD *pCur = pMap->m_pWordMap;
            const FX_WORD *pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3;
            while (pCur < pEnd) {
                if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) {
                    return pCur[0] + cid - pCur[2];
                }
                pCur += 3;
            }
        }
        if (pMap->m_UseOffset == 0) {
            return 0;
        }
        pMap = pMap + pMap->m_UseOffset;
    }
    while (1) {
        if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
            const FX_WORD *pCur = pMap->m_pDWordMap;
            const FX_WORD *pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 4;
            while (pCur < pEnd) {
                if (cid >= pCur[3] && cid <= pCur[3] + pCur[2] - pCur[1]) {
                    return (((FX_DWORD)pCur[0] << 16) | pCur[1]) + cid - pCur[3];
                }
                pCur += 4;
            }
        } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
            const FX_WORD *pCur = pMap->m_pDWordMap;
            const FX_WORD *pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 3;
            while (pCur < pEnd) {
                if (pCur[2] == cid) {
                    return ((FX_DWORD)pCur[0] << 16) | pCur[1];
                }
                pCur += 3;
            }
        }
        if (pMap->m_UseOffset == 0) {
            return 0;
        }
        pMap = pMap + pMap->m_UseOffset;
    }
    return 0;
}
void FPDFAPI_LoadCID2UnicodeMap(int charset, const FX_WORD*& pMap, FX_DWORD& count)
{
    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
    pMap = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
    count = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
}
