/*!
Copyright (C) 2004-2005  Christian Stigen Larsen
Released under the GNU GENERAL PUBLIC LICENSE (GPL) v2 or later.
*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

const char* version = "jpname 1.1";
const char* copyright = "Copyright (C) 2004-2005  Christian Stigen Larsen";
const char* license = "Licensed under the GPL v2 or later.";

static const char* nouns[] = {
"GHOST",
"SHELL",
"PATLABOR",
"METAL",
"GEAR",
"SOLID",
"FANTASY",
"ADVENT",
"CHILDREN",
"LIQUID",
"SNAKE",
"ALCHEMIST",
"DREAM",
"CARNIVAL",
"MARIO",
"BALL",
"FIRE",
"SUMMON",
"NIGHT",
"CRAFT",
"SWORD",
"POKEMON",
"FIRE",
"LEAF",
"NARUTO",
"LABYRINTH",
"MIRROR",
"SONS",
"LIBERTY",
"HACK",
"LIMINALITY",
"RECKONING",
"AKIRA",
"RISE",
"SWORD",
"SIEGE",
"TERROR",
"MACROSS",
"MECH",
"ZODIAC",
"ROBOT",
"STORM",
"NINJA",
"PRINCESS",
"SCROLL",
"FIREFLIES",
"COWBOY",
"BLOOD",
"HELL",
"RIDER",
"VAMPIRE",
"RETURN",
"SNAKE",
"EATER",
"COMPLEX",
"SEED",
"GIRL",
"EXILE",
"PULSE",
"RAIN",
"REUNION",
"HEROES",
"LEGEND",
"POKEMON",
"FIST",
"NORTH",
"STAR",
"OVERFIEND",
"SAMURAI",
"KING",
"DRAGON",
"FIGHTERS",
"SLAYERS",
"OMEN",
"BLADE",
"WARS",
"MEGAMAN",
"MOONLIGHT",
"NOCTURNE",
"SLUG",
"SHODOWN",
"DIMENSION",
"FORTRESS",
"SAILER",
"GEARBOLT",
"EVE",
"PARASITE",
0
};

static const char* adjectives[] = {
"FINAL",
"SUPER",
"SUPER",
"BUSHIDO",
"RED",
"GREEN",
"BLACK",
"MYTHICAL",
"SILVER",
"COSMIC",
"BLUE",
"EXTREME",
"MASKED",
"ELEMENTAL",
"SOUL",
"SPIRITED",
"FULLMETAL",
"LAST",
"PERFECT",
"ROBOTECH",
"NEON",
"MASTER",
"POKEMON",
"LIQUID",
"STANDALONE",
"GREAT",
"ADVANCED",
"BONUS",
"ZERO",
"METAL",
"FULL",
"REUNION",
"PROJECT",
"THUNDERDOME",
"THUNDER",
0
};

static const char* articles[] = {
"IN",
"IN",
"IN",
"OF",
"OF",
"OF",
"OF",
"BEYOND",
"BEYOND",
"BEYOND",
"UNDER",
"UNDER",
"UNDER",
"OVER",
"OVER",
"OVER",
"BEYOND",
"BEYOND",
"BEYOND",
"AFTER",
"AFTER",
"AFTER",
"EVANGELION",
"GHOST",
"SOUL",
0,
};

static const char* numbers[] = {
"II",
"III",
"IV",
"V",
"VI",
"VII",
"VIII",
"IX",
"X",
"XI",
"XII",
"XIII",
"XIV",
"XV",
"XVI",
"XVII",
"XVIII",
0
};

int getrand(const int min, const int max) {
	return min + (int)((float)max*rand()/(RAND_MAX+1.0));
}

const char* randname(const char* arr[], const int size) {
	return arr[getrand(0, size - 1)];
}

int percenthit(const int percent) {
	if ( getrand(1, 100) <= percent )
		return 1;
	return 0;
}

const char* getadj() {
	return randname(adjectives, sizeof adjectives/sizeof(char*));
}

const char* getnoun() {
	return randname(nouns, sizeof nouns/sizeof(char*));
}

const char* getnumber() {
	return randname(numbers, sizeof numbers/sizeof(char*));
}

const char* getart() {
	return randname(articles, sizeof articles/sizeof(char*));
}

void maketitle(const int minwords, const int maxwords,
	const int chanceArticle,
	const int chanceStartAdjective,
	const int chanceThe,
	const int chanceSequel,
	const int chanceAdj)
{
	int i, words = getrand(minwords, maxwords);

	for ( i=0; i<words; ++i ) {
		if ( i>0 )
			printf(" ");

		int usedadj = 0;
		if ( i==0 && percenthit(chanceStartAdjective) ) {
			printf("%s ", getadj());
			usedadj = 1;
		}

		if ( !usedadj && i>0 && percenthit(chanceArticle) )
			printf("%s ", getart());

		if ( !usedadj && percenthit(chanceThe) )
			printf("THE ");

		if ( !usedadj && percenthit(chanceAdj) ) {
			printf("%s ", getadj());

			if ( percenthit(chanceAdj) )
				printf("%s ", getadj());
		}

		printf("%s", getnoun());
	}

	if ( percenthit(chanceSequel) )
		printf(" %s", getnumber());
}



int main(int argc, char* argv[]) {
	puts(version);
	puts(copyright);
	puts(license);
	puts("");

	// use BOTH microsecond precision AND pid as seed
	struct timeval tv;
	gettimeofday(&tv, 0);	
	srand(tv.tv_usec * getpid());

	int titles = argc>1? atoi(argv[1]) : 1;
	if ( titles <= 0 ) titles = 1;
	
	int minWords = 1;
	int maxWords = 3;
	int chanceArticle = 100;
	int chanceStartAdj = 67;
	int chanceThe = 44;
	int chanceSequel = 48;
	int chanceAdjective = 21;
	int chanceSubtitle = 19;

	int i;
	for ( i=0; i<titles; ++i ) {
		maketitle(minWords, maxWords, chanceArticle,
			chanceStartAdj, chanceThe, chanceSequel,
			chanceAdjective);

		if ( percenthit(chanceSubtitle) ) {
			printf(": ");
			maketitle(1, maxWords>2? maxWords-2 : maxWords, chanceArticle,
			chanceStartAdj, chanceThe, 0,
			chanceAdjective);
		}

		printf("\n");
	}

	return 0;
}
