/*
 * Support for system colors
 *
 * Copyright  David W. Metcalfe, 1993
 * Copyright  Alexandre Julliard, 1994
 *
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "windef.h"
#include "wingdi.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "sysmetrics.h"
#include "winbase.h"
#include "winuser.h"
#include "debugtools.h"
#include "winreg.h"
#include "local.h"
#include "user.h"
#include "gdi.h" /* sic */

DEFAULT_DEBUG_CHANNEL(syscolor);

static const char * const DefSysColors[] =
{
    "Scrollbar", "224 224 224",      /* COLOR_SCROLLBAR           */
    "Background", "192 192 192",     /* COLOR_BACKGROUND          */
    "ActiveTitle", "0 64 128",       /* COLOR_ACTIVECAPTION       */
    "InactiveTitle", "255 255 255",  /* COLOR_INACTIVECAPTION     */
    "Menu", "255 255 255",           /* COLOR_MENU                */
    "Window", "255 255 255",         /* COLOR_WINDOW              */
    "WindowFrame", "0 0 0",          /* COLOR_WINDOWFRAME         */
    "MenuText", "0 0 0",             /* COLOR_MENUTEXT            */
    "WindowText", "0 0 0",           /* COLOR_WINDOWTEXT          */
    "TitleText", "255 255 255",      /* COLOR_CAPTIONTEXT         */
    "ActiveBorder", "128 128 128",   /* COLOR_ACTIVEBORDER        */
    "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER      */
    "AppWorkspace", "255 255 232",   /* COLOR_APPWORKSPACE        */
    "Hilight", "224 224 224",        /* COLOR_HIGHLIGHT           */
    "HilightText", "0 0 0",          /* COLOR_HIGHLIGHTTEXT       */
    "ButtonFace", "192 192 192",     /* COLOR_BTNFACE             */
    "ButtonShadow", "128 128 128",   /* COLOR_BTNSHADOW           */
    "GrayText", "192 192 192",       /* COLOR_GRAYTEXT            */
    "ButtonText", "0 0 0",           /* COLOR_BTNTEXT             */
    "InactiveTitleText", "0 0 0",    /* COLOR_INACTIVECAPTIONTEXT */
    "ButtonHilight", "255 255 255",  /* COLOR_BTNHIGHLIGHT        */
    "3DDarkShadow", "32 32 32",      /* COLOR_3DDKSHADOW          */
    "3DLight", "192 192 192",        /* COLOR_3DLIGHT             */
    "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
    "InfoBackground", "255 255 192", /* COLOR_INFOBK              */
    "AlternateButtonFace", "184 180 184",  /* COLOR_ALTERNATEBTNFACE */
    "HotTrackingColor", "0 0 255",         /* COLOR_HOTLIGHT */
    "GradientActiveTitle", "16 132 208",   /* COLOR_GRADIENTACTIVECAPTION */
    "GradientInactiveTitle", "181 181 181" /* COLOR_GRADIENTINACTIVECAPTION */
};

static const char * const DefSysColors95[] =
{
    "Scrollbar", "192 192 192",      /* COLOR_SCROLLBAR           */
    "Background", "0 128 128",       /* COLOR_BACKGROUND          */
    "ActiveTitle", "0 0 128",        /* COLOR_ACTIVECAPTION       */
    "InactiveTitle", "128 128 128",  /* COLOR_INACTIVECAPTION     */
    "Menu", "192 192 192",           /* COLOR_MENU                */
    "Window", "255 255 255",         /* COLOR_WINDOW              */
    "WindowFrame", "0 0 0",          /* COLOR_WINDOWFRAME         */
    "MenuText", "0 0 0",             /* COLOR_MENUTEXT            */
    "WindowText", "0 0 0",           /* COLOR_WINDOWTEXT          */
    "TitleText", "255 255 255",      /* COLOR_CAPTIONTEXT         */
    "ActiveBorder", "192 192 192",   /* COLOR_ACTIVEBORDER        */
    "InactiveBorder", "192 192 192", /* COLOR_INACTIVEBORDER      */
    "AppWorkspace", "128 128 128",   /* COLOR_APPWORKSPACE        */
    "Hilight", "0 0 128",            /* COLOR_HIGHLIGHT           */
    "HilightText", "255 255 255",    /* COLOR_HIGHLIGHTTEXT       */
    "ButtonFace", "192 192 192",     /* COLOR_BTNFACE             */
    "ButtonShadow", "128 128 128",   /* COLOR_BTNSHADOW           */
    "GrayText", "128 128 128",       /* COLOR_GRAYTEXT            */
    "ButtonText", "0 0 0",           /* COLOR_BTNTEXT             */
    "InactiveTitleText", "192 192 192",/* COLOR_INACTIVECAPTIONTEXT */
    "ButtonHilight", "255 255 255",  /* COLOR_BTNHIGHLIGHT        */
    "3DDarkShadow", "0 0 0",         /* COLOR_3DDKSHADOW          */
    "3DLight", "224 224 224",        /* COLOR_3DLIGHT             */
    "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
    "InfoBackground", "255 255 225", /* COLOR_INFOBK              */
    "AlternateButtonFace", "180 180 180",  /* COLOR_ALTERNATEBTNFACE */
    "HotTrackingColor", "0 0 255",         /* COLOR_HOTLIGHT */
    "GradientActiveTitle", "16 132 208",   /* COLOR_GRADIENTACTIVECAPTION */
    "GradientInactiveTitle", "181 181 181" /* COLOR_GRADIENTINACTIVECAPTION */
};


