// 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/fxge/fx_ge.h"
#if _FX_OS_ == _FX_WIN32_DESKTOP_ ||  _FX_OS_ == _FX_WIN64_
#include <windows.h>
#include "../../../include/fxge/fx_ge_win32.h"
#include "win32_int.h"
CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap)
{
    CFX_ByteString result;
    int len = sizeof (BITMAPINFOHEADER);
    if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
        len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP());
    }
    BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
    FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
    pbmih->biSize = sizeof(BITMAPINFOHEADER);
    pbmih->biBitCount = pBitmap->GetBPP();
    pbmih->biCompression = BI_RGB;
    pbmih->biHeight = -(int)pBitmap->GetHeight();
    pbmih->biPlanes = 1;
    pbmih->biWidth = pBitmap->GetWidth();
    if (pBitmap->GetBPP() == 8) {
        FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
        if (pBitmap->GetPalette() == NULL) {
            for (int i = 0; i < 256; i ++) {
                pPalette[i] = i * 0x010101;
            }
        } else {
            for (int i = 0; i < 256; i ++) {
                pPalette[i] = pBitmap->GetPalette()[i];
            }
        }
    }
    if (pBitmap->GetBPP() == 1) {
        FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
        if (pBitmap->GetPalette() == NULL) {
            pPalette[0] = 0;
            pPalette[1] = 0xffffff;
        } else {
            pPalette[0] = pBitmap->GetPalette()[0];
            pPalette[1] = pBitmap->GetPalette()[1];
        }
    }
    result.ReleaseBuffer(len);
    return result;
}
CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha)
{
    int width = pbmi->bmiHeader.biWidth;
    int height = pbmi->bmiHeader.biHeight;
    BOOL bBottomUp = TRUE;
    if (height < 0) {
        height = -height;
        bBottomUp = FALSE;
    }
    int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
    CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
    if (!pBitmap) {
        return NULL;
    }
    FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
    FX_BOOL ret = pBitmap->Create(width, height, format);
    if (!ret) {
        delete pBitmap;
        return NULL;
    }
    FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height);
    if (bBottomUp) {
        FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch);
        if (!temp_buf) {
            if (pBitmap) {
                delete pBitmap;
            }
            return NULL;
        }
        int top = 0, bottom = height - 1;
        while (top < bottom) {
            FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch);
            FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer() + bottom * pitch, pitch);
            FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
            top ++;
            bottom --;
        }
        FX_Free(temp_buf);
        temp_buf = NULL;
    }
    if (pbmi->bmiHeader.biBitCount == 1) {
        for (int i = 0; i < 2; i ++) {
            pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
        }
    } else if (pbmi->bmiHeader.biBitCount == 8) {
        for (int i = 0; i < 256; i ++) {
            pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
        }
    }
    return pBitmap;
}
CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData)
{
    return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE);
}
HBITMAP	CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC)
{
    CFX_ByteString info = GetBitmapInfo(pBitmap);
    HBITMAP hBitmap = NULL;
    hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)(FX_LPCSTR)info, CBM_INIT,
                             pBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
    return hBitmap;
}
void GetBitmapSize(HBITMAP hBitmap, int& w, int& h)
{
    BITMAP bmp;
    GetObject(hBitmap, sizeof bmp, &bmp);
    w = bmp.bmWidth;
    h = bmp.bmHeight;
}
CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename)
{
    CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
    if (pPlatform->m_GdiplusExt.IsAvailable()) {
        WINDIB_Open_Args_ args;
        args.flags = WINDIB_OPEN_PATHNAME;
        args.path_name = filename;
        return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
    }
    HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hBitmap == NULL) {
        return NULL;
    }
    HDC hDC = CreateCompatibleDC(NULL);
    int width, height;
    GetBitmapSize(hBitmap, width, height);
    CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
    if (!pDIBitmap) {
        DeleteDC(hDC);
        return NULL;
    }
    if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
        delete pDIBitmap;
        DeleteDC(hDC);
        return NULL;
    }
    CFX_ByteString info = GetBitmapInfo(pDIBitmap);
    int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
    if (!ret) {
        if (pDIBitmap) {
            delete pDIBitmap;
        }
        pDIBitmap = NULL;
    }
    DeleteDC(hDC);
    return pDIBitmap;
}
CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args)
{
    CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
    if (pPlatform->m_GdiplusExt.IsAvailable()) {
        return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
    } else if (args.flags == WINDIB_OPEN_MEMORY) {
        return NULL;
    }
    HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hBitmap == NULL) {
        return NULL;
    }
    HDC hDC = CreateCompatibleDC(NULL);
    int width, height;
    GetBitmapSize(hBitmap, width, height);
    CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
    if (!pDIBitmap) {
        DeleteDC(hDC);
        return NULL;
    }
    if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
        delete pDIBitmap;
        DeleteDC(hDC);
        return NULL;
    }
    CFX_ByteString info = GetBitmapInfo(pDIBitmap);
    int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
    if (!ret) {
        if (pDIBitmap) {
            delete pDIBitmap;
        }
        pDIBitmap = NULL;
    }
    DeleteDC(hDC);
    return pDIBitmap;
}
CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
{
    FX_BOOL bCreatedDC = hDC == NULL;
    if (hDC == NULL) {
        hDC = CreateCompatibleDC(NULL);
    }
    BITMAPINFOHEADER bmih;
    FXSYS_memset32(&bmih, 0, sizeof bmih);
    bmih.biSize = sizeof bmih;
    GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
    int width = bmih.biWidth;
    int height = abs(bmih.biHeight);
    bmih.biHeight = -height;
    bmih.biCompression = BI_RGB;
    CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
    if (!pDIBitmap) {
        return NULL;
    }
    int ret = 0;
    if (bmih.biBitCount == 1 || bmih.biBitCount == 8) {
        int size = sizeof (BITMAPINFOHEADER) + 8;
        if (bmih.biBitCount == 8) {
            size += sizeof (FX_DWORD) * 254;
        }
        BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size);
        if (!pbmih) {
            delete pDIBitmap;
            if (bCreatedDC) {
                DeleteDC(hDC);
            }
            return NULL;
        }
        FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
        pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pbmih->bmiHeader.biBitCount = bmih.biBitCount;
        pbmih->bmiHeader.biCompression = BI_RGB;
        pbmih->bmiHeader.biHeight = -height;
        pbmih->bmiHeader.biPlanes = 1;
        pbmih->bmiHeader.biWidth = bmih.biWidth;
        if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
            delete pDIBitmap;
            FX_Free(pbmih);
            if (bCreatedDC) {
                DeleteDC(hDC);
            }
            return NULL;
        }
        ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
        FX_Free(pbmih);
        pbmih = NULL;
        pDIBitmap->CopyPalette(pPalette, palsize);
    } else {
        if (bmih.biBitCount <= 24) {
            bmih.biBitCount = 24;
        } else {
            bmih.biBitCount = 32;
        }
        if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
            delete pDIBitmap;
            if (bCreatedDC) {
                DeleteDC(hDC);
            }
            return NULL;
        }
        ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
        if (ret != 0 && bmih.biBitCount == 32) {
            int pitch = pDIBitmap->GetPitch();
            for (int row = 0; row < height; row ++) {
                FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * pitch);
                for (int col = 0; col < width; col++) {
                    dest_scan[3] = 255;
                    dest_scan += 4;
                }
            }
        }
    }
    if (ret == 0) {
        if (pDIBitmap) {
            delete pDIBitmap;
        }
        pDIBitmap = NULL;
    }
    if (bCreatedDC) {
        DeleteDC(hDC);
    }
    return pDIBitmap;
}
CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height)
{
    Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1);
    BITMAPINFOHEADER bmih;
    FXSYS_memset32(&bmih, 0, sizeof bmih);
    bmih.biSize = sizeof bmih;
    bmih.biBitCount = 24;
    bmih.biHeight = -height;
    bmih.biPlanes = 1;
    bmih.biWidth = width;
    m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0);
    m_hMemDC = CreateCompatibleDC(hDC);
    m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
}
CFX_WindowsDIB::~CFX_WindowsDIB()
{
    SelectObject(m_hMemDC, m_hOldBitmap);
    DeleteDC(m_hMemDC);
    DeleteObject(m_hBitmap);
}
void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top)
{
    ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
}
void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top)
{
    ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);
}
#endif
