/*
 * Theming - Dialogs
 *
 * Copyright (c) 2005 by Frank Richter
 *
 * 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
 *
 */

#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "uxtheme.h"
#include "tmschema.h"
#include "comctl32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(themingdialog);

/**********************************************************************
 * The dialog subclass window proc.
 */
LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, 
                                             WPARAM wParam, LPARAM lParam, 
                                             ULONG_PTR dwRefData)
{
    HTHEME theme = GetWindowTheme ( hWnd );
    static const WCHAR themeClass[] = { 'W','i','n','d','o','w',0 };
    BOOL themingActive = IsThemeDialogTextureEnabled (hWnd);
    BOOL doTheming = themingActive && (theme != NULL);
    LRESULT result;
      
    switch (msg)
    {
    case WM_CREATE:
	result = THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
	theme = OpenThemeData( hWnd, themeClass );
	return result;
    
    case WM_DESTROY:
        CloseThemeData ( theme );
	return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);

    case WM_THEMECHANGED:
        CloseThemeData ( theme );
	OpenThemeData( hWnd, themeClass );
	InvalidateRect( hWnd, NULL, TRUE );
	return 0;
	
    case WM_SYSCOLORCHANGE:
	if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
        /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
   	 * which will do the repaint. */
        break;
        
    case WM_ERASEBKGND:
	if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
        {
            RECT rc;
            DLGPROC dlgp = (DLGPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC);
            if (!dlgp (hWnd, msg, wParam, lParam))
            {
                /* Draw background*/
                GetClientRect (hWnd, &rc);
                if (IsThemePartDefined (theme, WP_DIALOG, 0))
                    /* Although there is a theme for the WINDOW class/DIALOG part, 
                     * but I[res] haven't seen Windows using it yet... Even when
                     * dialog theming is activated, the good ol' BTNFACE 
                     * background seems to be used. */
#if 0
                    DrawThemeBackground (theme, (HDC)wParam, WP_DIALOG, 0, &rc, 
                        NULL);
#endif
                    return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
                else 
                /* We might have gotten a TAB theme class, so check if we can 
                 * draw as a tab page. */
                if (IsThemePartDefined (theme, TABP_BODY, 0))
                    DrawThemeBackground (theme, (HDC)wParam, TABP_BODY, 0, &rc, 
                        NULL);
                else
                    return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
            }
            return 1;
        }

    case WM_CTLCOLORSTATIC:
        if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
        {
            DLGPROC dlgp = (DLGPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC);
            LRESULT result = (LRESULT)dlgp (hWnd, msg, wParam, lParam);
            if (!result)
            {
                /* Override defaults with more suitable values when themed */
                HDC controlDC = (HDC)wParam;
                HWND controlWnd = (HWND)lParam;
                WCHAR controlClass[32];
                RECT rc;

                GetClassNameW (controlWnd, controlClass, 
                    sizeof(controlClass) / sizeof(controlClass[0]));
                if (lstrcmpiW (controlClass, WC_STATICW) == 0)
                {
                    /* Static control - draw parent background and set text to 
                     * transparent, so it looks right on tab pages. */
                    GetClientRect (controlWnd, &rc);
                    DrawThemeParentBackground (controlWnd, controlDC, &rc);
                    SetBkMode (controlDC, TRANSPARENT);

                    /* Return NULL brush since we painted the BG already */
                    return (LRESULT)GetStockObject (NULL_BRUSH);
                }
                else
                    return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);

            }
            return result;
        }

    default: 
	/* Call old proc */
	return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
    }
    return 0;
}
