/*
 * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include "splashscreen_impl.h"
#include <windowsx.h>
#include <windows.h>
#include <winuser.h>

/* layered windows api prototypes. wouldn't be needed if we could use an updated version of the MS PSDK. */

typedef BOOL WINAPI UpdateLayeredWindowT(HWND hwnd,     // handle to layered window
                                         HDC hdcDst,    // handle to screen DC
                                         POINT * pptDst,        // new screen position
                                         SIZE * psize,  // new size of the layered window
                                         HDC hdcSrc,    // handle to surface DC
                                         POINT * pptSrc,        // layer position
                                         COLORREF crKey,        // color key
                                         BLENDFUNCTION * pblend,        // blend function
                                         DWORD dwFlags  // options
    );

#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x80000
#endif

#ifndef ULW_ALPHA
#define ULW_ALPHA               0x00000002
#endif

#ifndef AC_SRC_OVER
#define AC_SRC_OVER                 0x00
#endif

#ifndef AC_SRC_ALPHA
#define AC_SRC_ALPHA                0x01
#endif

static UpdateLayeredWindowT *UpdateLayeredWindow = NULL;

/*      Get/SetWindowLongPtr prototypes, for the case we're compiling with old headers for a 32-bit platform
        copied from Component.cpp
        FIXME: remove this as soon as the build process is using up-to-date headers */
#if !defined(__int3264)
#define GetWindowLongPtr GetWindowLong
#define SetWindowLongPtr SetWindowLong
#define GWLP_USERDATA GWL_USERDATA
#define GWLP_WNDPROC  GWL_WNDPROC
typedef __int32 LONG_PTR;
typedef unsigned __int32 ULONG_PTR;
#endif // __int3264


#define WM_SPLASHUPDATE         WM_USER+1
#define WM_SPLASHRECONFIGURE    WM_USER+2

/* Could use npt but decided to cut down on linked code size */
char* SplashConvertStringAlloc(const char* in, int *size) {
    int len, outChars, rc;
    WCHAR* buf;
    if (!in) {
        return NULL;
    }
    len = strlen(in);
    outChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, len,
                                       NULL, 0);
    buf = malloc(outChars*sizeof(WCHAR));
    rc = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, len,
                                 buf, outChars);
    if (rc==0) {
        free(buf);
        return NULL;
    } else {
        if (size) {
            *size = rc;
        }
        return (char*)buf;
    }
}

unsigned
SplashTime(void)
{
    return GetTickCount();
}

void
SplashInitFrameShape(Splash * splash, int imageIndex)
{
    RGNDATA *pRgnData;
    RGNDATAHEADER *pRgnHdr;
    ImageRect maskRect;

    if (!splash->maskRequired)
        return;

    /* reserving memory for the worst case */
    pRgnData = (RGNDATA *) malloc(sizeof(RGNDATAHEADER) +
            sizeof(RECT) * (splash->width / 2 + 1) * splash->height);
    pRgnHdr = (RGNDATAHEADER *) pRgnData;
    initRect(&maskRect, 0, 0, splash->width, splash->height, 1,
            splash->width * splash->imageFormat.depthBytes,
            splash->frames[imageIndex].bitmapBits, &splash->imageFormat);

    pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
    pRgnHdr->iType = RDH_RECTANGLES;
    pRgnHdr->nRgnSize = 0;
    pRgnHdr->rcBound.top = 0;
    pRgnHdr->rcBound.left = 0;
    pRgnHdr->rcBound.bottom = splash->height;
    pRgnHdr->rcBound.right = splash->width;

    pRgnHdr->nCount = BitmapToYXBandedRectangles(&maskRect,
            (RECT *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER)));

    splash->frames[imageIndex].hRgn = ExtCreateRegion(NULL,
            sizeof(RGNDATAHEADER) + sizeof(RECT) * pRgnHdr->nCount, pRgnData);

    free(pRgnData);
}

/* paint current splash screen frame to hdc
   this function is unused in layered window mode */

