/*
 * Default window procedure
 *
 * Copyright 1993 Alexandre Julliard
 *	     1995 Alex Korobka
 */

#include <stdlib.h>
#include <stdio.h>
#include "win.h"
#include "user.h"
#include "nonclient.h"
#include "winpos.h"
#include "syscolor.h"
#include "stddebug.h"
/* #define DEBUG_MESSAGE */
#include "debug.h"
#include "spy.h"

  /* Last COLOR id */
#define COLOR_MAX   COLOR_BTNHIGHLIGHT

  /* bits in the dwKeyData */
#define KEYDATA_ALT 		0x2000
#define KEYDATA_PREVSTATE	0x4000

static short iF10Key = 0;
static short iMenuSysKey = 0;

/***********************************************************************
 *           DEFWND_InitSysMenuPopup
 *
 * Handle the WM_INITMENUPOPUP message on the system menu.
 */
static void DEFWND_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle )
{
    BOOL gray;

    gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
    EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
    gray = ((style & WS_MAXIMIZE) != 0);
    EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
    gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
    EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
    gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
    EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
    gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
    EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
    gray = (clsStyle & CS_NOCLOSE) != 0;
    EnableMenuItem( hmenu, SC_CLOSE, (gray ? MF_GRAYED : MF_ENABLED) );
}


/***********************************************************************
 *           DEFWND_SetText
 *
 * Set the window text.
 */
void DEFWND_SetText( WND *wndPtr, LPSTR text )
{
    LPSTR textPtr;

    if (!text) text = "";
    if (wndPtr->hText) USER_HEAP_FREE( wndPtr->hText );
    wndPtr->hText = USER_HEAP_ALLOC( strlen(text) + 1 );
    textPtr = (LPSTR) USER_HEAP_LIN_ADDR( wndPtr->hText );
    strcpy( textPtr, text );
    if (wndPtr->window)
        XStoreName( display, wndPtr->window, text );
}


/***********************************************************************
 *           DefWindowProc   (USER.107)
 */
LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    LPSTR textPtr;
    int len;
    WND * wndPtr = WIN_FindWndPtr( hwnd );

    SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );

    switch(msg)
    {
    case WM_NCCREATE:
	{
	    CREATESTRUCT *createStruct = (CREATESTRUCT*)PTR_SEG_TO_LIN(lParam);
	    if (createStruct->lpszName)
		DEFWND_SetText( wndPtr,
                               (LPSTR)PTR_SEG_TO_LIN(createStruct->lpszName) );
	    return 1;
	}

    case WM_NCCALCSIZE:
	return NC_HandleNCCalcSize( hwnd,
                                 (NCCALCSIZE_PARAMS *)PTR_SEG_TO_LIN(lParam) );

    case WM_PAINTICON: 
    case WM_NCPAINT:
	return NC_HandleNCPaint( hwnd, (HRGN)wParam );

    case WM_NCHITTEST:
        {
            POINT pt = { LOWORD(lParam), HIWORD(lParam) };
            return NC_HandleNCHitTest( hwnd, pt );
        }

    case WM_NCLBUTTONDOWN:
	return NC_HandleNCLButtonDown( hwnd, wParam, lParam );

    case WM_LBUTTONDBLCLK:
    case WM_NCLBUTTONDBLCLK:
	return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );

    case WM_NCACTIVATE:
	return NC_HandleNCActivate( hwnd, wParam );

    case WM_NCDESTROY:
	if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText);
	if (wndPtr->hVScroll) USER_HEAP_FREE(wndPtr->hVScroll);
	if (wndPtr->hHScroll) USER_HEAP_FREE(wndPtr->hHScroll);
	wndPtr->hText = wndPtr->hVScroll = wndPtr->hHScroll = 0;
	return 0;
	
    case WM_PAINT:
	{
	    PAINTSTRUCT paintstruct;
	    BeginPaint( hwnd, &paintstruct );
	    EndPaint( hwnd, &paintstruct );
	    return 0;
	}

    case WM_SETREDRAW:
        if (!wParam)
        {
            ValidateRect( hwnd, NULL );
            wndPtr->flags |= WIN_NO_REDRAW;
        }
        else wndPtr->flags &= ~WIN_NO_REDRAW;
        return 0;

    case WM_CLOSE:
	DestroyWindow( hwnd );
	return 0;

    case WM_MOUSEACTIVATE:
	if (wndPtr->dwStyle & WS_CHILD)
	{
	    LONG ret = SendMessage( wndPtr->parent->hwndSelf, WM_MOUSEACTIVATE,
				    wParam, lParam );
	    if (ret) return ret;
	}
	return MA_ACTIVATE;

    case WM_ACTIVATE:
      /* LOWORD() needed for WINELIB32 implementation.  Should be fine. */
	if (LOWORD(wParam)!=WA_INACTIVE) SetFocus( hwnd );
	break;

    case WM_WINDOWPOSCHANGING:
	return WINPOS_HandleWindowPosChanging( (WINDOWPOS *)PTR_SEG_TO_LIN(lParam) );

    case WM_WINDOWPOSCHANGED:
	{
	    WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam);
	    WPARAM	wp     = SIZE_RESTORED;

	    if (!(winPos->flags & SWP_NOCLIENTMOVE))
		SendMessage( hwnd, WM_MOVE, 0,
		             MAKELONG( wndPtr->rectClient.left,
				       wndPtr->rectClient.top ));
	    if (!(winPos->flags & SWP_NOCLIENTSIZE))
		 {
	       	   if( wndPtr->dwStyle & WS_MAXIMIZE ) wp = SIZE_MAXIMIZED;
		   else if(wndPtr->dwStyle & WS_MINIMIZE ) wp = SIZE_MINIMIZED;

		   SendMessage( hwnd, WM_SIZE, wp, 
			        MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
			                 wndPtr->rectClient.bottom-wndPtr->rectClient.top));

                 }
	    return 0;
	}

    case WM_ERASEBKGND:
    case WM_ICONERASEBKGND:
	{
	    if (!wndPtr->class->hbrBackground) return 0;
            if (wndPtr->class->hbrBackground <= (HBRUSH)(COLOR_MAX+1))
            {
                 HBRUSH hbrush;
                 hbrush = CreateSolidBrush(
                     GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
                 FillWindow( GetParent(hwnd), hwnd, (HDC)wParam, hbrush);
                 DeleteObject (hbrush);
            }
            else
	         FillWindow( GetParent(hwnd), hwnd, (HDC)wParam,
                             wndPtr->class->hbrBackground );
	    return 1;
	}

    case WM_GETDLGCODE:
	return 0;

    case WM_CTLCOLORMSGBOX:
    case WM_CTLCOLOREDIT:
    case WM_CTLCOLORLISTBOX:
    case WM_CTLCOLORBTN:
    case WM_CTLCOLORDLG:
    case WM_CTLCOLORSTATIC:
        SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
        SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
        return (LONG)sysColorObjects.hbrushWindow;

    case WM_CTLCOLORSCROLLBAR:
        SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
        SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
        UnrealizeObject( sysColorObjects.hbrushScrollbar );
        return (LONG)sysColorObjects.hbrushScrollbar;

    case WM_CTLCOLOR:
	{
	    if (HIWORD(lParam) == CTLCOLOR_SCROLLBAR)
	    {
		SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
		SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
		UnrealizeObject( sysColorObjects.hbrushScrollbar );
		return (LONG)sysColorObjects.hbrushScrollbar;
	    }
	    else
	    {
		SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
		SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
		return (LONG)sysColorObjects.hbrushWindow;
	    }
	}
	
    case WM_GETTEXT:
	{
	    if (wParam)
	    {
		if (wndPtr->hText)
		{
		    textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
		    if ((int)wParam > (len = strlen(textPtr)))
		    {
			strcpy((char *)PTR_SEG_TO_LIN(lParam), textPtr);
			return (DWORD)len;
		    }
		}
	    }
	    return 0;
	}

    case WM_GETTEXTLENGTH:
	{
	    if (wndPtr->hText)
	    {
		textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
		return (DWORD)strlen(textPtr);
	    }
	    return 0;
	}

    case WM_SETTEXT:
	DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
	NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
	return 0;

    case WM_SETCURSOR:
	if (wndPtr->dwStyle & WS_CHILD)
	    if (SendMessage(wndPtr->parent->hwndSelf, WM_SETCURSOR,
                            wParam, lParam))
		return TRUE;
	return NC_HandleSetCursor( hwnd, wParam, lParam );

    case WM_SYSCOMMAND:
	{
          POINT pt = { LOWORD(lParam), HIWORD(lParam) };
          return NC_HandleSysCommand( hwnd, wParam, pt );
	}
    case WM_KEYDOWN:

	if(wParam == VK_F10) iF10Key = VK_F10;
	break;

    case WM_SYSKEYDOWN:

	if( HIWORD(lParam) & KEYDATA_ALT )
	  {
	    /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
	      if( wParam == VK_MENU && !iMenuSysKey )
		iMenuSysKey = 1;
	      else
		iMenuSysKey = 0;
	    
	    iF10Key = 0;

	  } 
	else if( wParam == VK_F10 )
	         iF10Key = 1;
	     else
	         if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 )
		     SendMessage( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, 
 						       (LPARAM)VK_SPACE);
	break;

    case WM_KEYUP:
    case WM_SYSKEYUP:

	/* Press and release F10 or ALT */

	if( ( wParam == VK_MENU && iMenuSysKey ) 
	      || ( wParam == VK_F10 && iF10Key ) )

	      SendMessage( WIN_GetTopParent(hwnd), WM_SYSCOMMAND,
			   SC_KEYMENU, 0L );

	iMenuSysKey = iF10Key = 0;
        break;

    case WM_SYSCHAR:

	iMenuSysKey = 0;

	if( wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE) )
	  {
	    PostMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0L ); 
	    break;
	  }  

	if( (HIWORD(lParam) & KEYDATA_ALT) && wParam )
	  {
	    if( wParam == VK_TAB || wParam == VK_ESCAPE )
	      break;

	    if( wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD) )
	      SendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
	    else
	      SendMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
	  } 
	else
	  /* check for Ctrl-Esc */
	  if( wParam != VK_ESCAPE )   
	      MessageBeep(0);
	  
	break;

    case WM_SHOWWINDOW:
	if( !lParam ) return 0; /* sent from ShowWindow */

	if( !(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner ) 
	      return 0;

	if( wndPtr->dwStyle & WS_VISIBLE )
	    { if( wParam ) return 0; }
	else
	      if(!wParam ) return 0;
  
	ShowWindow(hwnd,(wParam)? SW_SHOWNOACTIVATE: SW_HIDE);
	break; 

    case WM_INITMENUPOPUP:
        /* Not absolutely sure this belongs here -- AJ */
        if (HIWORD(lParam))  /* system menu */
            DEFWND_InitSysMenuPopup( (HMENU)wParam, wndPtr->dwStyle,
                                     wndPtr->class->style );
        break;

    case WM_CANCELMODE:

	/* EndMenu() should be called if in menu state but currently it's
	   impossible to detect - menu code should be updated*/

	if( GetCapture() == hwnd )
	    ReleaseCapture();

	break;

    case WM_VKEYTOITEM:
    case WM_CHARTOITEM:
	return -1;

    case WM_DROPOBJECT:
	return DRAG_FILE;  

    case WM_QUERYDROPOBJECT:
	if(wndPtr->dwExStyle & WS_EX_ACCEPTFILES)
	   return 1;
	break;

    case WM_QUERYDRAGICON:
	{
	 HICON hI = 0;

	 len = 1;
	 while(len < 64)
		if( (hI = LoadIcon(wndPtr->hInstance,MAKEINTRESOURCE(len))) )
		     return (LRESULT)hI;
	}
        break;

    case WM_QUERYOPEN:
    case WM_QUERYENDSESSION:
	return 1;

    }
    return 0;
}
