/*
 * DC clipping functions
 *
 * Copyright 1993 Alexandre Julliard
 */

#include <stdlib.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "gdi.h"
#include "region.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(clipping);


/***********************************************************************
 *           CLIPPING_UpdateGCRegion
 *
 * Update the GC clip region when the ClipRgn or VisRgn have changed.
 */
void CLIPPING_UpdateGCRegion( DC * dc )
{
    if (!dc->hGCClipRgn) dc->hGCClipRgn = CreateRectRgn( 0, 0, 0, 0 );

    if (!dc->hVisRgn)
    {
        ERR("hVisRgn is zero. Please report this.\n" );
        exit(1);
    }

    if (dc->flags & DC_DIRTY) ERR( "DC is dirty. Please report this.\n" );

    if (!dc->hClipRgn)
        CombineRgn( dc->hGCClipRgn, dc->hVisRgn, 0, RGN_COPY );
    else
        CombineRgn(dc->hGCClipRgn, dc->hClipRgn, dc->hVisRgn, RGN_AND);
    if (dc->funcs->pSetDeviceClipping) dc->funcs->pSetDeviceClipping( dc );
}


/***********************************************************************
 *           SelectClipRgn    (GDI.44)
 */
INT16 WINAPI SelectClipRgn16( HDC16 hdc, HRGN16 hrgn )
{
    return (INT16)SelectClipRgn( hdc, hrgn );
}


/***********************************************************************
 *           SelectClipRgn    (GDI32.@)
 */
INT WINAPI SelectClipRgn( HDC hdc, HRGN hrgn )
{
    return ExtSelectClipRgn( hdc, hrgn, RGN_COPY );
}

/******************************************************************************
 *		ExtSelectClipRgn	[GDI.508]
 */
INT16 WINAPI ExtSelectClipRgn16( HDC16 hdc, HRGN16 hrgn, INT16 fnMode )
{
  return (INT16) ExtSelectClipRgn((HDC) hdc, (HRGN) hrgn, fnMode);
}

/******************************************************************************
 *		ExtSelectClipRgn	[GDI32.@]
 */
INT WINAPI ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT fnMode )
{
    INT retval;
    DC * dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;

    TRACE("%04x %04x %d\n", hdc, hrgn, fnMode );

    if (!hrgn)
    {
        if (fnMode == RGN_COPY)
        {
            if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
            dc->hClipRgn = 0;
            retval = SIMPLEREGION; /* Clip region == whole DC */
        }
        else
        {
            FIXME("Unimplemented: hrgn NULL in mode: %d\n", fnMode); 
            GDI_ReleaseObj( hdc );
            return ERROR;
        }
    }
    else 
    {
        if (!dc->hClipRgn)
        {
            RECT rect;
            GetRgnBox( dc->hVisRgn, &rect );
            dc->hClipRgn = CreateRectRgnIndirect( &rect );
        }

        OffsetRgn( dc->hClipRgn, -dc->DCOrgX, -dc->DCOrgY );
        if(fnMode == RGN_COPY)
            retval = CombineRgn( dc->hClipRgn, hrgn, 0, fnMode );
        else
            retval = CombineRgn( dc->hClipRgn, dc->hClipRgn, hrgn, fnMode);
        OffsetRgn( dc->hClipRgn, dc->DCOrgX, dc->DCOrgY );
    }

    CLIPPING_UpdateGCRegion( dc );
    GDI_ReleaseObj( hdc );
    return retval;
}

/***********************************************************************
 *           SelectVisRgn    (GDI.105)
 */
INT16 WINAPI SelectVisRgn16( HDC16 hdc, HRGN16 hrgn )
{
    int retval;
    DC * dc;

    if (!hrgn) return ERROR;
    if (!(dc = DC_GetDCPtr( hdc ))) return ERROR;

    TRACE("%04x %04x\n", hdc, hrgn );

    dc->flags &= ~DC_DIRTY;

    retval = CombineRgn16( dc->hVisRgn, hrgn, 0, RGN_COPY );
    CLIPPING_UpdateGCRegion( dc );
    GDI_ReleaseObj( hdc );
    return retval;
}


/***********************************************************************
 *           OffsetClipRgn    (GDI.32)
 */
