/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2004 Sam Lantinga
    Copyright (C) 2001  Hsieh-Fu Tsai
    Copyright (C) 2002  Greg Haerr <greg@censoft.com>

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

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

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
    
    Hsieh-Fu Tsai
    clare@setabox.com
*/
#include "SDL_config.h"

#include "SDL_keysym.h"
#include "../../events/SDL_events_c.h"

#include "SDL_nxevents_c.h"
#include "SDL_nximage_c.h"

// The translation tables from a nanox keysym to a SDL keysym
static SDLKey NX_NONASCII_keymap [MWKEY_LAST + 1] ;

void NX_InitOSKeymap (_THIS)
{
    int i ;

    Dprintf ("enter NX_InitOSKeymap\n") ;

    // Map the nanox scancodes to SDL keysyms
    for (i = 0; i < SDL_arraysize (NX_NONASCII_keymap); ++ i)
        NX_NONASCII_keymap [i] = SDLK_UNKNOWN ;

    NX_NONASCII_keymap [MWKEY_LEFT        & 0xFF] = SDLK_LEFT ;
    NX_NONASCII_keymap [MWKEY_RIGHT       & 0xFF] = SDLK_RIGHT ;
    NX_NONASCII_keymap [MWKEY_UP          & 0xFF] = SDLK_UP ;
    NX_NONASCII_keymap [MWKEY_DOWN        & 0xFF] = SDLK_DOWN ;
    NX_NONASCII_keymap [MWKEY_INSERT      & 0xFF] = SDLK_INSERT ;
    NX_NONASCII_keymap [MWKEY_DELETE      & 0xFF] = SDLK_DELETE ;
    NX_NONASCII_keymap [MWKEY_HOME        & 0xFF] = SDLK_HOME ;
    NX_NONASCII_keymap [MWKEY_END         & 0xFF] = SDLK_END ;
    NX_NONASCII_keymap [MWKEY_PAGEUP      & 0xFF] = SDLK_PAGEUP ;
    NX_NONASCII_keymap [MWKEY_PAGEDOWN    & 0xFF] = SDLK_PAGEDOWN ;

    NX_NONASCII_keymap [MWKEY_KP0         & 0xFF] = SDLK_KP0 ;
    NX_NONASCII_keymap [MWKEY_KP1         & 0xFF] = SDLK_KP1 ;
    NX_NONASCII_keymap [MWKEY_KP2         & 0xFF] = SDLK_KP2 ;
    NX_NONASCII_keymap [MWKEY_KP3         & 0xFF] = SDLK_KP3 ;
    NX_NONASCII_keymap [MWKEY_KP4         & 0xFF] = SDLK_KP4 ;
    NX_NONASCII_keymap [MWKEY_KP5         & 0xFF] = SDLK_KP5 ;
    NX_NONASCII_keymap [MWKEY_KP6         & 0xFF] = SDLK_KP6 ;
    NX_NONASCII_keymap [MWKEY_KP7         & 0xFF] = SDLK_KP7 ;
    NX_NONASCII_keymap [MWKEY_KP8         & 0xFF] = SDLK_KP8 ;
    NX_NONASCII_keymap [MWKEY_KP9         & 0xFF] = SDLK_KP9 ;
    NX_NONASCII_keymap [MWKEY_KP_PERIOD   & 0xFF] = SDLK_KP_PERIOD ;
    NX_NONASCII_keymap [MWKEY_KP_DIVIDE   & 0xFF] = SDLK_KP_DIVIDE ;
    NX_NONASCII_keymap [MWKEY_KP_MULTIPLY & 0xFF] = SDLK_KP_MULTIPLY ;
    NX_NONASCII_keymap [MWKEY_KP_MINUS    & 0xFF] = SDLK_KP_MINUS ;
    NX_NONASCII_keymap [MWKEY_KP_PLUS     & 0xFF] = SDLK_KP_PLUS ;
    NX_NONASCII_keymap [MWKEY_KP_ENTER    & 0xFF] = SDLK_KP_ENTER ;
    NX_NONASCII_keymap [MWKEY_KP_EQUALS   & 0xFF] = SDLK_KP_EQUALS ;

    NX_NONASCII_keymap [MWKEY_F1          & 0xFF] = SDLK_F1 ;
    NX_NONASCII_keymap [MWKEY_F2          & 0xFF] = SDLK_F2 ;
    NX_NONASCII_keymap [MWKEY_F3          & 0xFF] = SDLK_F3 ;
    NX_NONASCII_keymap [MWKEY_F4          & 0xFF] = SDLK_F4 ;
    NX_NONASCII_keymap [MWKEY_F5          & 0xFF] = SDLK_F5 ;
    NX_NONASCII_keymap [MWKEY_F6          & 0xFF] = SDLK_F6 ;
    NX_NONASCII_keymap [MWKEY_F7          & 0xFF] = SDLK_F7 ;
    NX_NONASCII_keymap [MWKEY_F8          & 0xFF] = SDLK_F8 ;
    NX_NONASCII_keymap [MWKEY_F9          & 0xFF] = SDLK_F9 ;
    NX_NONASCII_keymap [MWKEY_F10         & 0xFF] = SDLK_F10 ;
    NX_NONASCII_keymap [MWKEY_F11         & 0xFF] = SDLK_F11 ;
    NX_NONASCII_keymap [MWKEY_F12         & 0xFF] = SDLK_F12 ;

    NX_NONASCII_keymap [MWKEY_NUMLOCK     & 0xFF] = SDLK_NUMLOCK ;
    NX_NONASCII_keymap [MWKEY_CAPSLOCK    & 0xFF] = SDLK_CAPSLOCK ;
    NX_NONASCII_keymap [MWKEY_SCROLLOCK   & 0xFF] = SDLK_SCROLLOCK ;
    NX_NONASCII_keymap [MWKEY_LSHIFT      & 0xFF] = SDLK_LSHIFT ;
    NX_NONASCII_keymap [MWKEY_RSHIFT      & 0xFF] = SDLK_RSHIFT ;
    NX_NONASCII_keymap [MWKEY_LCTRL       & 0xFF] = SDLK_LCTRL ;
    NX_NONASCII_keymap [MWKEY_RCTRL       & 0xFF] = SDLK_RCTRL ;
    NX_NONASCII_keymap [MWKEY_LALT        & 0xFF] = SDLK_LALT ;
    NX_NONASCII_keymap [MWKEY_RALT        & 0xFF] = SDLK_RALT ;
    NX_NONASCII_keymap [MWKEY_LMETA       & 0xFF] = SDLK_LMETA ;
    NX_NONASCII_keymap [MWKEY_RMETA       & 0xFF] = SDLK_RMETA ;
    NX_NONASCII_keymap [MWKEY_ALTGR       & 0xFF] = SDLK_MODE ;

    NX_NONASCII_keymap [MWKEY_PRINT       & 0xFF] = SDLK_PRINT ;
    NX_NONASCII_keymap [MWKEY_SYSREQ      & 0xFF] = SDLK_SYSREQ ;
    NX_NONASCII_keymap [MWKEY_PAUSE       & 0xFF] = SDLK_PAUSE ;
    NX_NONASCII_keymap [MWKEY_BREAK       & 0xFF] = SDLK_BREAK ;
    NX_NONASCII_keymap [MWKEY_MENU        & 0xFF] = SDLK_MENU ;

    Dprintf ("leave NX_InitOSKeymap\n") ;
}

