/* 
 * xcolor.c --
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * All rights reserved.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */
/*
 * Copyright (c) 1994 Software Research Associates, Inc.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Software Research Associates not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.  Software Research
 * Associates makes no representations about the suitability of this software
 * for any purpose.  It is provided "as is" without express or implied
 * warranty.
 */

#include "xlibInt.h" 

#define NEAREST_COLOR
/*
 * use management color
 */
static int built = 0;

static Lx_HashTable ceDBTable;

typedef struct {
    unsigned char red;
    unsigned char green;
    unsigned char blue;
    char *name;
} ColorEntry;

static ColorEntry colorDB[] = {
#include "xcolor2.h"
      0,   0,   0, NULL
};

typedef struct {
    char *name;
    int index;
} SystemColorEntry;

static SystemColorEntry sysColorEntries[] = {
    "SystemActiveBorder",		COLOR_ACTIVEBORDER,
    "SystemActiveCaption",		COLOR_ACTIVECAPTION,
    "SystemAppWorkspace",		COLOR_APPWORKSPACE,
    "SystemBackground",			COLOR_BACKGROUND,
    "SystemButtonFace",			COLOR_BTNFACE,
    "SystemButtonHighlight",		COLOR_BTNHIGHLIGHT,
    "SystemButtonShadow",		COLOR_BTNSHADOW,
    "SystemButtonText",			COLOR_BTNTEXT,
    "SystemCaptionText",		COLOR_CAPTIONTEXT,
    "SystemDisabledText",		COLOR_GRAYTEXT,
    "SystemHighlight",			COLOR_HIGHLIGHT,
    "SystemHighlightText",		COLOR_HIGHLIGHTTEXT,
    "SystemInactiveBorder",		COLOR_INACTIVEBORDER,
    "SystemInactiveCaption",		COLOR_INACTIVECAPTION,
    "SystemInactiveCaptionText",	COLOR_INACTIVECAPTIONTEXT,
    "SystemMenu",			COLOR_MENU,
    "SystemMenuText",			COLOR_MENUTEXT,
    "SystemScrollbar",			COLOR_SCROLLBAR,
    "SystemWindow",			COLOR_WINDOW,
    "SystemWindowFrame",		COLOR_WINDOWFRAME,
    "SystemWindowText",			COLOR_WINDOWTEXT,
    NULL,				0
};

static ColorEntry sysColorDB[] = {
    0, 0, 0, "SystemActiveBorder",
    0, 0, 0, "SystemActiveCaption",
    0, 0, 0, "SystemAppWorkspace",
    0, 0, 0, "SystemBackground",
    0, 0, 0, "SystemButtonFace",
    0, 0, 0, "SystemButtonHighlight",
    0, 0, 0, "SystemButtonShadow",
    0, 0, 0, "SystemButtonText",
    0, 0, 0, "SystemCaptionText",
    0, 0, 0, "SystemDisabledText",
    0, 0, 0, "SystemHighlight",
    0, 0, 0, "SystemHighlightText",
    0, 0, 0, "SystemInactiveBorder",
    0, 0, 0, "SystemInactiveCaption",
    0, 0, 0, "SystemInactiveCaptionText",
    0, 0, 0, "SystemMenu",
    0, 0, 0, "SystemMenuText",
    0, 0, 0, "SystemScrollbar",
    0, 0, 0, "SystemWindow",
    0, 0, 0, "SystemWindowFrame",
    0, 0, 0, "SystemWindowText",
    0, 0, 0, NULL
};

typedef struct _LxColormap LxColormap;
struct _LxColormap {
    LxColormap *next;
    int type;
    int size;
    int *colors;
    int *refcount;
};
    
/*
 *----------------------------------------------------------------------
 * SetSystemColorDB
 * Purpose:
 *    Set all the system colors in our database
 *----------------------------------------------------------------------
 */
void
LxSetSystemColors()
{
    SystemColorEntry *sPtr;
    ColorEntry *ePtr;
    COLORREF color;

    for (ePtr = sysColorDB, sPtr = sysColorEntries;
	 sPtr->name != NULL; ePtr++, sPtr++)
    {
	color = GetSysColor(sPtr->index);
	ePtr->red = GetRValue(color);
	ePtr->green = GetGValue(color);
	ePtr->blue = GetBValue(color);
    }
}

/*
 * BuildColorDB
 *
 */

