#include <windows.h>
#include <stdio.h>
#include "shmgdefs.h"

#undef COLOR_MAX

#define COLOR_MAX (COLOR_GRADIENTINACTIVECAPTION + 1)
#define COLOR_MAX_NT4 (COLOR_INFOBK + 1)
#define SCHEME_MAX 27

CONST TCHAR* rgpszSchemes[SCHEME_MAX] = {
    TEXT("High Contrast Black (EL)"),       // 0
    TEXT("High Contrast White (EL)"),       // 1
    TEXT("Brick"),                          // 2
    TEXT("Desert"),                         // 3
    TEXT("Eggplant"),                       // 4
    TEXT("High Contrast Black"),            // 5
    TEXT("High Contrast White"),            // 6
    TEXT("Lilac"),                          // 7
    TEXT("Marine (HC)"),                    // 8
    TEXT("Plum (HC)"),                      // 9
    TEXT("Pumpkin (L)"),                    // 10
    TEXT("Rainy Day"),                      // 11
    TEXT("Red, White, and Blue (VGA)"),     // 12
    TEXT("Rose"),                           // 13
    TEXT("Slate"),                          // 14
    TEXT("Spruce"),                         // 15
    TEXT("Storm (VGA)"),                    // 16
    TEXT("Teal (VGA)"),                     // 17
    TEXT("Windows Standard"),               // 18
    TEXT("Rose (large)"),                   // 19
    TEXT("High Contrast Black (L)"),        // 20
    TEXT("High Contrast White (L)"),        // 21
    TEXT("Lilac (large)"),                  // 22
    TEXT("Windows Standard (EL)"),          // 23
    TEXT("Windows Standard (L)"),           // 24
    TEXT("Maple"),                          // 25
    TEXT("Wheat)")                          // 26
};

CONST TCHAR* rgpsz[COLOR_MAX] = {
    TEXT("Scrollbar"),
    TEXT("Background"),
    TEXT("ActiveTitle"),
    TEXT("InactiveTitle"),
    TEXT("Menu"),
    TEXT("Window"),
    TEXT("WindowFrame"),
    TEXT("MenuText"),
    TEXT("WindowText"),
    TEXT("TitleText"),
    TEXT("ActiveBorder"),
    TEXT("InactiveBorder"),
    TEXT("AppWorkspace"),
    TEXT("Hilight"),
    TEXT("HilightText"),
    TEXT("ButtonFace"),
    TEXT("ButtonShadow"),
    TEXT("GrayText"),
    TEXT("ButtonText"),
    TEXT("InactiveTitleText"),
    TEXT("ButtonHilight"),
    TEXT("ButtonDkShadow"),
    TEXT("ButtonLight"),
    TEXT("InfoText"),
    TEXT("InfoWindow"),
    TEXT("ButtonAlternateFace"),
    TEXT("HotTracking"),
    TEXT("GradientActiveTitle"),
    TEXT("GradientInactiveTitle")
};

