/* $Id: sdl_main.c,v 1.16 2014/03/06 22:21:46 steffen Exp $ */
#include <SDL.h>
#include "osmroute.h"
#include "system.h"
#include "memoryleak.h"
#include "sdl_port.h"
#include "gui.h"

#define RESOLUTION_X 640
#define RESOLUTION_Y 480

int msdl_eventloop ();
Uint32 msdl_timercallback (Uint32 interval, void *param);
int videoflags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE | SDL_HWPALETTE;

SDL_TimerID cycletimer;
SDL_Surface *screen = NULL;

/*************************************************************************
 * 
 * only needed for testing 
 *
 *************************************************************************/
struct image *img, *img1;

void test_img () {
	struct line_style style;
	d_printf ("*** test_img () ***");

	style.width = 1;
	style.c = color[COLOR_green][3];

	img = gfx_img_alloc (400, 300);
	gfx_clear (img, &color[COLOR_blue][2]);
	
	img1 = gfx_img_load ("sample_01.png");
	gfx_draw_img (img, 10, 10, 150, 150, img1, 150, 150);

	gfx_draw_text (img, 20, 10, "sample_01.png nur ein toller test bla bla", &color[COLOR_yellow][3]);
	gfx_draw_text (img, 20, 30, "sample_01.png nur ein toller test bla bla", &color[COLOR_yellow][3]);
	gfx_draw_text (NULL, 20, 10, "sample_01.png nur ein toller test bla bla", &color[COLOR_yellow][3]);
	gfx_draw_text (NULL, 20, 30, "sample_01.png nur ein toller test bla bla", &color[COLOR_yellow][3]);
	gfx_draw_line (img, 20, 100, 200, 100, style);
};

#define TEST_WIDTH 200
void test_draw () {
	static int once = 1;
	static int _delay = 0;
	static int _tmpx, _tmpy = 0;
	static int _tmpdx = 1, _tmpdy = 1;
	struct line_style style;
	GLfloat vp[] = {500, 210, 540, 210};

	_delay ++;	
	gfx_clear (NULL, &color[COLOR_white][0]);
	
	if (once) {
		once = 0;
		test_img ();
	}
	if (_tmpx > img->width-TEST_WIDTH) _tmpdx = -1;
	if (_tmpx < 0) _tmpdx = 1;
	if (_delay % 1 == 0) _tmpx += _tmpdx;
	
	if (_tmpy > img->height-TEST_WIDTH) _tmpdy = -1;
	if (_tmpy < 0) _tmpdy = 1;
	if (_delay % 20 == 0) _tmpy += _tmpdy;
	
	style.width = 1;
	style.c = color[COLOR_white][3];

	gfx_draw_line (NULL, 0, gfx_screensize.y, gfx_screensize.x, 0, style); 
	gfx_draw_line (NULL, gfx_screensize.x, gfx_screensize.y, 0, 0, style); 

	glColor4f (color[COLOR_green][3].c.r, color[COLOR_green][3].c.g, color[COLOR_green][3].c.b, 1.0f);

	glLineWidth (style.width);
	glColor4f (style.c.c.r, style.c.c.g, style.c.c.b, 1.0f);

	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(2, GL_FLOAT, 0, vp);
    glDrawArrays(GL_LINES,0,2);
    glDisableClientState(GL_VERTEX_ARRAY);

	gfx_draw_img (NULL, 10, 10, TEST_WIDTH, TEST_WIDTH, img, _tmpx, _tmpy);

	style.c = color[COLOR_yellow][3];
	gfx_draw_line (NULL, gfx_screensize.x, 0, 0, 10, style);
	gfx_draw_text (NULL, 10, 300, "sollte gehen", &color[COLOR_red][3]);
	gfx_draw_img (NULL, 20, 320, 150, 150, img1, 200, 200);
	
	gfx_flip();
};



Uint32 msdl_timercallback (Uint32 interval, void *param) {
	app_loop ();

	d_printf ("timer %d", interval);

	return (interval);
};


