/* xdragon interface to Windows

Copyright (C) 2015 Ken D. Olum

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "xdragon.h"
#include <windows.h>

bool haveFocus = False;		/* Does our window have focus? */

LRESULT CALLBACK mainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  // debug("Message: %d, w=%d, l=%d\n",msg,wParam,lParam);
  switch (msg) {

  // case WM_CREATE:		/* When our window is created */
  //  break;

  case WM_KEYDOWN:
  case WM_SYSKEYDOWN:
    // debug("Key down: 0x%x\n", wParam);
    /* Don't pass on key used for Dragon reset */
    if (wParam != XDRAGON_RESET_VK) xSendKey((char)wParam, True);
    break;

  case WM_KEYUP:
  case WM_SYSKEYUP:
    // debug("Key up: 0x%x\n", wParam);
    if (wParam != XDRAGON_RESET_VK) xSendKey((char)wParam, False);
    break;

    /* When the focus in the VM is on our window, then we want to bury the
       VM window in X Windows, so that the user sees the X Windows to which
       the characters are really going */
  case WM_SETFOCUS:
    haveFocus = True;
    xBury();
    break;

  case WM_KILLFOCUS:
    haveFocus = False;
    xShow();
    break;

  case WM_DESTROY:
  case WM_CLOSE:
    PostQuitMessage(0);
    break;
  }
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

/* Create Windows window to receive input from NaturallySpeaking */
createWindow() {
  WNDCLASS wcMain;

  /* Set up class for main window */
  ZeroMemory(&wcMain, sizeof (wcMain));
  wcMain.lpfnWndProc = mainWndProc;
  wcMain.hInstance = GetModuleHandle(NULL); /* handle on ourselves */
  wcMain.lpszClassName = "Xdragon";
  wcMain.hbrBackground = (HBRUSH)(1+COLOR_WINDOW);

  if (!RegisterClass(&wcMain))
    errorExit("Failed to register main window class");

  HWND hwndMain = CreateWindow("Xdragon", "Linux",
			       WS_OVERLAPPEDWINDOW | WS_VISIBLE,
			       CW_USEDEFAULT, CW_USEDEFAULT, 
			       200, 200, 0, 0, wcMain.hInstance, 0);
  if (!hwndMain) errorExit("Creating main window failed");
  }

handleWindow() {
  MSG msg;

  while (GetMessage (&msg, NULL, 0, 0)) {
    /* Do not translate key up and down messages, because it is in
       translation that Alt keys will be turned into menu items,
       causing an error because we don't have any. */
    if(msg.message != WM_KEYUP && msg.message != WM_KEYDOWN
       && msg.message != WM_SYSKEYUP && msg.message != WM_SYSKEYDOWN)
      TranslateMessage(&msg);
    DispatchMessage(&msg);
  }}

/* Push and release given key in Windows */
doSendInput(vk) {
  INPUT sendInput;

  sendInput.type = INPUT_KEYBOARD;
  sendInput.ki.wVk = vk;
  sendInput.ki.dwFlags = 0;
  sendInput.ki.time = 0;	/* use system time */

  if(SendInput(1, &sendInput, sizeof sendInput) != 1)
    errorExit("Can't send keypress to Windows");

  sendInput.ki.dwFlags = KEYEVENTF_KEYUP; /* now release key */

  if(SendInput(1, &sendInput, sizeof sendInput) != 1)
    errorExit("Can't send keyrelease to Windows");
}

/* Request Dragon to forget spacing, capitalization, etc.  This is set
    for key, button, and focus events.  Thus if you use the keyboard,
    or a window pops up, you will not get extra spaces, etc. */
resetDictationState() {
  /* Only reset if characters are currently going to us, and thus to X */
  if (haveFocus) doSendInput(XDRAGON_RESET_VK);
  }


