/*
 * GDI graphics operations
 *
 * Copyright 1993 Alexandre Julliard
 */

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

#include <math.h>
#include <X11/Xlib.h>
#ifndef PI
#define PI M_PI
#endif

#include "gdi.h"

/***********************************************************************
 *           LineTo    (GDI.19)
 */
BOOL LineTo( HDC hdc, short x, short y )
{
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;
    if (DC_SetupGCForPen( dc ))
	XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc, 
		  dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ),
		  dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ),
		  dc->w.DCOrgX + XLPTODP( dc, x ),
		  dc->w.DCOrgY + YLPTODP( dc, y ) );
    dc->w.CursPosX = x;
    dc->w.CursPosY = y;
    return TRUE;
}


/***********************************************************************
 *           MoveTo    (GDI.20)
 */
DWORD MoveTo( HDC hdc, short x, short y )
{
    POINT pt;
    if (MoveToEx( hdc, x, y, &pt )) return pt.x | (pt.y << 16);
    else return 0;
}


/***********************************************************************
 *           MoveToEx    (GDI.483)
 */
BOOL MoveToEx( HDC hdc, short x, short y, LPPOINT pt )
{
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;
    if (pt)
    {
	pt->x = dc->w.CursPosX;
	pt->y = dc->w.CursPosY;
    }
    dc->w.CursPosX = x;
    dc->w.CursPosY = y;
    return TRUE;
}


/***********************************************************************
 *           GRAPH_DrawArc
 *
 * Helper functions for Arc(), Chord() and Pie().
 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
 */
BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom,
		    int xstart, int ystart, int xend, int yend, int lines )
{
    int xcenter, ycenter;
    double start_angle, end_angle, diff_angle;
    XPoint points[3];
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;

    left   = XLPTODP( dc, left );
    top    = YLPTODP( dc, top );
    right  = XLPTODP( dc, right );
    bottom = YLPTODP( dc, bottom );
    xstart = XLPTODP( dc, xstart );
    ystart = YLPTODP( dc, ystart );
    xend   = XLPTODP( dc, xend );
    yend   = YLPTODP( dc, yend );
    if ((left == right) || (top == bottom)) return FALSE;

    if (!DC_SetupGCForPen( dc )) return TRUE;

    xcenter = (right + left) / 2;
    ycenter = (bottom + top) / 2;
    start_angle = atan2( (double)(ycenter-ystart)*(right-left),
			 (double)(xstart-xcenter)*(bottom-top) );
    end_angle   = atan2( (double)(ycenter-yend)*(right-left),
			 (double)(xend-xcenter)*(bottom-top) );
    diff_angle  = end_angle - start_angle;
    if (diff_angle < 0.0) diff_angle += 2*PI;

    XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
	      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
	      right-left-1, bottom-top-1,
	      (int)(start_angle * 180 * 64 / PI),
	      (int)(diff_angle * 180 * 64 / PI) );
    if (!lines) return TRUE;

    points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2);
    points[0].y = dc->w.DCOrgY + ycenter - (int)(sin(start_angle) * (bottom-top) / 2);
    points[1].x = dc->w.DCOrgX + xcenter + (int)(cos(end_angle) * (right-left) / 2);
    points[1].y = dc->w.DCOrgY + ycenter - (int)(sin(end_angle) * (bottom-top) / 2);
    if (lines == 2)
    {
	points[2] = points[1];
	points[1].x = dc->w.DCOrgX + xcenter;
	points[1].y = dc->w.DCOrgY + ycenter;
    }
    XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
	        points, lines+1, CoordModeOrigin );
    return TRUE;
}


/***********************************************************************
 *           Arc    (GDI.23)
 */
BOOL Arc( HDC hdc, int left, int top, int right, int bottom,
	  int xstart, int ystart, int xend, int yend )
{
    return GRAPH_DrawArc( hdc, left, top, right, bottom,
			  xstart, ystart, xend, yend, 0 );
}


/***********************************************************************
 *           Pie    (GDI.26)
 */
BOOL Pie( HDC hdc, int left, int top, int right, int bottom,
	  int xstart, int ystart, int xend, int yend )
{
    return GRAPH_DrawArc( hdc, left, top, right, bottom,
			  xstart, ystart, xend, yend, 2 );
}


/***********************************************************************
 *           Chord    (GDI.348)
 */
BOOL Chord( HDC hdc, int left, int top, int right, int bottom,
	    int xstart, int ystart, int xend, int yend )
{
    return GRAPH_DrawArc( hdc, left, top, right, bottom,
			  xstart, ystart, xend, yend, 1 );
}


/***********************************************************************
 *           Ellipse    (GDI.24)
 */
BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom )
{
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;

    left   = XLPTODP( dc, left );
    top    = YLPTODP( dc, top );
    right  = XLPTODP( dc, right );
    bottom = YLPTODP( dc, bottom );
    if ((left == right) || (top == bottom)) return FALSE;
    
    if (DC_SetupGCForBrush( dc ))
	XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
		  dc->w.DCOrgX + left, dc->w.DCOrgY + top,
		  right-left-1, bottom-top-1, 0, 360*64 );
    if (DC_SetupGCForPen( dc ))
	XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
		  dc->w.DCOrgX + left, dc->w.DCOrgY + top,
		  right-left-1, bottom-top-1, 0, 360*64 );
    return TRUE;
}


/***********************************************************************
 *           Rectangle    (GDI.27)
 */
BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom )
{
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;

    left   = XLPTODP( dc, left );
    top    = YLPTODP( dc, top );
    right  = XLPTODP( dc, right );
    bottom = YLPTODP( dc, bottom );
    
    if (DC_SetupGCForBrush( dc ))
	XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
		        right-left-1, bottom-top-1 );
    if (DC_SetupGCForPen( dc ))
	XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
		        right-left-1, bottom-top-1 );
    return TRUE;
}


/***********************************************************************
 *           FillRect    (USER.81)
 */
int FillRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
{
    HBRUSH prevBrush;

    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
    PatBlt( hdc, rect->left, rect->top,
	    rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
    SelectObject( hdc, prevBrush );
    return 1;
}


/***********************************************************************
 *           InvertRect    (USER.82)
 */
void InvertRect( HDC hdc, LPRECT rect )
{
    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return;
    PatBlt( hdc, rect->left, rect->top,
	    rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
}


/***********************************************************************
 *           FrameRect    (USER.83)
 */
int FrameRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
{
    HBRUSH prevBrush;
    int left, top, right, bottom;

    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;

    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
    
    left   = XLPTODP( dc, rect->left );
    top    = YLPTODP( dc, rect->top );
    right  = XLPTODP( dc, rect->right );
    bottom = YLPTODP( dc, rect->bottom );
    
    if (DC_SetupGCForBrush( dc )) {
   	PatBlt( hdc, rect->left, rect->top, 1,
	    rect->bottom - rect->top, PATCOPY );
	PatBlt( hdc, rect->right - 1, rect->top, 1,
	    rect->bottom - rect->top, PATCOPY );
	PatBlt( hdc, rect->left, rect->top,
	    rect->right - rect->left, 1, PATCOPY );
	PatBlt( hdc, rect->left, rect->bottom - 1,
	    rect->right - rect->left, 1, PATCOPY );
	}    
    SelectObject( hdc, prevBrush );
    return 1;
}


/***********************************************************************
 *           SetPixel    (GDI.31)
 */
COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color )
{
    int pixel;
    PALETTEENTRY entry;
    
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return 0;

    x = dc->w.DCOrgX + XLPTODP( dc, x );
    y = dc->w.DCOrgY + YLPTODP( dc, y );
    pixel = GetNearestPaletteIndex( dc->w.hPalette, color );
    GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
    
    XSetForeground( XT_display, dc->u.x.gc, pixel );
    XSetFunction( XT_display, dc->u.x.gc, GXcopy );
    XDrawPoint( XT_display, dc->u.x.drawable, dc->u.x.gc, x, y );

    return RGB( entry.peRed, entry.peGreen, entry.peBlue );
}


/***********************************************************************
 *           GetPixel    (GDI.83)
 */
COLORREF GetPixel( HDC hdc, short x, short y )
{
    PALETTEENTRY entry;
    XImage * image;
    
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return 0;

    x = dc->w.DCOrgX + XLPTODP( dc, x );
    y = dc->w.DCOrgY + YLPTODP( dc, y );
    if ((x < 0) || (y < 0)) return 0;
    
    if (!(dc->w.flags & DC_MEMORY))
    {
	XWindowAttributes win_attr;
	
	if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr ))
	    return 0;
	if (win_attr.map_state != IsViewable) return 0;
	if ((x >= win_attr.width) || (y >= win_attr.height)) return 0;
    }
    
    image = XGetImage( XT_display, dc->u.x.drawable, x, y,
		       1, 1, AllPlanes, ZPixmap );
    GetPaletteEntries( dc->w.hPalette, XGetPixel( image, 0, 0 ), 1, &entry );
    XDestroyImage( image );
    return RGB( entry.peRed, entry.peGreen, entry.peBlue );
}


/***********************************************************************
 *           PaintRgn    (GDI.43)
 */
