/*
 * Windows widgets (built-in window classes)
 *
 * Copyright 1993 Alexandre Julliard
 */

#include <assert.h>

#include "win.h"
#include "commctrl.h"
#include "button.h"
#include "progress.h"
#include "static.h"
#include "status.h"
#include "updown.h"
#include "scroll.h"
#include "updown.h"
#include "desktop.h"
#include "mdi.h"
#include "gdi.h"
#include "module.h"
#include "heap.h"

/* Window procedures */

extern LRESULT WINAPI EditWndProc( HWND32 hwnd, UINT32 msg,
                                   WPARAM32 wParam, LPARAM lParam );
extern LRESULT WINAPI ComboWndProc( HWND32 hwnd, UINT32 msg,
                                    WPARAM32 wParam, LPARAM lParam );
extern LRESULT WINAPI ComboLBWndProc( HWND32 hwnd, UINT32 msg,
                                      WPARAM32 wParam, LPARAM lParam );
extern LRESULT WINAPI ListBoxWndProc( HWND32 hwnd, UINT32 msg,
                                      WPARAM32 wParam, LPARAM lParam );
extern LRESULT WINAPI PopupMenuWndProc( HWND32 hwnd, UINT32 msg,
                                        WPARAM32 wParam, LPARAM lParam );
extern LRESULT WINAPI IconTitleWndProc( HWND32 hwnd, UINT32 msg,
                                        WPARAM32 wParam, LPARAM lParam );

/* Win16 class info */

typedef struct
{
    UINT16     style;
    INT16      wndExtra;
    HBRUSH16   background;
    LPCSTR     procName;
    LPCSTR     className;
} BUILTIN_CLASS_INFO16;

/* Win16 built-in classes */

static const BUILTIN_CLASS_INFO16 WIDGETS_BuiltinClasses16[] =
{
    { CS_GLOBALCLASS, sizeof(MDICLIENTINFO),
      STOCK_LTGRAY_BRUSH, "MDIClientWndProc", "MDIClient" }
};

#define NB_BUILTIN_CLASSES16 \
         (sizeof(WIDGETS_BuiltinClasses16)/sizeof(WIDGETS_BuiltinClasses16[0]))

/* Win32 built-in classes */

static WNDCLASS32A WIDGETS_BuiltinClasses32[BIC32_NB_CLASSES] =
{
    /* BIC32_BUTTON */
    { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
      ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0, IDC_ARROW, 0, 0, "Button" },
    /* BIC32_EDIT */
    { CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,
      EditWndProc, 0, sizeof(void *), 0, 0, IDC_IBEAM, 0, 0, "Edit" },
    /* BIC32_LISTBOX */
    { CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,
      ListBoxWndProc, 0, sizeof(void *), 0, 0, IDC_ARROW, 0, 0, "ListBox" },
    /* BIC32_COMBO */
    { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, 
      ComboWndProc, 0, sizeof(void *), 0, 0, IDC_ARROW, 0, 0, "ComboBox" },
    /* BIC32_COMBOLB */
    { CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS,
      ComboLBWndProc, 0, sizeof(void *), 0, 0, IDC_ARROW, 0, 0, "ComboLBox" },
    /* BIC32_POPUPMENU */
    { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0,
      sizeof(HMENU32), 0, 0, IDC_ARROW, NULL_BRUSH, 0, POPUPMENU_CLASS_NAME },
    /* BIC32_STATIC */
    { CS_GLOBALCLASS | CS_PARENTDC, StaticWndProc,
      0, sizeof(STATICINFO), 0, 0, IDC_ARROW, 0, 0, "Static" },
    /* BIC32_SCROLL */
    { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
      ScrollBarWndProc, 0, sizeof(SCROLLBAR_INFO), 0, 0, IDC_ARROW, 0, 0, "ScrollBar"},
    /* BIC32_DESKTOP */
    { CS_GLOBALCLASS, DesktopWndProc, 0, sizeof(DESKTOPINFO),
      0, 0, IDC_ARROW, 0, 0, DESKTOP_CLASS_NAME },
    /* BIC32_DIALOG */
    { CS_GLOBALCLASS | CS_SAVEBITS, DefDlgProc32A, 0, DLGWINDOWEXTRA,
      0, 0, IDC_ARROW, 0, 0, DIALOG_CLASS_NAME },
    /* BIC32_ICONTITLE */
    { CS_GLOBALCLASS, IconTitleWndProc, 0, 0, 
      0, 0, IDC_ARROW, 0, 0, ICONTITLE_CLASS_NAME }
};

