/*
 *	PostScript driver graphics functions
 *
 *	Copyright 1998  Huw D M Davies
 *
 * 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 <string.h>
#include <math.h>
#if defined(HAVE_FLOAT_H)
 #include <float.h>
#endif
#if !defined(PI)
 #define PI M_PI
#endif
#include "psdrv.h"
#include "wine/debug.h"
#include "winspool.h"

WINE_DEFAULT_DEBUG_CHANNEL(psdrv);


/***********************************************************************
 *           PSDRV_LineTo
 */
BOOL PSDRV_LineTo(PSDRV_PDEVICE *physDev, INT x, INT y)
{
    POINT pt[2];

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

    GetCurrentPositionEx( physDev->hdc, pt );
    pt[1].x = x;
    pt[1].y = y;
    LPtoDP( physDev->hdc, pt, 2 );

    PSDRV_SetPen(physDev);
    PSDRV_WriteMoveTo(physDev, pt[0].x, pt[0].y );
    PSDRV_WriteLineTo(physDev, pt[1].x, pt[1].y );
    PSDRV_DrawLine(physDev);

    return TRUE;
}


/***********************************************************************
 *           PSDRV_Rectangle
 */
BOOL PSDRV_Rectangle( PSDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom )
{
    RECT rect;

    TRACE("%d %d - %d %d\n", left, top, right, bottom);

    rect.left = left;
    rect.top = top;
    rect.right = right;
    rect.bottom = bottom;
    LPtoDP( physDev->hdc, (POINT *)&rect, 2 );

    PSDRV_WriteRectangle(physDev, rect.left, rect.top, rect.right - rect.left,
                         rect.bottom - rect.top );
    PSDRV_Brush(physDev,0);
    PSDRV_SetPen(physDev);
    PSDRV_DrawLine(physDev);
    return TRUE;
}


/***********************************************************************
 *           PSDRV_RoundRect
 */
BOOL PSDRV_RoundRect( PSDRV_PDEVICE *physDev, INT left, INT top, INT right,
                      INT bottom, INT ell_width, INT ell_height )
{
    RECT rect[2];

    rect[0].left   = left;
    rect[0].top    = top;
    rect[0].right  = right;
    rect[0].bottom = bottom;
    rect[1].left   = 0;
    rect[1].top    = 0;
    rect[1].right  = ell_width;
    rect[1].bottom = ell_height;
    LPtoDP( physDev->hdc, (POINT *)rect, 4 );

    left   = rect[0].left;
    top    = rect[0].top;
    right  = rect[0].right;
    bottom = rect[0].bottom;
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }

    ell_width  = rect[1].right - rect[1].left;
    ell_height = rect[1].bottom - rect[1].top;
    if (ell_width > right - left) ell_width = right - left;
    if (ell_height > bottom - top) ell_height = bottom - top;

    PSDRV_WriteMoveTo( physDev, left, top + ell_height/2 );
    PSDRV_WriteArc( physDev, left + ell_width/2, top + ell_height/2, ell_width,
		    ell_height, 90.0, 180.0);
    PSDRV_WriteLineTo( physDev, right - ell_width/2, top );
    PSDRV_WriteArc( physDev, right - ell_width/2, top + ell_height/2, ell_width,
		    ell_height, 0.0, 90.0);
    PSDRV_WriteLineTo( physDev, right, bottom - ell_height/2 );
    PSDRV_WriteArc( physDev, right - ell_width/2, bottom - ell_height/2, ell_width,
		    ell_height, -90.0, 0.0);
    PSDRV_WriteLineTo( physDev, right - ell_width/2, bottom);
    PSDRV_WriteArc( physDev, left + ell_width/2, bottom - ell_height/2, ell_width,
		    ell_height, 180.0, -90.0);
    PSDRV_WriteClosePath( physDev );

    PSDRV_Brush(physDev,0);
    PSDRV_SetPen(physDev);
    PSDRV_DrawLine(physDev);
    return TRUE;
}