void
SplashPaint(Splash * splash, HDC hdc)
{
    unsigned numColors = splash->screenFormat.colorMap ?
        splash->screenFormat.numColors : 0;
    unsigned bmiSize;
    BITMAPV4HEADER *pBmi;
    HPALETTE hOldPal = NULL;

    if (!splash->frames)
        return;
    if (splash->currentFrame < 0 || splash->currentFrame >= splash->frameCount)
        return;
    bmiSize = sizeof(BITMAPV4HEADER) + sizeof(RGBQUAD) * numColors;
    pBmi = (BITMAPV4HEADER *) alloca(bmiSize);
    memset(pBmi, 0, sizeof(BITMAPV4HEADER));
    if (splash->screenFormat.colorMap)
        memcpy(((BYTE *) pBmi) + sizeof(BITMAPV4HEADER),
                splash->screenFormat.colorMap, sizeof(RGBQUAD) * numColors);

    pBmi->bV4Size = sizeof(BITMAPV4HEADER);
    pBmi->bV4Width = splash->width;
    pBmi->bV4Height = -splash->height;
    pBmi->bV4Planes = 1;
    pBmi->bV4BitCount = (WORD) (splash->screenFormat.depthBytes * 8);
    /* we're ALWAYS using BGRA in screenFormat */
    pBmi->bV4V4Compression = BI_RGB;
    pBmi->bV4ClrUsed = numColors;
    pBmi->bV4ClrImportant = numColors;
    pBmi->bV4AlphaMask = splash->screenFormat.mask[3];
    pBmi->bV4RedMask = splash->screenFormat.mask[2];
    pBmi->bV4GreenMask = splash->screenFormat.mask[1];
    pBmi->bV4BlueMask = splash->screenFormat.mask[0];

    /*  creating the palette in SplashInitPlatform does not work, so I'm creating it
       here on demand */
    if (!splash->hPalette) {
        unsigned i;
        LOGPALETTE *pLogPal =
            malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * numColors);

        pLogPal->palVersion = 0x300;
        pLogPal->palNumEntries = (WORD) numColors;
        for (i = 0; i < numColors; i++) {
            pLogPal->palPalEntry[i].peRed = (BYTE)
                QUAD_RED(splash->colorMap[i]);
            pLogPal->palPalEntry[i].peGreen = (BYTE)
                QUAD_GREEN(splash->colorMap[i]);
            pLogPal->palPalEntry[i].peBlue = (BYTE)
                QUAD_BLUE(splash->colorMap[i]);
            pLogPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
        }
        splash->hPalette = CreatePalette(pLogPal);
        free(pLogPal);
    }
    if (splash->hPalette) {
        hOldPal = SelectPalette(hdc, splash->hPalette, FALSE);
        RealizePalette(hdc);
    }

    StretchDIBits(hdc, 0, 0, splash->width, splash->height, 0, 0,
            splash->width, splash->height, splash->screenData,
            (BITMAPINFO *) pBmi, DIB_RGB_COLORS, SRCCOPY);
    if (hOldPal)
        SelectPalette(hdc, hOldPal, FALSE);
}


/* The function makes the window visible if it is hidden
 or is not yet shown. */
void
SplashRedrawWindow(Splash * splash)
{
    SplashUpdateScreenData(splash);
    if (splash->isLayered) {
        BLENDFUNCTION bf;
        POINT ptSrc;
        HDC hdcSrc = CreateCompatibleDC(NULL), hdcDst;
        BITMAPINFOHEADER bmi;
        void *bitmapBits;
        HBITMAP hBitmap, hOldBitmap;
        RECT rect;
        POINT ptDst;
        SIZE size;

        bf.BlendOp = AC_SRC_OVER;
        bf.BlendFlags = 0;
        bf.AlphaFormat = AC_SRC_ALPHA;
        bf.SourceConstantAlpha = 0xFF;
        ptSrc.x = ptSrc.y = 0;

        memset(&bmi, 0, sizeof(bmi));
        bmi.biSize = sizeof(BITMAPINFOHEADER);
        bmi.biWidth = splash->width;
        bmi.biHeight = -splash->height;
        bmi.biPlanes = 1;
        bmi.biBitCount = 32;
        bmi.biCompression = BI_RGB;

        //      FIXME: this is somewhat ineffective
        //      maybe if we allocate memory for all frames as DIBSections,
        //      then we could select the frames into the DC directly

        hBitmap = CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
                &bitmapBits, NULL, 0);
        memcpy(bitmapBits, splash->screenData,
                splash->screenStride * splash->height);
        hOldBitmap = (HBITMAP) SelectObject(hdcSrc, hBitmap);
        hdcDst = GetDC(splash->hWnd);

        GetWindowRect(splash->hWnd, &rect);

        ptDst.x = rect.left;
        ptDst.y = rect.top;

        size.cx = splash->width;
        size.cy = splash->height;

        UpdateLayeredWindow(splash->hWnd, hdcDst, &ptDst, &size,
                hdcSrc, &ptSrc, 0, &bf, ULW_ALPHA);

        ReleaseDC(splash->hWnd, hdcDst);
        SelectObject(hdcSrc, hOldBitmap);
        DeleteObject(hBitmap);
        DeleteDC(hdcSrc);
    }
    else {
       InvalidateRect(splash->hWnd, NULL, FALSE);
       if (splash->maskRequired) {
            HRGN hRgn = CreateRectRgn(0, 0, 0, 0);

            CombineRgn(hRgn, splash->frames[splash->currentFrame].hRgn,
                    splash->frames[splash->currentFrame].hRgn, RGN_COPY);
            SetWindowRgn(splash->hWnd, hRgn, TRUE);
        } else {
            SetWindowRgn(splash->hWnd, NULL, TRUE);
        }
        UpdateWindow(splash->hWnd);
    }
    if (!IsWindowVisible(splash->hWnd)) {
        POINT cursorPos;
        ShowWindow(splash->hWnd, SW_SHOW);
        // Windows won't update the cursor after the window is shown,
        // if the cursor is already above the window. need to do this manually.
        GetCursorPos(&cursorPos);
        if (WindowFromPoint(cursorPos) == splash->hWnd) {
            // unfortunately Windows fail to understand that the window
            // thread should own the cursor, even though the mouse pointer
            // is over the window, until the mouse has been moved.
            // we're using SetCursorPos here to fake the mouse movement
            // and enable proper update of the cursor.
            SetCursorPos(cursorPos.x, cursorPos.y);
            SetCursor(LoadCursor(NULL, IDC_WAIT));
        }
    }
    if (SplashIsStillLooping(splash)) {
        int time = splash->time +
            splash->frames[splash->currentFrame].delay - SplashTime();

        if (time < 0)
            time = 0;
        SetTimer(splash->hWnd, 0, time, NULL);
    }
    else {
        KillTimer(splash->hWnd, 0);
    }
}

