#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mem.h>
#include <dos.h>
#include <dir.h>

#include "players.h"


#define MAXLINE 140
#define MIN_SPEED 40
#define MIN_RATING 20
#define ASCII_OFF 48
#define HEIGHT_BASE 48
#define WEIGHT_BASE 150


int GetPlayer(FILE *datafile, struct RosterInfo *player);
void GetTeam(FILE *datafile, struct TeamSpec *team);
int GetNextDataLine(FILE *infile,  char buffer[]);
void InsertEmptyPlayer(struct RosterInfo *player);
void GetFNameFromBuffer(char buffer[], struct RosterInfo *player);
void GetLNameFromBuffer(char buffer[], struct RosterInfo *player);
void GetNumberFromBuffer(char buffer[], struct RosterInfo *player);
void GetWeightFromBuffer(char buffer[], struct RosterInfo *player);
void GetHeightFromBuffer(char buffer[], struct RosterInfo *player);
void GetPosFromBuffer(char buffer[], struct RosterInfo *player);
void GetRatingsFromBuffer(char buffer[], struct RosterInfo *player);
short save_team(struct TeamSpec *teamfile);

int total_players;

main (int argc,  char *argv[]) {
	struct TeamSpec team;
	struct ffblk file;
  int done;
	FILE *datafile;
//  int file;

/*  if ( argc != 2 ) {
		puts("SYNTAX: teamconv <filename>");
		exit(0);
	}
	else {
 	   datafile = fopen(argv[1], "rt");
	}

	if ( !datafile ) {
		puts("Error: Unable to open team file");
		exit(0);
	}
*/

  done = findfirst("*.txt", &file, FA_DIREC);
	while ( !done ) {
     if ( (datafile = fopen(file.ff_name, "rt")) == NULL ) {
			printf("Error: Unable to open team file %s", file.ff_name);
			exit(1);
		}

     memset(&team, NULL, sizeof(struct TeamSpec));
     total_players = 0;
     GetTeam(datafile, &team);
     if ( total_players < MAX_PLAYERS ) {
        printf("Warning: Roster contains only %d players \n\n", total_players);
     }
     if (save_team(&team))
        puts("Team file written successfully");
     else
        puts("Error: Unable to write team file");
     fclose(datafile);
		done = findnext(&file);
	}

	return 0;
}


void GetTeam(FILE *datafile, struct TeamSpec *team) {
	int player_index;
  int temp;


	// These scanf commands are DANGEROUS. They are reading integers and inserting them into one byte fields.
	// Therefore, the next byte is always overwritten. This is OK if the fields are read in order.
	fscanf(datafile, "%*s ");
	fgets(team->Description, MAX_DESCRIPTION, datafile);
	fscanf(datafile, "%*s ");
	fgets(team->TeamName, MAX_TEAMNAME, datafile);
	fscanf(datafile, "%*s ");
	fgets(team->CityName, MAX_CITYNAME, datafile);
	fscanf(datafile, "%*s ");
	fgets(team->CoachName, MAX_COACHNAME, datafile);
	fscanf(datafile, "%*s");
	fscanf(datafile, "%d", &team->Year);
	fscanf(datafile, "%*s");
	fscanf(datafile, "%d", &team->Uniform);

	fscanf(datafile, "%*s");
	for ( player_index=0; player_index <= MAX_STARTERS; player_index++ ) {
//     fscanf(datafile, "%d", &team->Starters[player_index]);
     fscanf(datafile, "%d", &temp);
     team->Starters[ player_index ] = -1;
	}
	fscanf(datafile, "%*s %*s");
	for ( player_index=0; player_index < MAX_COACH_RATINGS; player_index++ ) {
		fscanf(datafile, "%d",  &team->CoachRatings[player_index]);
	}
	fscanf(datafile, "%*s %*s");
	for ( player_index=0; player_index < MAX_TEAM_RATINGS; player_index++ ) {
		fscanf(datafile, "%d ", &team->TeamRatings[player_index]);
	}

	team->CtrlZ = '\0';
	team->Version = 8193;
	strcpy(team->Playbook, "default\0\0\0");

	*(strchr(team->Description, '\n')) = '\0';
	*(strchr(team->TeamName, '\n'))    = '\0';
	*(strchr(team->CityName, '\n'))    = '\0';
	*(strchr(team->CoachName, '\n'))   = '\0';

	for (player_index=0; player_index < MAX_PLAYERS; player_index++) {
		total_players += GetPlayer(datafile, &team->Players[player_index]);
	}
}


