/*
 * GDI palette objects
 *
 * Copyright 1993,1994 Alexandre Julliard
 * Copyright 1996 Alex Korobka
 *
 */
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>

#include "color.h"
#include "palette.h"
#include "stddebug.h"
/* #define DEBUG_PALETTE */
#include "debug.h"

extern HWND 		DCE_hDC2hWnd( HDC );			/* get associated window by 
								 * walking DCE list */

static WORD SystemPaletteUse = SYSPAL_STATIC;	/* currently not considered */

static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */


/***********************************************************************
 *           PALETTE_GetNearestIndexAndColor
 */
static WORD PALETTE_GetNearestIndexAndColor( HPALETTE16 hpalette,
                                             COLORREF *color)
{
    int i, minDist, dist;
    WORD index = 0;
    BYTE r, g, b;
    PALETTEENTRY * entry;
    PALETTEOBJ * palPtr;
    
    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
    if (!palPtr) return 0;

    if ( hpalette == STOCK_DEFAULT_PALETTE )
    {
	if ((*color & 0xffffff) == 0) return 0;  /* Entry 0 is black */
	if ((*color & 0xffffff) == 0xffffff)     /* Max entry is white */
	    return palPtr->logpalette.palNumEntries - 1;
    }

    r = GetRValue(*color);
    g = GetGValue(*color);
    b = GetBValue(*color);

    entry = palPtr->logpalette.palPalEntry;
    for (i = 0, minDist = 0xffffff; minDist !=0 &&
         i < palPtr->logpalette.palNumEntries ; i++)
    {
	if (entry->peFlags != 0xff)
	{
	    dist = (r - entry->peRed) * (r - entry->peRed) +
		   (g - entry->peGreen) * (g - entry->peGreen) +
		   (b - entry->peBlue) * (b - entry->peBlue);	
	    if (dist < minDist)
	    {
		minDist = dist;
		index = i;
	    }
	}
	entry++;
    }

    entry = &palPtr->logpalette.palPalEntry[index];
    *color = RGB( entry->peRed, entry->peGreen, entry->peBlue );
    return index;
}


/***********************************************************************
 *           PALETTE_ValidateFlags
 */
void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
{
    int i = 0;
    for( ; i<size ; i++ )
        lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
}


/***********************************************************************
 *           CreatePalette    (GDI.360)
 */
HPALETTE16 CreatePalette( const LOGPALETTE* palette )
{
    PALETTEOBJ * palettePtr;
    HPALETTE16 hpalette;
    int size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);

    dprintf_palette(stddeb,"CreatePalette: ");

    dprintf_palette(stddeb,"%i entries, ", palette->palNumEntries);

    hpalette = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR) , PALETTE_MAGIC );
    if (!hpalette) return 0;

    palettePtr = (PALETTEOBJ *) GDI_HEAP_LIN_ADDR( hpalette );
    memcpy( &palettePtr->logpalette, palette, size );
    PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry, 
			  palettePtr->logpalette.palNumEntries);
    palettePtr->mapping = NULL;

    dprintf_palette(stddeb,"returning %04x\n", hpalette);
    return hpalette;
}


/***********************************************************************
 *           GetPaletteEntries    (GDI.363)
 */
WORD GetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
		        LPPALETTEENTRY entries )
{
    PALETTEOBJ * palPtr;
    int numEntries;

    dprintf_palette(stddeb,"GetPaletteEntries: hpal = %04x, %i entries\n", hpalette, count);
        
    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
    if (!palPtr) return 0;

    numEntries = palPtr->logpalette.palNumEntries;
    if (start >= numEntries) return 0;
    if (start+count > numEntries) count = numEntries - start;
    memcpy( entries, &palPtr->logpalette.palPalEntry[start],
	    count * sizeof(PALETTEENTRY) );
    for( numEntries = 0; numEntries < count ; numEntries++ )
         if( entries[numEntries].peFlags & 0xF0 ) entries[numEntries].peFlags = 0;
    return count;
}


/***********************************************************************
 *           SetPaletteEntries    (GDI.364)
 */
