/*
 * SDL DC driver
 *
 * Copyright 1999 Patrik Stridvall
 * Copyright 2002 TransGaming Technologies, Inc.
 */

#include "config.h"

#include "gdi.h"
#include "bitmap.h"
#include "palette.h"
#include "sdldrv.h"
#include "winbase.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(sdldrv);

/**********************************************************************/

BITMAP_DRIVER SDLDRV_BITMAP_Driver =
{
  SDLDRV_BITMAP_SetDIBits,
  SDLDRV_BITMAP_GetDIBits,
  SDLDRV_BITMAP_DeleteDIBSection,
  SDLDRV_BITMAP_SetDIBColorTable,
  SDLDRV_BITMAP_GetDIBColorTable,
  SDLDRV_BITMAP_Lock,
  SDLDRV_BITMAP_Unlock
};

PALETTE_DRIVER SDLDRV_PALETTE_Driver =
{
  SDLDRV_PALETTE_SetMapping,
  SDLDRV_PALETTE_UpdateMapping,
  SDLDRV_PALETTE_IsDark
};

const DC_FUNCTIONS *SDLDRV_DC_Funcs = NULL;  /* hack */

/**********************************************************************
 *	     SDLDRV_GDI_Initialize
 */
BOOL SDLDRV_GDI_Initialize(void)
{
  BITMAP_Driver = &SDLDRV_BITMAP_Driver;
  PALETTE_Driver = &SDLDRV_PALETTE_Driver;

  return SDLDRV_PALETTE_Initialize();
}

/***********************************************************************
 *	     SDLDRV_DC_CreateDC
 */
BOOL SDLDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device,
			LPCSTR output, const DEVMODEA *initData)
{
  SDLDRV_PDEVICE *physDev;
  BITMAPOBJ *bmp;

  TRACE("(%p, %s, %s, %s, %p)\n",
    dc, debugstr_a(driver), debugstr_a(device),
    debugstr_a(output), initData);

  if (!SDLDRV_DC_Funcs) SDLDRV_DC_Funcs = dc->funcs;  /* hack */

  dc->physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
			  sizeof(SDLDRV_PDEVICE));
  if(!dc->physDev) {
    ERR("Can't allocate physDev\n");
    return FALSE;
  }
  physDev = (SDLDRV_PDEVICE *) dc->physDev;

  if(dc->flags & DC_MEMORY){
    SDLDRV_DC_CreateBitmap(dc->hBitmap);
    bmp = (BITMAPOBJ *) GDI_GetObjPtr(dc->hBitmap, BITMAP_MAGIC);

    physDev->surface = bmp->physBitmap;

    dc->bitsPerPixel       = bmp->bitmap.bmBitsPixel;
    dc->totalExtent.left   = 0;
    dc->totalExtent.top    = 0;
    dc->totalExtent.right  = bmp->bitmap.bmWidth;
    dc->totalExtent.bottom = bmp->bitmap.bmHeight;

    GDI_ReleaseObj( dc->hBitmap );
  } else {
    physDev->surface = primary_surface;

    dc->bitsPerPixel       = primary_surface->format->BitsPerPixel;
    dc->totalExtent.left   = 0;
    dc->totalExtent.top    = 0;
    dc->totalExtent.right  = primary_surface->w;
    dc->totalExtent.bottom = primary_surface->h;
  }

  if (!(dc->hVisRgn = CreateRectRgnIndirect( &dc->totalExtent )))
  {
    HeapFree(GetProcessHeap(), 0, physDev);
    return FALSE;
  }

  return TRUE;
}

/***********************************************************************
 *	     SDLDRV_DC_DeleteDC
 */
BOOL SDLDRV_DC_DeleteDC(DC *dc)
{
  TRACE("(%p)\n", dc);

  HeapFree( GetProcessHeap(), 0, dc->physDev );
  dc->physDev = NULL;

  return TRUE;
}


/***********************************************************************
 *           GetDeviceCaps    (SDLDRV.@)
 */
INT SDLDRV_GetDeviceCaps( DC *dc, INT cap )
{
    switch(cap)
    {
    case DRIVERVERSION:
        return 0x300;
    case TECHNOLOGY:
        return DT_RASDISPLAY;
    case HORZSIZE:
        return 0;    /* FIXME: Screen width in mm */
    case VERTSIZE:
        return 0;    /* FIXME: Screen height in mm */
    case HORZRES:
        return primary_surface->w;
    case VERTRES:
        return primary_surface->h;
    case BITSPIXEL:
        return primary_surface->format->BitsPerPixel;
    case PLANES:
        return 1;
    case NUMBRUSHES:
        return 16 + 6;
    case NUMPENS:
        return 16;
    case NUMMARKERS:
        return 0;
    case NUMFONTS:
        return 0;
    case NUMCOLORS:
        return 100;
    case PDEVICESIZE:
        return sizeof(SDLDRV_PDEVICE);
    case CURVECAPS:
        return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
                CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
    case LINECAPS:
        return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
                LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
    case POLYGONALCAPS:
        return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
                PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
    case TEXTCAPS:
        return 0;
    case CLIPCAPS:
        return CP_REGION;
    case RASTERCAPS:
        return (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
                RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS);
    case ASPECTX:
    case ASPECTY:
        return 36;
    case ASPECTXY:
        return 51;
    case LOGPIXELSX:
    case LOGPIXELSY:
        return 72;  /* FIXME */
    case SIZEPALETTE:
        return 256;  /* FIXME */
    case NUMRESERVED:
        return 0;
    case COLORRES:
        return 0;
    case PHYSICALWIDTH:
    case PHYSICALHEIGHT:
    case PHYSICALOFFSETX:
    case PHYSICALOFFSETY:
    case SCALINGFACTORX:
    case SCALINGFACTORY:
    case VREFRESH:
    case DESKTOPVERTRES:
    case DESKTOPHORZRES:
    case BTLALIGNMENT:
        return 0;
    default:
        FIXME("(%04x): unsupported capability %d, will return 0\n", dc->hSelf, cap );
        return 0;
    }
}


/***********************************************************************
 *		SDLDRV_DC_SetDeviceClipping
 */
void SDLDRV_DC_SetDeviceClipping(DC *dc)
{
  TRACE("(%p)\n", dc);
}
