/*
 * Keyboard related functions
 *
 * Copyright 1993 Bob Amstadt
 * Copyright 1996 Albrecht Kleine 
 */

#include <stdio.h>
#include <string.h>
#include "win.h"
#include "windows.h"
#include "accel.h"
#include "debug.h"

extern BOOL MouseButtonsStates[3];
extern BOOL AsyncMouseButtonsStates[3];
extern BYTE InputKeyStateTable[256];
BYTE AsyncKeyStateTable[256];

extern BYTE QueueKeyStateTable[256];

/**********************************************************************
 *		GetKeyState			[USER.106]
 * An application calls the GetKeyState function in response to a
 * keyboard-input message.  This function retrieves the state of the key
 * at the time the input message was generated.  (SDK 3.1 Vol 2. p 390)
 */
INT GetKeyState(INT keycode)
{
    INT retval;

    if( keycode >= VK_LBUTTON && keycode <= VK_RBUTTON )
	retval = MouseButtonsStates[keycode - VK_LBUTTON];
    else
    {
	if (keycode >= 'a' && keycode <= 'z')
	    keycode += 'A' - 'a';
	retval = ( (INT)(QueueKeyStateTable[keycode] & 0x80) << 8 ) |
		   (INT)(QueueKeyStateTable[keycode] & 0x01);
    }

    dprintf_key(stddeb, "GetKeyState(%x) -> %x\n", keycode, retval);
    return retval;
}

/**********************************************************************
 *		GetKeyboardState			[USER.222]
 * An application calls the GetKeyboardState function in response to a
 * keyboard-input message.  This function retrieves the state of the keyboard
 * at the time the input message was generated.  (SDK 3.1 Vol 2. p 387)
 */
void GetKeyboardState(BYTE *lpKeyState)
{
    if (lpKeyState != NULL) {
	QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] >> 8;
	QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] >> 8;
	QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] >> 8;
	memcpy(lpKeyState, QueueKeyStateTable, 256);
    }
}

/**********************************************************************
 *      SetKeyboardState            [USER.223]
 */
void SetKeyboardState(BYTE *lpKeyState)
{
    if (lpKeyState != NULL) {
	memcpy(QueueKeyStateTable, lpKeyState, 256);
	MouseButtonsStates[0] = QueueKeyStateTable[VK_LBUTTON]? 0x8000: 0;
	MouseButtonsStates[1] = QueueKeyStateTable[VK_MBUTTON]? 0x8000: 0;
	MouseButtonsStates[2] = QueueKeyStateTable[VK_RBUTTON]? 0x8000: 0;
    }
}

/**********************************************************************
 *            GetAsyncKeyState        (USER.249)
 *
 *	Determine if a key is or was pressed.  retval has high-order 
 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
 * been pressed.
 *
 *	This uses the variable AsyncMouseButtonsStates and
 * AsyncKeyStateTable (set in event.c) which have the mouse button
 * number or key number (whichever is applicable) set to true if the
 * mouse or key had been depressed since the last call to 
 * GetAsyncKeyState.
 */
int GetAsyncKeyState(int nKey)
{
    short retval;	

    switch (nKey) {
     case VK_LBUTTON:
	retval = AsyncMouseButtonsStates[0] | 
	MouseButtonsStates[0]? 0x0001: 0;
	break;
     case VK_MBUTTON:
	retval = AsyncMouseButtonsStates[1] |
	MouseButtonsStates[1]? 0x0001: 0;
	break;
     case VK_RBUTTON:
	retval = AsyncMouseButtonsStates[2] |
	MouseButtonsStates[2]? 0x0001: 0;
	break;
     default:
	retval = AsyncKeyStateTable[nKey] | 
	(InputKeyStateTable[nKey] ? 0x8000 : 0);
	break;
    }

    memset( AsyncMouseButtonsStates, 0, 3 );  /* all states to false */
    memset( AsyncKeyStateTable, 0, 256 );

    dprintf_key(stddeb, "GetAsyncKeyState(%x) -> %x\n", nKey, retval);
    return retval;
}


/**********************************************************************
 *			TranslateAccelerator 	[USER.178]
 *
 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
 */
