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

#include <stdlib.h>
#include "dc.h"
#include "region.h"
#include "debugtools.h"
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.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->w.hGCClipRgn) dc->w.hGCClipRgn = CreateRectRgn( 0, 0, 0, 0 );

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

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

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


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


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

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

/******************************************************************************
 *		ExtSelectClipRgn	[GDI32.97]
 */
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->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
            dc->w.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->w.hClipRgn)
        {
            RECT rect;
            GetRgnBox( dc->w.hVisRgn, &rect );
            dc->w.hClipRgn = CreateRectRgnIndirect( &rect );
        }

        OffsetRgn( dc->w.hClipRgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
        if(fnMode == RGN_COPY)
            retval = CombineRgn( dc->w.hClipRgn, hrgn, 0, fnMode );
        else
            retval = CombineRgn( dc->w.hClipRgn, dc->w.hClipRgn, hrgn, fnMode);
        OffsetRgn( dc->w.hClipRgn, dc->w.DCOrgX, dc->w.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->w.flags &= ~DC_DIRTY;

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


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


/***********************************************************************
 *           OffsetClipRgn    (GDI32.255)
 */
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->w.hClipRgn) {
        ret = OffsetRgn( dc->w.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->w.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->w.DCOrgX;
    right  += dc->w.DCOrgX;
    top    += dc->w.DCOrgY;
    bottom += dc->w.DCOrgY;

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

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


/***********************************************************************
 *           ExcludeClipRect16    (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.92)
 */
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;
}


/***********************************************************************
 *           IntersectClipRect16    (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.245)
 */
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->w.DCOrgX;
    right  += dc->w.DCOrgX;
    top    += dc->w.DCOrgY;
    bottom += dc->w.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->w.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->w.hVisRgn, REGION_MAGIC);
            if (prevObj)
            {
                newObj->header.hNext = prevObj->header.hNext;
                GDI_ReleaseObj( dc->w.hVisRgn );
            }
            GDI_ReleaseObj( newRgn );
        }
        DeleteObject( dc->w.hVisRgn );
        dc->w.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 *) GDI_GetObjPtr( hdc, DC_MAGIC );
    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;
}


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


/***********************************************************************
 *           PtVisible    (GDI32.279)
 */
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->w.hGCClipRgn)
    {
        ret = PtInRegion( dc->w.hGCClipRgn, XLPTODP(dc,x) + dc->w.DCOrgX, 
                                           YLPTODP(dc,y) + dc->w.DCOrgY );
}
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           RectVisible16    (GDI.104)
 */
BOOL16 WINAPI RectVisible16( HDC16 hdc, const RECT16* rect )
{
    BOOL ret = FALSE;
    RECT16 tmpRect;
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;
    TRACE("%04x %d,%dx%d,%d\n",
          hdc, rect->left, rect->top, rect->right, rect->bottom );
    if (dc->w.hGCClipRgn)
    {
        /* copy rectangle to avoid overwriting by LPtoDP */
        tmpRect = *rect;
        LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 );
        tmpRect.left   += dc->w.DCOrgX;
        tmpRect.right  += dc->w.DCOrgX;
        tmpRect.top    += dc->w.DCOrgY;
        tmpRect.bottom += dc->w.DCOrgY;
        ret = RectInRegion16( dc->w.hGCClipRgn, &tmpRect );
    }
    GDI_ReleaseObj( hdc );
    return ret;
}


/***********************************************************************
 *           RectVisible    (GDI32.282)
 */
BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
{
    RECT16 rect16;
    CONV_RECT32TO16( rect, &rect16 );
    return RectVisible16( (HDC16)hdc, &rect16 );
}


/***********************************************************************
 *           GetClipBox16    (GDI.77)
 */
INT16 WINAPI GetClipBox16( HDC16 hdc, LPRECT16 rect )
{
    int ret;
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return ERROR;    
    ret = GetRgnBox16( dc->w.hGCClipRgn, rect );
    rect->left   -= dc->w.DCOrgX;
    rect->right  -= dc->w.DCOrgX;
    rect->top    -= dc->w.DCOrgY;
    rect->bottom -= dc->w.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.162)
 */
INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
{
    INT ret;
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return ERROR;    
    ret = GetRgnBox( dc->w.hGCClipRgn, rect );
    rect->left   -= dc->w.DCOrgX;
    rect->right  -= dc->w.DCOrgX;
    rect->top    -= dc->w.DCOrgY;
    rect->bottom -= dc->w.DCOrgY;
    DPtoLP( hdc, (LPPOINT)rect, 2 );
    GDI_ReleaseObj( hdc );
    return ret;
}


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

	if( CombineRgn(hRgn, dc->w.hClipRgn, 0, RGN_COPY) != ERROR )
        {
            OffsetRgn( hRgn, -dc->w.DCOrgX, -dc->w.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->w.hVisRgn, REGION_MAGIC )))
    {
        GDI_ReleaseObj( hdc );
	return 0;
    }
    if (!(copy = CreateRectRgn( 0, 0, 0, 0 )))
    {
        GDI_ReleaseObj( dc->w.hVisRgn );
        GDI_ReleaseObj( hdc );
        return 0;
    }  
    CombineRgn( copy, dc->w.hVisRgn, 0, RGN_COPY );
    if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC )))
    {
        DeleteObject( copy );
        GDI_ReleaseObj( dc->w.hVisRgn );
        GDI_ReleaseObj( hdc );
	return 0;
    }
    copyObj->header.hNext = obj->header.hNext;
    obj->header.hNext = copy;
    GDI_ReleaseObj( copy );
    GDI_ReleaseObj( dc->w.hVisRgn );
    GDI_ReleaseObj( hdc );
    return copy;
}


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

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

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

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