/*
 * GDI region objects
 *
 * Copyright 1993, 1994 Alexandre Julliard
 */

static char Copyright[] = "Copyright  Alexandre Julliard, 1993, 1994";

#include <stdlib.h>
#include <stdio.h>

#include "gdi.h"

  /* GC used for region operations */
static GC regionGC = 0;

/***********************************************************************
 *           REGION_Init
 */
BOOL REGION_Init()
{
    Pixmap tmpPixmap;

      /* CreateGC needs a drawable */
    tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 );
    if (tmpPixmap)
    {
	regionGC = XCreateGC( display, tmpPixmap, 0, NULL );
	XFreePixmap( display, tmpPixmap );
	if (!regionGC) return FALSE;
	XSetForeground( display, regionGC, 1 );
	XSetGraphicsExposures( display, regionGC, False );
	return TRUE;
    }
    else return FALSE;
}


/***********************************************************************
 *           REGION_MakePixmap
 *
 * Make a pixmap of an X region.
 */
static BOOL REGION_MakePixmap( REGION *region )
{
    int width = region->box.right - region->box.left;
    int height = region->box.bottom - region->box.top;

    if (!region->xrgn) return TRUE;  /* Null region */
    region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
    if (!region->pixmap) return FALSE;
    XSetRegion( display, regionGC, region->xrgn );
    XSetClipOrigin( display, regionGC, region->box.left, region->box.top );
    XSetFunction( display, regionGC, GXcopy );
    XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height );
    XSetClipMask( display, regionGC, None );  /* Clear clip region */
    return TRUE;
}


/***********************************************************************
 *           REGION_SetRect
 *
 * Set the bounding box of the region and create the pixmap (or the X rgn).
 * The hrgn must be valid.
 */
static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect, BOOL createXrgn )
{
    int width, height;

      /* Fill region */

    REGION * region = &((RGNOBJ *)GDI_HEAP_ADDR( hrgn ))->region;
    width  = rect->right - rect->left;
    height = rect->bottom - rect->top;
    if ((width <= 0) || (height <= 0))
    {
	region->type       = NULLREGION;
	region->box.left   = 0;
	region->box.right  = 0;
	region->box.top    = 0;
	region->box.bottom = 0;
	region->pixmap     = 0;
	region->xrgn       = 0;
	return TRUE;
    }
    region->type   = SIMPLEREGION;
    region->box    = *rect;
    region->xrgn   = 0;
    region->pixmap = 0;

    if (createXrgn)  /* Create and set the X region */
    {
	Region tmprgn;
	XRectangle xrect = { region->box.left, region->box.top, width, height};

	if (!(tmprgn = XCreateRegion())) return FALSE;
	if ((region->xrgn = XCreateRegion()))
	    XUnionRectWithRegion( &xrect, tmprgn, region->xrgn );
	XDestroyRegion( tmprgn );
	if (!region->xrgn) return FALSE;
    }
    else  /* Create the pixmap */
    {
	region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1);
	if (!region->pixmap) return FALSE;
	  /* Fill the pixmap */
	XSetFunction( display, regionGC, GXclear );
	XFillRectangle(display, region->pixmap, regionGC, 0, 0, width, height);
    }
    return TRUE;
}


/***********************************************************************
 *           REGION_DeleteObject
 */
BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj )
{
    if (obj->region.pixmap) XFreePixmap( display, obj->region.pixmap );
    if (obj->region.xrgn) XDestroyRegion( obj->region.xrgn );
    return GDI_FreeObject( hrgn );
}


/***********************************************************************
 *           OffsetRgn    (GDI.101)
 */
int OffsetRgn( HRGN hrgn, short x, short y )
{
    RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
    if (!obj) return ERROR;
#ifdef DEBUG_REGION
    printf( "OffsetRgn: %d %d,%d\n", hrgn, x, y );
#endif
    OffsetRect( &obj->region.box, x, y );
    if (obj->region.xrgn) XOffsetRegion( obj->region.xrgn, x, y );
    return obj->region.type;
}


/***********************************************************************
 *           GetRgnBox    (GDI.134)
 */
int GetRgnBox( HRGN hrgn, LPRECT rect )
{
    RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
    if (!obj) return ERROR;
#ifdef DEBUG_REGION
    printf( "GetRgnBox: %d\n", hrgn );
#endif
    *rect = obj->region.box;
    return obj->region.type;
}


