#include	"compiler.h"
#ifdef GEKKO
#include	<math.h>
#include	"wiiuse/wpad.h"
#include	"pccore.h"
#endif
// #include	<signal.h>
#include	"inputmng.h"
#include	"taskmng.h"
#include	"sdlkbd.h"
#include	"vramhdl.h"
#include	"menubase.h"
#include	"sysmenu.h"


	BOOL	task_avail;

#ifdef GEKKO
extern int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *keysym);
extern int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y);
extern int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y); 

int lastX = 0;
int lastY = 0;
Uint8 lastButtonStateA = SDL_RELEASED;
Uint8 lastButtonStateB = SDL_RELEASED;
Uint8 lastButtonStateP = SDL_RELEASED;
Uint8 lastButtonStateM = SDL_RELEASED;
Uint8 lastButtonState1 = SDL_RELEASED;
Uint8 lastButtonState2 = SDL_RELEASED;
Uint8 lastButtonStateL = SDL_RELEASED;
Uint8 lastButtonStateR = SDL_RELEASED;
Uint8 lastButtonStateU = SDL_RELEASED;
Uint8 lastButtonStateD = SDL_RELEASED;
Uint8 lastButtonStateH = SDL_RELEASED;
Uint8 lastButtonStateFL = SDL_RELEASED;
Uint8 lastButtonStateFR = SDL_RELEASED;

inline BOOL stick_left(Sint8 claX, Sint8 gcX) { return claX < -60 || gcX < -46; }
inline BOOL stick_right(Sint8 claX, Sint8 gcX) { return claX > 60 || gcX > 46; }

inline BOOL stick_up(Sint8 claY, Sint8 gcY) { return claY > 70 || gcY > 54; }
inline BOOL stick_down(Sint8 claY, Sint8 gcY) { return claY < -70 || gcY < -54; }
#endif


void sighandler(int signo) {

	(void)signo;
	task_avail = FALSE;
}


void taskmng_initialize(void) {

	task_avail = TRUE;
}

void taskmng_exit(void) {

	task_avail = FALSE;
}

#ifdef GEKKO
Sint8 classic_analog_val( const expansion_t* exp, bool isX)
{
    float mag = 0.0;
    float ang = 0.0;

    if( exp->type == WPAD_EXP_CLASSIC )
    {
        mag = exp->classic.ljs.mag;
        ang = exp->classic.ljs.ang;
    } else
    {
        return 0.0;
    }

    if( mag > 1.0 ) mag = 1.0;
    else if( mag < -1.0 ) mag = -1.0;
    double val = ( isX ?
        mag * sin( PI * ang / 180.0f ) :
        mag * cos( PI * ang / 180.0f ) );

    return (Sint8)(val * 128.0f);
}
#endif