INT16 WINAPI OffsetClipRgn16( HDC16 hdc, INT16 x, INT16 y )
{
    return (INT16)OffsetClipRgn( hdc, x, y );
}


/***********************************************************************
 *           OffsetClipRgn    (GDI32.@)
 */
INT WINAPI OffsetClipRgn( HDC hdc, INT x, INT y )
{
    INT ret = SIMPLEREGION;
    DC *dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;

    TRACE("%04x %d,%d\n", hdc, x, y );

    if(dc->funcs->pOffsetClipRgn)
        ret = dc->funcs->pOffsetClipRgn( dc, x, y );
    else if (dc->hClipRgn) {
        ret = OffsetRgn( dc->hClipRgn, XLSTODS(dc,x), YLSTODS(dc,y));
	CLIPPING_UpdateGCRegion( dc );
    }
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           OffsetVisRgn    (GDI.102)
 */
INT16 WINAPI OffsetVisRgn16( HDC16 hdc, INT16 x, INT16 y )
{
    INT16 retval;
    DC * dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;    
    TRACE("%04x %d,%d\n", hdc, x, y );
    retval = OffsetRgn( dc->hVisRgn, x, y );
    CLIPPING_UpdateGCRegion( dc );
    GDI_ReleaseObj( hdc );
    return retval;
}


/***********************************************************************
 *           CLIPPING_IntersectClipRect
 *
 * Helper function for {Intersect,Exclude}ClipRect, can be called from
 * elsewhere (like ExtTextOut()) to skip redundant metafile update and
 * coordinate conversion.
 */
INT CLIPPING_IntersectClipRect( DC * dc, INT left, INT top,
                                  INT right, INT bottom, UINT flags )
{
    HRGN newRgn;
    INT ret;

    left   += dc->DCOrgX;
    right  += dc->DCOrgX;
    top    += dc->DCOrgY;
    bottom += dc->DCOrgY;

    if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) return ERROR;
    if (!dc->hClipRgn)
    {
       if( flags & CLIP_INTERSECT )
       {
	   dc->hClipRgn = newRgn;
	   CLIPPING_UpdateGCRegion( dc );
           return SIMPLEREGION;
       }
       else if( flags & CLIP_EXCLUDE )
       {
           dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
     	   CombineRgn( dc->hClipRgn, dc->hVisRgn, 0, RGN_COPY );
       }
       else WARN("No hClipRgn and flags are %x\n",flags);
    }

    ret = CombineRgn( newRgn, dc->hClipRgn, newRgn, 
                        (flags & CLIP_EXCLUDE) ? RGN_DIFF : RGN_AND );
    if (ret != ERROR)
    {
        if (!(flags & CLIP_KEEPRGN)) DeleteObject( dc->hClipRgn );
        dc->hClipRgn = newRgn;    
        CLIPPING_UpdateGCRegion( dc );
    }
    else DeleteObject( newRgn );
    return ret;
}


/***********************************************************************
 *           ExcludeClipRect    (GDI.21)
 */
INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top,
                                INT16 right, INT16 bottom )
{
    return (INT16)ExcludeClipRect( hdc, left, top, right, bottom );
}


/***********************************************************************
 *           ExcludeClipRect    (GDI32.@)
 */
INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
                                INT right, INT bottom )
{
    INT ret;
    DC *dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;

    TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );

    if(dc->funcs->pExcludeClipRect)
        ret = dc->funcs->pExcludeClipRect( dc, left, top, right, bottom );
    else {
        left   = XLPTODP( dc, left );
	right  = XLPTODP( dc, right );
	top    = YLPTODP( dc, top );
	bottom = YLPTODP( dc, bottom );

	ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_EXCLUDE );
    }
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           IntersectClipRect    (GDI.22)
 */
INT16 WINAPI IntersectClipRect16( HDC16 hdc, INT16 left, INT16 top,
                                  INT16 right, INT16 bottom )
{
    return (INT16)IntersectClipRect( hdc, left, top, right, bottom );
}


/***********************************************************************
 *           IntersectClipRect    (GDI32.@)
 */
INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top,
                                  INT right, INT bottom )
{
    INT ret;
    DC *dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;

    TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );

    if(dc->funcs->pIntersectClipRect)
        ret = dc->funcs->pIntersectClipRect( dc, left, top, right, bottom );
    else {
        left   = XLPTODP( dc, left );
	right  = XLPTODP( dc, right );
	top    = YLPTODP( dc, top );
	bottom = YLPTODP( dc, bottom );

	ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_INTERSECT );
    }
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           CLIPPING_IntersectVisRect
 *
 * Helper function for {Intersect,Exclude}VisRect, can be called from
 * elsewhere (like ExtTextOut()) to skip redundant metafile update and
 * coordinate conversion.
 */
INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
                                 INT right, INT bottom,
                                 BOOL exclude )
{
    HRGN tempRgn, newRgn;
    INT ret;

    left   += dc->DCOrgX;
    right  += dc->DCOrgX;
    top    += dc->DCOrgY;
    bottom += dc->DCOrgY;

    if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
    if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
    {
        DeleteObject( newRgn );
        return ERROR;
    }
    ret = CombineRgn( newRgn, dc->hVisRgn, tempRgn,
                        exclude ? RGN_DIFF : RGN_AND );
    DeleteObject( tempRgn );

    if (ret != ERROR)
    {
        RGNOBJ *newObj  = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC);
        if (newObj)
        {
            RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC);
            if (prevObj)
            {
                newObj->header.hNext = prevObj->header.hNext;
                GDI_ReleaseObj( dc->hVisRgn );
            }
            GDI_ReleaseObj( newRgn );
        }
        DeleteObject( dc->hVisRgn );
        dc->hVisRgn = newRgn;    
        CLIPPING_UpdateGCRegion( dc );
    }
    else DeleteObject( newRgn );
    return ret;
}


/***********************************************************************
 *           ExcludeVisRect    (GDI.73)
 */
INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
                             INT16 right, INT16 bottom )
{
    INT16 ret;
    DC * dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;    

    left   = XLPTODP( dc, left );
    right  = XLPTODP( dc, right );
    top    = YLPTODP( dc, top );
    bottom = YLPTODP( dc, bottom );

    TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );

    ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE );
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           IntersectVisRect    (GDI.98)
 */
INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top,
                               INT16 right, INT16 bottom )
{
    INT16 ret;
    DC * dc = DC_GetDCUpdate( hdc );
    if (!dc) return ERROR;    

    left   = XLPTODP( dc, left );
    right  = XLPTODP( dc, right );
    top    = YLPTODP( dc, top );
    bottom = YLPTODP( dc, bottom );

    TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );

    ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE );
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           PtVisible    (GDI.103)
 */
BOOL16 WINAPI PtVisible16( HDC16 hdc, INT16 x, INT16 y )
{
    return PtVisible( hdc, x, y );
}


/***********************************************************************
 *           PtVisible    (GDI32.@)
 */
BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
{
    BOOL ret = FALSE;
    DC *dc = DC_GetDCUpdate( hdc );

    TRACE("%04x %d,%d\n", hdc, x, y );
    if (!dc) return FALSE;
    if (dc->hGCClipRgn)
    {
        ret = PtInRegion( dc->hGCClipRgn, XLPTODP(dc,x) + dc->DCOrgX, 
                                           YLPTODP(dc,y) + dc->DCOrgY );
    }
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           RectVisible    (GDI.465)
 *           RectVisibleOld (GDI.104)
 */
BOOL16 WINAPI RectVisible16( HDC16 hdc, const RECT16* rect16 )
{
    RECT rect;
    CONV_RECT16TO32( rect16, &rect );
    return RectVisible( hdc, &rect );
}


/***********************************************************************
 *           RectVisible    (GDI32.@)
 */
BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
{
    BOOL ret = FALSE;
    RECT tmpRect;
    DC *dc = DC_GetDCUpdate( hdc );
    if (!dc) return FALSE;
    TRACE("%04x %d,%dx%d,%d\n",
          hdc, rect->left, rect->top, rect->right, rect->bottom );
    if (dc->hGCClipRgn)
    {
        /* copy rectangle to avoid overwriting by LPtoDP */
        tmpRect = *rect;
        LPtoDP( hdc, (LPPOINT)&tmpRect, 2 );
        tmpRect.left   += dc->DCOrgX;
        tmpRect.right  += dc->DCOrgX;
        tmpRect.top    += dc->DCOrgY;
        tmpRect.bottom += dc->DCOrgY;
        ret = RectInRegion( dc->hGCClipRgn, &tmpRect );
    }
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           GetClipBox    (GDI.77)
 */
INT16 WINAPI GetClipBox16( HDC16 hdc, LPRECT16 rect )
{
    int ret;
    DC *dc = DC_GetDCPtr( hdc );
    if (!dc) return ERROR;    
    ret = GetRgnBox16( dc->hGCClipRgn, rect );
    rect->left   -= dc->DCOrgX;
    rect->right  -= dc->DCOrgX;
    rect->top    -= dc->DCOrgY;
    rect->bottom -= dc->DCOrgY;
    DPtoLP16( hdc, (LPPOINT16)rect, 2 );
    TRACE("%d,%d-%d,%d\n", rect->left,rect->top,rect->right,rect->bottom );
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           GetClipBox    (GDI32.@)
 */
INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
{
    INT ret;
    DC *dc = DC_GetDCPtr( hdc );
    if (!dc) return ERROR;    
    ret = GetRgnBox( dc->hGCClipRgn, rect );
    rect->left   -= dc->DCOrgX;
    rect->right  -= dc->DCOrgX;
    rect->top    -= dc->DCOrgY;
    rect->bottom -= dc->DCOrgY;
    DPtoLP( hdc, (LPPOINT)rect, 2 );
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           GetClipRgn  (GDI32.@)
 */
INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn )
{
    INT ret = -1;
    DC * dc;
    if (hRgn && (dc = DC_GetDCPtr( hdc )))
    {
      if( dc->hClipRgn )
      { 
	/* this assumes that dc->hClipRgn is in coordinates
	   relative to the device (not DC origin) */

	if( CombineRgn(hRgn, dc->hClipRgn, 0, RGN_COPY) != ERROR )
        {
            OffsetRgn( hRgn, -dc->DCOrgX, -dc->DCOrgY );
            ret = 1;
        }
      }
      else ret = 0;
      GDI_ReleaseObj( hdc );
    }
    return ret;
}

/***********************************************************************
 *           SaveVisRgn    (GDI.129)
 */
HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
{
    HRGN copy;
    RGNOBJ *obj, *copyObj;
    DC *dc = DC_GetDCUpdate( hdc );

    if (!dc) return 0;
    TRACE("%04x\n", hdc );

    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC )))
    {
        GDI_ReleaseObj( hdc );
	return 0;
    }
    if (!(copy = CreateRectRgn( 0, 0, 0, 0 )))
    {
        GDI_ReleaseObj( dc->hVisRgn );
        GDI_ReleaseObj( hdc );
        return 0;
    }  
    CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY );
    if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC )))
    {
        DeleteObject( copy );
        GDI_ReleaseObj( dc->hVisRgn );
        GDI_ReleaseObj( hdc );
	return 0;
    }
    copyObj->header.hNext = obj->header.hNext;
    obj->header.hNext = copy;
    GDI_ReleaseObj( copy );
    GDI_ReleaseObj( dc->hVisRgn );
    GDI_ReleaseObj( hdc );
    return copy;
}


/***********************************************************************
 *           RestoreVisRgn    (GDI.130)
 */
INT16 WINAPI RestoreVisRgn16( HDC16 hdc )
{
    HRGN saved;
    RGNOBJ *obj, *savedObj;
    DC *dc = DC_GetDCPtr( hdc );
    INT16 ret = ERROR;

    if (!dc) return ERROR;    
    if (!dc->hVisRgn) goto done;
    TRACE("%04x\n", hdc );
    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;

    saved = obj->header.hNext;
    GDI_ReleaseObj( dc->hVisRgn );
    if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done;

    DeleteObject( dc->hVisRgn );
    dc->hVisRgn = saved;
    dc->flags &= ~DC_DIRTY;
    CLIPPING_UpdateGCRegion( dc );
    ret = savedObj->rgn->type; /* FIXME */
    GDI_ReleaseObj( saved );
 done:
    GDI_ReleaseObj( hdc );
    return ret;
}