static void
BuildColorDB()
{
    ColorEntry *ePtr;
    Lx_HashEntry *hPtr;
    int dummy;

    built = 1;

    Lx_InitHashTable(&ceDBTable, LX_STRING_KEYS);
    for (ePtr = colorDB; ePtr->name != NULL; ePtr++) {
        hPtr = Lx_CreateHashEntry(&ceDBTable, strlwr(ePtr->name), &dummy);
        Lx_SetHashValue(hPtr, ePtr);
    }

    LxSetSystemColors();

    for (ePtr = sysColorDB; ePtr->name != NULL; ePtr++) {
        hPtr = Lx_CreateHashEntry(&ceDBTable, strlwr(ePtr->name), &dummy);
        Lx_SetHashValue(hPtr, ePtr);
    }
}

Colormap
XCreateColormap(Display *display, Window w, Visual *visual, int alloc)
{
    display->request++;

    return 0;
}


Status
XLookupColor(Display *display, Colormap colormap, const char *colorname, 
	     XColor *exact_def_return, XColor *screen_def_return)
{
    Lx_HashEntry *hPtr;
    ColorEntry *cPtr;
    HDC hdc;
    XColor *col1, *col2;
    static char *name;

    display->request++;

    if (!built) {
        BuildColorDB();
    }

    if (name != NULL) {
	free(name);
    }
    name = strdup(colorname);
    if (name == NULL) {
	return 0;
    }
    hPtr = Lx_FindHashEntry(&ceDBTable, (char *) strlwr(name));

    if (hPtr == NULL) {
        return 0;
    }
    col1 = exact_def_return;
    col2 = screen_def_return;

    cPtr = (ColorEntry *) Lx_GetHashValue(hPtr);
    hdc = GetDC((HWND)NULL);
#ifdef NEAREST_COLOR
    col1->pixel = GetNearestColor(hdc, RGB(cPtr->red, cPtr->green, cPtr->blue));
    col2->pixel = GetNearestColor(hdc, RGB(cPtr->red, cPtr->green, cPtr->blue));
#else
    col1->pixel = RGB(cPtr->red, cPtr->green, cPtr->blue);
    col2->pixel = RGB(cPtr->red, cPtr->green, cPtr->blue);
#endif
    ReleaseDC((HWND)NULL, hdc);
    col1->red = GetRValue(col1->pixel);
    col1->green = GetGValue(col1->pixel);
    col1->blue = GetBValue(col1->pixel);
    col1->pad = 0;

    col2->red = GetRValue(col2->pixel);
    col2->green = GetGValue(col2->pixel);
    col2->blue = GetBValue(col2->pixel);
    col2->pad = 0;

    return 1;
}

Status
XAllocNamedColor(Display *display, Colormap colormap, const char *colorname, 
		 XColor *exact_def_return, XColor *screen_def_return)
{		 
    display->request++;

    return XLookupColor(display, colormap, colorname,
			exact_def_return, screen_def_return);
}

Status
XParseColor(Display *display, Colormap colormap, const char *spec,
	    XColor *color)
{
    char fmt[16];
    int i;
    HDC hdc;

    if ((i = strlen(spec+1))%3)
	return 0;
    i /= 3;

    sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i);
    sscanf(spec+1, fmt, &color->red, &color->green, &color->blue);
    color->pad = 0;
    hdc = GetDC((HWND)NULL);
#ifdef NEAREST_COLOR
    color->pixel = GetNearestColor(hdc, RGB(color->red, color->green, color->blue));
#else
    color->pixel = RGB(color->red, color->green, color->blue);
#endif
    color->red = GetRValue(color->pixel);
    color->green = GetGValue(color->pixel);
    color->blue = GetBValue(color->pixel);
    ReleaseDC((HWND)NULL, hdc);

    return 1;
}

Status
XAllocColor(Display *display, Colormap colormap, XColor *color)
{
    HDC hdc;

    display->request++;

    hdc = GetDC((HWND)NULL);
#ifdef NEAREST_COLOR
    color->pixel = GetNearestColor(hdc, RGB(color->red, color->green, color->blue));
#else
    color->pixel = RGB(color->red, color->green, color->blue);
#endif
    ReleaseDC((HWND)NULL, hdc);

    return 1;
}

void
XFreeColors(Display *display, Colormap colormap, unsigned long pixels[],
	    int npixels, unsigned long planes)
{
    display->request++;
}