COLORREF rgcr[SCHEME_MAX][COLOR_MAX] = {
{0x02000000,0x02000000,0x02800080,0x02008000,0x02000000,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x0200FFFF,0x02008000,0x02000000,0x02800080,0x02FFFFFF,0x02000000,0x02808080,0x0200FF00,0x02FFFFFF,0x02FFFFFF,0x02C0C0C0,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02000000,0x02800080,0x02800080,0x02800080,0x02008000},
{0x02FFFFFF,0x02FFFFFF,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02808080,0x02C0C0C0,0x02808080,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02808080,0x0200FF00,0x02000000,0x02000000,0x02C0C0C0,0x02000000,0x02C0C0C0,0x02000000,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF},
{0x02D2E0E1,0x00000042,0x02000080,0x0261898D,0x02A5BFC2,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02D2E0E1,0x02A5BFC2,0x02A5BFC2,0x02D2E0E1,0x0261898D,0x02FFFFFF,0x02A5BFC2,0x0261898D,0x0261898D,0x02000000,0x02D2E0E1,0x02D2E0E1,0x02000000,0x02A5BFC2,0x02000080,0x02D2E0E1,0x00C0C0C0,0x02000080,0x004074B0,0x0270B8C8},
{0x02DDE6EA,0x02688DA2,0x02808000,0x02688DA2,0x02BBCCD5,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02BBCCD5,0x02BBCCD5,0x02688DA2,0x02808000,0x02FFFFFF,0x02BBCCD5,0x02688DA2,0x02688DA2,0x02000000,0x02FFFFFF,0x02DDE6EA,0x02000000,0x02BBCCD5,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02808000,0x00AABD84,0x0280D0E8},
{0x02A8B090,0x00400040,0x02788058,0x02A8B090,0x02A8B090,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02A8B090,0x02A8B090,0x02808080,0x02788058,0x02FFFFFF,0x02A8B090,0x02788058,0x02788058,0x02000000,0x02788058,0x02D8D8C8,0x02000000,0x02A8B090,0x02800080,0x02FFFFFF,0x00C0C0C0,0x02788058,0x00834B83,0x00D2BDCB},
{0x02000000,0x02000000,0x02800080,0x02008000,0x02000000,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x0200FFFF,0x02008000,0x02000000,0x02800080,0x02FFFFFF,0x02000000,0x02808080,0x0200FF00,0x02FFFFFF,0x02FFFFFF,0x02C0C0C0,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02000000,0x00C0C0C0,0x02800080,0x02D88CC8,0x0012B42B},
{0x02FFFFFF,0x02FFFFFF,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02808080,0x02C0C0C0,0x02808080,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02808080,0x0200FF00,0x02000000,0x02000000,0x02C0C0C0,0x02000000,0x02C0C0C0,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02000000,0x02A09CA0,0x02D8D4D8},
{0x02D9A8AE,0x02000000,0x02B14E5A,0x02808080,0x02D9A8AE,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02D9A8AE,0x02D9A8AE,0x02B14E5A,0x02B14E5A,0x02FFFFFF,0x02D9A8AE,0x02B14E5A,0x02B14E5A,0x02000000,0x02FFFFFF,0x02ECD5D8,0x02000000,0x02D9A8AE,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02B14E5A,0x02CB8FB6,0x02D0B4B8},
{0x02D8E0C8,0x00474E2C,0x02800000,0x02889048,0x02B8C088,0x02D8E0C8,0x02000000,0x02000000,0x02000000,0x02C0C0C0,0x02B8C088,0x02B8C088,0x00848D4B,0x02800000,0x02FFFFFF,0x02B8C088,0x02889048,0x02889048,0x02000000,0x02C0C0C0,0x02D8E0C8,0x02000000,0x02B8C088,0x02000000,0x02D8E0C8,0x00C0C0C0,0x02800000,0x02C0B418,0x02D8CC78},
{0x00C8D0D8,0x00402840,0x00604048,0x00586078,0x009098A8,0x00C8D0D8,0x00000000,0x00000000,0x00000000,0x00C8D0D8,0x009098A8,0x009098A8,0x005A6374,0x00484828,0x00C8D0D8,0x009098A8,0x00586078,0x00586078,0x00000000,0x009098A8,0x00C8D0D8,0x00000000,0x009098A8,0x00580030,0x00C8CCD5,0x00C0C0C0,0x00604048,0x00B884A0,0x007898A8},
{0x02CFEAF5,0x00420042,0x022FA5D7,0x02A4A0A0,0x029DD5EC,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x029DD5EC,0x029DD5EC,0x02CFEAF5,0x02800080,0x02FFFFFF,0x029DD5EC,0x022FA5D7,0x022FA5D7,0x02000000,0x02CFEAF5,0x02CFEAF5,0x02000000,0x029DD5EC,0x02800080,0x02FFFFFF,0x00C0C0C0,0x022FA5D7,0x0288CCE0,0x0290CCD0},
{0x02D9CCC1,0x02000000,0x027D654F,0x02808080,0x02B19983,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02B19983,0x02B19983,0x02808080,0x027D654F,0x02FFFFFF,0x02B19983,0x027D654F,0x027D654F,0x02000000,0x02D9CCC1,0x02D9CCC1,0x02000000,0x02B19983,0x02000000,0x02FFFFFF,0x00C0C0C0,0x027D654F,0x02D0B480,0x02D0BCB0},
{0x02C0C0C0,0x00420000,0x02000080,0x02808080,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02C0C0C0,0x02C0C0C0,0x02FFFFFF,0x02000080,0x02FFFFFF,0x02C0C0C0,0x02808080,0x02808080,0x02000000,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02C0C0C0,0x02800000,0x02FFFFFF,0x00C0C0C0,0x02000080,0x02A81000,0x00C9BEBA},
{0x02B7AFCF,0x02808080,0x0270609F,0x02A4A0A0,0x02B7AFCF,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02B7AFCF,0x02B7AFCF,0x0270609F,0x0270609F,0x02FFFFFF,0x02B7AFCF,0x0270609F,0x0270609F,0x02000000,0x02000000,0x02DCD8E7,0x02000000,0x02B7AFCF,0x02000000,0x02FFFFFF,0x00C0C0C0,0x0270609F,0x02D0CCD8,0x02D0D4D0},
{0x02E3DCCE,0x00414141,0x02978055,0x02808080,0x02C8B99D,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02C8B99D,0x02C8B99D,0x00424242,0x02978055,0x02FFFFFF,0x02C8B99D,0x02978055,0x02978055,0x02000000,0x02C0C0C0,0x02E3DCCE,0x02000000,0x02C8B99D,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02978055,0x02D8B888,0x02C8BCA0},
{0x02D3E3D0,0x00213F21,0x02649759,0x02808080,0x02A9C8A2,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02A9C8A2,0x02A9C8A2,0x02D3E3D0,0x02649759,0x02FFFFFF,0x02A9C8A2,0x02649759,0x02649759,0x02000000,0x02D3E3D0,0x02D3E3D0,0x02000000,0x02A9C8A2,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02649759,0x02E8C898,0x02B0CCA8},
{0x02C0C0C0,0x02000000,0x02800080,0x02808080,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02C0C0C0,0x02C0C0C0,0x02808080,0x02800080,0x02FFFFFF,0x02C0C0C0,0x02808080,0x02808080,0x02000000,0x02000000,0x02FFFFFF,0x02000000,0x02C0C0C0,0x02800080,0x02FFFFFF,0x00C0C0C0,0x02800080,0x02B08C38,0x02A8ACA8},
{0x02C0C0C0,0x00404000,0x02808000,0x02808080,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02C0C0C0,0x02C0C0C0,0x02808080,0x02808000,0x02FFFFFF,0x02C0C0C0,0x02808080,0x02808080,0x02000000,0x02F0FBFF,0x02FFFFFF,0x02000000,0x02C0C0C0,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02808000,0x00D8CC00,0x02B8C898},
{0x00C0C0C0,0x00808000,0x00800000,0x00808080,0x00C0C0C0,0x00FFFFFF,0x00000000,0x00000000,0x00000000,0x00FFFFFF,0x00C0C0C0,0x00C0C0C0,0x00808080,0x00800000,0x00FFFFFF,0x00C0C0C0,0x00808080,0x00808080,0x00000000,0x00C0C0C0,0x00FFFFFF,0x00000000,0x00C0C0C0,0x00000000,0x00E1FFFF,0x00C0C0C0,0x00800000,0x00D08410,0x00B5B5B5},
{0x02C0C0C0,0x02808080,0x027060A0,0x02A4A0A0,0x02B8B0D0,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02B8B0D0,0x02B8B0D0,0x02E0D8E8,0x027060A0,0x02FFFFFF,0x02B8B0D0,0x027060A0,0x027060A0,0x02000000,0x027D7D7D,0x02E0D8E8,0x02000000,0x02B8B0D0,0x02000000,0x02FFFFFF,0x00C0C0C0,0x027060A0,0x02D0CCD8,0x02D0D4D0},
{0x02000000,0x02000000,0x02800080,0x02008000,0x02000000,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x0200FFFF,0x02008000,0x02000000,0x02800080,0x02FFFFFF,0x02000000,0x02808080,0x0200FF00,0x02FFFFFF,0x02FFFFFF,0x02C0C0C0,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02000000,0x00C0C0C0,0x02800080,0x00800080,0x00008000},
{0x02FFFFFF,0x02FFFFFF,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02808080,0x02C0C0C0,0x02808080,0x02000000,0x02FFFFFF,0x02FFFFFF,0x02808080,0x0200FF00,0x02000000,0x02000000,0x02C0C0C0,0x02000000,0x02C0C0C0,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02000000,0x00000000,0x00FFFFFF},
{0x02D9A8AE,0x02000000,0x02B14E5A,0x02808080,0x02D9A8AE,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02D9A8AE,0x02D9A8AE,0x02B14E5A,0x02B14E5A,0x02FFFFFF,0x02D9A8AE,0x02B14E5A,0x02B14E5A,0x02000000,0x02FFFFFF,0x02ECD5D8,0x02000000,0x02D9A8AE,0x02000000,0x02FFFFFF,0x00C0C0C0,0x02B14E5A,0x02CB8FB6,0x02D0B4B8},
{0x02C0C0C0,0x02808000,0x02800000,0x02808080,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02C0C0C0,0x02C0C0C0,0x02808080,0x02800000,0x02FFFFFF,0x02C0C0C0,0x02808080,0x02808080,0x02000000,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02DFDFDF,0x02000000,0x00E1FFFF,0x00C0C0C0,0x02800000,0x02D08410,0x02B5B5B5},
{0x02C0C0C0,0x02808000,0x02800000,0x02808080,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02C0C0C0,0x02C0C0C0,0x02808080,0x02800000,0x02FFFFFF,0x02C0C0C0,0x02808080,0x02808080,0x02000000,0x02C0C0C0,0x02FFFFFF,0x02000000,0x02DFDFDF,0x02000000,0x02E1FFFF,0x00C0C0C0,0x02800000,0x02D08410,0x02B5B5B5},
{0x02D7ECF2,0x02000000,0x0246A6C6,0x02A4A0A0,0x02AED8E6,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02AED8E6,0x02AED8E6,0x02D7ECF2,0x0246A6C6,0x02000000,0x02AED8E6,0x0246A6C6,0x0246A6C6,0x02000000,0x02D7ECF2,0x02D7ECF2,0x02000000,0x02AED8E6,0x02000000,0x02FFFFFF,0x02C0C0C0,0x0246A6C6,0x02389CC0,0x0288C8E0},
{0x02D0EEEE,0x021D4000,0x02008080,0x0241BCBC,0x02A0DEDE,0x02FFFFFF,0x02000000,0x02000000,0x02000000,0x02FFFFFF,0x02A0DEDE,0x02A0DEDE,0x02D0EEEE,0x02008080,0x02FFFFFF,0x02A0DEDE,0x0241BCBC,0x0241BCBC,0x02000000,0x02FFFFFF,0x02D0EEEE,0x02000000,0x02A0DEDE,0x02000000,0x02FFFFFF,0x02C0C0C0,0x02008080,0x0248B0C8,0x0280B8B8},
};

