/*
 * MS-dependent event code
 */

#include <InterViews\itable.h>
#include <InterViews\event.h>
#include <InterViews\interactor.h>
#include <InterViews\X11\eventrep.h>
#include <InterViews\X11\worldrep.h>
#include <InterViews\canvas.h>
#include <string.h>
#include <ctype.h>

Event::Event() {
    rep = new EventRep;
}

Event::~Event() {
    delete rep;
}

void Event::GetMotionInfo() {
    MSG msg = rep->msg;

    eventType = MotionEvent;
    timestamp = msg.time;
    x = LOWORD(msg.lParam);
    y = HIWORD(msg.lParam);
    GetRootCoord(x, y);
    GetKeyState(msg.wParam);
    FindWorld((void*)msg.hwnd);
}

void Event::GetButtonInfo(EventType t) {
    MSG msg = rep->msg;

    eventType = t;
    timestamp = msg.time;
    x = LOWORD(msg.lParam);
    y = HIWORD(msg.lParam);

    switch(msg.message) {
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	    button = LEFTMOUSE;
	    break;
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
	    button = MIDDLEMOUSE;
	    break;
	case WM_RBUTTONDOWN:
	case WM_RBUTTONUP:
	    button = RIGHTMOUSE;
	    break;
    };

    len = 0;
    GetKeyState(msg.wParam);
    GetRootCoord(x, y);
    FindWorld((void*)msg.hwnd);
}

void Event::GetKeyInfo() {
    MSG msg = rep->msg;

    eventType = KeyEvent;
    timestamp = msg.time;
    x = msg.pt.x;
    y = msg.pt.y;
    GetRootCoord(x, y);
    button = msg.wParam;
    keystring = keydata;
    if (isascii(msg.wParam)) {
	keystring[0] = msg.wParam;
	keystring[1] = '\0';
	len = 1;
    } else {
	keystring[0] = '\0';
	len = 0;
    }
    GetKeybState();
    FindWorld((void*)msg.hwnd);
}

/*
 *   Als Eintrittspunkt wird die neue Position des Cursors verwendet. Dieser
 *   entspricht sicherlich nicht dem tats„chlichen, da die Berechnung der
 *   neuen Cursorposition im Intervall 0.1 Sekunden oder nach WM_MOUSEMOVE
 *   Nachrichten erfolgt, und bei einer schnellen Mausbewegung die Schritt-
 *   weite merklich gr”áer wird.
 */


boolean Event::GetCrossingInfo(EventType t) {
    MSG msg = rep->msg;
    POINT p;

    eventType = t;
    timestamp = msg.time;
    p.x = msg.pt.x;
    p.y = msg.pt.y;
    ScreenToClient(msg.hwnd, &p);
    x = p.x;
    y = p.y;
    wx = msg.pt.x;
    wy = msg.pt.y;
    GetKeybState();
    FindWorld((void*)msg.hwnd);
    return true;
}

void Event::GetRootCoord(int x, int y) {
    POINT p;
    p.x = x;
    p.y = y;
    ClientToScreen(rep->msg.hwnd, (LPPOINT)&p);
    wx = p.x;
    wy = p.y;
}

void Event::GetKeyState(WORD state) {
    shift = (state & MK_SHIFT) != 0;
    control = (state & MK_CONTROL) != 0;
    leftmouse = (state & MK_LBUTTON) != 0;
    middlemouse = (state & MK_MBUTTON) != 0;
    rightmouse = (state & MK_RBUTTON) != 0;
    meta = 0;
    shiftlock = 0;
}

void Event::GetKeybState () {
    shift = 0;
    control = 0;
    leftmouse = 0;
    middlemouse = 0;
    rightmouse = 0;
    meta = 0;
    shiftlock = 0;
}

void Event::FindWorld(void* hwnd) {
    Interactor* i;

    if (_world->itable()->Find(i, hwnd)) {
	w = i->GetWorld();
    } else {
	w = nil;
    }
}