SDL_keysym * NX_TranslateKey (GR_EVENT_KEYSTROKE * keystroke, SDL_keysym * keysym)
{
    GR_KEY ch = keystroke -> ch ;

    Dprintf ("enter NX_TranslateKey\n") ;

    keysym -> scancode = keystroke -> scancode ;
    keysym -> sym = SDLK_UNKNOWN ;

    if (ch & MWKEY_NONASCII_MASK) {
        keysym -> sym = NX_NONASCII_keymap [ch & 0xFF] ;
    } else {
        keysym -> sym = ch & 0x7F ;
    }

    keysym -> mod = KMOD_NONE ;
    
#if 1   //   Retrieve more mode information
    {
        GR_KEYMOD   mod = keystroke -> modifiers ;

        if (mod & MWKMOD_LSHIFT)
            keysym -> mod |= KMOD_LSHIFT ;
        if (mod & MWKMOD_RSHIFT)
            keysym -> mod |= KMOD_RSHIFT ;
        if (mod & MWKMOD_LCTRL)
            keysym -> mod |= KMOD_LCTRL ;
        if (mod & MWKMOD_RCTRL)
            keysym -> mod |= KMOD_RCTRL ;
        if (mod & MWKMOD_LALT)
            keysym -> mod |= KMOD_LALT ;
        if (mod & MWKMOD_RALT)
            keysym -> mod |= KMOD_RALT ;
        if (mod & MWKMOD_LMETA)
            keysym -> mod |= KMOD_LMETA ;
        if (mod & MWKMOD_RMETA)
            keysym -> mod |= KMOD_RMETA ;
        if (mod & MWKMOD_NUM)
            keysym -> mod |= KMOD_NUM ;
        if (mod & MWKMOD_CAPS)
            keysym -> mod |= KMOD_CAPS ;
        if (mod & MWKMOD_ALTGR)
            keysym -> mod |= KMOD_MODE ;
    }
#endif

    keysym -> unicode = ch ;

    Dprintf ("leave NX_TranslateKey\n") ;
    return keysym ;
}