WORD SetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
		        LPPALETTEENTRY entries )
{
    PALETTEOBJ * palPtr;
    int numEntries;

    dprintf_palette(stddeb,"SetPaletteEntries: hpal = %04x, %i entries\n", hpalette, count);

    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
    if (!palPtr) return 0;

    numEntries = palPtr->logpalette.palNumEntries;
    if (start >= numEntries) return 0;
    if (start+count > numEntries) count = numEntries - start;
    memcpy( &palPtr->logpalette.palPalEntry[start], entries,
	    count * sizeof(PALETTEENTRY) );
    PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, 
			  palPtr->logpalette.palNumEntries);
    return count;
}

/***********************************************************************
 *           ResizePalette          (GDI.368)
 */
BOOL ResizePalette(HPALETTE16 hPal, UINT cEntries)
{

    /* should simply realloc memory and zero out
     * added entries, if any */

    fprintf(stdnimp,"ResizePalette: empty stub! \n");
    return FALSE;
}

/***********************************************************************
 *           AnimatePalette          (GDI.367)
 */
BOOL AnimatePalette(HPALETTE16 hPal, UINT StartIndex, UINT NumEntries,
		    LPPALETTEENTRY PaletteColors)
{
    fprintf(stdnimp,"AnimatePalette: empty stub! \n");
    return TRUE;
}

/***********************************************************************
 *           SetSystemPaletteUse    (GDI.373)
 */
WORD SetSystemPaletteUse( HDC hdc, WORD use)
{
	 WORD old=SystemPaletteUse;
	 fprintf(stdnimp,"SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n", hdc, use);
	 SystemPaletteUse=use;
	 return old;
}

/***********************************************************************
 *           GetSystemPaletteUse    (GDI.374)
 */
WORD GetSystemPaletteUse( HDC hdc )
{
	fprintf(stdnimp,"GetSystemPaletteUse(%04x) // empty stub !!!\n", hdc);
	return SystemPaletteUse;
}


/***********************************************************************
 *           GetSystemPaletteEntries    (GDI.375)
 */
WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count,
			      LPPALETTEENTRY entries )
{
    WORD i;
    DC *dc;
    XColor color;

    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
    if (start >= dc->w.devCaps->sizePalette) return 0;
    if (start+count >= dc->w.devCaps->sizePalette)
	count = dc->w.devCaps->sizePalette - start;
    for (i = 0; i < count; i++)
    {
	color.pixel = (COLOR_PaletteToPixel)
		      ? COLOR_PaletteToPixel[start + i]
		      : start + i;
	XQueryColor( display, COLOR_GetColormap(), &color );
	entries[i].peRed   = color.red >> 8;
	entries[i].peGreen = color.green >> 8;
	entries[i].peBlue  = color.blue >> 8;
	entries[i].peFlags = 0;	
    }
    return count;
}


/***********************************************************************
 *           GetNearestPaletteIndex    (GDI.370)
 */
WORD GetNearestPaletteIndex( HPALETTE16 hpalette, COLORREF color )
{
    WORD index = PALETTE_GetNearestIndexAndColor( hpalette, &color );
    dprintf_palette(stddeb,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n", 
                    hpalette, color, index );
    return index;
}


/***********************************************************************
 *           GetNearestColor    (GDI.154)
 */
COLORREF GetNearestColor( HDC hdc, COLORREF color )
{
    COLORREF nearest = color;
    DC *dc;

    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
    PALETTE_GetNearestIndexAndColor( dc->w.hPalette, &nearest );
    dprintf_palette(stddeb,"GetNearestColor(%06lx): returning %06lx\n", 
                    color, nearest );
    return nearest;
}


/***********************************************************************
 *           PALETTE_GetObject
 */
int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
{
    if (count > sizeof(WORD)) count = sizeof(WORD);
    memcpy( buffer, &palette->logpalette.palNumEntries, count );
    return count;
}


/***********************************************************************
 *           PALETTE_UnrealizeObject
 */
BOOL PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
{
    if (palette->mapping)
    {
        free( palette->mapping );
        palette->mapping = NULL;
    }
    if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
    return TRUE;
}


/***********************************************************************
 *           PALETTE_DeleteObject
 */
BOOL PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
{
    free( palette->mapping );
    return GDI_FreeObject( hpalette );
}


/***********************************************************************
 *           GDISelectPalette    (GDI.361)
 */