BOOL PaintRgn( HDC hdc, HRGN hrgn )
{
    RECT box;
    HRGN tmpVisRgn, prevVisRgn;
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;

      /* Modify visible region */

    prevVisRgn = SaveVisRgn( hdc );
    if (prevVisRgn)
    {
	if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 )))
	{
	    RestoreVisRgn( hdc );
	    return FALSE;
	}
	CombineRgn( tmpVisRgn, prevVisRgn, hrgn, RGN_AND );
	SelectVisRgn( hdc, tmpVisRgn );
	DeleteObject( tmpVisRgn );
    }
    else SelectVisRgn( hdc, hrgn );

      /* Fill the region */

    GetClipBox( hdc, &box );
    if (DC_SetupGCForBrush( dc ))
	XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
		        dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
		        box.right-box.left, box.bottom-box.top );

      /* Restore the visible region */

    if (prevVisRgn) RestoreVisRgn( hdc );
    else SelectVisRgn( hdc, 0 );
    return TRUE;
}


/***********************************************************************
 *           FillRgn    (GDI.40)
 */
BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
{
    BOOL retval;
    HBRUSH prevBrush = SelectObject( hdc, hbrush );
    if (!prevBrush) return FALSE;
    retval = PaintRgn( hdc, hrgn );
    SelectObject( hdc, prevBrush );
    return retval;
}


/***********************************************************************
 *           DrawFocusRect    (GDI.466)
 */
void DrawFocusRect( HDC hdc, LPRECT rc )
{
    HPEN hPen, hOldPen;
    int oldDrawMode, oldBkMode;
    int left, top, right, bottom;
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return;

    left   = XLPTODP( dc, rc->left );
    top    = YLPTODP( dc, rc->top );
    right  = XLPTODP( dc, rc->right );
    bottom = YLPTODP( dc, rc->bottom );
    
    hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT)); 
    hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
    oldDrawMode = SetROP2(hdc, R2_XORPEN);
    oldBkMode = SetBkMode(hdc, TRANSPARENT);

    if (DC_SetupGCForPen( dc ))
	XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
		        right-left-1, bottom-top-1 );

    SetBkMode(hdc, oldBkMode);
    SetROP2(hdc, oldDrawMode);
    SelectObject(hdc, (HANDLE)hOldPen);
    DeleteObject((HANDLE)hPen);
}


/**********************************************************************
 *          Line  (Not a MSWin Call)
 */
void Line(HDC hDC, int X1, int Y1, int X2, int Y2)
{
MoveTo(hDC, X1, Y1);
LineTo(hDC, X2, Y2);
}


/**********************************************************************
 *          DrawReliefRect  (Not a MSWin Call)
 */
 void DrawReliefRect(HDC hDC, RECT rect, int ThickNess, int Mode)
{
HPEN   hWHITEPen;
HPEN   hDKGRAYPen;
HPEN   hOldPen;
int    OldColor;
rect.right--;  rect.bottom--;
hDKGRAYPen = CreatePen(PS_SOLID, 1, 0x00808080L);
hWHITEPen = GetStockObject(WHITE_PEN);
hOldPen = SelectObject(hDC, hWHITEPen);
while(ThickNess > 0) {
    if (Mode == 0)
	SelectObject(hDC, hWHITEPen);
    else
	SelectObject(hDC, hDKGRAYPen);
    Line(hDC, rect.left, rect.top, rect.right, rect.top);
    Line(hDC, rect.left, rect.top, rect.left, rect.bottom + 1);
    if (Mode == 0)
	SelectObject(hDC, hDKGRAYPen);
    else
	SelectObject(hDC, hWHITEPen);
    Line(hDC, rect.right, rect.bottom, rect.left, rect.bottom);
    Line(hDC, rect.right, rect.bottom, rect.right, rect.top - 1);
    InflateRect(&rect, -1, -1);
    ThickNess--;
    }
SelectObject(hDC, hOldPen);
DeleteObject(hDKGRAYPen);
}

/**********************************************************************
 *          Polyline  (GDI.37)
 */
BOOL Polyline (HDC hdc, LPPOINT pt, int count)
{
	register int i;
    	DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );

    	if (DC_SetupGCForPen( dc ))
    	{
		for (i = 0; i < count-1; i ++)
			XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,  
				   dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
				   dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
				   dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
				   dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y));
		XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,  
			   dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x),
			   dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y),
			   dc->w.DCOrgX + XLPTODP(dc, pt [0].x),
			   dc->w.DCOrgY + YLPTODP(dc, pt [0].y));
	} 
	
	return (TRUE);
}


/**********************************************************************
 *          Polygon  (GDI.36)
 */
BOOL Polygon (HDC hdc, LPPOINT pt, int count)
{
	register int i;
    	DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
	XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1);

    	if (DC_SetupGCForBrush( dc ))
    	{
    		
		for (i = 0; i < count; i++)
		{
			points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x);
			points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y);
		}
		points [count] = points [0];
		
		XFillPolygon( XT_display, dc->u.x.drawable, dc->u.x.gc,
		  	points, count, Complex, CoordModeOrigin);
		
		if (DC_SetupGCForPen ( dc ))
		{
		    XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
			        points, count, CoordModeOrigin );
		}
	}
    	free ((void *) points);
	return (TRUE);
}
 