void SplashReconfigureNow(Splash * splash) {
    splash->x = (GetSystemMetrics(SM_CXSCREEN) - splash->width) / 2;
    splash->y = (GetSystemMetrics(SM_CYSCREEN) - splash->height) / 2;
    if (splash->hWnd) {
        //Fixed 6474657: splash screen image jumps towards left while
        //    setting the new image using setImageURL()
        // We may safely hide the splash window because SplashRedrawWindow()
        //    will show the window again.
        ShowWindow(splash->hWnd, SW_HIDE);
        MoveWindow(splash->hWnd, splash->x, splash->y, splash->width, splash->height, FALSE);
    }
    SplashRedrawWindow(splash);
}

static LRESULT CALLBACK
SplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;


    switch (message) {

    case WM_ERASEBKGND:
        return TRUE;            // to avoid flicker

    case WM_SYSCOMMAND:
        if (wParam==SC_CLOSE||wParam==SC_DEFAULT||wParam==SC_HOTKEY||
            wParam==SC_KEYMENU||wParam==SC_MAXIMIZE||
            wParam==SC_MINIMIZE||wParam==SC_MOUSEMENU||wParam==SC_MOVE||
            wParam==SC_RESTORE||wParam==SC_SIZE)
        {
            return 0;
        }

    /* double switch to avoid prologue/epilogue duplication */
    case WM_TIMER:
    case WM_SPLASHUPDATE:
    case WM_PAINT:
    case WM_SPLASHRECONFIGURE:
        {
            Splash *splash = (Splash *) GetWindowLongPtr(hWnd, GWLP_USERDATA);

            SplashLock(splash);
            if (splash->isVisible>0) {
                switch(message) {
                case WM_TIMER:
                    SplashNextFrame(splash);
                    SplashRedrawWindow(splash);
                    break;
                case WM_SPLASHUPDATE:
                    SplashRedrawWindow(splash);
                    break;
                case WM_PAINT:
                    hdc = BeginPaint(hWnd, &ps);
                    SplashPaint(splash, hdc);
                    EndPaint(hWnd, &ps);
                    break;
                case WM_SPLASHRECONFIGURE:
                    SplashReconfigureNow(splash);
                    break;
                }
            }
            SplashUnlock(splash);
            break;
        }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);

    }
    return 0;
}