static int check_boundary (_THIS, int x, int y)
{
    if (x < OffsetX || y < OffsetY || x > OffsetX + this -> screen -> w ||
        y > OffsetY + this -> screen -> h)
        return 0 ;
            
    return 1 ;
}

void NX_PumpEvents (_THIS)
{
    GR_EVENT         event ;
    static GR_BUTTON last_button_down = 0 ;

    GrCheckNextEvent (& event) ;
    while (event.type != GR_EVENT_TYPE_NONE) {

        // dispatch event
        switch (event.type) {
            case GR_EVENT_TYPE_MOUSE_ENTER :
            {
                Dprintf ("mouse enter\n") ;
                SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS) ;
                break ;
            }

            case GR_EVENT_TYPE_MOUSE_EXIT :
            {
                Dprintf ("mouse exit\n") ;
                SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS) ;
                break ;
            }

            case GR_EVENT_TYPE_FOCUS_IN :
            {
                Dprintf ("focus in\n") ;
                SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS) ;
                break ;
            }

            case GR_EVENT_TYPE_FOCUS_OUT :
            {
                Dprintf ("focus out\n") ;
                SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS) ;
                break ;
            }

            case GR_EVENT_TYPE_MOUSE_MOTION :
            {               
                Dprintf ("mouse motion\n") ;

                if (SDL_VideoSurface) {
                    if (currently_fullscreen) {
                        if (check_boundary (this, event.button.x, event.button.y)) {
                            SDL_PrivateMouseMotion (0, 0, event.button.x - OffsetX, 
                                event.button.y - OffsetY) ;
                        }
                    } else {
                        SDL_PrivateMouseMotion (0, 0, event.button.x, event.button.y) ;
                    }
                }
                break ;
            }

            case GR_EVENT_TYPE_BUTTON_DOWN :
            {
                int button = event.button.buttons ;
                
                Dprintf ("button down\n") ;

                switch (button) {
                    case MWBUTTON_L :
                        button = 1 ;
                        break ;
                    case MWBUTTON_M :
                        button = 2 ;
                        break ;
                    case MWBUTTON_R :
                        button = 3 ;
                        break ;
                    default :
                        button = 0 ;
                }
                last_button_down = button ;
                
                if (currently_fullscreen) {
                    if (check_boundary (this, event.button.x, event.button.y)) {
                        SDL_PrivateMouseButton (SDL_PRESSED, button, 
                            event.button.x - OffsetX, event.button.y - OffsetY) ;
                    }
                } else {
                    SDL_PrivateMouseButton (SDL_PRESSED, button, 
                        event.button.x, event.button.y) ;
                }
                break ;
            }

            // do not konw which button is released
            case GR_EVENT_TYPE_BUTTON_UP :
            {   
                Dprintf ("button up\n") ;

                if (currently_fullscreen) {
                    if (check_boundary (this, event.button.x, event.button.y)) {
                        SDL_PrivateMouseButton (SDL_RELEASED, last_button_down, 
                            event.button.x - OffsetX, event.button.y - OffsetY) ;
                    }
                } else {
                    SDL_PrivateMouseButton (SDL_RELEASED, last_button_down, 
                        event.button.x, event.button.y) ;
                }
                last_button_down = 0 ;
                break ;
            }

            case GR_EVENT_TYPE_KEY_DOWN :
            {
                SDL_keysym keysym ;

                Dprintf ("key down\n") ;
                SDL_PrivateKeyboard (SDL_PRESSED,
                    NX_TranslateKey (& event.keystroke, & keysym)) ;
                break ;
            }

            case GR_EVENT_TYPE_KEY_UP :
            {
                SDL_keysym keysym ;

                Dprintf ("key up\n") ;
                SDL_PrivateKeyboard (SDL_RELEASED,
                    NX_TranslateKey (& event.keystroke, & keysym)) ;
                break ;
            }

            case GR_EVENT_TYPE_CLOSE_REQ :
            {
                Dprintf ("close require\n") ;
                SDL_PrivateQuit () ;
                break ;
            }

            case GR_EVENT_TYPE_EXPOSURE :
            {
                Dprintf ("event_type_exposure\n") ;
                if (SDL_VideoSurface) {
                    NX_RefreshDisplay (this) ;//, & event.exposure) ;
                }
                break ;
            }

            case GR_EVENT_TYPE_UPDATE :
            {
                switch (event.update.utype) {
                    case GR_UPDATE_MAP :
                    {
                        Dprintf ("GR_UPDATE_MAP\n") ;
                        // If we're not active, make ourselves active
                        if (!(SDL_GetAppState () & SDL_APPACTIVE)) {
                            // Send an internal activate event
                            SDL_PrivateAppActive (1, SDL_APPACTIVE) ;
                        }
                        if (SDL_VideoSurface) {
                            NX_RefreshDisplay (this) ;
                        }
                        break ;
                    }
                    
                    case GR_UPDATE_UNMAP :
                    case GR_UPDATE_UNMAPTEMP :
                    {
                        Dprintf ("GR_UPDATE_UNMAP or GR_UPDATE_UNMAPTEMP\n") ;
                        // If we're active, make ourselves inactive
                        if (SDL_GetAppState () & SDL_APPACTIVE) {
                            // Send an internal deactivate event
                            SDL_PrivateAppActive (0, SDL_APPACTIVE | SDL_APPINPUTFOCUS) ;
                        }
                        break ; 
                    }
                    
                    case GR_UPDATE_SIZE :
                    {
                        Dprintf ("GR_UPDATE_SIZE\n") ;
                        SDL_PrivateResize (event.update.width, event.update.height) ;
                        break ; 
                    }

                    case GR_UPDATE_MOVE :
		    case GR_UPDATE_REPARENT :
                    {
                        Dprintf ("GR_UPDATE_MOVE or GR_UPDATE_REPARENT\n") ;
#ifdef ENABLE_NANOX_DIRECT_FB
			if (Clientfb) {
			    /* Get current window position and fb pointer*/
			    if (currently_fullscreen) 
				GrGetWindowFBInfo(FSwindow, &fbinfo);
			    else
				GrGetWindowFBInfo(SDL_Window, &fbinfo);
			}
#endif
                        break ; 
                    }
                    
                    default :
                        Dprintf ("unknown GR_EVENT_TYPE_UPDATE\n") ;
                        break ; 
                }
                break ; 
            }
                
            default :
            {
                Dprintf ("pump event default\n") ;
            }
        }

        GrCheckNextEvent (& event) ;
    }
}