int msdl_eventloop () {
    SDL_Event event, lastevent;
	int gotevent = 0, keeppoll = 1;
	GUIEvent gevent;
	static int oldkey = 0;

	/* only the last MOUSEMOTION event will handled */
	while (keeppoll && SDL_PollEvent (&lastevent)) {
		event = lastevent;
		gotevent = 1;
		keeppoll = 0;
		if (event.type == SDL_MOUSEMOTION) keeppoll = 1;
	}
	if (gotevent) {
		switch (event.type) {
			case (SDL_QUIT):
				app.status = APPSTATUS_quit;
				break;
			case SDL_VIDEORESIZE: 
				{
					SDL_Surface *scr;
			    	scr = SDL_SetVideoMode( event.resize.w, event.resize.h, 0, videoflags);
			    	if ( !scr )	{
				    	fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) );
				    	SDL_Quit();
						exit (2);
					}
			   		gfx_resize (event.resize.w, event.resize.h);
					draw ();
				}
				break;
			case SDL_MOUSEMOTION:
				gevent.scr_mpos.x = event.motion.x;
				gevent.scr_mpos.y = event.motion.y;
				gevent.mousebtn = event.motion.state;
				gevent.event = EGUI_MOUSEMOVE;
				gui_event (gevent);
				break;

			case SDL_MOUSEBUTTONDOWN:
				gevent.scr_mpos.x = event.motion.x;
				gevent.scr_mpos.y = event.motion.y;
	            gevent.mousebtn = 1;
    	        gevent.event = EGUI_MOUSEPRESSED;
        	    gui_event (gevent);
				break;
	
			case SDL_MOUSEBUTTONUP:
				gevent.scr_mpos.x = event.motion.x;
				gevent.scr_mpos.y = event.motion.y;
	            gevent.mousebtn = 1;
    	        gevent.event = EGUI_MOUSERELEASED;
        	    gui_event (gevent);
			break;

			case SDL_KEYDOWN: {
				int keyu = 0;
				d_printf ("keydown. old_key:%d keysym:%d ukey:%d", oldkey, event.key.keysym.sym, event.key.keysym.unicode);
				if (oldkey != event.key.keysym.sym) {
					keyu = oldkey = event.key.keysym.unicode; 
					gevent.keychar = keyu;
					if (event.key.keysym.sym == SDLK_UP)    gevent.key = GUIKEY_UP;
					else if (event.key.keysym.sym == SDLK_DOWN)    gevent.key = GUIKEY_DOWN;
					else if (event.key.keysym.sym == SDLK_LEFT)    gevent.key = GUIKEY_LEFT;
					else if (event.key.keysym.sym == SDLK_RIGHT)    gevent.key = GUIKEY_RIGHT;
					else gevent.key = event.key.keysym.sym;
					gevent.event = EGUI_KEYCHAR;
					gevent.scr_mpos.x = -1;
					gevent.scr_mpos.y = -1;
					if (gui_event (gevent) != 0) draw();
				}
				} break;
			case SDL_KEYUP:
				d_printf ("keyup. old_key:%d keysym:%d ukey:%d", oldkey, event.key.keysym.sym, event.key.keysym.unicode);
				oldkey = 0;
				break;

			default:
				break;
		}
		return 1;
	}
	else return 0;
};




/*
 * some input handling code.. in sdl it seemed to work fine... used alot 
 * within the bomberclone code.
 * 
 	int key = 0, keyu = 0;

	ki->changed = 0;
	
	if (event->type == SDL_KEYDOWN && keybinput_oldkey != event->key.keysym.sym) {
		key = keybinput_oldkey = event->key.keysym.sym;
		keyu = event->key.keysym.unicode;
	
		if (key == 8) { // BACKSPACE
			if (ki->curpos > 0) {
				ki->curpos--;
				ki->text[ki->curpos] = 0;
				ki->changed = 1;
			}
		}
		else if (ki->type == KEYBI_text && ((keyu >= 32 && keyu <= 126) || (keyu >= 128 && keyu <= 255))) {
			if (ki->curpos < ki->maxlen) {
				ki->text[ki->curpos++] = event->key.keysym.unicode;
				ki->text[ki->curpos] = 0;
				ki->changed = 1;
			}
		}
		else if (ki->type == KEYBI_int && (keyu == '-' || (keyu >= '0' && keyu <= '9'))) {
			if (ki->curpos < 255) {
				ki->text[ki->curpos] = event->key.keysym.unicode;
				if (atoi(ki->text) <= ki->maxlen)
					ki->curpos++;
				ki->text[ki->curpos] = 0;
				ki->changed = 1;
			}
		}
		else if (ki->type == KEYBI_float && (keyu == '-' || keyu == '.' || (keyu >= '0' && keyu <= '9'))) {
			if (ki->curpos < 255) {
				ki->text[ki->curpos++] = event->key.keysym.unicode;
				ki->text[ki->curpos] = 0;
				ki->changed = 1;
			}
		}
		ki->len = strlen (ki->text);
	}
	
	if (keybinput_oldkey == SDLK_RETURN && event->type == SDL_KEYUP)
		keyu = 1;
	else if (keybinput_oldkey == SDLK_ESCAPE && event->type == SDL_KEYUP)
		keyu = -1;
	else
		keyu = 0;
	
	if (event->type == SDL_KEYUP)
		keybinput_oldkey = 0;
	
	return keyu;
*/


int main (int argc, char **argv) {
	SDL_Surface *scr;
	static time_t to;
	time_t t1;

	/* Initialize SDL for video output */
	if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
	fprintf (stderr, "Unable to initialize SDL: %s\n",
			 SDL_GetError ());
		exit (1);
	}

   	scr = SDL_SetVideoMode(RESOLUTION_X, RESOLUTION_Y, 0, videoflags);
   	if ( !scr )	{
    	fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) );
    	SDL_Quit();
		exit (2);
	}
	SDL_EnableUNICODE(1);
	
	app_init (argc, argv);
	gfx_init (RESOLUTION_X, RESOLUTION_Y);
	draw ();
	
	while (app.status != APPSTATUS_quit) {
		while (msdl_eventloop ());

		t1 = time (NULL);
		if (to != t1) {
			app_loop ();
			to = t1;
		}

		draw ();
	}

	SDL_Quit ();
	app_shutdown ();

	return 0;
}


void main_wnd_update () {
	// d_printf ("main_wnd_update : %d", app.status);
	app_loop();
	while (msdl_eventloop ());
}