HWND
SplashCreateWindow(Splash * splash)
{
    WNDCLASSEX wcex;
    ATOM wndClass;
    DWORD style, exStyle;
    HWND hWnd;

    ZeroMemory(&wcex, sizeof(WNDCLASSEX));

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = (WNDPROC) SplashWndProc;
    wcex.hInstance = GetModuleHandle(NULL);
    wcex.lpszClassName = "JavaSplash";
    wcex.hCursor = LoadCursor(NULL, IDC_WAIT);

    wndClass = RegisterClassEx(&wcex);
    if (!wndClass) {
        return 0;
    }

    splash->x = (GetSystemMetrics(SM_CXSCREEN) - splash->width) / 2;
    splash->y = (GetSystemMetrics(SM_CYSCREEN) - splash->height) / 2;
    exStyle = splash->isLayered ? WS_EX_LAYERED : 0;
    exStyle |= WS_EX_TOOLWINDOW;        /* don't show the window on taskbar */
    style = WS_POPUP;
    hWnd = CreateWindowEx(exStyle, (LPCSTR) wndClass, "", style,
            splash->x, splash->y, splash->width, splash->height, NULL, NULL,
            wcex.hInstance, NULL);
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) splash);
    return hWnd;
}

void
SplashLock(Splash * splash)
{
    EnterCriticalSection(&splash->lock);
}

void
SplashUnlock(Splash * splash)
{
    LeaveCriticalSection(&splash->lock);
}

void
SplashInitPlatform(Splash * splash)
{
    HMODULE user32 = LoadLibrary("user32.dll");
    HDC hdc;
    int paletteMode;

    InitializeCriticalSection(&splash->lock);
    splash->isLayered = FALSE;
    if (user32) {
        UpdateLayeredWindow = (UpdateLayeredWindowT *)
            GetProcAddress(user32, "UpdateLayeredWindow");
    }
    hdc = GetDC(NULL);
    paletteMode = (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) != 0;
    if (UpdateLayeredWindow && !paletteMode) {
        splash->isLayered = TRUE;
    }
    splash->byteAlignment = 4;
    if (splash->isLayered) {
        initFormat(&splash->screenFormat,
                0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        splash->screenFormat.premultiplied = 1;
        splash->maskRequired = 0;
    }
    else {
        splash->maskRequired = 1;
        if (paletteMode) {
            int numColors = GetDeviceCaps(hdc, SIZEPALETTE) -
                GetDeviceCaps(hdc, NUMRESERVED);
            int i;
            int numComponents[3];

            initFormat(&splash->screenFormat, 0, 0, 0, 0);
            /*      FIXME: maybe remapping to non-reserved colors would improve performance */
            for (i = 0; i < numColors; i++) {
                splash->colorIndex[i] = i;
            }
            numColors = quantizeColors(numColors, numComponents);
            initColorCube(numComponents, splash->colorMap, splash->dithers,
                    splash->colorIndex);
            splash->screenFormat.colorIndex = splash->colorIndex;
            splash->screenFormat.depthBytes = 1;
            splash->screenFormat.colorMap = splash->colorMap;
            splash->screenFormat.dithers = splash->dithers;
            splash->screenFormat.numColors = numColors;
            splash->hPalette = NULL;
        }
        else {
            initFormat(&splash->screenFormat,
                    0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        }
    }
    ReleaseDC(NULL, hdc);
}

void
SplashCleanupPlatform(Splash * splash)
{
    int i;

    if (splash->frames) {
        for (i = 0; i < splash->frameCount; i++) {
            if (splash->frames[i].hRgn) {
                DeleteObject(splash->frames[i].hRgn);
                splash->frames[i].hRgn = NULL;
            }
        }
    }
    if (splash->hPalette)
        DeleteObject(splash->hPalette);
    splash->maskRequired = !splash->isLayered;
}

void
SplashDonePlatform(Splash * splash)
{
    if (splash->hWnd)
        DestroyWindow(splash->hWnd);
}

void
SplashMessagePump()
{
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

DWORD WINAPI
SplashScreenThread(LPVOID param)
{
    Splash *splash = (Splash *) param;

    splash->currentFrame = 0;
    SplashLock(splash);
    splash->time = SplashTime();
    splash->hWnd = SplashCreateWindow(splash);
    if (splash->hWnd) {
        SplashRedrawWindow(splash);
        SplashUnlock(splash);
        SplashMessagePump();
        SplashLock(splash);
    }
    SplashDone(splash);
    splash->isVisible = -1;
    SplashUnlock(splash);
    return 0;
}

void
SplashCreateThread(Splash * splash)
{
    DWORD threadId;

    CreateThread(NULL, 0, SplashScreenThread, (LPVOID) splash, 0, &threadId);
}

void
SplashClosePlatform(Splash * splash)
{
    PostMessage(splash->hWnd, WM_QUIT, 0, 0);
}

void
SplashUpdate(Splash * splash)
{
    PostMessage(splash->hWnd, WM_SPLASHUPDATE, 0, 0);
}

void
SplashReconfigure(Splash * splash)
{
    PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0);
}
