#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/time.h>
#include <assert.h>

#define WIDTH 356
#define HEIGHT 292
#define BUFLEN 256

double timediff(struct timeval *tv1, struct timeval *tv2) {
	long dsec, dusec;
	dsec = tv2->tv_sec - tv1->tv_sec;
	dusec = tv2->tv_usec - tv1->tv_usec;
	return (double)dsec + (double)dusec/(1000*1000);
}
int main(int argc, char **argv) {
	SDL_Surface *screen;
	SDL_Event event;
	unsigned char buf[WIDTH*HEIGHT*3];

        Uint32 *bufp;
	Uint32 x,y;
	int frames, last_frames;
	struct timeval tv1, tv2;
	int verbose;
	if (argc==2 && argv[1][0] == '-' && argv[1][1] == 'v' && argv[1][2] == 0)
		verbose = 1;
	else
		verbose = 0;

	if(SDL_Init(SDL_INIT_VIDEO)) {
		puts("failed to initialize SDL");
		exit(EXIT_FAILURE);
	}
	atexit(SDL_Quit);
	
	screen=SDL_SetVideoMode(WIDTH, HEIGHT,
                                32, SDL_HWSURFACE|SDL_DOUBLEBUF);
	
	if(screen==NULL) {
		puts("failed to set video mode");
		exit(EXIT_FAILURE);
	}
	
	bufp = (Uint32 *)screen->pixels;
	frames = last_frames = 0;
	gettimeofday(&tv1, NULL);
	for(;;) {
		double tdiff;
		// skip header
		fgets((char*)buf, BUFLEN, stdin);
		assert(buf[0] == 'P' && buf[1] == '6');
		fgets((char*)buf, BUFLEN, stdin);
		fgets((char*)buf, BUFLEN, stdin);
		if (fread(buf, WIDTH*HEIGHT*3, 1, stdin) != 1) {
			SDL_Quit();
			exit(0);
		}
		for(y=0; y<HEIGHT; y++) {
			for(x=0; x<WIDTH; x++) {
				bufp[x+WIDTH*y]=(buf[x*3+y*WIDTH*3+0]<<16)+(buf[x*3+y*WIDTH*3+1]<<8)+(buf[x*3+y*WIDTH*3+2]);
			}
		}
		SDL_Flip(screen);
		if (verbose) {
			frames++;
			gettimeofday(&tv2, NULL);

			tdiff = timediff(&tv1, &tv2);
			if (tdiff >= 5) {
				printf("%.3f fps\n",
				       frames / tdiff);
				frames = 0;
				memcpy(&tv1, &tv2, sizeof(tv2));
			}
		}

		SDL_PollEvent(&event);
		if((event.type==SDL_KEYDOWN && event.key.keysym.sym=='q') || event.type==SDL_QUIT) {
			SDL_Quit();
			exit(0);
		}

	}
	return 0;
}
	
