/*
 * Color functions
 *
 * Copyright 1993 Alexandre Julliard
 *
static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
*/
#include <stdlib.h>
#include <X11/Xlib.h>
#include <stdio.h>
#include "windows.h"
#include "options.h"
#include "gdi.h"
#include "color.h"


Colormap COLOR_WinColormap = 0;

  /* System palette static colors */

#define NB_RESERVED_COLORS  20

  /* The first and last eight colors are EGA colors */
static PALETTEENTRY COLOR_sysPaletteEntries[NB_RESERVED_COLORS] =
{
    /* red  green blue  flags */
    { 0x00, 0x00, 0x00, 0 },
    { 0x80, 0x00, 0x00, 0 },
    { 0x00, 0x80, 0x00, 0 },
    { 0x80, 0x80, 0x00, 0 },
    { 0x00, 0x00, 0x80, 0 },
    { 0x80, 0x00, 0x80, 0 },
    { 0x00, 0x80, 0x80, 0 },
    { 0xc0, 0xc0, 0xc0, 0 },
    { 0xc0, 0xdc, 0xc0, 0 },
    { 0xa6, 0xca, 0xf0, 0 },

    { 0xff, 0xfb, 0xf0, 0 },
    { 0xa0, 0xa0, 0xa4, 0 },
    { 0x80, 0x80, 0x80, 0 },
    { 0xff, 0x00, 0x00, 0 },
    { 0x00, 0xff, 0x00, 0 },
    { 0xff, 0xff, 0x00, 0 },
    { 0x00, 0x00, 0xff, 0 },
    { 0xff, 0x00, 0xff, 0 },
    { 0x00, 0xff, 0xff, 0 },
    { 0xff, 0xff, 0xff, 0 }
};

static HANDLE hSysColorTranslation = 0;
static HANDLE hRevSysColorTranslation = 0;

   /* Map an EGA index (0..15) to a pixel value. Used for dithering. */
int COLOR_mapEGAPixel[16];

int* COLOR_PaletteToPixel = NULL;
int* COLOR_PixelToPalette = NULL;
int COLOR_ColormapSize = 0;

/***********************************************************************
 *           COLOR_BuildMap
 *
 * Fill the private colormap.
 */
static BOOL COLOR_BuildMap( Colormap map, int depth, int size )
{
    XColor color;
    int r, g, b, red_incr, green_incr, blue_incr;
    int index = 0;

      /* Fill the whole map with a range of colors */

    blue_incr  = 0x10000 >> (depth / 3);
    red_incr   = 0x10000 >> ((depth + 1) / 3);
    green_incr = 0x10000 >> ((depth + 2) / 3);

    for (r = red_incr - 1; r < 0x10000; r += red_incr)
	for (g = green_incr - 1; g < 0x10000; g += green_incr)
	    for (b = blue_incr - 1; b < 0x10000; b += blue_incr)
	    {
		if (index >= size) break;
		color.pixel = index++;
		color.red   = r;
		color.green = g;
		color.blue  = b;
		XStoreColor( display, map, &color );
	    }

    return TRUE;
}


/***********************************************************************
 *           COLOR_InitPalette
 *
 * Create the system palette.
 */