/***********************************************************************
 *           PSDRV_DrawArc
 *
 * Does the work of Arc, Chord and Pie. lines is 0, 1 or 2 respectively.
 */
static BOOL PSDRV_DrawArc( PSDRV_PDEVICE *physDev, INT left, INT top,
                           INT right, INT bottom, INT xstart, INT ystart,
                           INT xend, INT yend, int lines )
{
    INT x, y, h, w;
    double start_angle, end_angle, ratio;
    RECT rect;

    rect.left = left;
    rect.top = top;
    rect.right = right;
    rect.bottom = bottom;
    LPtoDP( physDev->hdc, (POINT *)&rect, 2 );

    x = (rect.left + rect.right) / 2;
    y = (rect.top + rect.bottom) / 2;
    w = rect.right - rect.left;
    h = rect.bottom - rect.top;

    if(w < 0) w = -w;
    if(h < 0) h = -h;
    ratio = ((double)w)/h;

    /* angle is the angle after the rectangle is transformed to a square and is
       measured anticlockwise from the +ve x-axis */

    start_angle = atan2((double)(y - ystart) * ratio, (double)(xstart - x));
    end_angle = atan2((double)(y - yend) * ratio, (double)(xend - x));

    start_angle *= 180.0 / PI;
    end_angle *= 180.0 / PI;

    if(lines == 2) /* pie */
        PSDRV_WriteMoveTo(physDev, x, y);
    else
        PSDRV_WriteNewPath( physDev );

    PSDRV_WriteArc(physDev, x, y, w, h, start_angle, end_angle);
    if(lines == 1 || lines == 2) { /* chord or pie */
        PSDRV_WriteClosePath(physDev);
	PSDRV_Brush(physDev,0);
    }
    PSDRV_SetPen(physDev);
    PSDRV_DrawLine(physDev);
    return TRUE;
}


/***********************************************************************
 *           PSDRV_Arc
 */
BOOL PSDRV_Arc( PSDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom,
                INT xstart, INT ystart, INT xend, INT yend )
{
    return PSDRV_DrawArc( physDev, left, top, right, bottom, xstart, ystart, xend, yend, 0 );
}

/***********************************************************************
 *           PSDRV_Chord
 */
BOOL PSDRV_Chord( PSDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom,
                  INT xstart, INT ystart, INT xend, INT yend )
{
    return PSDRV_DrawArc( physDev, left, top, right, bottom, xstart, ystart, xend, yend, 1 );
}


/***********************************************************************
 *           PSDRV_Pie
 */
BOOL PSDRV_Pie( PSDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom,
                INT xstart, INT ystart, INT xend, INT yend )
{
    return PSDRV_DrawArc( physDev, left, top, right, bottom, xstart, ystart, xend, yend, 2 );
}


/***********************************************************************
 *           PSDRV_Ellipse
 */
BOOL PSDRV_Ellipse( PSDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom)
{
    INT x, y, w, h;
    RECT rect;

    TRACE("%d %d - %d %d\n", left, top, right, bottom);

    rect.left   = left;
    rect.top    = top;
    rect.right  = right;
    rect.bottom = bottom;
    LPtoDP( physDev->hdc, (POINT *)&rect, 2 );

    x = (rect.left + rect.right) / 2;
    y = (rect.top + rect.bottom) / 2;
    w = rect.right - rect.left;
    h = rect.bottom - rect.top;

    PSDRV_WriteNewPath(physDev);
    PSDRV_WriteArc(physDev, x, y, w, h, 0.0, 360.0);
    PSDRV_WriteClosePath(physDev);
    PSDRV_Brush(physDev,0);
    PSDRV_SetPen(physDev);
    PSDRV_DrawLine(physDev);
    return TRUE;
}


/***********************************************************************
 *           PSDRV_PolyPolyline
 */