static ATOM bicAtomTable[BIC32_NB_CLASSES];

/* Win32 common controls */

static WNDCLASS32A WIDGETS_CommonControls32[] =
{
    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
      sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, UpDownWindowProc, 0,
      sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A },
    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, ProgressWindowProc, 0,
      sizeof(PROGRESS_INFO), 0, 0, 0, 0, 0, PROGRESS_CLASS32A }
};

#define NB_COMMON_CONTROLS32 \
         (sizeof(WIDGETS_CommonControls32)/sizeof(WIDGETS_CommonControls32[0]))


/***********************************************************************
 *           WIDGETS_Init
 * 
 * Initialize the built-in window classes.
 */
BOOL32 WIDGETS_Init(void)
{
    int i;
    char *name;
    const BUILTIN_CLASS_INFO16 *info16 = WIDGETS_BuiltinClasses16;
    WNDCLASS16 class16;
    WNDCLASS32A *class32 = WIDGETS_BuiltinClasses32;

    if (!(name = SEGPTR_ALLOC( 20 * sizeof(char) ))) return FALSE;

    /* Create 16-bit classes */

    class16.cbClsExtra    = 0;
    class16.hInstance     = 0;
    class16.hIcon         = 0;
    class16.hCursor       = LoadCursor16( 0, IDC_ARROW );
    class16.lpszMenuName  = (SEGPTR)0;
    class16.lpszClassName = SEGPTR_GET(name);
    for (i = 0; i < NB_BUILTIN_CLASSES16; i++, info16++)
    {
        class16.style         = info16->style;
        class16.lpfnWndProc   = (WNDPROC16)MODULE_GetWndProcEntry16( info16->procName );
        class16.cbWndExtra    = info16->wndExtra;
        class16.hbrBackground = info16->background;
        strcpy( name, info16->className );
        if (!RegisterClass16( &class16 )) return FALSE;
    }

    /* Create 32-bit classes */

    for (i = 0; i < BIC32_NB_CLASSES; i++, class32++)
    {
        /* Just to make sure the string is > 0x10000 */
        strcpy( name, (char *)class32->lpszClassName );
        class32->lpszClassName = name;
        class32->hCursor = LoadCursor16( 0, class32->hCursor );
        if (!(bicAtomTable[i] = RegisterClass32A( class32 ))) return FALSE;
    }

    /* FIXME: hack to enable using built-in controls with Windows COMCTL32 */
    InitCommonControls();
    SEGPTR_FREE(name);
    return TRUE;
}


/***********************************************************************
 *           InitCommonControls   (COMCTL32.15)
 */
void WINAPI InitCommonControls(void)
{
    int i;
    char name[30];
    const char *old_name;
    WNDCLASS32A *class32 = WIDGETS_CommonControls32;

    for (i = 0; i < NB_COMMON_CONTROLS32; i++, class32++)
    {
        /* Just to make sure the string is > 0x10000 */
        old_name = class32->lpszClassName;
        strcpy( name, (char *)class32->lpszClassName );
        class32->lpszClassName = name;
        class32->hCursor = LoadCursor16( 0, IDC_ARROW );
        RegisterClass32A( class32 );
        class32->lpszClassName = old_name;	
    }
}


/***********************************************************************
 *           WIDGETS_IsControl32
 *
 * Check whether pWnd is a built-in control or not.
 */
BOOL32	WIDGETS_IsControl32( WND* pWnd, BUILTIN_CLASS32 cls )
{
    assert( cls < BIC32_NB_CLASSES );
    return (pWnd->class->atomName == bicAtomTable[cls]);
}
