/*
 * PROJECT:     ReactOS Column List Box
 * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
 * PURPOSE:     Column List Box
 * COPYRIGHT:   Copyright 2005 Thomas Weidenmueller <w3seek@reactos.com>
 */
#include <precomp.h>

static HINSTANCE hDllInstance;

static const WCHAR ClbClassName[] = L"ColumnListBox";
static const WCHAR ClbColumns[] = L"Column1;Column2;Column3";

typedef struct _CLB_PRIVATEDATA
{
    HWND hwnd;
} CLB_PRIVATEDATA, *PCLB_PRIVATEDATA;

static const CLBS_INFO ClbsSupportedStyles[] =
{
    {
        CLBS_NOTIFY,
        0x0,
        L"CLBS_NOTIFY"
    },
    {
        CLBS_SORT,
        0x0,
        L"CLBS_SORT"
    },
    {
        CLBS_DISABLENOSCROLL,
        0x0,
        L"CLBS_DISABLENOSCROLL"
    },
    {
        CLBS_VSCROLL,
        0x0,
        L"CLBS_VSCROLL"
    },
    {
        CLBS_BORDER,
        0x0,
        L"CLBS_BORDER"
    },
    {
        CLBS_POPOUT_HEADINGS,
        0x0,
        L"CLBS_POPOUT_HEADINGS"
    },
    {
        CLBS_SPRINGLY_COLUMNS,
        0x0,
        L"CLBS_SPRINGLY_COLUMNS"
    },
    {
        LBS_OWNERDRAWFIXED,
        0x0,
        L"LBS_OWNERDRAWFIXED"
    }
};

/*
 * @unimplemented
 */
DWORD
WINAPI
ClbAddData(IN DWORD Unknown1,
           IN DWORD Unknown2,
           IN DWORD Unknown3)
{
    DPRINT1("ClbAddData(0x%x, 0x%x, 0x%x)\n", Unknown1, Unknown2, Unknown3);
    return 0;
}

/*
 * @unimplemented
 */
DWORD
WINAPI
ClbSetColumnWidths(IN DWORD Unknown1,
                   IN DWORD Unknown2,
                   IN DWORD Unknown3)
{
    DPRINT1("ClbSetColumnWidths(0x%x, 0x%x, 0x%x)\n", Unknown1, Unknown2, Unknown3);
    return 0;
}

/*
 * @unimplemented
 */
LRESULT
CALLBACK
ClbWndProc(IN HWND hwnd,
           IN UINT uMsg,
           IN WPARAM wParam,
           IN LPARAM lParam)
{
    PCLB_PRIVATEDATA PrivData;
    LRESULT Ret = 0;

    DPRINT1("ClbWndProc(0x%p, 0x%x, 0x%p, 0x%p)\n", hwnd, uMsg, wParam, lParam);

    PrivData = (PCLB_PRIVATEDATA)GetWindowLongPtr(hwnd, 0);
    if (PrivData == NULL && uMsg != WM_CREATE)
    {
        goto HandleDefMsg;
    }

    switch (uMsg)
    {
    case WM_CREATE:
        PrivData = HeapAlloc(GetProcessHeap(),
                             0,
                             sizeof(CLB_PRIVATEDATA));
        if (PrivData == NULL)
        {
            Ret = (LRESULT)-1;
            break;
        }
        PrivData->hwnd = hwnd;
        break;

    case WM_DESTROY:
        HeapFree(GetProcessHeap(), 0, PrivData);
        break;

    default:
HandleDefMsg:
        Ret = DefWindowProc(hwnd, uMsg, wParam, lParam);
        break;
    }

    return Ret;
}

static INT_PTR CALLBACK
ClbpStyleDlgProc(IN HWND hwndDlg,
                 IN UINT uMsg,
                 IN WPARAM wParam,
                 IN LPARAM lParam)
{
    INT_PTR Ret = FALSE;

    DPRINT1("ClbpStyleDlgProc(0x%p, 0x%x, 0x%p, 0x%p)\n", hwndDlg, uMsg, wParam, lParam);

    switch (uMsg)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
        case IDCANCEL:
            EndDialog(hwndDlg, LOWORD(wParam));
            break;
        }
        break;

    case WM_CLOSE:
        EndDialog(hwndDlg, IDCANCEL);
        break;

    case WM_INITDIALOG:
        Ret = TRUE;
        break;
    }

    return Ret;
}

/*
 * @implemented
 */
INT_PTR
WINAPI
ClbStyleW(IN HWND hWndParent,
          IN LPARAM dwInitParam)
{
    return DialogBoxParam(hDllInstance,
                          MAKEINTRESOURCE(IDD_COLUMNLISTBOXSTYLES),
                          hWndParent,
                          ClbpStyleDlgProc,
                          dwInitParam);
}

/*
 * @implemented
 */
BOOL
WINAPI
CustomControlInfoW(OUT LPCUSTOM_CONTROL_INFO CustomControlInfo OPTIONAL)
{
    if (CustomControlInfo != NULL)
    {
        wcscpy(CustomControlInfo->ClassName, ClbClassName);

        CustomControlInfo->Zero1 = 0;

        wcscpy(CustomControlInfo->ClassName2, ClbClassName);

        CustomControlInfo->Unknown1 = 0x60; // FIXME - ???
        CustomControlInfo->Unknown2 = 0x50; // FIXME - ???
        CustomControlInfo->Unknown3 = 0x50A10013; // FIXME - ???

        CustomControlInfo->Zero2 = 0;
        CustomControlInfo->Zero3 = 0;

        CustomControlInfo->StylesCount = _countof(ClbsSupportedStyles);
        CustomControlInfo->SupportedStyles = ClbsSupportedStyles;

        wcscpy(CustomControlInfo->Columns, ClbColumns);

        CustomControlInfo->ClbStyleW = ClbStyleW;

        CustomControlInfo->Zero4 = 0;
        CustomControlInfo->Zero5 = 0;
        CustomControlInfo->Zero6 = 0;
    }

    return TRUE;
}

BOOL
WINAPI
DllMain(IN HINSTANCE hinstDLL,
        IN DWORD dwReason,
        IN LPVOID lpvReserved)
{
    BOOL Ret = TRUE;

    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        WNDCLASS ClbWndClass;

        hDllInstance = hinstDLL;

        InitCommonControls();

        /* register the control's window class */
        ClbWndClass.style = CS_GLOBALCLASS | CS_OWNDC;
        ClbWndClass.lpfnWndProc = ClbWndProc;
        ClbWndClass.cbClsExtra = 0;
        ClbWndClass.cbWndExtra = sizeof(PCLB_PRIVATEDATA);
        ClbWndClass.hInstance = hinstDLL;
        ClbWndClass.hIcon = NULL;
        ClbWndClass.hCursor = LoadCursor(NULL, (LPWSTR)IDC_ARROW);
        ClbWndClass.hbrBackground = NULL;
        ClbWndClass.lpszMenuName = NULL;
        ClbWndClass.lpszClassName = ClbClassName;

        if (!RegisterClass(&ClbWndClass))
        {
            Ret = FALSE;
            break;
        }
        break;
    }

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        UnregisterClass(ClbClassName, hinstDLL);
        break;
    }
    return Ret;
}

/* EOF */