#define NUM_SYS_COLORS     (COLOR_GRADIENTINACTIVECAPTION+1)

static COLORREF SysColors[NUM_SYS_COLORS];
static HBRUSH SysColorBrushes[NUM_SYS_COLORS];
static HPEN   SysColorPens[NUM_SYS_COLORS];


/*************************************************************************
 * SYSCOLOR_MakeObjectSystem
 *
 * OK, now for a very ugly hack.
 * USER somehow has to tell GDI that its system brushes and pens are
 * non-deletable.
 * We don't want to export a function from GDI doing this for us,
 * so we just do that ourselves by "wildly flipping some bits in memory".
 * For a description of the GDI object magics and their flags,
 * see "Undocumented Windows" (wrong about the OBJECT_NOSYSTEM flag, though).
 */
static void SYSCOLOR_MakeObjectSystem( HGDIOBJ handle, BOOL set)
{
    static WORD GDI_heap_sel = 0;
    LPWORD ptr;

    if (!GDI_heap_sel)
    {
	GDI_heap_sel = LoadLibrary16("gdi");
	FreeLibrary16(GDI_heap_sel);
    }

    ptr = (LPWORD)LOCAL_Lock(GDI_heap_sel, handle);

    /* touch the "system" bit of the wMagic field of a GDIOBJHDR */
    if (set)
        *(ptr+1) &= ~OBJECT_NOSYSTEM;
    else
	*(ptr+1) |= OBJECT_NOSYSTEM;
    LOCAL_Unlock( GDI_heap_sel, handle );
}

/*************************************************************************
 *             SYSCOLOR_SetColor
 */
static void SYSCOLOR_SetColor( int index, COLORREF color )
{
    if (index < 0 || index >= NUM_SYS_COLORS) return;
    SysColors[index] = color;
    if (SysColorBrushes[index])
    {
	SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], FALSE);
	DeleteObject( SysColorBrushes[index] );
    }
    SysColorBrushes[index] = CreateSolidBrush( color );
    SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], TRUE);

    if (SysColorPens[index])
    {
        SYSCOLOR_MakeObjectSystem(SysColorPens[index], FALSE);
	DeleteObject( SysColorPens[index] ); 
    }
    SysColorPens[index] = CreatePen( PS_SOLID, 1, color );
    SYSCOLOR_MakeObjectSystem(SysColorPens[index], TRUE);
}


/*************************************************************************
 *             SYSCOLOR_Init
 */
void SYSCOLOR_Init(void)
{
    int i, r, g, b;
    const char * const *p;
    char buffer[100];
    BOOL bOk = FALSE, bNoReg = FALSE;
    HKEY  hKey;

    p = (TWEAK_WineLook == WIN31_LOOK) ? DefSysColors : DefSysColors95;

    /* first, try to read the values from the registry */
    if (RegCreateKeyExA(HKEY_CURRENT_USER, "Control Panel\\Colors", 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
      bNoReg = TRUE;
    for (i = 0; i < NUM_SYS_COLORS; i++)
    { bOk = FALSE;

      /* first try, registry */
      if (!bNoReg)
      {
	DWORD dwDataSize = sizeof(buffer);
	if (!(RegQueryValueExA(hKey,(LPSTR)p[i*2], 0, 0, buffer, &dwDataSize)))
	  if (sscanf( buffer, "%d %d %d", &r, &g, &b ) == 3) 
	    bOk = TRUE;
      }

      /* second try, win.ini */
      if (!bOk)
      { GetProfileStringA( "colors", p[i*2], p[i*2+1], buffer, 100 );
	if (sscanf( buffer, " %d %d %d", &r, &g, &b ) == 3)
	  bOk = TRUE;
      }
      
      /* last chance, take the default */
      if (!bOk)
      { int iNumColors = sscanf( p[i*2+1], " %d %d %d", &r, &g, &b );
	assert (iNumColors==3);
      }
      
      SYSCOLOR_SetColor( i, RGB(r,g,b) );
    }
    if (!bNoReg)
      RegCloseKey(hKey);
}


/*************************************************************************
 *		GetSysColor (USER.180)
 */
COLORREF WINAPI GetSysColor16( INT16 nIndex )
{
    return GetSysColor (nIndex);
}


/*************************************************************************
 *		GetSysColor (USER32.@)
 */
COLORREF WINAPI GetSysColor( INT nIndex )
{
    if (nIndex >= 0 && nIndex < NUM_SYS_COLORS)
	return SysColors[nIndex];
    else
	return 0;
}


/*************************************************************************
 *		SetSysColors (USER.181)
 */
VOID WINAPI SetSysColors16( INT16 nChanges, const INT16 *lpSysColor,
			    const COLORREF *lpColorValues )
{
    int i;

    for (i = 0; i < nChanges; i++)
    {
	SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] );
    }

    /* Send WM_SYSCOLORCHANGE message to all windows */

    SendMessageA( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0 );

    /* Repaint affected portions of all visible windows */

    RedrawWindow( GetDesktopWindow(), NULL, 0,
                RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
}


/*************************************************************************
 *		SetSysColors (USER32.@)
 */
BOOL WINAPI SetSysColors( INT nChanges, const INT *lpSysColor,
                              const COLORREF *lpColorValues )
{
    int i;

    for (i = 0; i < nChanges; i++)
    {
	SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] );
    }

    /* Send WM_SYSCOLORCHANGE message to all windows */

    SendMessageA( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0 );

    /* Repaint affected portions of all visible windows */

    RedrawWindow( GetDesktopWindow(), NULL, 0,
                RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
    return TRUE;
}