/***********************************************************************
 *           CreateRectRgn    (GDI.64)
 */
HRGN CreateRectRgn( short left, short top, short right, short bottom )
{
    RECT rect = { left, top, right, bottom };    
    return CreateRectRgnIndirect( &rect );
}


/***********************************************************************
 *           CreateRectRgnIndirect    (GDI.65)
 */
HRGN CreateRectRgnIndirect( LPRECT rect )
{
    HRGN hrgn;

#ifdef DEBUG_REGION
    printf( "CreateRectRgnIndirect: %d,%d-%d,%d\n",
	    rect->left, rect->top, rect->right, rect->bottom );
#endif
    
      /* Create region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
    if (!REGION_SetRect( hrgn, rect, TRUE ))
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    return hrgn;
}


/***********************************************************************
 *           CreateRoundRectRgn    (GDI.444)
 */
HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
			 short ellipse_width, short ellipse_height )
{
    RECT rect = { left, top, right, bottom };    
    RGNOBJ * rgnObj;
    HRGN hrgn;

#ifdef DEBUG_REGION
    printf( "CreateRoundRectRgn: %d,%d-%d,%d %dx%d\n",
	    left, top, right, bottom, ellipse_width, ellipse_height );
#endif
    
      /* Create region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
    if (!REGION_SetRect( hrgn, &rect, FALSE ))
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );

      /* Fill pixmap */
    
    if (rgnObj->region.type != NULLREGION)
    {
	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
	XSetFunction( display, regionGC, GXcopy );
	XFillRectangle( display, rgnObj->region.pixmap, regionGC,
		        0, ellipse_height / 2,
		        width, height - ellipse_height );
	XFillRectangle( display, rgnObj->region.pixmap, regionGC,
		        ellipse_width / 2, 0,
		        width - ellipse_width, height );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  0, 0,
		  ellipse_width, ellipse_height, 0, 360*64 );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  width - ellipse_width, 0,
		  ellipse_width, ellipse_height, 0, 360*64 );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  0, height - ellipse_height,
		  ellipse_width, ellipse_height, 0, 360*64 );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  width - ellipse_width, height - ellipse_height,
		  ellipse_width, ellipse_height, 0, 360*64 );
    }
    
    return hrgn;
}


/***********************************************************************
 *           SetRectRgn    (GDI.172)
 */
void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
{
    RECT rect = { left, top, right, bottom };    
    RGNOBJ * rgnObj;

#ifdef DEBUG_REGION
    printf( "SetRectRgn: %d %d,%d-%d,%d\n", hrgn, left, top, right, bottom );
#endif
    
      /* Free previous pixmap */

    if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
    if (rgnObj->region.pixmap) XFreePixmap( display, rgnObj->region.pixmap );
    if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
    REGION_SetRect( hrgn, &rect, TRUE );
}


/***********************************************************************
 *           CreateEllipticRgn    (GDI.54)
 */
HRGN CreateEllipticRgn( short left, short top, short right, short bottom )
{
    RECT rect = { left, top, right, bottom };    
    return CreateEllipticRgnIndirect( &rect );
}


/***********************************************************************
 *           CreateEllipticRgnIndirect    (GDI.55)
 */
HRGN CreateEllipticRgnIndirect( LPRECT rect )
{
    RGNOBJ * rgnObj;
    HRGN hrgn;

#ifdef DEBUG_REGION
    printf( "CreateEllipticRgnIndirect: %d,%d-%d,%d\n",
	    rect->left, rect->top, rect->right, rect->bottom );
#endif
    
      /* Create region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
    if (!REGION_SetRect( hrgn, rect, FALSE ))
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );

      /* Fill pixmap */
    
    if (rgnObj->region.type != NULLREGION)
    {
	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
	XSetFunction( display, regionGC, GXcopy );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  0, 0, width, height, 0, 360*64 );
    }
    
    return hrgn;
}


/***********************************************************************
 *           CreatePolygonRgn    (GDI.63)
 */
HRGN CreatePolygonRgn( POINT * points, short count, short mode )
{
    return CreatePolyPolygonRgn( points, &count, 1, mode );
}


