/* main.m,
 *
 * This just processes command line arguments.  See game.m for the
 * game loop, and map-editor/redit.m for editor loop.
 */

#include <allegro.h>
#include <getopt.h>
#include <objc/Object.h>
#include <string.h>
#include "common.h"
#include "debug.inc"
#include "game.h"
#include "hiscore.h"
#include "init.h"
#include "input.h"
#include "map-editor/redit.h"
#include "music-ad.h"
#include "newmenu.h"
#include "player.h"
#include "projectiles/all-projs.h"
#include "seborrhea/seborrhea.h"
#include "units/all-units.h"


#ifdef DEBUG_MALLOC_TRACE

/*------------------------------------------------------------*/
/* MTrace.  Note: some memory leaks out of my control.        */
/*------------------------------------------------------------*/

#include <mcheck.h>

@interface mtraceInit
@end

@implementation mtraceInit
+ (void) load
{
    setenv("MALLOC_TRACE", "./memtrace.log", 0);
    mtrace();
}
@end

#endif

static void close_window_hook(void)
{
    game_flags |= FLAG_QUIT;
    emergency_exit = YES;		/* Menus. */
}

/*--------------------------------------------------------------*/

static int main_init(void)
{
    if (game_init() < 0)
	return -1;

    set_window_title(GAME_NAME_AND_VERSION);
    set_window_close_hook(&close_window_hook);
    return 0;
}

static void main_shutdown(void)
{
    game_shutdown();
}

/*--------------------------------------------------------------*/

static void display_compilation_options(void)
{
    const char str[] =			/* Yuck. */
	"\nCompile-time options: "

#ifdef CHEAT
	"CHEAT "
#endif
#ifdef NO_FBLEND
	"NO_FBLEND "
#endif
#ifdef NO_ID3TAGS
	"NO_ID3TAGS "
#endif
#ifdef NO_VIDEO_BITMAPS
	"NO_VIDEO_BITMAPS"
#endif
#ifdef WINFF
	"WINFF (force feedback)"
#endif
	"\n";

    if (strneq(str, "\nCompile-time options: \n"))
	printf(str);
}

static void display_help(void)
{
    printf(GAME_NAME_AND_VERSION "\n"
	   " -J, --jumpstart <map>\tJump straight into the game, bypassing menus\n"
	   " -1\t\t\tOne player mode (when jumpstarting)\n"
	   " -2\t\t\tTwo player mode (when jumpstarting)\n"

	   "\n"				/* Video. */
	   " -f, --fullscreen\tRun in fullscreen mode\n"
	   " -w, --windowed  \tRun in windowed mode\n"
	   " -d, --depth <num>\tTry to run with colour depth <num>\n"
#ifndef NO_VIDEO_BITMAPS
	   " -p, --nopageflipping\tDisable page flipping\n"
	   " -t, --notriplebuffer\tDisable triple buffering\n"
#endif

	   "\n"				/* Input. */
	   " -j, --nojoystick\tDisable joystick support\n"

	   "\n"				/* Sound. */
	   " -m, --mute\t\tDisable sound and music\n"
#ifndef NO_ID3TAGS
	   " -a, --noads\t\tDisable ID3 tag scanning\n"
#endif

	   "\n"				/* REdit options. */
	   " -e, --edit [map]\tRun the map editor, REdit\n"
	   " -W, --width <num>\tRun REdit with width <num>\n"
	   " -H, --height <num>\tRun REdit with height <num>\n"

	   "\n"				/* Extra info. */
	   " -h, --help   \t\tShow this screen and exit\n"
	   " -v, --version\t\tDisplay the name and version number\n");

    display_compilation_options();
}

static void display_version(void)
{
    printf(GAME_NAME_AND_VERSION "\n");
    display_compilation_options();
}

/*--------------------------------------------------------------*/

