#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "SDL.h"
#include "SDL_thread.h"
#include "SDLUtils.h"

static int doneYet = 0;
static SDL_cond *eventWait = NULL;
static SDL_mutex *eventLock = NULL;
static int num = 0;

static int runThread(void *nothing)
{
  int i;
  int val;
  SDL_Event ev;

  ev.type = SDL_USEREVENT;
  ev.user.code = 0;
  ev.user.data1 = 0;
  ev.user.data2 = 0;

  i = 0;
  while (!doneYet)
  {
    ev.user.data1 = (void *)i;
    SDL_LockMutex(eventLock);
    while ((!doneYet) && (-1 == (val = SDL_PushEvent(&ev))))
    {
      SDL_CondWait(eventWait, eventLock);
    }
    SDL_UnlockMutex(eventLock);
    SDL_CondSignal(eventWait);
    num++;
    //printf("%d\n", num);

    i++;
  }

  return 0;
}

Uint32 eventTimer(Uint32 interval, void *param)
{
  SDL_CondBroadcast(eventWait);
  //trace();
  return interval;
}

int WaitEvent(SDL_Event *ev)
{
  int val = 0;

  SDL_LockMutex(eventLock);
  while (0 == (val = SDL_PollEvent(ev)))
  {
    SDL_CondWait(eventWait, eventLock);
  }
  SDL_UnlockMutex(eventLock);
  SDL_CondSignal(eventWait);

  num--;
  //printf("%d\n", num);

  return val;
}

int main(int argc, char **argv)
{
  int count = 0;
  double rate = 0.0;
  Uint32 start = 0;
  Uint32 end = 0;
  Uint32 limit = (10 * 1000);
  SDL_Thread *thread = NULL;
  SDL_Event ev;

  if (2 <= argc)
  {
    limit = 1000 * atoi(argv[1]);
  }

  SDL_Init(SDL_INIT_EVENTTHREAD |
           SDL_INIT_VIDEO | 
           SDL_INIT_TIMER | 
           SDL_INIT_NOPARACHUTE);

  eventWait = SDL_CreateCond();
  eventLock = SDL_CreateMutex();

  thread = SDL_CreateThread(runThread, NULL);
  SDL_AddTimer(10, eventTimer, NULL);
  //printf("%08x\n", (int)thread);

  start = SDL_GetTicks();
  while ((SDL_GetTicks() < (start + limit)) &&
         WaitEvent(&ev))
  {
    //printf("time=%u\n", SDL_GetTicks());
    switch (ev.type)
    {
    case SDL_USEREVENT:
      //printf("count=%d data1=%d\n", count, (int)ev.user.data1);
      count++;
      break;

    case SDL_QUIT:
      printf("got here\n");
      exit(0); // this isn't supposed to happen
      break;

    default:
      printSDLEvent(&ev);
      break;
    }
  }
  doneYet = 1;
  SDL_CondSignal(eventWait);    // it might be waiting
  SDL_WaitThread(thread, NULL); // wait for it to die

  end = SDL_GetTicks();

  rate = ((double)count) / (((double)(end - start)) / 1000.0);
  printf("events/second=%f\n", rate);

  SDL_Quit();
  exit(0);
}