/***********************************************************************
 *           CreatePolyPolygonRgn    (GDI.451)
 */
HRGN CreatePolyPolygonRgn( POINT * points, short * count,
			   short nbpolygons, short mode )
{
    RGNOBJ * rgnObj;
    HRGN hrgn;
    int i, j, maxPoints;
    XPoint *xpoints, *pt;
    XRectangle rect;
    Region xrgn;

#ifdef DEBUG_REGION
    printf( "CreatePolyPolygonRgn: %d polygons\n", nbpolygons );
#endif

      /* Allocate points array */

    if (!nbpolygons) return 0;
    for (i = maxPoints = 0; i < nbpolygons; i++)
	if (maxPoints < count[i]) maxPoints = count[i];
    if (!maxPoints) return 0;
    if (!(xpoints = (XPoint *) malloc( sizeof(XPoint) * maxPoints )))
	return 0;

      /* Allocate region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )))
    {
	free( xpoints );
	return 0;
    }
    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
    rgnObj->region.type   = SIMPLEREGION;
    rgnObj->region.pixmap = 0;

      /* Create X region */

    for (i = 0; i < nbpolygons; i++, count++)
    {
	for (j = *count, pt = xpoints; j > 0; j--, points++, pt++)
	{
	    pt->x = points->x;
	    pt->y = points->y;
	}
	xrgn = XPolygonRegion( xpoints, *count,
			       (mode == WINDING) ? WindingRule : EvenOddRule );
	if (!xrgn) break;
	if (i > 0)
	{
	    Region tmprgn = XCreateRegion();
	    if (mode == WINDING) XUnionRegion(xrgn,rgnObj->region.xrgn,tmprgn);
	    else XXorRegion( xrgn, rgnObj->region.xrgn, tmprgn );
	    XDestroyRegion( rgnObj->region.xrgn );
	    rgnObj->region.xrgn = tmprgn;
	}
	else rgnObj->region.xrgn = xrgn;
    }

    free( xpoints );
    if (!xrgn)
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    XClipBox( rgnObj->region.xrgn, &rect );
    SetRect( &rgnObj->region.box, rect.x, rect.y,
	     rect.x + rect.width, rect.y + rect.height);
    return hrgn;
}


/***********************************************************************
 *           PtInRegion    (GDI.161)
 */
BOOL PtInRegion( HRGN hrgn, short x, short y )
{
    BOOL res;
    RGNOBJ * obj;
    POINT pt = { x, y };
    
    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
    if (!PtInRect( &obj->region.box, pt )) return FALSE;
    if (obj->region.xrgn)
    {
	return XPointInRegion( obj->region.xrgn, x, y );
    }
    else
    {
	XImage *image = XGetImage( display, obj->region.pixmap,
			    x - obj->region.box.left, y - obj->region.box.top,
			    1, 1, AllPlanes, ZPixmap );
	if (!image) return FALSE;
	res = (XGetPixel( image, 0, 0 ) != 0);
	XDestroyImage( image );
    }
    return res;
}


/***********************************************************************
 *           RectInRegion    (GDI.181)
 */
BOOL RectInRegion( HRGN hrgn, LPRECT rect )
{
    XImage * image;
    RGNOBJ * obj;
    RECT intersect;
    int x, y;
    
    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
    if (obj->region.xrgn)
    {
	return (XRectInRegion( obj->region.xrgn, rect->left, rect->top,
			       rect->right-rect->left,
			       rect->bottom-rect->top ) != RectangleOut);
    }
    else
    {
	if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE;
    
	image = XGetImage( display, obj->region.pixmap,
			   intersect.left - obj->region.box.left,
			   intersect.top - obj->region.box.top,
			   intersect.right - intersect.left,
			   intersect.bottom - intersect.top,
			   AllPlanes, ZPixmap );
	if (!image) return FALSE;
	for (y = 0; y < image->height; y++)
	    for (x = 0; x < image->width; x++)
		if (XGetPixel( image, x, y ) != 0)
		{
		    XDestroyImage( image );
		    return TRUE;
		}
    
	XDestroyImage( image );
    }
    return FALSE;
}


/***********************************************************************
 *           EqualRgn    (GDI.72)
 */
BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
{
    RGNOBJ *obj1, *obj2;
    XImage *image1, *image2;
    Pixmap pixmap1, pixmap2;
    int width, height, x, y;

      /* Compare bounding boxes */

    if (!(obj1 = (RGNOBJ *) GDI_GetObjPtr( rgn1, REGION_MAGIC ))) return FALSE;
    if (!(obj2 = (RGNOBJ *) GDI_GetObjPtr( rgn2, REGION_MAGIC ))) return FALSE;
    if (obj1->region.type == NULLREGION)
	return (obj2->region.type == NULLREGION);
    else if (obj2->region.type == NULLREGION) return FALSE;
    if (!EqualRect( &obj1->region.box, &obj2->region.box )) return FALSE;
    if (obj1->region.xrgn && obj2->region.xrgn)
    {
	return XEqualRegion( obj1->region.xrgn, obj2->region.xrgn );
    }
    
      /* Get pixmap contents */

    if (!(pixmap1 = obj1->region.pixmap) &&
	!REGION_MakePixmap( &obj1->region )) return FALSE;
    if (!(pixmap2 = obj2->region.pixmap) &&
	!REGION_MakePixmap( &obj2->region )) return FALSE;
    width  = obj1->region.box.right - obj1->region.box.left;
    height = obj1->region.box.bottom - obj1->region.box.top;
    image1 = XGetImage( display, obj1->region.pixmap,
			0, 0, width, height, AllPlanes, ZPixmap );
    image2 = XGetImage( display, obj2->region.pixmap,
		        0, 0, width, height, AllPlanes, ZPixmap );
    if (!image1 || !image2)
    {
	if (image1) XDestroyImage( image1 );
	if (image2) XDestroyImage( image2 );
	return FALSE;
    }
    
      /* Compare pixmaps */
    for (y = 0; y < height; y++)
	for (x = 0; x < width; x++)
	    if (XGetPixel( image1, x, y ) != XGetPixel( image2, x, y))
	    {
		XDestroyImage( image1 );
		XDestroyImage( image2 );
		return FALSE;
	    }
    
    XDestroyImage( image1 );
    XDestroyImage( image2 );
    return TRUE;
}


/***********************************************************************
 *           REGION_CopyIntersection
 *
 * Copy to dest->pixmap the area of src->pixmap delimited by
 * the intersection of dest and src regions, using the current GC function.
 */
void REGION_CopyIntersection( REGION * dest, REGION * src )
{
    RECT inter;
    if (!IntersectRect( &inter, &dest->box, &src->box )) return;
    XCopyArea( display, src->pixmap, dest->pixmap, regionGC,
	       inter.left - src->box.left, inter.top - src->box.top,
	       inter.right - inter.left, inter.bottom - inter.top,
	       inter.left - dest->box.left, inter.top - dest->box.top );
}


/***********************************************************************
 *           CombineRgn    (GDI.451)
 */