int GetPlayer(FILE *datafile, struct RosterInfo *player) {
	char buffer[MAXLINE+1];

//	if (!GetNextDataLine(datafile, buffer))	{
//		return 0;
//	}

	if ( !GetNextDataLine(datafile, buffer) ) {
		InsertEmptyPlayer(player);
		return 0;
	}

   GetPosFromBuffer(buffer, player);
	if (player->Position == OPEN_POSITION)
	{
		InsertEmptyPlayer(player);
		return 0;
	}

	GetFNameFromBuffer(buffer, player);
	GetLNameFromBuffer(buffer, player);
	GetNumberFromBuffer(buffer, player);
	GetHeightFromBuffer(buffer, player);
	GetWeightFromBuffer(buffer, player);
	GetRatingsFromBuffer(buffer, player);

	putchar('.');

	return 1;
}


int GetNextDataLine(FILE *infile,  char buffer[]) {
	if (fgets(buffer, MAXLINE+1, infile))	{
		return 1;
	}
	else
		return 0;
}


void InsertEmptyPlayer(struct RosterInfo *player) {
	int rating_index;

	*player->FName = '\0';
	*player->LName = '\0';

	player->Position = OPEN_POSITION;
	player->Number = 0;
	player->Weight = 0;
	player->Height = 0;

	for (rating_index=0; rating_index < 20; rating_index++ )
	{
		player->Rating[rating_index] = 20;
	}
	player->Specialty = 0;
	player->Special_rating = 0;
}

void GetFNameFromBuffer(char buffer[], struct RosterInfo *player) {
  char name[ 20 ];

  memset(name, NULL, 20);
  sscanf(buffer, "%s", name);
  strncpy(player->FName, name, 10);
}


void GetLNameFromBuffer(char buffer[], struct RosterInfo *player) {
  char name[ 30 ];

  memset(name, NULL, 30);
  sscanf(buffer, "%*s %s", name);
  strncpy(player->LName, name, 20);
}


void GetNumberFromBuffer(char buffer[], struct RosterInfo *player) {
	sscanf(buffer, "%*s %*s %*s %i", &player->Number);
}


void GetWeightFromBuffer(char buffer[], struct RosterInfo *player) {
	int true_weight;

	sscanf(buffer, "%*s %*s %*s %*d %d", &true_weight);
	player->Weight = true_weight-WEIGHT_BASE;
}


void GetHeightFromBuffer(char buffer[], struct RosterInfo *player) {
	int feet, inches;
	char unfrmheight[5];      /* Hold value of type 'f-ii' */

	sscanf(buffer, "%*s %*s %*s %*d %*d %s", unfrmheight);
	sscanf(unfrmheight, "%d - %d", &feet, &inches);

	/* Height = # of feet * 12 inches/foot + # of inches */
	player->Height = (feet*12) + inches - HEIGHT_BASE;
}


void GetRatingsFromBuffer(char buffer[], struct RosterInfo *player) {
	int err_chk;
	int ratings[ 20 ];
	int rating_index;
	int specialty, specialty_rating;


	err_chk = sscanf(buffer, "%*s %*s %*s %*d %*d %*s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
	               &ratings[ POS_RATING ], &ratings[ ATHLETIC_ABILITY],
 						&ratings[ FITNESS ], &ratings[ INJURY ],
 						&ratings[ EXPERIENCE ], &ratings[ SPEED ],
                  &ratings[ QUICKNESS ], &ratings[ HANDS ],
 						&ratings[ FUMBLEDEF ], &ratings[ RUSHING ],
 						&ratings[ PASSING ], &ratings[ BLOCK_R ], &ratings[ BLOCK_P ],
						&ratings[ TACKLING ], &ratings[ PASS_RUSH ],
 						&ratings[ FIGHT_BLOCK ], &ratings[ 16 ], &ratings[ 17 ],
 						&ratings[ 18 ], &ratings[ 19 ], &specialty, &specialty_rating);

	for ( rating_index=0; rating_index < 20; rating_index++ ) {
		if ( ratings[ rating_index ] < MIN_RATING ) {
			player->Rating[ rating_index ] = MIN_RATING;
		}
		else {
			player->Rating[ rating_index ] = ratings[ rating_index ];
		}
	}

	player->Specialty = specialty;
	player->Special_rating = specialty_rating;

	if ( player->Rating[ SPEED ] < MIN_SPEED ) {
		player->Rating[ SPEED ] = MIN_SPEED;
	}

	if (err_chk != 22) {
		puts("Error - Unable to complete player rating input for player:");
		puts(player->LName);
		exit(0);
	}
}


