#include <unistd.h>
#include <stdio.h>
#include <string.h>

int paropen;
int width = 78;

char *countries[] = {
"AD", "Andorra",
"AE", "United Arab Emirates",
"AF", "Afghanistan",
"AG", "Antigua and Barbuda",
"AI", "Anguilla",
"AL", "Albania",
"AM", "Armenia",
"AN", "Netherlands Antilles",
"AO", "Angola",
"AQ", "Antarctica",
"AR", "Argentina",
"AS", "American Samoa",
"AT", "Austria",
"AU", "Australia",
"AW", "Aruba",
"AZ", "Azerbaijan",
"BA", "Bosnia and Herzegovina",
"BB", "Barbados",
"BD", "Bangladesh",
"BE", "Belgium",
"BF", "Burkina Faso",
"BG", "Bulgaria",
"BH", "Bahrain",
"BI", "Burundi",
"BJ", "Benin",
"BM", "Bermuda",
"BN", "Brunei",
"BO", "Bolivia",
"BR", "Brazil",
"BS", "Bahamas",
"BT", "Bhutan",
"BV", "Bouvet Island",
"BW", "Botswana",
"BY", "Belarus",
"BZ", "Belize",
"CA", "Canada",
"CC", "Cocos",
"CD", "Congo, Democratic Republic",
"CF", "Central African Republic",
"CG", "Congo, Republic of",
"CH", "Switzerland",
"CI", "Cote d'Ivoire",
"CK", "Cook Islands",
"CL", "Chile",
"CM", "Cameroon",
"CN", "China",
"CO", "Colombia",
"CR", "Costa Rica",
"CU", "Cuba",
"CV", "Cape Verde",
"CX", "Christmas Island",
"CY", "Cyprus",
"CZ", "Czech Republic",
"DE", "Germany",
"DJ", "Djibouti",
"DK", "Denmark",
"DO", "Dominican Republic",
"DM", "Dominica",
"DZ", "Algeria",
"EC", "Ecuador",
"EE", "Estonia",
"EG", "Egypt",
"EH", "Western Sahara",
"ER", "Eritrea",
"ES", "Spain",
"ET", "Ethiopia",
"FI", "Finland",
"FJ", "Fiji",
"FK", "Falkland",
"FM", "Micronesia",
"FO", "Faroe Islands",
"FR", "France",
"GA", "Gabon",
"GB", "United Kingdom",
"GD", "Grenada",
"GS", "South Georgia",
"GE", "Georgia",
"GF", "French Guiana",
"GG", "Guernsey",
"GH", "Ghana",
"GI", "Gibraltar",
"GL", "Greenland",
"GM", "Gambia",
"GP", "Guadeloupe",
"GQ", "Equatorial Guinea",
"GW", "Guinea-Bissau",
"PG", "Papua New Guinea",
"GN", "Guinea",
"GR", "Greece",
"GT", "Guatemala",
"GU", "Guam",
"GY", "Guyana",
"HK", "Hong Kong",
"HM", "Heard",
"HN", "Honduras",
"HR", "Croatia",
"HT", "Haiti",
"HU", "Hungary",
"ID", "Indonesia",
"IE", "Ireland",
"IL", "Israel",
"IM", "Man",
"IO", "British Indian Ocean Territory",
"IN", "India",
"IQ", "Iraq",
"IR", "Iran",
"IS", "Iceland",
"IT", "Italy",
"JE", "Jersey",
"JM", "Jamaica",
"JO", "Jordan",
"JP", "Japan",
"KE", "Kenya",
"KG", "Kyrgyzstan",
"KH", "Cambodia",
"KI", "Kiribati",
"KM", "Comoros",
"KN", "Kitts",
"KP", "Korea, North",
"KR", "Korea, South",
"KW", "Kuwait",
"KY", "Cayman Islands",
"KZ", "Kazakhstan",
"LA", "Laos",
"LB", "Lebanon",
"LC", "Saint Lucia",
"LI", "Liechtenstein",
"LK", "Sri Lanka",
"LR", "Liberia",
"LS", "Lesotho",
"LT", "Lithuania",
"LU", "Luxembourg",
"LV", "Latvia",
"LY", "Libya",
"MA", "Morocco",
"MC", "Monaco",
"MD", "Moldova",
"MG", "Madagascar",
"MH", "Marshall Islands",
"MK", "Macedonia",
"ML", "Mali",
"MM", "Burma",
"MN", "Mongolia",
"MO", "Macau",
"MP", "Northern Mariana Islands",
"MQ", "Martinique",
"MR", "Mauritania",
"MS", "Montserrat",
"MT", "Malta",
"MU", "Mauritius",
"MV", "Maldives",
"MW", "Malawi",
"MX", "Mexico",
"MY", "Malaysia",
"MZ", "Mozambique",
"NA", "Namibia",
"NC", "New Caledonia",
"NF", "Norfolk Island",
"NG", "Nigeria",
"NE", "Niger",
"NI", "Nicaragua",
"NL", "Netherlands",
"NO", "Norway",
"NP", "Nepal",
"NR", "Nauru",
"NU", "Niue",
"NZ", "New Zealand",
"OM", "Oman",
"PA", "Panama",
"PC", "Paracel Islands",
"PE", "Peru",
"PF", "French Polynesia",
"PH", "Philippines",
"PK", "Pakistan",
"PL", "Poland",
"PM", "Saint Pierre and Miquelon",
"PN", "Pitcairn Islands",
"PR", "Puerto Rico",
"PS", "Palestine",
"PT", "Portugal",
"PW", "Palau",
"PY", "Paraguay",
"QA", "Qatar",
"RE", "Reunion",
"RO", "Romania",
"RU", "Russia",
"RW", "Rwanda",
"SA", "Saudi Arabia",
"SB", "Solomon Islands",
"SC", "Seychelles",
"SD", "Sudan",
"SE", "Sweden",
"SG", "Singapore",
"SH", "Saint Helena",
"SI", "Slovenia",
"SJ", "Svalbard",
"SK", "Slovakia",
"SL", "Sierra Leone",
"SM", "San Marino",
"SN", "Senegal",
"SO", "Somalia",
"SR", "Suriname",
"ST", "Sao Tome and Principe",
"SV", "El Salvador",
"SY", "Syria",
"SZ", "Swaziland",
"TC", "Turks and Caicos Islands",
"TD", "Chad",
"TF", "French Southern and Antarctic Lands",
"TG", "Togo",
"TH", "Thailand",
"TJ", "Tajikistan",
"TK", "Tokelau",
"TM", "Turkmenistan",
"TN", "Tunisia",
"TO", "Tonga",
"TP", "Timor",
"TR", "Turkey",
"TT", "Trinidad and Tobago",
"TV", "Tuvalu",
"TW", "Taiwan",
"TZ", "Tanzania",
"UA", "Ukraine",
"UG", "Uganda",
"US", "United States",
"UY", "Uruguay",
"UZ", "Uzbekistan",
"VA", "Holy See",
"VC", "Vincent",
"VE", "Venezuela",
"VG", "British Virgin Islands",
"VI", "Virgin Islands",
"VN", "Vietnam",
"VU", "Vanuatu",
"WF", "Wallis and Futuna",
"WS", "Samoa",
"YE", "Yemen",
"YT", "Mayotte",
"YU", "Yugoslavia",
"ZA", "South Africa",
"ZM", "Zambia",
"ZW", "Zimbabwe"
};

