/***************************************************************************
 *   Copyright (C) 2005 by Berislav Kovacki                                *
 *   beca@sezampro.yu                                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <SDL.h>
#include "interlogic.h"
#include "mainmenu.h"
#include "splash.h"
#include "password.h"
#include "levels.h"
#include "credits.h"

#ifdef DREAMCAST
	#include <kos.h>
	#include <SDL_dreamcast.h>
	KOS_INIT_FLAGS(INIT_DEFAULT);
	extern uint8 romdisk[];
	KOS_INIT_ROMDISK(romdisk);
#endif

#define STATE_STARTUP   0
#define STATE_SPLASH    1
#define STATE_MAINMENU  2
#define STATE_LEVELS    3
#define STATE_CREDITS   4
#define STATE_PASSWORD  5

#define SDL_PushQuitEvent() {SDL_Event event; \
            event.type = SDL_QUIT; SDL_PushEvent(&event); }

static const char _program_title[] = "InterLOGIC V0.3";

static int interlogic_state = STATE_STARTUP;

SDL_Surface* interlogic_initialize_video();
int interlogic_keyboard(SDL_Surface* screen, Uint8 state, SDLKey key);
int interlogic_process_events(SDL_Surface* screen);
int interlogic_render(SDL_Surface* screen);
int interlogic_exit_state(SDL_Surface* screen);

//Simplified for Dreamcast
SDL_Surface* interlogic_initialize_video()
{
  SDL_Surface*   screen = NULL;
  SDL_VideoInfo* pSDLVideoInfo;
  pSDLVideoInfo = SDL_GetVideoInfo();
  
  #ifdef DREAMCAST
  	//screen = SDL_SetVideoMode(640, 480, pSDLVideoInfo->vfmt->BitsPerPixel, SDL_SWSURFACE);
  	screen = SDL_SetVideoMode(640, 480, pSDLVideoInfo->vfmt->BitsPerPixel, SDL_HWSURFACE | SDL_DOUBLEBUF); //16 bits
  #else
  	screen = SDL_SetVideoMode(640, 480, pSDLVideoInfo->vfmt->BitsPerPixel, SDL_HWSURFACE | SDL_DOUBLEBUF);
	SDL_WM_SetCaption(_program_title, _program_title);
  #endif


  return screen;
}

int interlogic_process_events(SDL_Surface* screen)
{
  SDL_Event      event;
  int bExitGame = 0;

  while (SDL_PollEvent(&event))
  {
    switch (event.type)
    {

      case SDL_KEYDOWN:
        interlogic_keyboard(screen, event.key.state,
          event.key.keysym.sym);
        break;

      case SDL_QUIT:
        bExitGame = 1;
        break;
    }
  }

  return bExitGame;
}

int interlogic_render(SDL_Surface* screen)
{
  switch (interlogic_state)
  {
    case STATE_SPLASH:   splash_render(screen);   break;
    case STATE_MAINMENU: mainmenu_render(screen); break;
    case STATE_LEVELS:   levels_render(screen);   break;
    case STATE_PASSWORD: password_render(screen); break;
    case STATE_CREDITS:  credits_render(screen);  break;
    default: return 0;
  }

  return SDL_Flip(screen);
}

int interlogic_exit_state(SDL_Surface* screen)
{
  switch (interlogic_state)
  {
    case STATE_SPLASH:   splash_uninitialize(screen);   break;
    case STATE_MAINMENU: mainmenu_uninitialize(screen); break;
    case STATE_LEVELS:   levels_uninitialize(screen);   break;
    case STATE_PASSWORD: password_uninitialize(screen); break;
    case STATE_CREDITS:  credits_uninitialize(screen);  break;
    case STATE_STARTUP: break;
    default: return 0;
  }

  return -1;
}

int interlogic_keyboard(SDL_Surface* screen, Uint8 state, SDLKey key)
{
  switch (interlogic_state)
  {
    case STATE_SPLASH:   splash_keyboard(screen, state, key);   break;
    case STATE_MAINMENU: mainmenu_keyboard(screen, state, key); break;
    case STATE_LEVELS:   levels_keyboard(screen, state, key);   break;
    case STATE_PASSWORD: password_keyboard(screen, state, key); break;
    case STATE_CREDITS:  credits_keyboard(screen, state, key);  break;
    default: return 0;
  }

  return -1;
}

int interlogic_switch_state(SDL_Surface* screen, int code)
{
  interlogic_exit_state(screen);

  switch (interlogic_state)
  {
    case STATE_STARTUP:
      interlogic_state = STATE_SPLASH;
      splash_initialize(screen);
      break;

    case STATE_SPLASH:
      interlogic_state = STATE_MAINMENU;
      mainmenu_initialize(screen);
      break;

    case STATE_MAINMENU:
      switch (code)
      {
        case 0:
          interlogic_state = STATE_LEVELS;
          levels_initialize(screen, 0);
          break;

        case 1:
          interlogic_state = STATE_PASSWORD;
          password_initialize(screen);
          break;

        case 2:
          interlogic_state = STATE_CREDITS;
          credits_initialize(screen);
          break;

        case 3:
          interlogic_state = STATE_STARTUP;
          SDL_PushQuitEvent();
          break;
      }
      break;

    case STATE_CREDITS:
      interlogic_state = STATE_MAINMENU;
      mainmenu_initialize(screen);
      break;

    case STATE_PASSWORD:
      if (code == -1)
      {
        interlogic_state = STATE_MAINMENU;
        mainmenu_initialize(screen);
      }
      else
      {
        interlogic_state = STATE_LEVELS;
        levels_initialize(screen, code);
      }
      break;

    case STATE_LEVELS:
      if (code == -1)
      {
        interlogic_state = STATE_MAINMENU;
        mainmenu_initialize(screen);
      }
      else
      {
        interlogic_state = STATE_LEVELS;
        levels_initialize(screen, code);
      }
      break;
  }

  return -1;
}

int main(int argc, char *argv[])
{
  SDL_Surface*   screen;

  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
  {
    SDL_Quit();
  }

  if (!(screen = interlogic_initialize_video()))
  {
    SDL_Quit();
  }

  #ifdef DREAMCAST
  
  	//Configure PAD
  	SDL_DC_MapKey(0,SDL_DC_START,SDLK_RETURN);
	SDL_DC_MapKey(0,SDL_DC_LEFT,SDLK_LEFT); 
	SDL_DC_MapKey(0,SDL_DC_RIGHT,SDLK_RIGHT); 
	SDL_DC_MapKey(0,SDL_DC_UP,SDLK_UP); 
	SDL_DC_MapKey(0,SDL_DC_DOWN,SDLK_DOWN); 
	SDL_DC_MapKey(0,SDL_DC_L,SDLK_ESCAPE); //right button on the controller
	SDL_DC_MapKey(0,SDL_DC_R,SDLK_ESCAPE);
	SDL_DC_MapKey(0,SDL_DC_A,SDLK_RETURN); 
	SDL_DC_MapKey(0,SDL_DC_B,SDLK_F1); 
	SDL_DC_MapKey(0,SDL_DC_X,SDLK_RSHIFT); //accept letter in password
	SDL_DC_MapKey(0,SDL_DC_Y,SDLK_BACKSPACE); //delete letter in password
  
  	SDL_JoystickOpen(0);
  	SDL_JoystickEventState(SDL_ENABLE);
  	SDL_ShowCursor(SDL_DISABLE); //no cursor, all by keyboard
  	
  	SDL_Event event;
    while(SDL_PollEvent(&event))
    	SDL_Delay(20);
  #endif

  interlogic_switch_state(screen, 0);

  while (!interlogic_process_events(screen))
  {
    interlogic_render(screen);
  }

  interlogic_exit_state(screen);

  SDL_Quit();
  return 0;
}
