/*
   Copyright 2007-2009 WebDriver committers
   Copyright 2007-2009 Google Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "stdafx.h"

#include <ctime>
#include <string>
#include <iostream>

#include "errorcodes.h"
#include "interactions.h"
#include "interactions_common.h"
#include "logging.h"
#include "event_firing_thread.h"

using namespace std;

#pragma data_seg(".LISTENER")
static bool pressed = false;
// The following booleans indicate whether any of the modifier keys are
// depressed. These booleans represent the state from the user's point of
// view - not if a modifier is depressed for the current key press (there
// is an explanation on why modifier keys have to be pressed and depressed
// for some keys below).
// Each modifier key can only be held down when sendKeys was called without
// calling releaseModifierKeys. The modifier key will only be released when
// sendKeys(Keys.NULL) is called or sendKeys() is called again (with the same
// modifier).
// Ordinarily, sendKeys would generate the following keys sequence when
// called with sendKeys("AB"):
// Shift_Down A_Down A_Up Shift_Up Shift_Down B_Down B_Up Shift_Up
// However, when sendKeys is called using the new Interactions API,
// the modifier keys are not released. So, we want the letters to be
// capitalized if Shift is pressed. The following calls:
// * sendKeyPress(SHIFT)
// * sendKeys("ab")
// * sendKeyRelease(SHIFT)
// Should generate the following events:
// Shift_Down A_Down A_Up B_Down B_Up Shift_Up
// With *capital* a and b. Using this boolean, we can tell if the shift key
// was held down by these calls and should generate upper-case chars.
static bool shiftPressed = false;
static bool controlPressed = false;
static bool altPressed = false;
static HHOOK hook = 0;
static HINSTANCE moduleHandle = NULL;

#pragma data_seg()
#pragma comment(linker, "/section:.LISTENER,rws")

// Left Mouse button pressed?
static bool leftMouseButtonPressed = false;

void backgroundUnicodeKeyPress(HWND ieWindow, wchar_t c, int pause)
{
  pause = pause / 3;

  // IE can crash if keyscan < 0. It's unclear this will
  // do anything unless the correct keyboard layout is active,
  // as the unicode character 'c' will already have its
  // appropriate capitalization.
  SHORT keyscan = VkKeyScanW(c);
  if (keyscan < 0) { 
    keyscan = 0;
  }
  pressed = false;
  PostMessage(ieWindow, WM_KEYDOWN, keyscan, 0);
  PostMessage(ieWindow, WM_USER, 1234, 5678);
  wait(pause);

  // TODO: There must be a better way to tell when the keydown is processed
  clock_t maxWait = clock() + 250;
  while (!pressed && clock() < maxWait) {
    wait(5);
  }

  PostMessage(ieWindow, WM_CHAR, c, 0);

  wait(pause);

  PostMessage(ieWindow, WM_KEYUP, keyscan, 0);

  wait(pause);
}

void sendModifierKeyDown(HWND hwnd, HKL layout, int modifierKeyCode,
    BYTE keyboardState[256], int pause) {
    keyboardState[modifierKeyCode] |= 0x80;

    LPARAM modifierKey = 1 | MapVirtualKeyEx(modifierKeyCode, 0, layout) << 16;
    if (!PostMessage(hwnd, WM_KEYDOWN, modifierKeyCode, modifierKey)) {
        LOG(WARN) << "Modifier keydown failed: " << GetLastError();
    }

    wait(pause);
}

void sendModifierKeyUp(HWND hwnd, HKL layout, int modifierKeyCode,
    BYTE keyboardState[256], int pause) {
    keyboardState[modifierKeyCode] &= ~0x80;

    LPARAM modifierKey = 1 | MapVirtualKeyEx(modifierKeyCode, 0, layout) << 16;
    modifierKey |= 0x3 << 30;

    if (!PostMessage(hwnd, WM_KEYUP, modifierKeyCode, modifierKey)) {
        LOG(WARN) << "Modifier keyup failed: " << GetLastError();
    }
    wait(pause);

}

void sendModifierKeyDownIfNeeded(bool shouldSend, HWND hwnd, HKL layout,
    int modifierKeyCode, BYTE keyboardState[256], int pause) {

    if (shouldSend) {
        sendModifierKeyDown(hwnd, layout, modifierKeyCode, keyboardState,
            pause);
    }
}

void sendModifierKeyUpIfNeeded(bool shouldSend, HWND hwnd, HKL layout,
    int modifierKeyCode, BYTE keyboardState[256], int pause) {

    if (shouldSend) {
        sendModifierKeyUp(hwnd, layout, modifierKeyCode, keyboardState,
            pause);
    }
}

bool isShiftPressNeeded(WORD keyCode) {
    return (keyCode & 0x0100) != 0;
}

bool isControlPressNeeded(WORD keyCode) {
    return (keyCode & 0x0200) != 0;
}

bool isAltPressNeeded(WORD keyCode) {
    return (keyCode & 0x0400) != 0; 
}

LPARAM generateKeyMessageParam(UINT scanCode, bool extended)
{
	LPARAM lparam = 1;
	lparam |= scanCode << 16;
	if (extended) {
		lparam |= 1 << 24;
	}
	
	return lparam;
}

void backgroundKeyDown(HWND hwnd, HKL layout, BYTE keyboardState[256],
		WORD keyCode, UINT scanCode, bool extended, int pause)
{
    // For capital letters and symbols requiring the shift key to be pressed,
    // A Shift key press must preceed. Unless the shift key is pressed - if
    // shiftPressed is true, then a shift key-down was sent in the past.
    sendModifierKeyDownIfNeeded(isShiftPressNeeded(keyCode) && (!shiftPressed), hwnd, layout,
        VK_SHIFT, keyboardState, pause);

    sendModifierKeyDownIfNeeded(isControlPressNeeded(keyCode) && (!controlPressed), hwnd, layout,
        VK_CONTROL, keyboardState, pause);

    sendModifierKeyDownIfNeeded(isAltPressNeeded(keyCode) && (!altPressed), hwnd, layout,
        VK_MENU, keyboardState, pause);

    // In order to produce an upper case character, the keyboard state should
    // be modified. See the documentation of shiftPressed to understand why
    // it's done only in this case.
    if ((shiftPressed) || (isShiftPressNeeded(keyCode))) {
      keyboardState[VK_SHIFT] |= 0x80;
    }

    keyCode = LOBYTE(keyCode);
    keyboardState[keyCode] |= 0x80;

    SetKeyboardState(keyboardState);

    LPARAM lparam = generateKeyMessageParam(scanCode, extended);

    pressed = false;
    if (!PostMessage(hwnd, WM_KEYDOWN, keyCode, lparam)) {
      LOG(WARN) << "Key down failed: " << GetLastError();
    }

    PostMessage(hwnd, WM_USER, 1234, 5678);

    // Listen out for the keypress event which IE synthesizes when IE
    // processes the keydown message. Use a time out, just in case we
    // have not got the logic right :)

    clock_t maxWait = clock() + 5000;
    while (!pressed) {
      wait(5);
      if (clock() >= maxWait) {
        LOG(WARN) << "Timeout awaiting keypress: " << keyCode;
        break;
      }
    }
}

void backgroundKeyUp(HWND hwnd, HKL layout, BYTE keyboardState[256],
		WORD keyCode, UINT scanCode, bool extended, int pause)
{
    WORD origKeyCode = keyCode;
	keyCode = LOBYTE(keyCode);
	keyboardState[keyCode] &= ~0x80;

    LPARAM lparam = generateKeyMessageParam(scanCode, extended);
	lparam |= 0x3 << 30;
	if (!PostMessage(hwnd, WM_KEYUP, keyCode, lparam)) {
	    LOG(WARN) << "Key up failed: " << GetLastError();
	}

	wait(pause);

  sendModifierKeyUpIfNeeded(isShiftPressNeeded(origKeyCode) && (!shiftPressed), hwnd, layout,
      VK_SHIFT, keyboardState, pause);
  sendModifierKeyUpIfNeeded(isControlPressNeeded(origKeyCode) && (!controlPressed), hwnd, layout,
      VK_CONTROL, keyboardState, pause);
  sendModifierKeyUpIfNeeded(isAltPressNeeded(origKeyCode) && (!altPressed), hwnd, layout,
      VK_MENU, keyboardState, pause);

    // If Shift was held down, we should reset the keyboard state for it
    // as well. See the comment in backgroundKeyDown on why it is set
    // in the first place.
    if ((shiftPressed) || (isShiftPressNeeded(origKeyCode))) {
      keyboardState[VK_SHIFT] &= ~0x80;
    }

	SetKeyboardState(keyboardState);
}


void backgroundKeyPress(HWND hwnd, HKL layout, BYTE keyboardState[256],
		WORD keyCode, UINT scanCode, bool extended, int pause)
{
	pause = pause / 3;

    backgroundKeyDown(hwnd, layout, keyboardState, keyCode, scanCode, extended, pause);
    backgroundKeyUp(hwnd, layout, keyboardState, keyCode, scanCode, extended, pause);
}

LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if ((nCode == HC_ACTION) && (wParam == PM_REMOVE)) {
		MSG* msg = reinterpret_cast<MSG*>(lParam);
		if (msg->message == WM_USER && msg->wParam == 1234 && msg->lParam == 5678) {
			pressed = true;
		}
	}

	return CallNextHookEx(hook, nCode, wParam, lParam);
}

bool isClearAllModifiersCode(wchar_t c)
{
  return (c == 0xE000U);
}

bool isShiftCode(wchar_t c)
{
  return (c == 0xE008U); // shift (left)
}

bool isControlCode(wchar_t c)
{
  return (c == 0xE009U); // control (left)
}

bool isAltCode(wchar_t c)
{
  return (c == 0xE00AU); // alt (left)
}

bool isModifierCharacter(wchar_t c)
{
  return isClearAllModifiersCode(c) || isShiftCode(c) || isControlCode(c) ||
    isAltCode(c);
}

// All the required information to post a keyboard event message.
struct KeySendingData {
  HWND to_window;
  HKL layout;
  BYTE* keyboardState;
  int pause_time;
};

void sendSingleModifierEventAndAdjustState(bool matchingModifier,
    bool& modifierState, int modifierKeyCode, KeySendingData sendData)
{
  if (!matchingModifier) {
    return;
  }

  if (modifierState) {
    sendModifierKeyUp(sendData.to_window, sendData.layout,
        modifierKeyCode, sendData.keyboardState, sendData.pause_time);
  } else {
    sendModifierKeyDown(sendData.to_window, sendData.layout,
        modifierKeyCode, sendData.keyboardState, sendData.pause_time);
  }
  modifierState = !modifierState;
}

void postModifierReleaseMessages(bool releaseShift, bool releaseControl, bool releaseAlt,
    KeySendingData sendData)
{
    sendModifierKeyUpIfNeeded(releaseShift, sendData.to_window, sendData.layout, VK_SHIFT, sendData.keyboardState, sendData.pause_time);
    sendModifierKeyUpIfNeeded(releaseControl, sendData.to_window, sendData.layout, VK_CONTROL, sendData.keyboardState, sendData.pause_time);
    sendModifierKeyUpIfNeeded(releaseAlt, sendData.to_window, sendData.layout, VK_MENU, sendData.keyboardState, sendData.pause_time);
}

void sendModifierKeyEvent(wchar_t c, bool& shiftKey, bool& controlKey,
    bool& altKey, KeySendingData sendData)

{
  if (isClearAllModifiersCode(c)) {
    postModifierReleaseMessages(shiftKey, controlKey, altKey, sendData);

    shiftKey = controlKey = altKey = false;
  } else {
    sendSingleModifierEventAndAdjustState(isShiftCode(c), shiftKey, VK_SHIFT, sendData);
    sendSingleModifierEventAndAdjustState(isControlCode(c), controlKey, VK_CONTROL, sendData);
    sendSingleModifierEventAndAdjustState(isAltCode(c), altKey, VK_MENU, sendData);
    if (isShiftCode(c)) {
      updateShiftKeyState(shiftKey);
    }
  }
}

static HKL attachInputToIEThread(HWND directInputTo)
{
	DWORD currThreadId = GetCurrentThreadId();
	DWORD ieWinThreadId = GetWindowThreadProcessId(directInputTo, NULL);

	GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)
			&sendKeys, &moduleHandle);

	hook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) &GetMessageProc,
			moduleHandle, ieWinThreadId);

	// Attach to the IE thread so we can send keys to it.
	if (ieWinThreadId != currThreadId) {
		AttachThreadInput(currThreadId, ieWinThreadId, true);
	}

	return GetKeyboardLayout(ieWinThreadId);
}

static void detachInputFromIEThread(HWND directInputTo)
{
	DWORD currThreadId = GetCurrentThreadId();
	DWORD ieWinThreadId = GetWindowThreadProcessId(directInputTo, NULL);

	if (hook) {
		UnhookWindowsHookEx(hook);
	}

	if (moduleHandle) {
		FreeLibrary(moduleHandle);
	}

	if (ieWinThreadId != currThreadId) {
		AttachThreadInput(currThreadId, ieWinThreadId, false);
	}
}

extern "C"
{
void sendKeys(WINDOW_HANDLE windowHandle, const wchar_t* value, int timePerKey)
{
	if (!windowHandle) {
	  LOG(WARN) << "Window handle is invalid";
	  return;
	}

	HWND directInputTo = static_cast<HWND>(windowHandle);

	HKL layout = attachInputToIEThread(directInputTo);
	BYTE keyboardState[256];
	::ZeroMemory(keyboardState, sizeof(keyboardState));

	bool controlKey = controlPressed;
	bool shiftKey = shiftPressed;
	bool altKey = altPressed;
  KeySendingData sendData;
  sendData.to_window = directInputTo;
  sendData.layout = layout;
  sendData.keyboardState = keyboardState;
  sendData.pause_time = timePerKey;

	for (const wchar_t *p = value; *p; ++p) {
		const wchar_t c = *p;

		bool extended = false;

		UINT scanCode = 0;
		WORD keyCode = 0;

    if (isModifierCharacter(c)) {
      sendModifierKeyEvent(c, shiftKey, controlKey, altKey, sendData);
      shiftPressed = shiftKey;
      controlPressed = controlKey;
      altPressed = altKey;
      continue;
		} else if (c == 0xE001U) {  // ^break
			keyCode = VK_CANCEL;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE002U) {  // help
			keyCode = VK_HELP;
			scanCode = keyCode;
		} else if (c == 0xE003U) {  // back space
			keyCode = VK_BACK;
			scanCode = keyCode;
		} else if (c == 0xE004U) {  // tab
			keyCode = VK_TAB;
			scanCode = keyCode;
		} else if (c == 0xE005U) {  // clear
			keyCode = VK_CLEAR;
			scanCode = keyCode;
		} else if (c == 0xE006U) {  // return
			keyCode = VK_RETURN;
			scanCode = keyCode;
		} else if (c == 0xE007U) {  // enter
			keyCode = VK_RETURN;
			scanCode = keyCode;
		} else if (c == 0xE00BU) {  // pause
			keyCode = VK_PAUSE;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE00CU) {  // escape
			keyCode = VK_ESCAPE;
			scanCode = keyCode;
		} else if (c == 0xE00DU) {  // space
			keyCode = VK_SPACE;
			scanCode = keyCode;
		} else if (c == 0xE00EU) {  // page up
			keyCode = VK_PRIOR;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE00FU) {  // page down
			keyCode = VK_NEXT;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE010U) {  // end
			keyCode = VK_END;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE011U) {  // home
			keyCode = VK_HOME;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE012U) {  // left arrow
			keyCode = VK_LEFT;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE013U) {  // up arrow
			keyCode = VK_UP;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE014U) {  // right arrow
			keyCode = VK_RIGHT;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE015U) {  // down arrow
			keyCode = VK_DOWN;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE016U) {  // insert
			keyCode = VK_INSERT;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE017U) {  // delete
			keyCode = VK_DELETE;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE018U) {  // semicolon
			keyCode = VkKeyScanExW(L';', layout);
			scanCode = MapVirtualKeyExW(LOBYTE(keyCode), 0, layout);
		} else if (c == 0xE019U) {  // equals
			keyCode = VkKeyScanExW(L'=', layout);
			scanCode = MapVirtualKeyExW(LOBYTE(keyCode), 0, layout);
		} else if (c == 0xE01AU) {  // numpad0
			keyCode = VK_NUMPAD0;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE01BU) {  // numpad1
			keyCode = VK_NUMPAD1;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE01CU) {  // numpad2
			keyCode = VK_NUMPAD2;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE01DU) {  // numpad3
			keyCode = VK_NUMPAD3;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE01EU) {  // numpad4
			keyCode = VK_NUMPAD4;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE01FU) {  // numpad5
			keyCode = VK_NUMPAD5;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE020U) {  // numpad6
			keyCode = VK_NUMPAD6;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE021U) {  // numpad7
			keyCode = VK_NUMPAD7;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE022U) {  // numpad8
			keyCode = VK_NUMPAD8;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE023U) {  // numpad9
			keyCode = VK_NUMPAD9;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE024U) {  // multiply
			keyCode = VK_MULTIPLY;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE025U) {  // add
			keyCode = VK_ADD;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE026U) {  // separator
			keyCode = VkKeyScanExW(L',', layout);
			scanCode = MapVirtualKeyExW(LOBYTE(keyCode), 0, layout);
		} else if (c == 0xE027U) {  // subtract
			keyCode = VK_SUBTRACT;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE028U) {  // decimal
			keyCode = VK_DECIMAL;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE029U) {  // divide
			keyCode = VK_DIVIDE;
			scanCode = keyCode;
			extended = true;
		} else if (c == 0xE031U) {  // F1
			keyCode = VK_F1;
			scanCode = keyCode;
		} else if (c == 0xE032U) {  // F2
			keyCode = VK_F2;
			scanCode = keyCode;
		} else if (c == 0xE033U) {  // F3
			keyCode = VK_F3;
			scanCode = keyCode;
		} else if (c == 0xE034U) {  // F4
			keyCode = VK_F4;
			scanCode = keyCode;
		} else if (c == 0xE035U) {  // F5
			keyCode = VK_F5;
			scanCode = keyCode;
		} else if (c == 0xE036U) {  // F6
			keyCode = VK_F6;
			scanCode = keyCode;
		} else if (c == 0xE037U) {  // F7
			keyCode = VK_F7;
			scanCode = keyCode;
		} else if (c == 0xE038U) {  // F8
			keyCode = VK_F8;
			scanCode = keyCode;
		} else if (c == 0xE039U) {  // F9
			keyCode = VK_F9;
			scanCode = keyCode;
		} else if (c == 0xE03AU) {  // F10
			keyCode = VK_F10;
			scanCode = keyCode;
		} else if (c == 0xE03BU) {  // F11
			keyCode = VK_F11;
			scanCode = keyCode;
		} else if (c == 0xE03CU) {  // F12
			keyCode = VK_F12;
			scanCode = keyCode;
		} else if (c == L'\n') {    // line feed
			keyCode = VK_RETURN;
			scanCode = keyCode;
		} else if (c == L'\r') {    // carriage return
			continue;  // skip it
		} else {
			keyCode = VkKeyScanExW(c, layout);
			scanCode = MapVirtualKeyExW(LOBYTE(keyCode), 0, layout);
			if (!scanCode || (keyCode == 0xFFFFU)) {
				LOG(WARN) << "No translation for key. Assuming unicode input: " << c;
				backgroundUnicodeKeyPress(directInputTo, c, timePerKey);
				continue;  // bogus
			}
		}

        // Note: There is *no* need to OR the keyCode with 0x0100 if
        // shiftPressed is true. ORing the keyCode with these values is to
        // indicate the backgroundKeyPress procedure that a modifier key
        // press and release should be produced for this keyCode. However,
        // when shiftPressed is true the events for the modifier were
        // already generated by the sendKeyPress function.
		if (shiftKey)
			keyCode |= static_cast<WORD>(0x0100);
		if (controlKey)
			keyCode |= static_cast<WORD>(0x0200);
		if (altKey)
			keyCode |= static_cast<WORD>(0x0400);

		int pause = timePerKey;

		// Pause for control, alt, and shift generation: if we create these
		// chars too fast, the target element may generated spurious chars.

		if (keyCode & static_cast<WORD>(0x0100)) {
			pause = (35 * 3);  // uppercase char
		} else if (shiftKey || controlKey || altKey) {
		    pause = (35 * 3);  // shift|alt|ctrl
		}

		backgroundKeyPress(directInputTo, layout, keyboardState, keyCode, scanCode,
				extended, pause);
	}

    detachInputFromIEThread(directInputTo);
}

void releaseModifierKeys(WINDOW_HANDLE windowHandle, int timePerKey)
{
	if (!windowHandle) {
	  LOG(WARN) << "Window handle is invalid";
	  return;
	}

	HWND directInputTo = static_cast<HWND>(windowHandle);

	HKL layout = attachInputToIEThread(directInputTo);
	BYTE keyboardState[256];
	::ZeroMemory(keyboardState, sizeof(keyboardState));

  KeySendingData sendData;

  sendData.to_window = directInputTo;
  sendData.layout = layout;
  sendData.keyboardState = keyboardState;
  sendData.pause_time = 35;

  if ((shiftPressed) || (controlPressed) || (altPressed)) {
    postModifierReleaseMessages(shiftPressed, controlPressed, altPressed, sendData);
    shiftPressed = false;
    controlPressed = false;
    altPressed = false;
  }

  detachInputFromIEThread(directInputTo);
}

bool isSameThreadAs(HWND other) 
{
	DWORD currThreadId = GetCurrentThreadId();
	DWORD winThreadId = GetWindowThreadProcessId(other, NULL);

	return winThreadId == currThreadId;
}

LRESULT clickAt(WINDOW_HANDLE handle, long x, long y, long button)
{
	if (!handle) {
	  LOG(WARN) << "Window handle is invalid";
	  return ENULLPOINTER;
	}

	HWND directInputTo = (HWND) handle;

	LRESULT result = mouseDownAt(handle, x, y, button);
    if (result != 0) {
		LOG(WARN) << "Mouse down did not succeed whilst clicking";
		return result;
	}

	return mouseUpAt(handle, x, y, button);
}

static LRESULT mouseDoubleClickDown(WINDOW_HANDLE directInputTo, long x, long y)
{
  if (!directInputTo) {
    LOG(WARN) << "Window handle is invalid";
    return ENULLPOINTER;
  }

  if (!isSameThreadAs((HWND) directInputTo)) {
    BOOL toReturn = PostMessage((HWND) directInputTo, WM_LBUTTONDBLCLK, MK_LBUTTON, MAKELONG(x, y));

    // Wait until we know that the previous message has been processed
    SendMessage((HWND) directInputTo, WM_USER, 0, 0);
    return toReturn ? 0 : 1;  // Because 0 means success.
  } else {
    return SendMessage((HWND) directInputTo, WM_LBUTTONDBLCLK, MK_LBUTTON, MAKELONG(x, y));
  }
}

LRESULT doubleClickAt(WINDOW_HANDLE handle, long x, long y)
{
  // A double click consists of the sequence
  // 1: mouseDown
  // 2: mouseUp
  // 3: doubleClick
  // 4: mouseUp
  // Which is the equivalent to two clicks with the second mouseDown event
  // is replaced by a doubleClick event.

  if (!handle) {
    LOG(WARN) << "Window handle is invalid";
    return ENULLPOINTER;
  }

  LRESULT  result = clickAt(handle, x, y, 0);
  if (result != 0) {
    LOG(WARN) << "Mouse down did not succeed whilst clicking";
    return result;
  }

  result = mouseDoubleClickDown(handle, x, y);
  if (result != 0) {
    LOG(WARN) << "Mouse down did not succeed whilst double clicking";
    return result;
  }

  return mouseUpAt(handle, x, y, 0);
}

static void fillEventData(long button, bool buttonDown, UINT *message, WPARAM *wparam)
{
  if(WD_CLIENT_RIGHT_MOUSE_BUTTON == button) {
    if(buttonDown) {
      *message = WM_RBUTTONDOWN;
    } else {
      *message = WM_RBUTTONUP;
    }
    *wparam = MK_RBUTTON;
  } else { // middle button support is declared in json wire protocol but it is not supported
    leftMouseButtonPressed = buttonDown;
    if(buttonDown) {
      *message = WM_LBUTTONDOWN;
    } else {
      *message = WM_LBUTTONUP;
    }
    *wparam = MK_LBUTTON;
  }
  if (shiftPressed) {
    *wparam |= MK_SHIFT;
  }
}

LRESULT mouseDownAt(WINDOW_HANDLE directInputTo, long x, long y, long button)
{
	if (!directInputTo) {
	  LOG(WARN) << "Window handle is invalid";
	  return ENULLPOINTER;
	}

	UINT message;
	WPARAM wparam;
        LRESULT returnValue;

	fillEventData(button, true, &message, &wparam);
        pausePersistentEventsFiring();

	if (!isSameThreadAs((HWND) directInputTo)) {
		BOOL toReturn = PostMessage((HWND) directInputTo, message, wparam, MAKELONG(x, y));

		// Wait until we know that the previous message has been processed
		SendMessage((HWND) directInputTo, WM_USER, 0, 0);
		returnValue = toReturn ? 0 : 1;  // Because 0 means success.
	} else {
		returnValue = SendMessage((HWND) directInputTo, message, wparam, MAKELONG(x, y));
	}

    // Assume it's the left mouse button.
    if(WD_CLIENT_RIGHT_MOUSE_BUTTON != button) {
      updateLeftMouseButtonState(true);
    }
    resumePersistentEventsFiring();

        return returnValue;
}

LRESULT mouseUpAt(WINDOW_HANDLE directInputTo, long x, long y, long button)
{
	if (!directInputTo) {
	  LOG(WARN) << "Window handle is invalid";
	  return ENULLPOINTER;
	}

 	UINT message;
 	WPARAM wparam;
        LRESULT returnValue;
 
 	fillEventData(button, false, &message, &wparam);
        pausePersistentEventsFiring();

	SendMessage((HWND) directInputTo, WM_MOUSEMOVE, (shiftPressed ? MK_SHIFT : 0), MAKELPARAM(x, y));
	if (!isSameThreadAs((HWND) directInputTo)) {
 		BOOL toReturn = PostMessage((HWND) directInputTo, message, wparam, MAKELONG(x, y));

		// Wait until we know that the previous message has been processed
		SendMessage((HWND) directInputTo, WM_USER, 0, 0);
		returnValue = toReturn ? 0 : 1;  // Because 0 means success.
	} else {
 		returnValue = SendMessage((HWND) directInputTo, message, wparam, MAKELONG(x, y));
	}
    // Assume it's the left mouse button.
    if(WD_CLIENT_RIGHT_MOUSE_BUTTON != button) {
      updateLeftMouseButtonState(false);
    }
    resumePersistentEventsFiring();

    return returnValue;
}

LRESULT mouseMoveTo(WINDOW_HANDLE handle, long duration, long fromX, long fromY, long toX, long toY)
{
  if (!handle) {
    LOG(WARN) << "Window handle is invalid";
    return ENULLPOINTER;
  }

  pausePersistentEventsFiring();

  HWND directInputTo = (HWND) handle;
  long pointsDistance = distanceBetweenPoints(fromX, fromY, toX, toY);
  const int stepSizeInPixels = 5;
  int steps = pointsDistance / stepSizeInPixels;

  long sleep = duration / max(steps, 1);

  WPARAM buttonValue = (leftMouseButtonPressed ? MK_LBUTTON : 0);
  if (shiftPressed) {
    buttonValue |= MK_SHIFT;
  }

  for (int i = 0; i < steps + 1; i++) {
    //To avoid integer division rounding and cumulative floating point errors,
    //calculate from scratch each time
    int currentX = (int)(fromX + ((toX - fromX) * ((double)i) / steps));
    int currentY = (int)(fromY + ((toY - fromY) * ((double)i) / steps));
    SendMessage(directInputTo, WM_MOUSEMOVE, buttonValue, MAKELPARAM(currentX, currentY));
    wait(sleep);
  }

  SendMessage(directInputTo, WM_MOUSEMOVE, buttonValue, MAKELPARAM(toX, toY));
  resumePersistentEventsFiring(directInputTo, toX, toY, buttonValue);

  return 0;
}

BOOL_TYPE pending_input_events()
{
  return false;
}

}