void SetColor(HKEY hkey, int iColor, COLORREF cr)
{
    TCHAR sz[16];
    wsprintf(sz, TEXT("%d %d %d"), GetRValue(cr), GetGValue(cr), GetBValue(cr));
    RegSetValueEx(hkey, rgpsz[iColor], 0, REG_SZ, (LPBYTE)sz, (wcslen(sz) + 1) * sizeof(TCHAR));
}

void SetGradient(HKEY hkey, int iScheme)
{
    SetColor(hkey, COLOR_GRADIENTACTIVECAPTION, rgcr[iScheme][COLOR_GRADIENTACTIVECAPTION]);
    SetColor(hkey, COLOR_GRADIENTINACTIVECAPTION, rgcr[iScheme][COLOR_GRADIENTINACTIVECAPTION]);
}

void SetDesktop(HKEY hkey)
{
    SetColor(hkey, COLOR_DESKTOP, 0x00A56E3A);
}

#if DBG
#define DebugOut fwprintf
#else
#define DebugOut
#endif

void FixGradientColors(void)
{
    COLORREF cr, rgcrCurrent[COLOR_MAX] = {0x00C0C0C0,0x00808000,0x00800000,0x00808080,0x00C0C0C0,0x00FFFFFF,0x00000000,0x00000000,0x00000000,0x00FFFFFF,0x00C0C0C0,0x00C0C0C0,0x00808080,0x00800000,0x00FFFFFF,0x00C0C0C0,0x00808080,0x00808080,0x00000000,0x00C0C0C0,0x00FFFFFF,0x00000000,0x00C0C0C0,0x00000000,0x00E1FFFF,0x00C0C0C0,0x00800000,0x00800000,0x00808080};
    HKEY hkey;
    DWORD dwSize;
    int i, j;
    TCHAR szColor[16];
    DWORD dwR, dwG, dwB;

    if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0,
            KEY_READ | KEY_SET_VALUE | KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
        RegDeleteValue(hkey, TEXT("UserPreferencesMask"));
        RegCloseKey(hkey);
    }

    if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_READ | KEY_SET_VALUE | KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
        return;

    for (i = 0; i < sizeof(rgpsz) / sizeof(rgpsz[0]); i++) {

        dwSize = sizeof(szColor) * sizeof(TCHAR);

        if (RegQueryValueEx(hkey, rgpsz[i], NULL, NULL, (LPBYTE)szColor, &dwSize) == ERROR_SUCCESS) {
            swscanf(szColor, TEXT("%d %d %d"), &dwR, &dwG, &dwB);
            rgcrCurrent[i] = RGB(dwR, dwG, dwB);
        }
    }

    for (i = 0; i < SCHEME_MAX; i++) {

        for (j = 0; j < COLOR_MAX_NT4; j++) {
            cr = (rgcr[i][j] & 0x00FFFFFF);
            if (rgcrCurrent[j] != cr) {
                break;
            }
        }

        if (j == COLOR_MAX_NT4) {
            break;
        }
    }

    if (j == COLOR_MAX_NT4) {
        DebugOut(stderr, TEXT("Upgrading NT4 color scheme %s\n"), rgpszSchemes[i]);
        SetGradient(hkey, i);

        /*
         * For Windows Standard, WS EL, WS L, update the desktop color.
         */
        if (i == 18 || i == 23 || i == 24) {
            DebugOut(stderr, TEXT("Updating %s desktop color\n"), rgpszSchemes[i]);
            SetDesktop(hkey);
        }

    } else {
        DebugOut(stderr, TEXT("No matching NT4 scheme found\n"));
    }

    RegCloseKey(hkey);
}