INT16 TranslateAccelerator(HWND hWnd, HACCEL16 hAccel, LPMSG16 msg)
{
    ACCELHEADER	*lpAccelTbl;
    int 	i;
    BOOL sendmsg;
    
    if (hAccel == 0 || msg == NULL) return 0;
    if (msg->message != WM_KEYDOWN &&
    	msg->message != WM_KEYUP &&
	msg->message != WM_SYSKEYDOWN &&
	msg->message != WM_SYSKEYUP &&
    	msg->message != WM_CHAR) return 0;

    dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);

    lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
    for (sendmsg= i = 0; i < lpAccelTbl->wCount; i++) 
    {
     if(msg->wParam == lpAccelTbl->tbl[i].wEvent) 
     {
      if (msg->message == WM_CHAR) 
      {
        if ( !(lpAccelTbl->tbl[i].type & ALT_ACCEL) && 
             !(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) )
        {
   	  dprintf_accel(stddeb,"found accel for WM_CHAR: ('%c')",msg->wParam&0xff);
   	  sendmsg=TRUE;
   	}  
      }
      else
      {
       if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) 
       {
	INT mask = 0;
        dprintf_accel(stddeb,"found accel for virt_key %04x (scan %04x)",
  	                       msg->wParam,0xff & HIWORD(msg->lParam));                
	if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
	if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
	if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
	if(mask == (lpAccelTbl->tbl[i].type &
			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL)))
          sendmsg=TRUE;			    
        else
          dprintf_accel(stddeb,", but incorrect SHIFT/CTRL/ALT-state\n");
       }
       else
       {
         if (!(msg->lParam & 0x01000000))  /* no special_key */
         {
           if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) && (msg->lParam & 0x20000000))
           {                                                   /* ^^ ALT pressed */
	    dprintf_accel(stddeb,"found accel for Alt-%c", msg->wParam&0xff);
	    sendmsg=TRUE;	    
	   } 
         } 
       }
      } 

      if (sendmsg)      /* found an accelerator, but send a message... ? */
      {
        INT16  iSysStat,iStat,mesg=0;
        HMENU16 hSysMenu,hMenu;
        
        if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
          mesg=1;
        else 
         if (GetCapture16())
           mesg=2;
         else
          if (!IsWindowEnabled(hWnd))
            mesg=3;
          else
          {
            hMenu=GetMenu(hWnd);
            hSysMenu=GetSystemMenu(hWnd,FALSE);
            if (hSysMenu)
              iSysStat=GetMenuState(hSysMenu,lpAccelTbl->tbl[i].wIDval,MF_BYCOMMAND);
            else
              iSysStat=-1;
            if (hMenu)
              iStat=GetMenuState(hMenu,lpAccelTbl->tbl[i].wIDval,MF_BYCOMMAND);
            else
              iStat=-1;
            if (iSysStat!=-1)
            {
              if (iSysStat & (MF_DISABLED|MF_GRAYED))
                mesg=4;
              else
                mesg=WM_SYSCOMMAND;
            }
            else
            {
              if (iStat!=-1)
              {
                if (IsIconic(hWnd))
                  mesg=5;
                else
                {
                 if (iStat & (MF_DISABLED|MF_GRAYED))
                   mesg=6;
                 else
                   mesg=WM_COMMAND;  
                }   
              }
              else
               mesg=WM_COMMAND;  
            }
          }
          if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
          {
              dprintf_accel(stddeb,", sending %s, wParam=%0x\n",
                  mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
                  lpAccelTbl->tbl[i].wIDval);
	      SendMessage16(hWnd, mesg, lpAccelTbl->tbl[i].wIDval,0x00010000L);
	  }
	  else
	  {
	   /*  some reasons for NOT sending the WM_{SYS}COMMAND message: 
	    *   #0: unknown (please report!)
	    *   #1: for WM_KEYUP,WM_SYKEYUP
	    *   #2: mouse is captured
	    *   #3: window is disabled 
	    *   #4: it's a disabled system menu option
	    *   #5: it's a menu option, but window is iconic
	    *   #6: it's a menu option, but disabled
	    */
	    dprintf_accel(stddeb,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
	  }          
          GlobalUnlock16(hAccel);
          return 1;         
      }
     }
    }
    GlobalUnlock16(hAccel);
    return 0;
}