void taskmng_rol(void) {

	SDL_Event	e;

#ifdef GEKKO
        SDL_keysym keysym;

        WPAD_ScanPads();
        PAD_ScanPads();
        WPADData *wd = WPAD_Data(0);
        Uint16 ki = PAD_ButtonsHeld(0);
        expansion_t exp;
                WPAD_Expansion(0, &exp);
                Sint8 claX = classic_analog_val(&exp, true);
                Sint8 claY = classic_analog_val(&exp, false);
                Sint8 gcX = PAD_StickX(0);
                Sint8 gcY = PAD_StickY(0);

                Uint8 stateA = SDL_RELEASED;
                Uint8 stateB = SDL_RELEASED;
                Uint8 stateP = SDL_RELEASED;
                Uint8 stateM = SDL_RELEASED;
                Uint8 state1 = SDL_RELEASED;
                Uint8 state2 = SDL_RELEASED;
                Uint8 stateL = SDL_RELEASED;
                Uint8 stateR = SDL_RELEASED;
                Uint8 stateU = SDL_RELEASED;
                Uint8 stateD = SDL_RELEASED;
                Uint8 stateH = SDL_RELEASED;
                Uint8 stateFL  = SDL_RELEASED;
                Uint8 stateFR = SDL_RELEASED;

                if(wd->btns_h & WPAD_BUTTON_A) stateA = SDL_PRESSED;
                if(wd->btns_h & WPAD_BUTTON_B) stateB = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_PLUS) || (wd->btns_h & WPAD_CLASSIC_BUTTON_Y) || (ki & PAD_BUTTON_Y)) stateP = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_MINUS) || (wd->btns_h & WPAD_CLASSIC_BUTTON_X) || (ki & PAD_BUTTON_X)) stateM = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_1) || (wd->btns_h & WPAD_CLASSIC_BUTTON_B) || (ki & PAD_BUTTON_B)) state1 = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_2) || (wd->btns_h & WPAD_CLASSIC_BUTTON_A) || (ki & PAD_BUTTON_A)) state2 = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_LEFT) || (wd->btns_h & WPAD_CLASSIC_BUTTON_DOWN) || (ki & PAD_BUTTON_DOWN) || stick_down(claY, gcY)) stateL = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_RIGHT) || (wd->btns_h & WPAD_CLASSIC_BUTTON_UP) || (ki & PAD_BUTTON_UP) || stick_up(claY, gcY)) stateR = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_UP) || (wd->btns_h & WPAD_CLASSIC_BUTTON_LEFT) || (ki & PAD_BUTTON_LEFT) || stick_left(claX, gcX)) stateU = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_DOWN) || (wd->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) || (ki & PAD_BUTTON_RIGHT) || stick_right(claX, gcX)) stateD = SDL_PRESSED;
                if((wd->btns_h & WPAD_BUTTON_HOME) || (wd->btns_h & WPAD_CLASSIC_BUTTON_HOME) || (ki & PAD_BUTTON_START)) stateH = SDL_PRESSED;
                if((wd->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) || (ki & PAD_TRIGGER_L)) stateFL = SDL_PRESSED;
                if((wd->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) || (ki & PAD_TRIGGER_R)) stateFR = SDL_PRESSED;

        if(wd->ir.valid)
        {
                int x = wd->ir.x;
                int y = wd->ir.y;

                if(lastX != x || lastY != y)
                {
                        SDL_PrivateMouseMotion(0, 0, x, y);
                        lastX = x;
                        lastY = y;
                }
                //vertical wiimote
                if(stateA != lastButtonStateA)
                {
                        lastButtonStateA = stateA;
                        SDL_PrivateMouseButton(stateA, SDL_BUTTON_LEFT, x, y);
                }
                if(stateB != lastButtonStateB)
                {
                        lastButtonStateB = stateB;
                        SDL_PrivateMouseButton(stateB, SDL_BUTTON_RIGHT, x, y);
                }
                if(stateP != lastButtonStateP)
                {
                        lastButtonStateP = stateP;
                        keysym.sym = SDLK_F11;
                        SDL_PrivateKeyboard(stateP, &keysym);
                }
                if(stateM != lastButtonStateM)
                {
                        lastButtonStateM = stateM;
                        keysym.sym = SDLK_END;
                        SDL_PrivateKeyboard(stateM, &keysym);
                }
        }
        {

                //horizontal wiimote
        if(!wd->ir.valid)
        {
                if(stateA != lastButtonStateA)
                {
                        lastButtonStateA = stateA;
                        keysym.sym = np2cfg.wpad_button_a;
                        SDL_PrivateKeyboard(stateA, &keysym);
                }
                if(stateB != lastButtonStateB)
                {
                        lastButtonStateB = stateB;
                        keysym.sym = np2cfg.wpad_button_b;
                        SDL_PrivateKeyboard(stateB, &keysym);
                }
                if(stateP != lastButtonStateP)
                {
                        lastButtonStateP = stateP;
                        keysym.sym = np2cfg.wpad_button_plus;
                        SDL_PrivateKeyboard(stateP, &keysym);
                }
                if(stateM != lastButtonStateM)
                {
                        lastButtonStateM = stateM;
                        keysym.sym = np2cfg.wpad_button_minus;
                        SDL_PrivateKeyboard(stateM, &keysym);
                }
        }
                if(state1 != lastButtonState1)
                {
                        lastButtonState1 = state1;
                        keysym.sym = np2cfg.wpad_button_1;
                        SDL_PrivateKeyboard(state1, &keysym);
                }
                if(state2 != lastButtonState2)
                {
                        lastButtonState2 = state2;
                        keysym.sym = np2cfg.wpad_button_2;
                        SDL_PrivateKeyboard(state2, &keysym);
                }
                if(stateL != lastButtonStateL)
                {
                        lastButtonStateL = stateL;
                        keysym.sym = np2cfg.wpad_button_left;
                        SDL_PrivateKeyboard(stateL, &keysym);
                }
                if(stateR != lastButtonStateR)
                {
                        lastButtonStateR = stateR;
                        keysym.sym = np2cfg.wpad_button_right;
                        SDL_PrivateKeyboard(stateR, &keysym);
                }
                if(stateU != lastButtonStateU)
                {
                        lastButtonStateU = stateU;
                        keysym.sym = np2cfg.wpad_button_up;
                        SDL_PrivateKeyboard(stateU, &keysym);
                }
                if(stateD != lastButtonStateD)
                {
                        lastButtonStateD = stateD;
                        keysym.sym = np2cfg.wpad_button_down;
                        SDL_PrivateKeyboard(stateD, &keysym);
                }
                if(stateH != lastButtonStateH)
		{
                        lastButtonStateH = stateH;
                        task_avail = FALSE;
                }
                if(stateFL != lastButtonStateFL)
		{
                        lastButtonStateFL = stateFL;
                        keysym.sym = np2cfg.wpad_button_fleft;
                        SDL_PrivateKeyboard(stateFL, &keysym);
                }
                if(stateFR != lastButtonStateFR)
		{
                        lastButtonStateFR = stateFR;
                        keysym.sym = np2cfg.wpad_button_fright;
                        SDL_PrivateKeyboard(stateFR, &keysym);
                }
        }
