/*
 * ReactOS Column List Box
 * Copyright (C) 2005 Thomas Weidenmueller
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 * PROJECT:         ReactOS Column List Box
 * FILE:            lib/clb/clb.c
 * PURPOSE:         Column List Box
 * PROGRAMMER:      Thomas Weidenmueller <w3seek@reactos.com>
 *
 * UPDATE HISTORY:
 *      10/29/2005  Created
 */
#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,
                              (INT_PTR)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 = sizeof(ClbsSupportedStyles) / sizeof(ClbsSupportedStyles[0]);
        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;
}

