/*
 * sdl/main.c - SDL library specific port code - main interface
 *
 * Copyright (c) 2001-2002 Jacek Poplawski
 * Copyright (C) 2001-2014 Atari800 development team (see DOC/CREDITS)
 *
 * This file is part of the Atari800 emulator project which emulates
 * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
 *
 * Atari800 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.
 *
 * Atari800 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 Atari800; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

/*
   Thanks to David Olofson for scaling tips!

   TODO:
   - implement all Atari800 parameters
   - turn off fullscreen when error happen
*/

#include "config.h"
#include <SDL.h>
#include <stdio.h>
#include <string.h>

/* Atari800 includes */
#include "atari.h"
#include "../input.h"
#include "log.h"
#include "monitor.h"
#include "platform.h"
#ifdef SOUND
#include "../pokeysnd.h"
#include "../sound.h"
#endif
#ifdef USE_UI_BASIC_ONSCREEN_KEYBOARD
#include "akey.h"
#include "ui_basic.h"
#endif
#include "videomode.h"
#include "sdl/video.h"
#include "sdl/input.h"

void PLATFORM_ConfigInit(void)
{
#if defined(SOUND) && defined(__MINT__)
	/* too slow on Falcon */
	POKEYSND_enable_new_pokey = FALSE;
	/* set default desired sound */
	Sound_desired.freq = 24585;
	Sound_desired.sample_size = 1;
	Sound_desired.channels = 2;
	Sound_desired.buffer_ms = 40;
	/* same as hardware buffer size */
	Sound_latency = 40;
#endif
}

int PLATFORM_Configure(char *option, char *parameters)
{
	return SDL_VIDEO_ReadConfig(option, parameters) ||
	       SDL_INPUT_ReadConfig(option, parameters);
}

void PLATFORM_ConfigSave(FILE *fp)
{
	SDL_VIDEO_WriteConfig(fp);
	SDL_INPUT_WriteConfig(fp);
}

int PLATFORM_Initialise(int *argc, char *argv[])
{
	int i, j;
	int help_only = FALSE;

	for (i = j = 1; i < *argc; i++) {
		if (strcmp(argv[i], "-help") == 0) {
			help_only = TRUE;
		}
		argv[j++] = argv[i];
	}
	*argc = j;

	if (!help_only) {
#if HAVE_WINDOWS_H
		/* Timers are used to avoid one Windows 7 glitch, see src/sdl/input.c */
		if (SDL_InitSubSystem(SDL_INIT_TIMER) != 0) {
			Log_print("SDL_InitSubSystem FAILED: %s", SDL_GetError());
			Log_flushlog();
			exit(-1);
		}
#endif /* HAVE_WINDOWS_H */
	}

	if (!SDL_VIDEO_Initialise(argc, argv)
#ifdef SOUND
	    || !Sound_Initialise(argc, argv)
#endif
	    || !SDL_INPUT_Initialise(argc, argv))
		return FALSE;

	return TRUE;
}

int PLATFORM_Exit(int run_monitor)
{
	SDL_INPUT_Exit();
	if (run_monitor) {
		/* disable graphics, set alpha mode */
		VIDEOMODE_ForceWindowed(TRUE);
#ifdef SOUND
		Sound_Pause();
#endif
		if (MONITOR_Run()) {
			/* set up graphics and all the stuff */
			VIDEOMODE_ForceWindowed(FALSE);
			SDL_INPUT_Restart();
#ifdef SOUND
			Sound_Continue();
#endif
			return 1;
		}
	}

	SDL_VIDEO_Exit();
	Log_flushlog();

	return 0;
}

#if HAVE_WINDOWS_H
static BOOL CtrlHandler(DWORD fdwCtrlType)
{
	switch (fdwCtrlType)
	{
	case CTRL_CLOSE_EVENT:
	case CTRL_BREAK_EVENT:
	case CTRL_LOGOFF_EVENT:
	case CTRL_SHUTDOWN_EVENT:
		/* Perform a normal exit. */
		Atari800_Exit(FALSE);
	case CTRL_C_EVENT:
		/* Ctrl+C is handled in atari.c */
		return TRUE;
	default:
		return FALSE;
	}
}
#endif /* HAVE_WINDOWS_H */

int main(int argc, char **argv)
{
#if HAVE_WINDOWS_H
	/* Handle Windows console signals myself. If not, then closing
	   the console window would cause emulator crash due to the sound
	   subsystem being active. */
	if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE)) {
		Log_print("ERROR: Could not set console control handler");
		return 1;
	}
#endif /* HAVE_WINDOWS_H */

	/* initialise Atari800 core */
	if (!Atari800_Initialise(&argc, argv))
		return 3;

	if(Atari800_start_in_monitor) {
		if (!Atari800_Exit(TRUE))
			/* if 'quit' typed in monitor, exit emulator */
			exit(0);
	}

	/* main loop */
	for (;;) {
		INPUT_key_code = PLATFORM_Keyboard();
#ifdef USE_UI_BASIC_ONSCREEN_KEYBOARD
		if (INPUT_key_code == AKEY_KEYB) {
			Sound_Pause();
			UI_BASIC_in_kbui = TRUE;
			INPUT_key_code = UI_BASIC_OnScreenKeyboard(NULL, 0);
			UI_BASIC_in_kbui = FALSE;
			switch (INPUT_key_code) {
				case AKEY_OPTION: INPUT_key_consol &= (~INPUT_CONSOL_OPTION); break;
				case AKEY_SELECT: INPUT_key_consol &= (~INPUT_CONSOL_SELECT); break;
				case AKEY_START: INPUT_key_consol &= (~INPUT_CONSOL_START); break;
			}

			Sound_Continue();
		}
#endif
		SDL_INPUT_Mouse();
		Atari800_Frame();
		if (Atari800_display_screen)
			PLATFORM_DisplayScreen();
	}
}

/*
vim:ts=4:sw=4:
*/