#endif

	if ((!task_avail) || (!SDL_PollEvent(&e))) {
		return;
	}
	switch(e.type) {
		case SDL_MOUSEMOTION:
			if (menuvram == NULL) {
			}
			else {
				menubase_moving(e.motion.x, e.motion.y, 0);
			}
			break;

		case SDL_MOUSEBUTTONUP:
			switch(e.button.button) {
				case SDL_BUTTON_LEFT:
					if (menuvram == NULL) {
						sysmenu_menuopen(0, e.button.x, e.button.y);
					}
					else {
						menubase_moving(e.button.x, e.button.y, 2);
					}
					break;

				case SDL_BUTTON_RIGHT:
					break;
			}
			break;

		case SDL_MOUSEBUTTONDOWN:
			switch(e.button.button) {
				case SDL_BUTTON_LEFT:
					if (menuvram == NULL) {
					}
					else {
						menubase_moving(e.button.x, e.button.y, 1);
					}
					break;

				case SDL_BUTTON_RIGHT:
					break;
			}
			break;

		case SDL_KEYDOWN:
			if (e.key.keysym.sym == SDLK_F11) {
				if (menuvram == NULL) {
					sysmenu_menuopen(0, 0, 0);
				}
				else {
					menubase_close();
				}
			}
			else {
				sdlkbd_keydown(e.key.keysym.sym);
			}
			break;

		case SDL_KEYUP:
			sdlkbd_keyup(e.key.keysym.sym);
			break;

		case SDL_QUIT:
			task_avail = FALSE;
			break;
	}
}

BOOL taskmng_sleep(UINT32 tick) {

	UINT32	base;

	base = GETTICK();
	while((task_avail) && ((GETTICK() - base) < tick)) {
		taskmng_rol();
#ifndef WIN32
		usleep(960);
#else
		Sleep(1);
#endif
	}
	return(task_avail);
}

