#include <string.h>
#include <dumbogg.h>
#include <aldumb.h>
#include "sheep2.h"



DATAFILE *dat;



static DUH *duh = NULL;
static AL_DUH_PLAYER *dp = NULL;

static BITMAP *buffer;



signed char ymove[] = {-1, 0, 1, 0, -1};



static volatile int true_time;
static int logic_time;

static void timer_handler(void)
{
	true_time++;
}
END_OF_FUNCTION(timer_handler);



static void output_winners_txt(void)
{
	FILE *f = fopen("winners.txt", "w");
	if (!f) return;
	fprintf(f,
		"Here are the ending celebrations, as promised:\n\n"
		"http://www.somethingawful.com/firemancomics/mygoodness.htm\n"
		"http://www.somethingawful.com/firemancomics/mygoodness2.htm\n");
	fclose(f);
}



static void play(STATE *state)
{
	true_time = logic_time = 0;
	install_int_ex(&timer_handler, BPS_TO_TIMER(100));
	for (;;) {
		while (logic_time >= true_time) {
			al_poll_duh(dp);
			yield_timeslice();
		}
		while (logic_time < true_time) {
			if (update_logic(state)) return;
			al_poll_duh(dp);
			while (keypressed()) {
				int k = readkey();
				if (k >> 8 == KEY_ESC) return;
			}
			logic_time++;
		}
		draw_level(buffer, state);
		al_poll_duh(dp);
		blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
	}
}



int main(int argc, char *argv[])
{
	LEVELSET *set;
	int levnum;
	int saved;
	int won = 0;
	int nomusic = 0;
	int gfx_mode = GFX_AUTODETECT;
	int gfx_w, gfx_h;
	int i;
	const char *filename = NULL;

	LOCK_VARIABLE(true_time);
	LOCK_FUNCTION(timer_handler);

	if (allegro_init()) return 1;

	set_config_file("sheep2.ini");

	if (install_timer()) return 1;
	if (install_keyboard()) return 1;

	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "--help") == 0) {
			allegro_message(
				"You may pass a filename at the command line;\n"
				"levels will be loaded from the specified file.\n"
				"If no file is specified, levels.sh2 is used.\n"
				"You may also pass the --nomusic flag, useful\n"
				"if you have Winamp, XMMS or a similar source\n"
				"of music set up to listen to already.\n"
#ifndef ALLEGRO_DOS
				"Finally, the --windowed flag will force the\n"
				"program to run in a window (not advisable in\n"
				"general since a palette is used).\n"
#endif
				"Check sheep2.ini for other options.\n");
			return 1;
		} else if (strcmp(argv[i], "--nomusic") == 0) {
			nomusic = 1;
#ifndef ALLEGRO_DOS
		} else if (strcmp(argv[i], "--windowed") == 0) {
			gfx_mode = GFX_AUTODETECT_WINDOWED;
#endif
		} else if (filename) {
			fprintf(stderr, "Warning: ignoring argument '%s'.\n", argv[i]);
		} else {
			filename = argv[i];
		}
	}

	if (!filename) filename = "levels.sh2";

	dat = load_datafile("sheep2.dat");
	if (!dat) {
		allegro_message("Unable to load sheep2.dat!\n");
		return 1;
	}

	set_window_title("Sheep 2");

#ifdef ALLEGRO_DOS
	gfx_w = get_config_int("graphics", "gfx_w", 320);
	gfx_h = get_config_int("graphics", "gfx_h", 200);
#else
	gfx_w = get_config_int("graphics", "gfx_w", 640);
	gfx_h = get_config_int("graphics", "gfx_h", 480);