static HPALETTE COLOR_InitPalette(void)
{
    int i, size, pixel;
    XColor color;
    HPALETTE hpalette;
    LOGPALETTE * palPtr;
    WORD *colorTranslation, *revTranslation;

    size = DefaultVisual( display, DefaultScreen(display) )->map_entries;
    COLOR_ColormapSize = size;
    if (screenDepth <= 8)
    {
        if (!(hSysColorTranslation = GDI_HEAP_ALLOC(sizeof(WORD)*NB_RESERVED_COLORS )))
            return FALSE;
        if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( sizeof(WORD)*size )))
            return FALSE;
        colorTranslation = (WORD *) GDI_HEAP_LIN_ADDR( hSysColorTranslation );
        revTranslation   = (WORD *) GDI_HEAP_LIN_ADDR( hRevSysColorTranslation );
    }
    else colorTranslation = revTranslation = NULL;

    if ((COLOR_WinColormap == DefaultColormapOfScreen(screen)) && (screenDepth <= 8))
    {
        COLOR_PaletteToPixel = (int *)malloc( sizeof(int) * size );
        COLOR_PixelToPalette = (int *)malloc( sizeof(int) * size );
        for (i = 0; i < size; i++)  /* Set the default mapping */
            COLOR_PaletteToPixel[i] = COLOR_PixelToPalette[i] = i;
    }

    for (i = 0; i < NB_RESERVED_COLORS; i++)
    {
	color.red   = COLOR_sysPaletteEntries[i].peRed * 65535 / 255;
	color.green = COLOR_sysPaletteEntries[i].peGreen * 65535 / 255;
	color.blue  = COLOR_sysPaletteEntries[i].peBlue * 65535 / 255;
	color.flags = DoRed | DoGreen | DoBlue;

        if (i < NB_RESERVED_COLORS/2)
        {
            /* Bottom half of the colormap */
            pixel = i;
            if (pixel >= size/2) continue;
        }
        else
        {
            /* Top half of the colormap */
            pixel = size - NB_RESERVED_COLORS + i;
            if (pixel < size/2) continue;
        }
	if (COLOR_WinColormap != DefaultColormapOfScreen(screen))
	{
            color.pixel = pixel;
	    XStoreColor( display, COLOR_WinColormap, &color );
	}
	else
        {
            if (!XAllocColor( display, COLOR_WinColormap, &color ))
            {
                fprintf(stderr, "Warning: Not enough free colors. Try using the -privatemap option.\n" );
                color.pixel = color.red = color.green = color.blue = 0;
            }
            else if (COLOR_PaletteToPixel)
            {
                COLOR_PaletteToPixel[pixel] = color.pixel;
                COLOR_PixelToPalette[color.pixel] = pixel;
            }
        }
        if (colorTranslation) colorTranslation[i] = color.pixel;
        if (revTranslation) revTranslation[color.pixel] = i;
	  /* Set EGA mapping if color in the first or last eight */
	if (i < 8)
	    COLOR_mapEGAPixel[i] = color.pixel;
	else if (i >= NB_RESERVED_COLORS-8)
	    COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel;
    }

    palPtr = malloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
    if (!palPtr) return FALSE;
    palPtr->palVersion = 0x300;
    palPtr->palNumEntries = NB_RESERVED_COLORS;
    memcpy( palPtr->palPalEntry, COLOR_sysPaletteEntries,
	    sizeof(COLOR_sysPaletteEntries) );
    hpalette = CreatePalette( palPtr );
    free( palPtr );
    return hpalette;
}


/***********************************************************************
 *           COLOR_Init
 *
 * Initialize color map and system palette.
 */
HPALETTE COLOR_Init(void)
{
    Visual * visual = DefaultVisual( display, DefaultScreen(display) );
    
    switch(visual->class)
    {
    case GrayScale:
    case PseudoColor:
    case DirectColor:
	if (Options.usePrivateMap)
	{
	    COLOR_WinColormap = XCreateColormap( display, rootWindow,
						 visual, AllocAll );
	    if (COLOR_WinColormap)
	    {
		COLOR_BuildMap( COLOR_WinColormap, screenDepth,
			        visual->map_entries );
		if (rootWindow != DefaultRootWindow(display))
		{
		    XSetWindowAttributes win_attr;
		    win_attr.colormap = COLOR_WinColormap;
		    XChangeWindowAttributes( display, rootWindow,
					     CWColormap, &win_attr );
		}
		break;
	    }
	}
	/* Fall through */
    case StaticGray:
    case StaticColor:
    case TrueColor:
	COLOR_WinColormap = DefaultColormapOfScreen( screen );
	break;	
    }
    return COLOR_InitPalette();
}


/***********************************************************************
 *           COLOR_IsSolid
 *
 * Check whether 'color' can be represented with a solid color.
 */
