/*
 * Scroll windows and DCs
 *
 * Copyright 1993  David W. Metcalfe
 * Copyright 1995, 1996 Alex Korobka
 * Copyright 2001 Alexandre Julliard
 *
 * 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 "ts_xlib.h"

#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"

#include "x11drv.h"
#include "win.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(scroll);


/*************************************************************************
 *		ScrollDC   (X11DRV.@)
 *
 * Only the hrgnUpdate is returned in device coordinates.
 * rcUpdate must be returned in logical coordinates to comply with win API.
 * FIXME: the doc explicitly states the opposite, to be checked
 */
BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc,
                      const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate )
{
    RECT rect, rClip, rDst;

    TRACE( "%p %d,%d hrgnUpdate=%p rcUpdate = %p\n", hdc, dx, dy, hrgnUpdate, rcUpdate );
    if (clipRect) TRACE( "cliprc = (%ld,%ld,%ld,%ld)\n",
                         clipRect->left, clipRect->top, clipRect->right, clipRect->bottom );
    if (rc) TRACE( "rc = (%ld,%ld,%ld,%ld)\n", rc->left, rc->top, rc->right, rc->bottom );

    /* compute device clipping region (in device coordinates) */

    if (rc) rect = *rc;
    else GetClipBox( hdc, &rect );

    if (clipRect)
    {
        rClip = *clipRect;
        IntersectRect( &rClip, &rect, &rClip );
    }
    else rClip = rect;

    rDst = rClip;
    OffsetRect( &rDst, dx,  dy );
    IntersectRect( &rDst, &rDst, &rClip );

    if (!IsRectEmpty(&rDst))
    {
        /* copy bits */
        if (!BitBlt( hdc, rDst.left, rDst.top,
                     rDst.right - rDst.left, rDst.bottom - rDst.top,
                     hdc, rDst.left - dx, rDst.top - dy, SRCCOPY))
            return FALSE;
    }

    /* compute update areas */

    if (hrgnUpdate || rcUpdate)
    {
        HRGN hrgn = hrgnUpdate, hrgn2;

        /* map everything to device coordinates */
        LPtoDP( hdc, (LPPOINT)&rClip, 2 );
        LPtoDP( hdc, (LPPOINT)&rDst, 2 );

        hrgn2 = CreateRectRgnIndirect( &rDst );
        if (hrgn) SetRectRgn( hrgn, rClip.left, rClip.top, rClip.right, rClip.bottom );
        else hrgn = CreateRectRgn( rClip.left, rClip.top, rClip.right, rClip.bottom );
        CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );

        if( rcUpdate )
        {
            GetRgnBox( hrgn, rcUpdate );

            /* Put the rcUpdate in logical coordinate */
            DPtoLP( hdc, (LPPOINT)rcUpdate, 2 );
        }
        if (!hrgnUpdate) DeleteObject( hrgn );
        DeleteObject( hrgn2 );
    }
    return TRUE;
}


/*************************************************************************
 *		ScrollWindowEx   (X11DRV.@)
 *
 * Note: contrary to what the doc says, pixels that are scrolled from the
 *      outside of clipRect to the inside are NOT painted.
 *
 * Parameter are the same as in ScrollWindowEx, with the additional
 * requirement that rect and clipRect are _valid_ pointers, to
 * rectangles _within_ the client are. Moreover, there is something
 * to scroll.
 */
INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
                           const RECT *rect, const RECT *clipRect,
                           HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags )
{
    INT   retVal;
    BOOL  bOwnRgn = TRUE;
    BOOL  bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
    HRGN  hrgnTemp;
    HDC   hDC;
    RECT  rc, cliprc;

    TRACE( "%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x\n",
           hwnd, dx, dy, hrgnUpdate, rcUpdate, wine_dbgstr_rect(rect), flags );
    TRACE( "clipRect = %s\n", wine_dbgstr_rect(clipRect));

    GetClientRect(hwnd, &rc);
    if (rect) IntersectRect(&rc, &rc, rect);

    if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
    else cliprc = rc;

    if( hrgnUpdate ) bOwnRgn = FALSE;
    else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );

    hDC = GetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE );
    if (hDC)
    {
        HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
        X11DRV_StartGraphicsExposures( hDC );
        X11DRV_ScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate );
        X11DRV_EndGraphicsExposures( hDC, hrgn );
        ReleaseDC( hwnd, hDC );
        if (bUpdate) CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_OR );
        else RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_ERASE );
        DeleteObject( hrgn );
    }

    /* Take into account the fact that some damages may have occured during the scroll */
    hrgnTemp = CreateRectRgn( 0, 0, 0, 0 );
    retVal = GetUpdateRgn( hwnd, hrgnTemp, FALSE );
    if (retVal != NULLREGION)
    {
        HRGN hrgnClip = CreateRectRgnIndirect(&cliprc);
        OffsetRgn( hrgnTemp, dx, dy );
        CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
        RedrawWindow( hwnd, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE );
        DeleteObject( hrgnClip );
    }
    DeleteObject( hrgnTemp );

    if( flags & SW_SCROLLCHILDREN )
    {
        HWND *list = WIN_ListChildren( hwnd );
        if (list)
        {
            int i;
            RECT r, dummy;
            for (i = 0; list[i]; i++)
            {
                GetWindowRect( list[i], &r );
                MapWindowPoints( 0, hwnd, (POINT *)&r, 2 );
                if (!rect || IntersectRect(&dummy, &r, &rc))
                    SetWindowPos( list[i], 0, r.left + dx, r.top  + dy, 0, 0,
                                  SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE |
                                  SWP_NOREDRAW | SWP_DEFERERASE );
            }
            HeapFree( GetProcessHeap(), 0, list );
        }
    }

    if( flags & (SW_INVALIDATE | SW_ERASE) )
        RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
                      ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
                      ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );

    if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
    
    return retVal;
}