void reformat(char *str)
{
char buf[65536];
int i, ip, j, k, kp, kini, l;

   strcpy(buf, str); 
   l = strlen(buf);
   i = 0;
   j = 1;
   k = 1;
   str[0] = ' ';
   if (index(buf, ':')) 
      kini = 4;
   else
      kini = 2;
 
   while (i<l) {
      ip = i;
      while (buf[ip] && !isspace(buf[ip])) ++ip;
      if (k+ip-i+1<width) {
         str[j] = ' ';
	 ++j;
         ++k;
      } else {
	 k = kini;
	 str[j] = '\n';
	 ++j;
	 for (kp=0; kp<kini; kp++) {
	    str[j] = ' ';
	    ++j;
	 }
      }
      for (kp=i; kp<ip; kp++) {
         str[j] = buf[kp];
	 ++j;
         ++k;
      }
      i = ip+1;
   }
   str[j] = '\0';
}

void nice_print(FILE *fo, char *buf, int mode)
{
   if (!*buf) return;
   reformat(buf);
   fprintf(fo, "%s\n", buf);
   if (mode) fprintf(fo, "\n");
   *buf = '\0';
}

int main(int argc, char **argv)
{
   FILE *fd, *fo;
   char filename[256];
   char name[512];
   char buf[512];
   char out[512];
   char title[512];
   char line[512];
   char textbuf[65536];
   char *finput;
   char *ptr;
   int found, year, l, n, start = 0, skip=0, numcountries;
   int verbose = 0;

   numcountries = sizeof(countries)/(2*sizeof(char *));

   for (l=1; l<argc; l++) {
       if (l<argc-1 && !strcmp(argv[l], "-f")) finput = strdup(argv[++l]);
       if (l<argc-1 && !strcmp(argv[l], "-y")) year = atoi(argv[++l]);
       if (!strcmp(argv[l], "-v")) verbose = 1;
   }   
	
   fd = fopen(finput, "r");
   if (!fd) return;
   n = 0;
   *textbuf = '\0';

   while (ptr=fgets(buf, 510, fd)) {
      if (!start && strstr(buf, "Introduction") && strstr(buf, "Top_of_Page"))
	 start = 1;
      if (!start) continue;
         else
      if (start==1 && verbose) {
	 fprintf(stderr, "Starting %s ...\n", finput);
	 start = 2;
      }
      if (ptr=strstr(buf, "Top_of_Page")) {
	 nice_print(fo, textbuf, 1);
         if (ptr>buf) --ptr;
	 while (isspace(*ptr) && ptr>buf) --ptr;
	 ++ptr;
	 ++n;
         if (verbose) fprintf(stderr, "Section %d\n", n); 	 
         *ptr = '\0';
	 if (ptr=strstr(buf, "Introduction")) {
	     ptr += 12;
	     while (isspace(*ptr)) ++ptr;
	     strcpy(name, ptr);
	     ptr = name + strlen(name) -1;
	     while (ptr>name && isspace(*ptr)) {
	       *ptr = '\0';
	       --ptr;
	     }
	     found = 0;
   	     for (l=0; l<numcountries; ++l) {
		if (strstr(name, countries[2*l+1])) {
		   sprintf(filename, "%s.txt", countries[2*l]);
		   filename[0] += 32;
		   filename[1] += 32;
		   found = 1;
		   break;
		}
	     }
             if (!found) {
	        strncpy(filename, name, 255);
		filename[255] = '\0';
		for (l=0; l<strlen(filename); l++) {
		   if (filename[l]==' ') filename[l]='_';
		}
	     }
             fo = fopen(filename, "w");
	     fprintf(fo, "%s\n\n", name);
	     ptr = index(name, ',');
	     if (ptr) *ptr = '\0';
	     ptr = name + strlen(name) -1;
	     while (ptr>name && isspace(*ptr)) {
	       *ptr = '\0';
	       --ptr;
	     }
	     
	 }
	 if (ptr=strstr(buf, name)) {
	     --ptr;
             while (ptr>buf && isspace(*ptr)) --ptr;
	     ++ptr;
	     *ptr = '\0';     
	 }
         ptr = buf;
	 while (isspace(*ptr)) ++ptr;
	 fprintf(fo, "§%d. %s %s\n\n", n, name, ptr);
      } else
      if (ptr=strstr(buf, "[Definition] [Field_Listing]")) {
	 nice_print(fo, textbuf, 1);
	 skip = ptr-buf;
         if (ptr>buf) --ptr;
	 while (isspace(*ptr) && ptr>buf) --ptr;
	 ++ptr;
         *ptr = '\0';
	 ptr = buf;
	 while (isspace(*ptr)) ++ptr;
	 *title = '\0';
	 *textbuf = '\0';
	 strcat(title, ptr);
	 if (index(title , ':')) {
            fprintf(fo, "%s\n", title);
	    *title = '\0';
	 }
      } else {
         if (verbose) fprintf(stderr, "%s", buf);
         if (ptr=strstr(buf, "[Rank_Order]")) {
            char *ptr1 = strdup(buf);
	    char *ptr2 = ptr1+(ptr-buf-1);
	    while (ptr2>=ptr1 && isspace(*ptr2)) --ptr2;
	    ++ptr2;
	    *ptr2 = '\0';
	    strcat(textbuf, ptr1);
	    free(ptr1);
	    ptr1 = ptr2 = strdup(ptr+13);
	    while (isspace(*ptr1)) ++ptr1;
	    strcpy(buf, ptr1);
	    free(ptr2);
	 }
         if (strstr(buf, "This page was last updated")) break;
	 if (strlen(buf)>=skip)	{
            char *ptr1 = strdup(buf+skip);
	    if (index(ptr1, ':'))
	       nice_print(fo, textbuf, 0);
	    strcat(textbuf, ptr1);
	    free(ptr1);
	 }

	 if (*title && index(title, ':')) {
            fprintf(fo, "%s\n", title);
	    *title = '\0';
	 }
	 if (*title && !index(title, ':')) {
	    if (skip) {
               strncpy(line, buf, skip-1);
	       line[skip-1] = '\0';
	       ptr = line+strlen(line)-1;
	    } else
	       ptr = line;
	    while (isspace(*ptr)) --ptr;
	    ++ptr;
	    *ptr = '\0';
	    ptr = line;
	    while(isspace(*ptr)) ++ptr;
	    strcat(title, " ");
	    strcat(title, ptr);
	 }
      }
   }
   if (!found)
      fprintf(stderr, "   Renaming file as %s\n", filename);
   nice_print(fo, textbuf, 0);   
   fprintf(fo, "\n\n<Factbook %d>\n", year);

   fclose(fd);
   fclose(fo);
   return 0;
}
