#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include "defs.h"

#ifdef SUPPORT_SDLLIB

#include	<signal.h>

#include	"term.h"
#include	"errors.h"
#include	"vc.h"
#include 	"hzinput.h"
#include	"mouse.h"
#include 	"ccesdl.h"

static int SDLProcessSpecialKeys(SDLKey sym, int tty_fd)
{
	char buf[16];

	switch (sym)
    {

    case SDLK_LEFT:
        write(tty_fd, "\033[D", 3);
        return 1;
    case SDLK_RIGHT:
        write(tty_fd, "\033[C", 3);
        return 1;
    case SDLK_UP:
        write(tty_fd, "\033[A", 3);
        return 1;
    case SDLK_DOWN:
        write(tty_fd, "\033[B", 3);
        return 1;

    case SDLK_HOME:
        write(tty_fd, "\033[H", 3); /* working in bash/vim */
        return 1;
    case SDLK_INSERT:
		write(tty_fd, "\033[2~", 4);  /* working in bash */
		return 1;

	case SDLK_END:
		write(tty_fd, "\033[4~", 4);   /* working in bash */
		return 1;
	case SDLK_PAGEUP:
		write(tty_fd, "\033[5~", 4);  /* working in bash */
		return 1;
	case SDLK_PAGEDOWN:
		write(tty_fd, "\033[6~", 4);  /* working in bash */
		return 1;

	}

	return 0;  /* not processed */
}

static void SDLProcessKeyEvents(SDL_Event *ev, int tty_fd)
{
	Uint16 unicode = ev->key.keysym.unicode;
	SDLKey sym = ev->key.keysym.sym;  /* SDL's virtual key */
	SDLMod mod = ev->key.keysym.mod;  

#ifdef DEBUG
	fprintf(stderr, "KeyRelease: key=0x%x(%c) mod=0x%x unicode=0x%x\r\n", sym, 
			sym > 0x20 && sym < 0x7F ? sym : ' ' , mod, unicode);
#endif

#ifdef __QNX__  /* QNX is using Ctrl-Alt-N for terminal switching ! */
	if ((mod & KMOD_SHIFT) && (mod & KMOD_ALT))  /* Shift-Alt-N */
#else
	if ((mod & KMOD_CTRL) && (mod & KMOD_ALT))   /* Ctrl-Alt- */
#endif
	{

		if (sym >= SDLK_0 && sym <= SDLK_9)
		{
	 		SetCurrentInputMethod( sym - SDLK_0);
			return;
		}

#ifdef __QNX__
	}
	if ((mod & KMOD_CTRL) && (mod & KMOD_ALT))  /* Ctrl-Alt- */
	{
#else
		else
#endif
		switch(sym)
		{
		case SDLK_a:
       		TermOpen();
       		TextRepaintAll(curCon);
       		return;
		case SDLK_e:
			ChangeSystemEncoding(-1);  /* switch to next available one! */
            return;
		case SDLK_n:
       		ChangeTerm(1);
       		return;
		case SDLK_p:
       		ChangeTerm(0);
       		return;
       	
		case SDLK_x:
#ifdef HAVE_KILL
	  		if ( curCon->terminate == 0 )
           		kill( curCon->childPid, SIGHUP);
#endif
       		return;
    	case SDLK_r:
       		TextRepaintAll(curCon);
          	return;
		case SDLK_l:
			ToggleAssociateMode();
			return;
		case SDLK_k:
			ChangePinyinZhuyinKeyboardMap();
			return;
		}	
	}
	else if (mod & KMOD_CTRL)
	{
		switch(sym)
		{
		case SDLK_PERIOD:
			ToggleChinesePunct();
			return;
       	case SDLK_SPACE:
			ToggleInputMethod();;
       		return;
		}
	}
	else if ((mod & KMOD_SHIFT) && (mod & KMOD_ALT))
	{

		switch(sym)
		{
		case SDLK_SPACE:
			ToggleHalfFull();
          	return;
		}
	}

	if (!SDLProcessSpecialKeys(sym, tty_fd))  /* handle Fn, Home, End, etc */
	{

#ifdef __QNX__
	if (unicode == 0 && mod == 0 && (sym <= 0x1B || sym == 0x7F) )
		unicode = sym;
	else if ( unicode == 0 && (mod == KMOD_LCTRL || mod == KMOD_RCTRL) &&
			  sym >= 0x61 && sym <= 0x7a)
		unicode = sym - 0x60; /* Ctrl-A~Z 0x01~0x1A */
#endif
	if (unicode > 0x0 && unicode < 0xff) HZFilter(tty_fd, unicode);
	}
}

static void SDLProcessMouseEvents(SDL_Event *ev, int tty_fd)
{
	u_char btn;
    static int  dx, dy;
	
	switch(ev->type)
	{
	case SDL_MOUSEBUTTONUP:
	case SDL_MOUSEBUTTONDOWN:
		btn = (ev->button.button == SDL_BUTTON_LEFT   ? MOUSE_LFT : 0) |
			  (ev->button.button == SDL_BUTTON_RIGHT  ? MOUSE_RGT : 0) |
			  (ev->button.button == SDL_BUTTON_MIDDLE ? MOUSE_MID : 0);
		if (ev->type == SDL_MOUSEBUTTONUP)
			mInfo.stat &= ~btn;
		else mInfo.stat |= btn;
		break;

	case SDL_MOUSEMOTION: /* absolute X/Y, SDL send this in X Windows & in console? */
		mInfo.dx = ev->motion.x/fontwidth - mInfo.x;
		mInfo.dy = ev->motion.y/dispInfo.glineChar - mInfo.y;
		break;
	}
	
	mInfo.sw = MOUSE_LIFETIME;
	HandleMouseSelection();
}

void HandleSDLEvents(int tty_fd)
{
	SDL_Event event;

	while(SDL_POLLEVENT(&event))  /* PollEvent is not blocking */
	{
		switch(event.type)
		{
    	case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
		case SDL_MOUSEMOTION:
			SDLProcessMouseEvents(&event, tty_fd);
			break;
	
    	case SDL_KEYDOWN: /* use KEYDOWN is better than KEYUP */
			SDLProcessKeyEvents(&event, tty_fd);
			break;
		} /* switch */
	}
	
}

#endif  /* SUPPORT_SDLLIB */
