/*
 * Window painting functions
 *
 * Copyright 1993, 1994, 1995, 2001 Alexandre Julliard
 * Copyright 1999 Alex Korobka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/server.h"
#include "win.h"
#include "dce.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(win);

/***********************************************************************
 *           add_paint_count
 *
 * Add an increment (normally 1 or -1) to the current paint count of a window.
 */
static void add_paint_count( HWND hwnd, int incr )
{
    SERVER_START_REQ( inc_window_paint_count )
    {
        req->handle = hwnd;
        req->incr   = incr;
        wine_server_call( req );
    }
    SERVER_END_REQ;
}


/***********************************************************************
 *           copy_rgn
 *
 * copy a region, doing the right thing if the source region is 0 or 1
 */
static HRGN copy_rgn( HRGN hSrc )
{
    if (hSrc > (HRGN)1)
    {
        HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
        CombineRgn( hrgn, hSrc, 0, RGN_COPY );
        return hrgn;
    }
    return hSrc;
}


/***********************************************************************
 *           get_update_region
 *
 * Return update region for a window.
 */
static HRGN get_update_region( WND *win )
{
    if (!win->hrgnUpdate) return CreateRectRgn( 0, 0, 0, 0 );
    if (win->hrgnUpdate > (HRGN)1) return copy_rgn( win->hrgnUpdate );
    return CreateRectRgn( 0, 0, win->rectWindow.right - win->rectWindow.left,
                          win->rectWindow.bottom - win->rectWindow.top );
}


/***********************************************************************
 *           get_update_regions
 *
 * Return update regions for the whole window and for the client area.
 */
static void get_update_regions( WND *win, HRGN *whole_rgn, HRGN *client_rgn )
{
    if (win->hrgnUpdate > (HRGN)1)
    {
        RECT client, update;

        /* check if update rgn overlaps with nonclient area */
        GetRgnBox( win->hrgnUpdate, &update );
        client = win->rectClient;
        OffsetRect( &client, -win->rectWindow.left, -win->rectWindow.top );

        if (update.left < client.left || update.top < client.top ||
            update.right > client.right || update.bottom > client.bottom)
        {
            *whole_rgn = copy_rgn( win->hrgnUpdate );
            *client_rgn = CreateRectRgnIndirect( &client );
            if (CombineRgn( *client_rgn, *client_rgn, win->hrgnUpdate, RGN_AND ) == NULLREGION)
            {
                DeleteObject( *client_rgn );
                *client_rgn = 0;
            }
        }
        else
        {
            *whole_rgn = 0;
            *client_rgn = copy_rgn( win->hrgnUpdate );
        }
    }
    else
    {
        *client_rgn = *whole_rgn = win->hrgnUpdate;  /* 0 or 1 */
    }
}


/***********************************************************************
 *           begin_ncpaint
 *
 * Send a WM_NCPAINT message from inside BeginPaint().
 * Returns update region cropped to client rectangle (and in client coords),
 * and clears window update region and internal paint flag.
 */
static HRGN begin_ncpaint( HWND hwnd )
{
    HRGN whole_rgn, client_rgn;
    WND *wnd = WIN_GetPtr( hwnd );

    if (!wnd || wnd == WND_OTHER_PROCESS) return 0;

    TRACE("hwnd %p [%p] ncf %i\n",
          hwnd, wnd->hrgnUpdate, wnd->flags & WIN_NEEDS_NCPAINT);

    get_update_regions( wnd, &whole_rgn, &client_rgn );

    if (whole_rgn) /* NOTE: WM_NCPAINT allows wParam to be 1 */
    {
        WIN_ReleasePtr( wnd );
        SendMessageA( hwnd, WM_NCPAINT, (WPARAM)whole_rgn, 0 );
        if (whole_rgn > (HRGN)1) DeleteObject( whole_rgn );
        /* make sure the window still exists before continuing */
        if (!(wnd = WIN_GetPtr( hwnd )) || wnd == WND_OTHER_PROCESS)
        {
            if (client_rgn > (HRGN)1) DeleteObject( client_rgn );
            return 0;
        }
    }

    if (wnd->hrgnUpdate || (wnd->flags & WIN_INTERNAL_PAINT)) add_paint_count( hwnd, -1 );
    if (wnd->hrgnUpdate > (HRGN)1) DeleteObject( wnd->hrgnUpdate );
    wnd->hrgnUpdate = 0;
    wnd->flags &= ~(WIN_INTERNAL_PAINT | WIN_NEEDS_NCPAINT | WIN_NEEDS_BEGINPAINT);
    if (client_rgn > (HRGN)1) OffsetRgn( client_rgn, wnd->rectWindow.left - wnd->rectClient.left,
                                         wnd->rectWindow.top - wnd->rectClient.top );
    WIN_ReleasePtr( wnd );
    return client_rgn;
}


/***********************************************************************
 *		BeginPaint (USER32.@)
 */
HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
{
    INT dcx_flags;
    BOOL bIcon;
    HRGN hrgnUpdate;
    RECT clipRect, clientRect;
    HWND full_handle;
    WND *wndPtr;

    if (!lps) return 0;

    if (!(full_handle = WIN_IsCurrentThread( hwnd )))
    {
        if (IsWindow(hwnd))
            FIXME( "window %p belongs to other thread\n", hwnd );
        return 0;
    }
    hwnd = full_handle;

    /* send WM_NCPAINT and retrieve update region */
    hrgnUpdate = begin_ncpaint( hwnd );
    if (!hrgnUpdate && !IsWindow( hwnd )) return 0;

    HideCaret( hwnd );

    bIcon = (IsIconic(hwnd) && GetClassLongA(hwnd, GCL_HICON));

    dcx_flags = DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE;
    if (bIcon) dcx_flags |= DCX_WINDOW;

    if (GetClassLongA( hwnd, GCL_STYLE ) & CS_PARENTDC)
    {
        /* Don't clip the output to the update region for CS_PARENTDC window */
        if (hrgnUpdate > (HRGN)1) DeleteObject( hrgnUpdate );
        hrgnUpdate = 0;
        dcx_flags &= ~DCX_INTERSECTRGN;
    }
    else
    {
        if (!hrgnUpdate)  /* empty region, clip everything */
        {
            hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
        }
        else if (hrgnUpdate == (HRGN)1)  /* whole client area, don't clip */
        {
            hrgnUpdate = 0;
            dcx_flags &= ~DCX_INTERSECTRGN;
        }
    }
    lps->hdc = GetDCEx( hwnd, hrgnUpdate, dcx_flags );
    /* ReleaseDC() in EndPaint() will delete the region */

    if (!lps->hdc)
    {
        WARN("GetDCEx() failed in BeginPaint(), hwnd=%p\n", hwnd);
        DeleteObject( hrgnUpdate );
        return 0;
    }

    /* It is possible that the clip box is bigger than the window itself,
       if CS_PARENTDC flag is set. Windows never return a paint rect bigger
       than the window itself, so we need to intersect the cliprect with
       the window  */
    GetClientRect( hwnd, &clientRect );

    GetClipBox( lps->hdc, &clipRect );
    LPtoDP(lps->hdc, (LPPOINT)&clipRect, 2);      /* GetClipBox returns LP */

    IntersectRect(&lps->rcPaint, &clientRect, &clipRect);
    DPtoLP(lps->hdc, (LPPOINT)&lps->rcPaint, 2);  /* we must return LP */

    TRACE("hdc = %p box = (%ld,%ld - %ld,%ld)\n",
          lps->hdc, lps->rcPaint.left, lps->rcPaint.top, lps->rcPaint.right, lps->rcPaint.bottom );

    if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
    lps->fErase = (wndPtr->flags & WIN_NEEDS_ERASEBKGND) != 0;
    wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
    WIN_ReleasePtr( wndPtr );

    if (lps->fErase)
        lps->fErase = !SendMessageA( hwnd, bIcon ? WM_ICONERASEBKGND : WM_ERASEBKGND,
                                     (WPARAM)lps->hdc, 0 );

    TRACE("hdc = %p box = (%ld,%ld - %ld,%ld), fErase = %d\n",
          lps->hdc, lps->rcPaint.left, lps->rcPaint.top, lps->rcPaint.right, lps->rcPaint.bottom,
          lps->fErase);

    return lps->hdc;
}


/***********************************************************************
 *		EndPaint (USER32.@)
 */
BOOL WINAPI EndPaint( HWND hwnd, const PAINTSTRUCT *lps )
{
    if (!lps) return FALSE;

    ReleaseDC( hwnd, lps->hdc );
    ShowCaret( hwnd );
    return TRUE;
}


/***********************************************************************
 *		GetUpdateRgn (USER32.@)
 */
INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{
    INT retval;
    HRGN update_rgn;
    WND *wndPtr = WIN_GetPtr( hwnd );

    if (!wndPtr) return ERROR;
    if (wndPtr == WND_OTHER_PROCESS)
    {
        FIXME( "not supported on other process window %p\n", hwnd );
        return ERROR;
    }

    if ((update_rgn = get_update_region( wndPtr )))
    {
        /* map coordinates and clip to client area */
        OffsetRgn( update_rgn, wndPtr->rectWindow.left - wndPtr->rectClient.left,
                   wndPtr->rectWindow.top - wndPtr->rectClient.top );
        SetRectRgn( hrgn, 0, 0, wndPtr->rectClient.right - wndPtr->rectClient.left,
                    wndPtr->rectClient.bottom - wndPtr->rectClient.top );
        retval = CombineRgn( hrgn, hrgn, update_rgn, RGN_AND );
        DeleteObject( update_rgn );
    }
    else retval = ERROR;

    WIN_ReleasePtr( wndPtr );

    if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
    return retval;
}


/***********************************************************************
 *		GetUpdateRect (USER32.@)
 */
BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
{
    WND *wndPtr;
    BOOL ret = FALSE;
    HRGN update_rgn = CreateRectRgn( 0, 0, 0, 0 );

    if (GetUpdateRgn( hwnd, update_rgn, erase ) == ERROR)
    {
        DeleteObject( update_rgn );
        return FALSE;
    }

    if (rect)
    {
        GetRgnBox( update_rgn, rect );
        if (GetClassLongA(hwnd, GCL_STYLE) & CS_OWNDC)
        {
            HDC hdc = GetDCEx( hwnd, 0, DCX_USESTYLE );
            if (hdc)
            {
                if (GetMapMode(hdc) != MM_TEXT) DPtoLP(hdc, (LPPOINT)rect,  2);
                ReleaseDC( hwnd, hdc );
            }
        }
    }
    DeleteObject( update_rgn );

    wndPtr = WIN_GetPtr( hwnd );
    if (wndPtr && wndPtr != WND_OTHER_PROCESS)
    {
        ret = (wndPtr->hrgnUpdate != 0);
        WIN_ReleasePtr( wndPtr );
    }
    return ret;
}


/***********************************************************************
 *		ExcludeUpdateRgn (USER32.@)
 */
INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
{
    HRGN update_rgn = CreateRectRgn( 0, 0, 0, 0 );
    INT ret = GetUpdateRgn( hwnd, update_rgn, FALSE );

    if (ret != ERROR)
    {
        /* do ugly coordinate translations in dce.c */

        ret = DCE_ExcludeRgn( hdc, hwnd, update_rgn );
        DeleteObject( update_rgn );
    }
    return ret;
}