void GetPosFromBuffer(char buffer[], struct RosterInfo *player) {
	char pos[5];      /* Player position in string format */

	sscanf(buffer, "%*s %*s %s", pos);
	if (strcmp(pos, "C") == 0)
	{
		player->Position = CENTER;
	}
	else if (strcmp(pos, "OC") == 0)
	{
		player->Position = CENTER;
	}
	else if (strcmp(pos, "OG") == 0)
	{
		player->Position = GUARD;
	}
	else if (strcmp(pos, "OT") == 0)
	{
		player->Position = TACKLE;
	}
	else if (strcmp(pos, "G") == 0)
	{
		player->Position = GUARD;
	}
	else if (strcmp(pos, "T") == 0)
	{
		player->Position = TACKLE;
	}
	else if (strcmp(pos, "TE") == 0)
	{
		player->Position = TIGHTEND;
	}
	else if (strcmp(pos, "QB") == 0)
	{
		player->Position = QUARTERBACK;
	}
	else if (strcmp(pos, "RB") == 0)
	{
		player->Position = RUNNINGBACK;
	}
	else if (strcmp(pos, "FB") == 0)
	{
		player->Position = FULLBACK;
	}
	else if (strcmp(pos, "WR") == 0)
	{
		player->Position = WIDERECEIVER;
	}
	else if (strcmp(pos, "P") == 0)
	{
		player->Position = PUNTER;
	}
	else if (strcmp(pos, "K") == 0)
	{
		player->Position = KICKER;
	}
	else if (strcmp(pos, "PK") == 0)
	{
		player->Position = KICKER;
	}
  else if (strcmp(pos, "P/K") == 0)
	{
		player->Position = KICKER;
	}
	else if (strcmp(pos, "DT") == 0)
	{
		player->Position = DEF_TACKLE;
	}
	else if (strcmp(pos, "DE") == 0)
	{
		player->Position = DEF_END;
	}
	else if (strcmp(pos, "OLB") == 0)
	{
		player->Position = OUTSIDE_LB;
	}
	else if (strcmp(pos, "LB") == 0)
	{
		player->Position = OUTSIDE_LB;
	}
	else if (strcmp(pos, "MLB") == 0)
	{
		player->Position = MIDDLE_LB;
	}
	else if (strcmp(pos, "CB") == 0)
	{
		player->Position = CORNERBACK;
	}
  else if (strcmp(pos, "DB") == 0)
	{
		player->Position = CORNERBACK;
	}
	else if (strcmp(pos, "SS") == 0)
	{
		player->Position = STRONG_SAFETY;
	}
  else if (strcmp(pos, "S") == 0)
	{
		player->Position = STRONG_SAFETY;
	}
	else if (strcmp(pos, "FS") == 0)
	{
		player->Position = FREE_SAFETY;
	}
	else if ( sscanf(buffer, "%s", pos) == 0) {
		player->Position = OPEN_POSITION;
	}
	else if ( strcmp(pos,  "NONE") == 0 )  {
			player->Position = OPEN_POSITION;
	}
	else {
			sscanf(buffer,"%*s %s", player->LName);
		   printf("\nWarning - unspecified position for player: %s\n", player->LName);
			printf("Blank player inserted\n\n");
			player->Position = OPEN_POSITION;
	}
}


short save_team(struct TeamSpec *teamfile) {
	int file,  err = -1;
	char teamname[_MAX_PATH];

	_makepath(teamname, NULL, ".", teamfile->TeamName, "tmn");
	if ((file = open(teamname,  O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,
	                 S_IREAD|S_IWRITE) ) != -1) {
		if ( write(file,  teamfile,  sizeof(struct TeamSpec)) ==
		     sizeof(struct TeamSpec) )
			err = 1;

		close(file);
	}

	return (err);
}