int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
{
    RGNOBJ *destObj, *src1Obj, *src2Obj;
    REGION * region;
    int width, height;
    BOOL res;
    
#ifdef DEBUG_REGION
    printf( "CombineRgn: %d %d %d %d\n", hDest, hSrc1, hSrc2, mode );
#endif
    
    if (!(destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC )))
	return ERROR;
    if (!(src1Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc1, REGION_MAGIC )))
	return ERROR;
    if (mode != RGN_COPY)
	if (!(src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC )))
	    return ERROR;
    region = &destObj->region;

    if (src1Obj->region.xrgn && ((mode == RGN_COPY) || src2Obj->region.xrgn))
    {
	/* Perform the operation with X regions */

	if (region->pixmap) XFreePixmap( display, region->pixmap );
	region->pixmap = 0;
	if (!region->xrgn) region->xrgn = XCreateRegion();
	switch(mode)
	{
	case RGN_AND:
	    XIntersectRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			      region->xrgn );
	    break;
	case RGN_OR:
	    XUnionRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			  region->xrgn );
	    break;
	case RGN_XOR:
	    XXorRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			region->xrgn );
	    break;
	case RGN_DIFF:
	    XSubtractRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			     region->xrgn );
	    break;
	case RGN_COPY:
	    {
		Region tmprgn = XCreateRegion();
		XUnionRegion( tmprgn, src1Obj->region.xrgn, region->xrgn );
		XDestroyRegion( tmprgn );
	    }
	    break;
	default:
	    return ERROR;
	}
	if (XEmptyRegion(region->xrgn))
	{
	    region->type = NULLREGION;
	    region->xrgn = 0;
	    return NULLREGION;
	}
	else
	{
	    XRectangle rect;
	    XClipBox( region->xrgn, &rect );
	    region->type       = COMPLEXREGION;
	    region->box.left   = rect.x;
	    region->box.top    = rect.y;
	    region->box.right  = rect.x + rect.width;
	    region->box.bottom = rect.y + rect.height;
	    return COMPLEXREGION;
	}
    }
    else  /* Create pixmaps if needed */
    {
	if (!src1Obj->region.pixmap)
	    if (!REGION_MakePixmap( &src1Obj->region )) return ERROR;
	if ((mode != RGN_COPY) && !src2Obj->region.pixmap)
	    if (!REGION_MakePixmap( &src2Obj->region )) return ERROR;
    }
    

    switch(mode)
    {
      case RGN_AND:
	res = IntersectRect( &region->box, &src1Obj->region.box,
			     &src2Obj->region.box );
	region->type = COMPLEXREGION;
	break;

      case RGN_OR:
      case RGN_XOR:
	res = UnionRect( &region->box, &src1Obj->region.box,
			 &src2Obj->region.box );
	region->type = COMPLEXREGION;
	break;

      case RGN_DIFF:
	res = SubtractRect( &region->box, &src1Obj->region.box,
			    &src2Obj->region.box );
	region->type = COMPLEXREGION;
	break;

      case RGN_COPY:
	region->box  = src1Obj->region.box;
	region->type = src1Obj->region.type;
	res = (region->type != NULLREGION);
	break;

      default:
	return ERROR;
    }

    if (region->pixmap) XFreePixmap( display, region->pixmap );
    if (region->xrgn) XDestroyRegion( region->xrgn );
    if (!res)
    {
	region->type   = NULLREGION;
	region->pixmap = 0;
	region->xrgn   = 0;
	return NULLREGION;
    }
    
    width  = region->box.right - region->box.left;
    height = region->box.bottom - region->box.top;
    if (!width || !height)
    {
	printf( "CombineRgn: width or height is 0. Please report this.\n" );
	printf( "src1=%d,%d-%d,%d  src2=%d,%d-%d,%d  dst=%d,%d-%d,%d  op=%d\n",
	        src1Obj->region.box.left, src1Obj->region.box.top,
	        src1Obj->region.box.right, src1Obj->region.box.bottom,
	        src2Obj->region.box.left, src2Obj->region.box.top,
	        src2Obj->region.box.right, src2Obj->region.box.bottom,
	        region->box.left, region->box.top,
	        region->box.right, region->box.bottom, mode );
	exit(1);
    }
    region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
    region->xrgn   = 0;

    switch(mode)
    {
      case RGN_AND:
	  XSetFunction( display, regionGC, GXcopy );
	  REGION_CopyIntersection( region, &src1Obj->region );
	  XSetFunction( display, regionGC, GXand );
	  REGION_CopyIntersection( region, &src2Obj->region );
	  break;

      case RGN_OR:
      case RGN_XOR:
	  XSetFunction( display, regionGC, GXclear );
	  XFillRectangle( display, region->pixmap, regionGC,
			  0, 0, width, height );
	  XSetFunction( display, regionGC, (mode == RGN_OR) ? GXor : GXxor);
	  REGION_CopyIntersection( region, &src1Obj->region );
	  REGION_CopyIntersection( region, &src2Obj->region );
	  break;
	  
      case RGN_DIFF:
	  XSetFunction( display, regionGC, GXclear );
	  XFillRectangle( display, region->pixmap, regionGC,
			  0, 0, width, height );
	  XSetFunction( display, regionGC, GXcopy );
	  REGION_CopyIntersection( region, &src1Obj->region );
	  XSetFunction( display, regionGC, GXandInverted );
	  REGION_CopyIntersection( region, &src2Obj->region );
	  break;
	  
      case RGN_COPY:
	  XSetFunction( display, regionGC, GXcopy );
	  XCopyArea( display, src1Obj->region.pixmap, region->pixmap,
		     regionGC, 0, 0, width, height, 0, 0 );
	  break;
    }
    return region->type;
}