int main(int argc, char *argv[])
{
    const char *load_filename = NULL;
    BOOL run_editor = NO, mute = NO;
    int gfx_mode = GFX_AUTODETECT, w = 640, h = 480, bpp = 0;
    char c;

    struct option long_opts[] = {	/* Long options. */
	{ "jumpstart",	    required_argument,  0, 'J' },
	{ "fs",		    no_argument,	0, 'f' },
	{ "fullscreen",	    no_argument,	0, 'f' },
	{ "win",	    no_argument,	0, 'w' },
	{ "windowed",	    no_argument,	0, 'w' },
	{ "depth",	    required_argument,	0, 'd' },
	{ "nopageflipping", no_argument,	0, 'p' },
	{ "notriplebuffer", no_argument,	0, 't' },
	{ "noshadow",	    no_argument,	0, 's' },
	{ "nojoy",	    no_argument,	0, 'j' },
	{ "nojoystick",	    no_argument,	0, 'j' },
	{ "mute",	    no_argument,	0, 'm' },
	{ "noads",	    no_argument,	0, 'a' },
	{ "edit",	    optional_argument,	0, 'e' },
	{ "width",	    required_argument,	0, 'W' },
	{ "height",	    required_argument,	0, 'H' },
	{ "help",	    no_argument,	0, 'h' },
	{ "version",	    no_argument,	0, 'v' },
	{ 0, 0, 0, 0 }
    };

    /* Command line options. */
    while ((c = getopt_long(argc, argv, "J:12fwd:ptjmae::W:H:hv", long_opts, NULL)) != -1) {
	switch (c) {
	  case 'J': load_filename = optarg; break;
	  case '1': num_players = 1; break;
	  case '2': num_players = 2; break;

	  case 'f': gfx_mode = GFX_AUTODETECT_FULLSCREEN; break;
	  case 'w': gfx_mode = GFX_AUTODETECT_WINDOWED; break;
	  case 'd': bpp = atoi(optarg); break;

#ifdef NO_VIDEO_BITMAPS
	  case 'p':
	  case 't': break;
#else
	  case 'p': raid_use_page_flipping = NO; break;
	  case 't': raid_use_triple_buffering = NO; break;
#endif

	  case 'j': joy_enabled = NO; break;

	  case 'm': mute = YES; break;
#ifdef NO_ID3TAGS
	  case 'a': break;
#else
	  case 'a': music_ad_enabled = NO; break;
#endif

	  case 'e':
	      run_editor = YES;
	      if (optarg)
		  load_filename = optarg;
	      break;
	  case 'W': w = atoi(optarg); break;
	  case 'H': h = atoi(optarg); break;

	  case '?':		/* Fall through. */
	  case 'h': display_help(); return 0;
	  case 'v': display_version(); return 0;
	}
    }

    /* Data directories. */
    {
	char *path;

	/* 'RAIDEM_DATA_DIR' environment variable. */
	path = getenv("RAIDEM_DATA_DIR");
	if (path) {
	    char canonical_path[PATH_MAX];
	    /* Use the old name for compatability with Allegro 4.0.x */
	    fix_filename_path(canonical_path, path, sizeof canonical_path);
	    seborrhea_add_root_directory(canonical_path);
	}

	/* The path in which Raid'em is currently placed. */
	path = strrchr(argv[0], '/');
	if (path) {
	    *path = '\0';
	    seborrhea_add_root_directory(argv[0]);
	    raid_binary_directory = strdup(argv[0]);
	    *path = '/';
	}

#ifdef __LINUX__
	/* 'RAID_DATA_DIR' defined by Makefile. */
	seborrhea_add_root_directory(RAIDEM_DATA_DIR);
#endif

	/* Current directory. */
	seborrhea_add_root_directory("./");
	if (not raid_binary_directory)
	    raid_binary_directory = strdup("./");
    }

    if (run_editor) {
	if (raid_init(gfx_mode, w, h, bpp, mute) < 0)
	    goto exit;
	if (redit_init() < 0)
	    goto exit;

	redit_loop(load_filename);
	redit_shutdown();
    }
    else {
	srand(time(0));
	if (raid_init(gfx_mode, 640, 480, bpp, mute) < 0)
	    goto exit;
	if (main_init() < 0)
	    goto exit;

	read_high_scores();

	if (load_filename)
	    raid_start_levels(&load_filename, 1, NO, NO);
	else
	    do_newmenu();

	write_high_scores();
	main_shutdown();
    }

 exit:
    raid_shutdown();

    unload_unnecessary_projectile_data();
    unload_unnecessary_unit_data();
    seborrhea_free_root_directories();

    free(raid_binary_directory);

    return 0;
}
END_OF_MAIN()
