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

#include <string.h>
#include "winbase.h"
#include "brush.h"
#include "bitmap.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(gdi)

static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
{
    BITMAPINFO  *newInfo;
    HGLOBAL16   hmem;
    INT         size;

    if (info->bmiHeader.biCompression)
        size = info->bmiHeader.biSizeImage;
    else
        size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
                                    info->bmiHeader.biHeight,
                                    info->bmiHeader.biBitCount);
    size += DIB_BitmapInfoSize( info, coloruse );

    if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
    {
        return 0;
    }
    newInfo = (BITMAPINFO *) GlobalLock16( hmem );
    memcpy( newInfo, info, size );
    GlobalUnlock16( hmem );
    return hmem;
}



static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
{
    LOGBRUSH *brush = &brushPtr->logbrush;

    switch (brush->lbStyle)
    {
       case BS_PATTERN8X8:
            brush->lbStyle = BS_PATTERN;
       case BS_PATTERN:
            brush->lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) brush->lbHatch );
            if (! brush->lbHatch)
               break;
            return TRUE;

       case BS_DIBPATTERNPT:
            brush->lbStyle = BS_DIBPATTERN;
            brush->lbHatch = (LONG)dib_copy( (BITMAPINFO *) brush->lbHatch,
                                             brush->lbColor);
            if (! brush->lbHatch)
               break;
            return TRUE;

       case BS_DIBPATTERN8X8:
       case BS_DIBPATTERN:
       {
            BITMAPINFO* bmi;
            HGLOBAL     h = brush->lbHatch;

            brush->lbStyle = BS_DIBPATTERN;
            if (v16)
            {
               if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
                  break;
            }
            else
            {
               if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
                  break;
            }

            brush->lbHatch = dib_copy( bmi, brush->lbColor);

            if (v16)  GlobalUnlock16( h );
            else      GlobalUnlock( h );

            if (!brush->lbHatch)
               break;

            return TRUE;
       }

       default:
          if( brush->lbStyle <= BS_MONOPATTERN)
             return TRUE;
    }

    return FALSE;
}


/***********************************************************************
 *           CreateBrushIndirect16    (GDI.50)
 */
HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
{
    BOOL success;
    BRUSHOBJ * brushPtr;
    HBRUSH16 hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
    if (!hbrush) return 0;
    brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush );
    brushPtr->logbrush.lbStyle = brush->lbStyle;
    brushPtr->logbrush.lbColor = brush->lbColor;
    brushPtr->logbrush.lbHatch = brush->lbHatch;
    success = create_brush_indirect(brushPtr, TRUE);
    GDI_HEAP_UNLOCK( hbrush );
    if(!success)
    {
       GDI_FreeObject(hbrush);
       hbrush = 0;
    }
    TRACE("%04x\n", hbrush);
    return hbrush;
}


/***********************************************************************
 *           CreateBrushIndirect32    (GDI32.27)
 *
 * BUGS
 *      As for Windows 95 and Windows 98:
 *      Creating brushes from bitmaps or DIBs larger than 8x8 pixels
 *      is not supported. If a larger bitmap is given, only a portion
 *      of the bitmap is used.
 */
HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
{
    BOOL success;
    BRUSHOBJ * brushPtr;
    HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
    if (!hbrush) return 0;
    brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush );
    brushPtr->logbrush.lbStyle = brush->lbStyle;
    brushPtr->logbrush.lbColor = brush->lbColor;
    brushPtr->logbrush.lbHatch = brush->lbHatch;
    success = create_brush_indirect(brushPtr, FALSE);
    GDI_HEAP_UNLOCK( hbrush );
    if(!success)
    {
       GDI_FreeObject(hbrush);
       hbrush = 0;
    }
    TRACE("%08x\n", hbrush);
    return hbrush;
}


/***********************************************************************
 *           CreateHatchBrush16    (GDI.58)
 */
HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
{
    return CreateHatchBrush( style, color );
}


/***********************************************************************
 *           CreateHatchBrush32    (GDI32.48)
 */
HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
{
    LOGBRUSH logbrush;

    TRACE("%d %06lx\n", style, color );

    logbrush.lbStyle = BS_HATCHED;
    logbrush.lbColor = color;
    logbrush.lbHatch = style;

    return CreateBrushIndirect( &logbrush );
}


/***********************************************************************
 *           CreatePatternBrush16    (GDI.60)
 */
HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
{
    return (HBRUSH16)CreatePatternBrush( hbitmap );
}


/***********************************************************************
 *           CreatePatternBrush32    (GDI32.54)
 */
HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
{
    LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
    TRACE("%04x\n", hbitmap );

    logbrush.lbHatch = hbitmap;
        return CreateBrushIndirect( &logbrush );
}


/***********************************************************************
 *           CreateDIBPatternBrush16    (GDI.445)
 */
HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
{
    LOGBRUSH16 logbrush;

    TRACE("%04x\n", hbitmap );

    logbrush.lbStyle = BS_DIBPATTERN;
    logbrush.lbColor = coloruse;
    logbrush.lbHatch = hbitmap;

    return CreateBrushIndirect16( &logbrush );
    }


/***********************************************************************
 *           CreateDIBPatternBrush32    (GDI32.34)
 *
 *	Create a logical brush which has the pattern specified by the DIB
 *
 *	Function call is for compatability only.  CreateDIBPatternBrushPt should be used.   
 *
 * RETURNS
 *
 *	Handle to a logical brush on success, NULL on failure.
 *
 * BUGS
 *	
 */
HBRUSH WINAPI CreateDIBPatternBrush( 
		HGLOBAL hbitmap, 		/* Global object containg BITMAPINFO structure */
		UINT coloruse 		/* Specifies color format, if provided */
)
{
    LOGBRUSH logbrush;
    
    TRACE("%04x\n", hbitmap );

    logbrush.lbStyle = BS_DIBPATTERN;
    logbrush.lbColor = coloruse;

    logbrush.lbHatch = (LONG)hbitmap;

    return CreateBrushIndirect( &logbrush );
}


/***********************************************************************
 *           CreateDIBPatternBrushPt    (GDI32.35)
 *
 *	Create a logical brush which has the pattern specified by the DIB
 *
 * RETURNS
 *
 *	Handle to a logical brush on success, NULL on failure.
 *
 * BUGS
 *	
 */
HBRUSH WINAPI CreateDIBPatternBrushPt(
		const void* data,		/* Pointer to a BITMAPINFO structure followed by more data */ 
		UINT coloruse 		/* Specifies color format, if provided */
)
{
    BITMAPINFO *info=(BITMAPINFO*)data;
    LOGBRUSH logbrush;
    
    TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
	  info->bmiHeader.biHeight,  info->bmiHeader.biBitCount);

    logbrush.lbStyle = BS_DIBPATTERNPT;
    logbrush.lbColor = coloruse;
    logbrush.lbHatch = (LONG) data;

    return CreateBrushIndirect( &logbrush );
}


/***********************************************************************
 *           CreateSolidBrush    (GDI.66)
 */
HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
{
    return CreateSolidBrush( color );
}


/***********************************************************************
 *           CreateSolidBrush32    (GDI32.64)
 */
HBRUSH WINAPI CreateSolidBrush( COLORREF color )
{
    LOGBRUSH logbrush;

    TRACE("%06lx\n", color );

    logbrush.lbStyle = BS_SOLID;
    logbrush.lbColor = color;
    logbrush.lbHatch = 0;

    return CreateBrushIndirect( &logbrush );
}


/***********************************************************************
 *           SetBrushOrg    (GDI.148)
 */
DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
{
    DWORD retval;
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return FALSE;
    retval = dc->w.brushOrgX | (dc->w.brushOrgY << 16);
    dc->w.brushOrgX = x;
    dc->w.brushOrgY = y;
    return retval;
}


/***********************************************************************
 *           SetBrushOrgEx    (GDI32.308)
 */
BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
{
    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );

    if (!dc) return FALSE;
    if (oldorg)
    {
        oldorg->x = dc->w.brushOrgX;
        oldorg->y = dc->w.brushOrgY;
    }
    dc->w.brushOrgX = x;
    dc->w.brushOrgY = y;
    return TRUE;
}

/***********************************************************************
 *           FixBrushOrgEx    (GDI32.102)
 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
 */
BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
{
    return SetBrushOrgEx(hdc,x,y,oldorg);
}


/***********************************************************************
 *           BRUSH_DeleteObject
 */
BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
{
    switch(brush->logbrush.lbStyle)
    {
      case BS_PATTERN:
	  DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
	  break;
      case BS_DIBPATTERN:
	  GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
	  break;
    }
    return GDI_FreeObject( hbrush );
}


/***********************************************************************
 *           BRUSH_GetObject16
 */
INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
{
    LOGBRUSH16 logbrush;

    logbrush.lbStyle = brush->logbrush.lbStyle;
    logbrush.lbColor = brush->logbrush.lbColor;
    logbrush.lbHatch = brush->logbrush.lbHatch;
    if (count > sizeof(logbrush)) count = sizeof(logbrush);
    memcpy( buffer, &logbrush, count );
    return count;
}


/***********************************************************************
 *           BRUSH_GetObject32
 */
INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
{
    if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
    memcpy( buffer, &brush->logbrush, count );
    return count;
}


/***********************************************************************
 *           SetSolidBrush16   (GDI.604)
 *
 *  If hBrush is a solid brush, change it's color to newColor.
 *
 *  RETURNS
 *           TRUE on success, FALSE on failure.
 *   FIXME: not yet implemented!
 */
BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
{
     FIXME("(hBrush %04x, newColor %04x): stub!\n", hBrush, (int)newColor);

     return(FALSE);
}