/*************************************************************************
 *		SetSysColorsTemp (USER32.@)
 *
 * UNDOCUMENTED !!
 * 
 * Called by W98SE desk.cpl Control Panel Applet:
 * handle = SetSysColorsTemp(ptr, ptr, nCount);     ("set" call)
 * result = SetSysColorsTemp(NULL, NULL, handle);   ("restore" call)
 *
 * pPens is an array of COLORREF values, which seems to be used
 * to indicate the color values to create new pens with.
 *
 * pBrushes is an array of solid brush handles (returned by a previous
 * CreateSolidBrush), which seems to contain the brush handles to set
 * for the system colors.
 *
 * n seems to be used for
 *   a) indicating the number of entries to operate on (length of pPens,
 *      pBrushes)
 *   b) passing the handle that points to the previously used color settings.
 *      I couldn't figure out in hell what kind of handle this is on
 *      Windows. I just use a heap handle instead. Shouldn't matter anyway.
 *
 * RETURNS
 *     heap handle of our own copy of the current syscolors in case of
 *                 "set" call, i.e. pPens, pBrushes != NULL.
 *     TRUE (unconditionally !) in case of "restore" call,
 *          i.e. pPens, pBrushes == NULL.
 *     FALSE in case of either pPens != NULL and pBrushes == NULL
 *          or pPens == NULL and pBrushes != NULL.
 *
 * I'm not sure whether this implementation is 100% correct. [AM]
 */
DWORD WINAPI SetSysColorsTemp( const COLORREF *pPens, const HBRUSH *pBrushes, DWORD n)
{
	int i;

	if (pPens && pBrushes) /* "set" call */
	{
	    /* allocate our structure to remember old colors */
	    LPVOID pOldCol = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD)+n*sizeof(HPEN)+n*sizeof(HBRUSH));
	    LPVOID p = pOldCol;
	    *(DWORD *)p = n; p += sizeof(DWORD);
	    memcpy(p, SysColorPens, n*sizeof(HPEN)); p += n*sizeof(HPEN);
	    memcpy(p, SysColorBrushes, n*sizeof(HBRUSH)); p += n*sizeof(HBRUSH);

	    for (i=0; i < n; i++)
	    {
		SysColorPens[i] = CreatePen( PS_SOLID, 1, pPens[i] );
		SysColorBrushes[i] = pBrushes[i];
	    }

	    return (DWORD)pOldCol;
	}
	if ((!pPens) && (!pBrushes)) /* "restore" call */
	{
	    LPVOID pOldCol = (LPVOID)n;
	    LPVOID p = pOldCol;
	    DWORD nCount = *(DWORD *)p;
	    p += sizeof(DWORD);

	    for (i=0; i < nCount; i++)
	    {
		DeleteObject(SysColorPens[i]);
		SysColorPens[i] = *(HPEN *)p; p += sizeof(HPEN);
	    }
	    for (i=0; i < nCount; i++)
	    {
		SysColorBrushes[i] = *(HBRUSH *)p; p += sizeof(HBRUSH);
	    }
	    /* get rid of storage structure */
	    HeapFree(GetProcessHeap(), 0, pOldCol);

	    return TRUE;
	}
	return FALSE;
}

/***********************************************************************
 *		GetSysColorBrush (USER.281)
 */
HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
{
    return (HBRUSH16)GetSysColorBrush(index);
}


/***********************************************************************
 *		GetSysColorBrush (USER32.@)
 */
HBRUSH WINAPI GetSysColorBrush( INT index )
{
    if (0 <= index && index < NUM_SYS_COLORS)
        return SysColorBrushes[index];
    WARN("Unknown index(%d)\n", index );
    return GetStockObject(LTGRAY_BRUSH);
}


/***********************************************************************
 *		GetSysColorPen (USER32.@) (Not a Windows API)
 *
 * This function is new to the Wine lib -- it does not exist in 
 * Windows. However, it is a natural complement for GetSysColorBrush
 * in the Win32 API and is needed quite a bit inside Wine.
 */
HPEN WINAPI GetSysColorPen( INT index )
{
    /* We can assert here, because this function is internal to Wine */
    assert (0 <= index && index < NUM_SYS_COLORS);
    return SysColorPens[index];

}