#endif

	if (set_gfx_mode(gfx_mode, gfx_w, gfx_h, 0, 0)) {
		allegro_message("Unable to set graphics mode! Check sheep2.ini.\n");
		return 1;
	}
	buffer = create_bitmap(gfx_w, gfx_h);
	if (!buffer) goto out_of_memory;
	set_palette(dat[THE_PALETTE].dat);

	set_volume_per_voice(0);

	if (!nomusic && install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == 0) {
		duh = dumb_load_ogg("music.ogg", 1);
		dp = al_start_duh(duh, 1, 0, 1.0f, 4096, 44100);
	}

	set = load_levelset(filename);
	if (!set) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Error loading levels from %s!\n", filename);
		return 1;
	}

	levnum = 0;
	saved = -1;

	for (;;) {
		int k;
		STATE *state;

		clear(buffer);
		text_mode(0);
		if (saved >= 0) {
			textprintf_centre(buffer, font, 160, 0, COL_YELLOW, "You saved %d sheep.", saved);
			textprintf_centre(buffer, font, 160, 8, COL_YELLOW, "You needed %d sheep.", set->level[levnum].sheep_needed);
			if (saved >= set->level[levnum].sheep_needed) levnum++;
		} else {
			textout_centre(buffer, font, "Welcome to Sheep 2", 160, 0, COL_YELLOW);
			textout_centre(buffer, font, set->name, 160, 8, COL_YELLOW);
		}
		if (levnum >= set->n_levels) {
			textout_centre(buffer, font, "CONGRATULATIONS", 80, 16, COL_WHITE);
			textout_centre(buffer, font, "ALL LEVELS COMPLETED", 80, 24, COL_WHITE);
			textout_centre(buffer, font, "Press Enter to", 160, 32, COL_YELLOW);
			textout_centre(buffer, font, "exit the game.", 160, 40, COL_YELLOW);
		} else {
			if (saved < 0 || saved >= set->level[levnum].sheep_needed)
				textout_centre(buffer, font, "PREPARE FOR", 80, 16, COL_WHITE);
			else
				textout_centre(buffer, font, "RETRYING", 80, 16, COL_WHITE);
			textprintf_centre(buffer, font, 80, 24, COL_WHITE, "LEVEL %d", levnum + 1);
			textout_centre(buffer, font, "Press Enter when ready", 160, 32, COL_YELLOW);
			textout_centre(buffer, font, "or Esc to quit.", 160, 40, COL_YELLOW);
		}
		stretch_blit(buffer, screen, 0, 0, 320, 16, 0, screen->cb >> 3, screen->cr, screen->cb >> 3);
		stretch_blit(buffer, screen, 0, 16, 160, 16, 0, (screen->cb >> 1) - (screen->cb >> 3), screen->cr, screen->cb >> 2);
		stretch_blit(buffer, screen, 0, 32, 320, 16, 0, screen->cb - (screen->cb >> 2), screen->cr, screen->cb >> 3);
		do {
			while (!keypressed()) { al_poll_duh(dp); yield_timeslice(); }
			k = readkey() >> 8;
		} while (k != KEY_ENTER && k != KEY_ESC);

		if (levnum >= set->n_levels) {
			if (!exists("winners.txt")) {
				output_winners_txt();
				won = 1;
			}
			break;
		}

		if (k == KEY_ESC) break;

		state = init_state(&set->level[levnum]);
		if (!state) goto out_of_memory;
		play(state);
		saved = state->sheep_saved;
		shut_down_state(state);
		clear(screen);
		set_palette(dat[THE_PALETTE].dat);
	}

	unload_levelset(set);

	al_stop_duh(dp);
	unload_duh(duh);

	set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);

	if (won) {
		allegro_message(
			"Oh dear, I'm so sorry. I know I let you down terribly with\n"
			"that anticlimax. I'm sure you're wondering whether it was\n"
			"really worth the effort to complete this game. If only people\n"
			"would devote more time to designing their game endings, the\n"
			"world would be a so much more fulfilling place. Sadly this\n"
			"author didn't get his priorities straight this time.\n\n"
			"We can be thankful; the ending celebrations were contributed\n"
			"by an anonymous (and oblivious) artist. They can be viewed at:\n\n"
			"http://www.somethingawful.com/firemancomics/mygoodness.htm\n"
			"http://www.somethingawful.com/firemancomics/mygoodness2.htm\n\n"
			"These links have been written to winners.txt for your\n"
			"convenience. Thank you for playing!\n");
	}

	return 0;

	out_of_memory:

	set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
	allegro_message("Out of memory!\n");
	return 1;
}
END_OF_MAIN();