BOOL PSDRV_PolyPolyline( PSDRV_PDEVICE *physDev, const POINT* pts, const DWORD* counts,
                         DWORD polylines )
{
    DWORD polyline, line, total;
    POINT *dev_pts, *pt;

    TRACE("\n");

    for (polyline = total = 0; polyline < polylines; polyline++) total += counts[polyline];
    if (!(dev_pts = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*dev_pts) ))) return FALSE;
    memcpy( dev_pts, pts, total * sizeof(*dev_pts) );
    LPtoDP( physDev->hdc, dev_pts, total );

    pt = dev_pts;
    for(polyline = 0; polyline < polylines; polyline++) {
        PSDRV_WriteMoveTo(physDev, pt->x, pt->y);
	pt++;
        for(line = 1; line < counts[polyline]; line++, pt++)
            PSDRV_WriteLineTo(physDev, pt->x, pt->y);
    }
    HeapFree( GetProcessHeap(), 0, dev_pts );
    PSDRV_SetPen(physDev);
    PSDRV_DrawLine(physDev);
    return TRUE;
}


/***********************************************************************
 *           PSDRV_Polyline
 */
BOOL PSDRV_Polyline( PSDRV_PDEVICE *physDev, const POINT* pt, INT count )
{
    return PSDRV_PolyPolyline( physDev, pt, (LPDWORD) &count, 1 );
}


/***********************************************************************
 *           PSDRV_PolyPolygon
 */
BOOL PSDRV_PolyPolygon( PSDRV_PDEVICE *physDev, const POINT* pts, const INT* counts,
                        UINT polygons )
{
    DWORD polygon, line, total;
    POINT *dev_pts, *pt;

    TRACE("\n");

    for (polygon = total = 0; polygon < polygons; polygon++) total += counts[polygon];
    if (!(dev_pts = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*dev_pts) ))) return FALSE;
    memcpy( dev_pts, pts, total * sizeof(*dev_pts) );
    LPtoDP( physDev->hdc, dev_pts, total );

    pt = dev_pts;
    for(polygon = 0; polygon < polygons; polygon++) {
        PSDRV_WriteMoveTo(physDev, pt->x, pt->y);
	pt++;
        for(line = 1; line < counts[polygon]; line++, pt++)
            PSDRV_WriteLineTo(physDev, pt->x, pt->y);
	PSDRV_WriteClosePath(physDev);
    }
    HeapFree( GetProcessHeap(), 0, dev_pts );

    if(GetPolyFillMode( physDev->hdc ) == ALTERNATE)
        PSDRV_Brush(physDev, 1);
    else /* WINDING */
        PSDRV_Brush(physDev, 0);
    PSDRV_SetPen(physDev);
    PSDRV_DrawLine(physDev);
    return TRUE;
}


/***********************************************************************
 *           PSDRV_Polygon
 */
BOOL PSDRV_Polygon( PSDRV_PDEVICE *physDev, const POINT* pt, INT count )
{
     return PSDRV_PolyPolygon( physDev, pt, &count, 1 );
}


/***********************************************************************
 *           PSDRV_SetPixel
 */
COLORREF PSDRV_SetPixel( PSDRV_PDEVICE *physDev, INT x, INT y, COLORREF color )
{
    PSCOLOR pscolor;
    POINT pt;

    pt.x = x;
    pt.y = y;
    LPtoDP( physDev->hdc, &pt, 1 );

    PSDRV_WriteRectangle( physDev, pt.x, pt.y, 0, 0 );
    PSDRV_CreateColor( physDev, &pscolor, color );
    PSDRV_WriteSetColor( physDev, &pscolor );
    PSDRV_WriteFill( physDev );
    return color;
}


/***********************************************************************
 *           PSDRV_DrawLine
 */
VOID PSDRV_DrawLine( PSDRV_PDEVICE *physDev )
{
    if (physDev->pen.style == PS_NULL)
	PSDRV_WriteNewPath(physDev);
    else
	PSDRV_WriteStroke(physDev);
}