HPALETTE16 GDISelectPalette( HDC hdc, HPALETTE16 hpal, WORD wBkg)
{
    HPALETTE16 prev;
    DC *dc;

    dprintf_palette(stddeb, "GDISelectPalette: %04x %04x\n", hdc, hpal );
    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
    prev = dc->w.hPalette;
    dc->w.hPalette = hpal;
    if (!wBkg) hPrimaryPalette = hpal; 
    return prev;
}


/***********************************************************************
 *           GDIRealizePalette    (GDI.362)
 *
 */
UINT GDIRealizePalette( HDC hdc )
{
    DC*         dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ) ;
    PALETTEOBJ* palPtr;
    int		realized = 0;

    dprintf_palette(stddeb, "GDIRealizePalette: %04x...", hdc );
    
    if( dc &&  dc->w.hPalette != hLastRealizedPalette )
    {
        palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
        
	realized = COLOR_SetMapping(palPtr, dc->w.hPalette != hPrimaryPalette 
                                  || dc->w.hPalette == STOCK_DEFAULT_PALETTE );
	hLastRealizedPalette = dc->w.hPalette;
    }
    else dprintf_palette(stddeb, " skipping ");
    
    dprintf_palette(stdnimp, " realized %i colors\n", realized );
    return (UINT)realized;
}


/***********************************************************************
 *           RealizeDefaultPalette    (GDI.365)
 */
WORD RealizeDefaultPalette( HDC hdc )
{
    DC *dc;

    dprintf_palette(stddeb,"RealizeDefaultPalette: %04x\n", hdc );

    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
    if ( dc->w.flags & DC_MEMORY ) return 0;

    hPrimaryPalette = STOCK_DEFAULT_PALETTE;
    hLastRealizedPalette = STOCK_DEFAULT_PALETTE;
    return COLOR_SetMapping( (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC ), TRUE);
}


/***********************************************************************
 *           IsDCCurrentPalette   (GDI.412)
 */
BOOL IsDCCurrentPalette(HDC hDC)
{
    DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
    return (dc->w.hPalette == hPrimaryPalette);
}

/***********************************************************************
 *           SelectPalette    (USER.282)
 */
HPALETTE16 SelectPalette( HDC hDC, HPALETTE16 hPal, BOOL bForceBackground )
{
    WORD	wBkgPalette = 1;
    PALETTEOBJ* lpt = (PALETTEOBJ*) GDI_GetObjPtr( hPal, PALETTE_MAGIC );

    dprintf_palette(stddeb,"SelectPalette: dc %04x pal %04x, force=%i ", 
			    hDC, hPal, bForceBackground);
    if( !lpt ) return 0;

    dprintf_palette(stddeb," entries = %d\n", 
			    lpt->logpalette.palNumEntries);

    if( hPal != STOCK_DEFAULT_PALETTE )
    {
	HWND hWnd = DCE_hDC2hWnd( hDC );
	HWND hActive = GetActiveWindow();
	
	/* set primary palette if it's related to current active */

	if( hWnd && (hActive == hWnd || IsChild(hActive,hWnd)) &&
            !bForceBackground )
	    wBkgPalette = 0;
    }
    return GDISelectPalette( hDC, hPal, wBkgPalette);
}


/***********************************************************************
 *           RealizePalette    (USER.283) (GDI32.280)
 */
UINT16 RealizePalette( HDC32 hDC )
{
    UINT16 realized = GDIRealizePalette( hDC );

    /* do not send anything if no colors were changed */

    if( IsDCCurrentPalette( hDC ) && realized )
    {
	/* Send palette change notification */

	HWND hWnd;
 	if( (hWnd = DCE_hDC2hWnd( hDC )) )
            SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
    }
    return realized;
}


/**********************************************************************
 *	    UpdateColors	(GDI.366)
 *
 */
int UpdateColors( HDC hDC )
{
    HWND hWnd = DCE_hDC2hWnd( hDC );

    /* Docs say that we have to remap current drawable pixel by pixel
     * but it would take forever given the speed of XGet/PutPixel.
     */
    if (hWnd) InvalidateRect16( hWnd, NULL, FALSE );
    return 0x666;
}