BOOL COLOR_IsSolid( COLORREF color )
{
    int i;
    PALETTEENTRY *pEntry = COLOR_sysPaletteEntries;

    if (color & 0xff000000) return TRUE;
    if (!color || (color == 0xffffff)) return TRUE;
    for (i = NB_RESERVED_COLORS; i > 0; i--, pEntry++)
    {
	if ((GetRValue(color) == pEntry->peRed) &&
	    (GetGValue(color) == pEntry->peGreen) &&
	    (GetBValue(color) == pEntry->peBlue)) return TRUE;
    }
    return FALSE;
}


/***********************************************************************
 *           COLOR_ToPhysical
 *
 * Return the physical color closest to 'color'.
 */
int COLOR_ToPhysical( DC *dc, COLORREF color )
{
    WORD index = 0;
    WORD *mapping;

    if (screenDepth > 8) return color;
    if (dc && (dc->w.bitsPerPixel == 1) && ((color >> 24) == 0))
    {
        if (((color >> 16) & 0xff) +
            ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2)
            return 1;  /* white */
        else return 0;  /* black */
    }
    
    switch(color >> 24)
    {
    case 0:  /* RGB */
	index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color );
	break;
    case 1:  /* PALETTEINDEX */
	index = color & 0xffff;
	break;
    case 2:  /* PALETTERGB */
	if (dc) index = GetNearestPaletteIndex( dc->w.hPalette, color );
        else index = 0;
	break;
    }
    if (dc&&dc->u.x.pal.mappingSize)
    {
        if (index >= dc->u.x.pal.mappingSize) return 0;
        mapping = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hMapping );
    }
    else
    {
        if (index >= NB_RESERVED_COLORS) return 0;
        mapping = (WORD *) GDI_HEAP_LIN_ADDR( hSysColorTranslation );
    }
    if (mapping) return mapping[index];
    else return index;  /* Identity mapping */
}


/***********************************************************************
 *           COLOR_SetMapping
 *
 * Set the color-mapping table in a DC.
 */
void COLOR_SetMapping( DC *dc, HANDLE map, HANDLE revMap, WORD size )
{
    WORD *pmap, *pnewmap;
    WORD i;

    if (dc->u.x.pal.hMapping && (dc->u.x.pal.hMapping != hSysColorTranslation))
	GDI_HEAP_FREE( dc->u.x.pal.hMapping );
    if (dc->u.x.pal.hRevMapping &&
        (dc->u.x.pal.hRevMapping != hRevSysColorTranslation))
	GDI_HEAP_FREE( dc->u.x.pal.hRevMapping );
    if (map && (map != hSysColorTranslation))
    {
	  /* Copy mapping table */
	dc->u.x.pal.hMapping = GDI_HEAP_ALLOC( sizeof(WORD) * size );
	pmap = (WORD *) GDI_HEAP_LIN_ADDR( map );
	pnewmap = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hMapping );
	memcpy( pnewmap, pmap, sizeof(WORD)*size );
          /* Build reverse table */
        dc->u.x.pal.hRevMapping = GDI_HEAP_ALLOC(sizeof(WORD)*COLOR_ColormapSize);
        pmap = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hRevMapping );
        for (i = 0; i < size; i++) pmap[pnewmap[i]] = i;
    }
    else
    {
        dc->u.x.pal.hMapping = map;
        dc->u.x.pal.hRevMapping = map ? hRevSysColorTranslation : 0;
    }
    dc->u.x.pal.mappingSize = size;
}


/***********************************************************************
 *           GetNearestColor    (GDI.154)
 */
COLORREF GetNearestColor( HDC hdc, COLORREF color )
{
    WORD index;
    DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
    if (!dc) return 0;
    if (screenDepth > 8) return color;
    index = (WORD)(COLOR_ToPhysical( dc, color & 0xffffff ) & 0xffff);
    return PALETTEINDEX( index );
}


/***********************************************************************
 *           RealizeDefaultPalette    (GDI.365)
 */
WORD RealizeDefaultPalette( HDC hdc )
{
    DC *dc;
    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
    dc->w.hPalette = STOCK_DEFAULT_PALETTE;
    COLOR_SetMapping( dc, hSysColorTranslation,
                      hRevSysColorTranslation, NB_RESERVED_COLORS );
    return NB_RESERVED_COLORS;
}
